Merge remote-tracking branch 'origin/main'

This commit is contained in:
漂泊 2025-12-09 18:17:53 +08:00
commit c043e2c845
10 changed files with 578 additions and 45 deletions

View File

@ -13,7 +13,9 @@ import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 羊只档案Controller
@ -32,23 +34,155 @@ public class SheepFileController extends BaseController
* 查询羊只档案列表
*/
@PreAuthorize("@ss.hasPermi('sheep_file:sheep_file:list')")
@GetMapping("/list")
public TableDataInfo list(SheepFile sheepFile)
@PostMapping("/list") // 改为 POST 请求
public TableDataInfo list(@RequestBody(required = false) Map<String, Object> queryParams)
{
startPage();
List<SheepFile> list = sheepFileService.selectSheepFileList(sheepFile);
// 解析查询参数
SheepFile sheepFile = new SheepFile();
Map<String, Object> customParams = new HashMap<>();
if (queryParams != null && !queryParams.isEmpty()) {
// 提取常规查询参数到 SheepFile 对象
if (queryParams.containsKey("bsManageTags") && queryParams.get("bsManageTags") != null) {
sheepFile.setBsManageTags(queryParams.get("bsManageTags").toString());
}
if (queryParams.containsKey("electronicTags") && queryParams.get("electronicTags") != null) {
sheepFile.setElectronicTags(queryParams.get("electronicTags").toString());
}
if (queryParams.containsKey("drRanch") && queryParams.get("drRanch") != null) {
sheepFile.setDrRanch(queryParams.get("drRanch").toString());
}
if (queryParams.containsKey("variety") && queryParams.get("variety") != null) {
sheepFile.setVariety(queryParams.get("variety").toString());
}
if (queryParams.containsKey("name") && queryParams.get("name") != null) {
sheepFile.setName(queryParams.get("name").toString());
}
if (queryParams.containsKey("gender") && queryParams.get("gender") != null) {
sheepFile.setGender(convertToLong(queryParams.get("gender")));
}
if (queryParams.containsKey("statusId") && queryParams.get("statusId") != null) {
sheepFile.setStatusId(convertToLong(queryParams.get("statusId")));
}
if (queryParams.containsKey("breed") && queryParams.get("breed") != null) {
sheepFile.setBreed(queryParams.get("breed").toString());
}
// 移除已经处理的参数剩下的作为自定义筛选参数
// 注意不直接修改原参数而是复制到新Map中
for (Map.Entry<String, Object> entry : queryParams.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
// 跳过常规参数
if ("bsManageTags".equals(key) || "electronicTags".equals(key) ||
"drRanch".equals(key) || "variety".equals(key) ||
"name".equals(key) || "gender".equals(key) ||
"statusId".equals(key) || "breed".equals(key) ||
"pageNum".equals(key) || "pageSize".equals(key)) {
continue;
}
// 添加到自定义参数中
if (value != null) {
customParams.put(key, value);
}
}
}
startPage(); // 分页处理
// 调用支持复杂查询的Service方法
List<SheepFile> list = sheepFileService.selectSheepFileListByCondition(customParams, sheepFile);
return getDataTable(list);
}
/**
* 转换对象为Long类型
*/
private Long convertToLong(Object obj) {
if (obj == null) {
return null;
}
if (obj instanceof Long) {
return (Long) obj;
}
if (obj instanceof Integer) {
return ((Integer) obj).longValue();
}
if (obj instanceof String) {
try {
return Long.parseLong((String) obj);
} catch (NumberFormatException e) {
return null;
}
}
return null;
}
/**
* 导出羊只档案列表
*/
@PreAuthorize("@ss.hasPermi('sheep_file:sheep_file:export')")
@Log(title = "羊只档案", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, SheepFile sheepFile)
@PostMapping("/export") // 改为 POST 请求
public void export(HttpServletResponse response, @RequestBody(required = false) Map<String, Object> queryParams)
{
List<SheepFile> list = sheepFileService.selectSheepFileList(sheepFile);
// 解析查询参数
SheepFile sheepFile = new SheepFile();
Map<String, Object> customParams = new HashMap<>();
if (queryParams != null && !queryParams.isEmpty()) {
// 提取常规查询参数到 SheepFile 对象
if (queryParams.containsKey("bsManageTags") && queryParams.get("bsManageTags") != null) {
sheepFile.setBsManageTags(queryParams.get("bsManageTags").toString());
}
if (queryParams.containsKey("electronicTags") && queryParams.get("electronicTags") != null) {
sheepFile.setElectronicTags(queryParams.get("electronicTags").toString());
}
if (queryParams.containsKey("drRanch") && queryParams.get("drRanch") != null) {
sheepFile.setDrRanch(queryParams.get("drRanch").toString());
}
if (queryParams.containsKey("variety") && queryParams.get("variety") != null) {
sheepFile.setVariety(queryParams.get("variety").toString());
}
if (queryParams.containsKey("name") && queryParams.get("name") != null) {
sheepFile.setName(queryParams.get("name").toString());
}
if (queryParams.containsKey("gender") && queryParams.get("gender") != null) {
sheepFile.setGender(convertToLong(queryParams.get("gender")));
}
if (queryParams.containsKey("statusId") && queryParams.get("statusId") != null) {
sheepFile.setStatusId(convertToLong(queryParams.get("statusId")));
}
if (queryParams.containsKey("breed") && queryParams.get("breed") != null) {
sheepFile.setBreed(queryParams.get("breed").toString());
}
// 提取自定义筛选参数
for (Map.Entry<String, Object> entry : queryParams.entrySet()) {
String key = entry.getKey();
Object value = entry.getValue();
// 跳过常规参数和分页参数
if ("bsManageTags".equals(key) || "electronicTags".equals(key) ||
"drRanch".equals(key) || "variety".equals(key) ||
"name".equals(key) || "gender".equals(key) ||
"statusId".equals(key) || "breed".equals(key) ||
"pageNum".equals(key) || "pageSize".equals(key)) {
continue;
}
// 添加到自定义参数中
if (value != null) {
customParams.put(key, value);
}
}
}
// 调用支持复杂查询的Service方法获取数据不分页
List<SheepFile> list = sheepFileService.selectSheepFileListByCondition(customParams, sheepFile);
ExcelUtil<SheepFile> util = new ExcelUtil<SheepFile>(SheepFile.class);
util.exportExcel(response, list, "羊只档案数据");
}
@ -99,4 +233,45 @@ public class SheepFileController extends BaseController
return success(sheepFileService.countInGroup());
}
/**
* 新增API获取字段的唯一值列表
*
* 这个API为前端自定义筛选功能提供数据支持
* 当用户选择某个字段进行筛选时前端调用此接口获取该字段的所有可能值
*
* @param fieldName 字段名数据库列名
* @return AjaxResult 包含字段值列表的响应结果
*
* 接口地址GET /sheep_file/sheep_file/field/{fieldName}
*
* 使用示例
* 前端请求GET /sheep_file/sheep_file/field/bs_manage_tags
* 后端返回{ "code": 200, "msg": "操作成功", "data": ["AF00001", "AF00002", "AF00003"] }
*
* 安全说明
* - 使用白名单机制防止SQL注入
* - 只有预定义的字段名可以被查询
*/
@GetMapping("/field/{fieldName}")
public AjaxResult getFieldValues(@PathVariable String fieldName) {
try {
// 调用Service层获取字段唯一值
List<String> fieldValues = sheepFileService.getFieldValues(fieldName);
// 返回成功响应包含字段值列表
return AjaxResult.success("获取字段值成功", fieldValues);
} catch (IllegalArgumentException e) {
// 处理字段名不合法的异常
// 这种情况通常是因为前端传入了不在白名单中的字段名
return AjaxResult.error("请求的字段名不合法: " + e.getMessage());
} catch (Exception e) {
// 处理其他未知异常
// 记录日志并返回友好的错误信息
logger.error("获取字段值失败,字段名: " + fieldName, e);
return AjaxResult.error("系统错误,获取字段值失败");
}
}
}

View File

@ -101,11 +101,20 @@ public class SheepFile extends BaseEntity
/** 断奶体重 */
@Excel(name = "断奶体重")
private Long weaningWeight;
private Double weaningWeight;
/** 当前体重 */
@Excel(name = "当前体重")
private Long currentWeight;
private Double currentWeight;
/** 断奶日龄 */
@Excel(name = "断奶日龄")
private Long weaningDayAge;
/** 断奶日增重 */
@Excel(name = "断奶日增重")
private Double weaningDailyGain;
/** 繁育状态id */
@Excel(name = "繁育状态id")

View File

@ -2,6 +2,7 @@ package com.zhyc.module.base.mapper;
import com.zhyc.module.base.domain.SheepFile;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
import java.util.Map;
@ -58,6 +59,32 @@ public interface SheepFileMapper
List<Map<String,Object>> countParityOfLactation();
/**
* 新增方法获取指定字段的唯一值列表
*
* 这个方法用于查询数据库中某个字段的所有不重复的值
* 主要用于前端筛选条件中的下拉选项数据
*
* @param fieldName 字段名数据库表中的列名
* @return 该字段的所有唯一值列表按字母顺序排序
*
* 使用场景示例
* - 用户选择"耳号"字段时返回所有不重复的耳号
* - 用户选择"品种"字段时返回所有不重复的品种名称
*/
List<String> selectFieldValues(String fieldName);
/**
* 根据复杂条件查询羊只档案列表
*
* @param params 查询参数映射
* @param sheepFile 原有的查询条件保持兼容
* @return 羊只档案列表
*/
List<SheepFile> selectSheepFileListByCondition(
@Param("params") Map<String, Object> params,
@Param("sheepFile") SheepFile sheepFile
);
}

View File

@ -38,4 +38,32 @@ public interface ISheepFileService
List<Map<String,Object>> countByBreedStatus();
List<Map<String,Object>> countByVariety();
List<Map<String,Object>> countParityOfLactation();
/**
* 新增方法获取指定字段的唯一值列表
*
* 这个方法为前端筛选功能提供数据支持
* 当用户选择某个字段进行筛选时调用此方法获取该字段的所有可能值
*
* @param fieldName 字段名需要是数据库表中的列名
* @return 该字段的所有唯一值列表
* @throws IllegalArgumentException 当字段名不在白名单中时抛出异常
*
* 示例用法
* List<String> earTags = getFieldValues("bs_manage_tags");
* // 返回结果可能是["AF00001", "AF00002", "AF00003", ...]
*/
List<String> getFieldValues(String fieldName);
/**
* 根据复杂条件查询羊只档案列表
*
* @param params 查询参数映射
* @param sheepFile 原有的查询条件
* @return 羊只档案列表
*/
List<SheepFile> selectSheepFileListByCondition(
Map<String, Object> params,
SheepFile sheepFile
);
}

View File

@ -6,6 +6,7 @@ import com.zhyc.module.base.service.ISheepFileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.List;import java.util.Map;
/**
@ -69,5 +70,141 @@ public class SheepFileServiceImpl implements ISheepFileService {
@Override
public Long countInGroup() { return sheepFileMapper.countInGroup(); }
/**
* 获取指定字段的唯一值列表
*
* 这个方法实现了获取字段唯一值的核心逻辑
* 包含安全验证和业务处理
*
* @param fieldName 字段名
* @return 该字段的所有唯一值列表
* @throws IllegalArgumentException 当字段名不在白名单中时抛出异常
*/
@Override
public List<String> getFieldValues(String fieldName) {
// 第一步安全性验证 - 防止SQL注入攻击
// 只允许预定义的字段名确保查询的安全性
if (!isValidFieldName(fieldName)) {
// 如果字段名不在白名单中抛出异常并记录日志
throw new IllegalArgumentException("非法的字段名: " + fieldName + ",请检查字段名是否正确");
}
// 第二步调用Mapper层执行数据库查询
// 这里会执行类似 SELECT DISTINCT fieldName FROM sheep_file 的SQL
List<String> fieldValues = sheepFileMapper.selectFieldValues(fieldName);
// 第三步返回查询结果
return fieldValues;
}
@Override
public List<SheepFile> selectSheepFileListByCondition(Map<String, Object> params, SheepFile sheepFile) {
// 验证参数中的字段名防止SQL注入
if (params != null && !params.isEmpty()) {
Map<String, Object> safeParams = new HashMap<>();
for (Map.Entry<String, Object> entry : params.entrySet()) {
String fieldName = entry.getKey();
Object value = entry.getValue();
// 将前端字段名转换为数据库字段名
String dbFieldName = convertToDbFieldName(fieldName);
// 验证字段名是否安全使用白名单
if (isValidFieldName(dbFieldName)) {
safeParams.put(dbFieldName, value);
} else {
// 记录日志或抛出异常
System.out.println("警告:忽略非法字段名: " + fieldName);
}
}
return sheepFileMapper.selectSheepFileListByCondition(safeParams, sheepFile);
}
// 如果没有额外参数使用原有的查询方法
return sheepFileMapper.selectSheepFileList(sheepFile);
}
/**
* 将前端字段名转换为数据库字段名
*/
private String convertToDbFieldName(String fieldName) {
// 将驼峰命名转换为下划线命名
String result = fieldName.replaceAll("([a-z])([A-Z])", "$1_$2").toLowerCase();
return result;
}
/**
* 扩展字段名白名单验证
*/
private boolean isValidFieldName(String fieldName) {
// 扩展允许查询的字段白名单
String[] allowedFields = {
"id",
"bs_manage_tags", // 管理耳号
"electronic_tags", // 电子耳号
"dr_ranch", // 牧场名称
"sheepfold_name", // 羊舍名称
"variety", // 品种
"family", // 家系
"name", // 羊只类型
"gender", // 性别
"birthday", // 出生日期
"day_age", // 日龄
"month_age", // 月龄
"parity", // 胎次
"birth_weight", // 出生体重
"weaning_date", // 断奶日期
"status_id", // 羊只状态
"weaning_weight", // 断奶体重
"current_weight", // 当前体重
"weaning_day_age", // 断奶日龄
"weaning_daily_gain", // 断奶日增重
"breed", // 繁殖状态
"father_manage_tags", // 父亲耳号
"mother_manage_tags", // 母亲耳号
"receptor_manage_tags", // 受体耳号
"grandfather_manage_tags", // 祖父耳号
"grandmother_manage_tags", // 祖母耳号
"maternal_grandfather_manage_tags", // 外祖父耳号
"maternal_grandmother_manage_tags", // 外祖母耳号
"mating_date", // 配种日期
"mating_type_id", // 配种类型
"preg_date", // 孕检日期
"lambing_date", // 产羔日期
"lambing_day", // 产羔时怀孕天数
"mating_day", // 配后天数
"gestation_day", // 怀孕天数
"expected_date", // 预产日期
"post_lambing_day", // 产后天数
"lactation_day", // 泌乳天数
"anestrous_day", // 空怀天数
"mating_counts", // 配种次数
"mating_total", // 累计配种次数
"miscarriage_counts", // 累计流产次数
"comment", // 备注
"controlled", // 是否性控
"body", // 体况评分
"breast", // 乳房评分
"source", // 入群来源
"source_date", // 入群日期
"source_ranch", // 来源牧场
"update_by", // 修改人
"update_time", // 修改日期
"create_by", // 创建人
"create_time" // 创建日期
};
for (String allowedField : allowedFields) {
if (allowedField.equals(fieldName)) {
return true;
}
}
return false;
}
}

View File

@ -6,6 +6,7 @@ import javax.servlet.http.HttpServletResponse;
import com.zhyc.common.utils.SecurityUtils;
import com.zhyc.common.utils.StringUtils;
import com.zhyc.module.frozen.mapper.DdFeMapper;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
@ -26,18 +27,18 @@ import com.zhyc.common.core.page.TableDataInfo;
*/
@RestController
@RequestMapping("/frozen/embryo")
public class DdFeController extends BaseController
{
public class DdFeController extends BaseController {
@Autowired
private IDdFeService ddFeService;
@Autowired
private DdFeMapper ddFeMapper;
/**
* 查询冻胚库存列表
*/
@PreAuthorize("@ss.hasPermi('frozen:embryo:list')")
@GetMapping("/list")
public TableDataInfo list(DdFe ddFe)
{
public TableDataInfo list(DdFe ddFe) {
startPage();
List<DdFe> list = ddFeService.selectDdFeList(ddFe);
return getDataTable(list);
@ -49,8 +50,7 @@ public class DdFeController extends BaseController
@PreAuthorize("@ss.hasPermi('frozen:embryo:export')")
@Log(title = "冻胚库存", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, DdFe ddFe)
{
public void export(HttpServletResponse response, DdFe ddFe) {
List<DdFe> list = ddFeService.selectDdFeList(ddFe);
ExcelUtil<DdFe> util = new ExcelUtil<DdFe>(DdFe.class);
util.exportExcel(response, list, "冻胚库存数据");
@ -61,8 +61,7 @@ public class DdFeController extends BaseController
*/
@PreAuthorize("@ss.hasPermi('frozen:embryo:query')")
@GetMapping(value = "/{id}")
public AjaxResult getInfo(@PathVariable("id") Long id)
{
public AjaxResult getInfo(@PathVariable("id") Long id) {
return success(ddFeService.selectDdFeById(id));
}
@ -72,8 +71,7 @@ public class DdFeController extends BaseController
@PreAuthorize("@ss.hasPermi('frozen:embryo:add')")
@Log(title = "冻胚库存", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody DdFe ddFe)
{
public AjaxResult add(@RequestBody DdFe ddFe) {
ddFe.setCreateBy(SecurityUtils.getUsername());
return toAjax(ddFeService.insertDdFe(ddFe));
}
@ -84,8 +82,7 @@ public class DdFeController extends BaseController
@PreAuthorize("@ss.hasPermi('frozen:embryo:edit')")
@Log(title = "冻胚库存", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody DdFe ddFe)
{
public AjaxResult edit(@RequestBody DdFe ddFe) {
return toAjax(ddFeService.updateDdFe(ddFe));
}
@ -95,8 +92,7 @@ public class DdFeController extends BaseController
@PreAuthorize("@ss.hasPermi('frozen:embryo:remove')")
@Log(title = "冻胚库存", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids)
{
public AjaxResult remove(@PathVariable Long[] ids) {
return toAjax(ddFeService.deleteDdFeByIds(ids));
}
@ -126,13 +122,26 @@ public class DdFeController extends BaseController
Integer qty;
switch (grade) {
case "A": qty = (Integer) flush.getOrDefault("gradeA", 0); break;
case "B": qty = (Integer) flush.getOrDefault("gradeB", 0); break;
case "C": qty = (Integer) flush.getOrDefault("gradeC", 0); break;
case "D": qty = (Integer) flush.getOrDefault("gradeD", 0); break;
case "囊胚": qty = (Integer) flush.getOrDefault("cell24", 0); break;
case "桑椹胚": qty = (Integer) flush.getOrDefault("cell8", 0); break;
default: qty = 0;
case "A":
qty = (Integer) flush.getOrDefault("gradeA", 0);
break;
case "B":
qty = (Integer) flush.getOrDefault("gradeB", 0);
break;
case "C":
qty = (Integer) flush.getOrDefault("gradeC", 0);
break;
case "D":
qty = (Integer) flush.getOrDefault("gradeD", 0);
break;
case "囊胚":
qty = (Integer) flush.getOrDefault("cell24", 0);
break;
case "桑椹胚":
qty = (Integer) flush.getOrDefault("cell8", 0);
break;
default:
qty = 0;
}
return success(qty);
}
@ -153,4 +162,10 @@ public class DdFeController extends BaseController
});
return success();
}
// 唯一性校验
@GetMapping("/checkCode")
public AjaxResult exist(@RequestParam String code) {
return success(ddFeMapper.existsByCode(code) > 0);
}
}

View File

@ -72,4 +72,6 @@ public interface DdFeMapper
* 废弃更新只改状态出库日期废弃原因更新人
*/
int updateDiscard(DdFe dto);
// 唯一性校验
int existsByCode(@Param("code") String code);
}

View File

@ -4,6 +4,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.zhyc.common.exception.ServiceException;
import com.zhyc.common.utils.DateUtils;
import com.zhyc.common.utils.StringUtils;
import com.zhyc.module.produce.breed.domain.ScEmbryoFlush;
@ -65,6 +66,9 @@ public class DdFeServiceImpl implements IDdFeService
@Override
public int insertDdFe(DdFe ddFe)
{
if (ddFeMapper.existsByCode(ddFe.getCode()) > 0) {
throw new ServiceException("胚胎编号已存在,请勿重复录入");
}
ddFe.setCreateTime(DateUtils.getNowDate());
return ddFeMapper.insertDdFe(ddFe);
}

View File

@ -26,6 +26,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="statusId" column="status_id" />
<result property="weaningWeight" column="weaning_weight" />
<result property="currentWeight" column="current_weight" />
<result property="weaningDayAge" column="weaning_day_age" />
<result property="weaningDailyGain" column="weaning_daily_gain" />
<result property="breedStatusId" column="breed_status_id" />
<result property="breed" column="breed" />
<result property="bsFatherId" column="bs_father_id" />
@ -72,7 +74,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</resultMap>
<sql id="selectSheepFileVo">
select id, bs_manage_tags, ranch_id, dr_ranch, sheepfold_id, sheepfold_name, electronic_tags, variety_id, variety, family, name, gender, birthday, day_age, month_age, parity, birth_weight, weaning_date, status_id, weaning_weight, current_weight, breed_status_id, breed, bs_father_id, father_manage_tags, bs_mother_id, mother_manage_tags, receptor_id, receptor_manage_tags, father_father_id, grandfather_manage_tags, father_mother_id, grandmother_manage_tags, father_id, maternal_grandfather_manage_tags, mother_id, maternal_grandmother_manage_tags, mating_date, mating_type_id, preg_date, lambing_date, lambing_day, mating_day, gestation_day, expected_date, post_lambing_day, lactation_day, anestrous_day, mating_counts, mating_total, miscarriage_counts, comment, controlled, body, breast, source, source_date, source_ranch_id, source_ranch, update_by, update_time, create_by, create_time, is_delete from sheep_file
select id, bs_manage_tags, ranch_id, dr_ranch, sheepfold_id, sheepfold_name, electronic_tags, variety_id, variety, family, name, gender, birthday, day_age, month_age, parity, birth_weight, weaning_date, status_id, weaning_weight, current_weight,weaning_day_age,weaning_daily_gain,breed_status_id, breed, bs_father_id, father_manage_tags, bs_mother_id, mother_manage_tags, receptor_id, receptor_manage_tags, father_father_id, grandfather_manage_tags, father_mother_id, grandmother_manage_tags, father_id, maternal_grandfather_manage_tags, mother_id, maternal_grandmother_manage_tags, mating_date, mating_type_id, preg_date, lambing_date, lambing_day, mating_day, gestation_day, expected_date, post_lambing_day, lactation_day, anestrous_day, mating_counts, mating_total, miscarriage_counts, comment, controlled, body, breast, source, source_date, source_ranch_id, source_ranch, update_by, update_time, create_by, create_time, is_delete from sheep_file
</sql>
<select id="selectSheepFileList" parameterType="SheepFile" resultMap="SheepFileResult">
@ -139,5 +141,134 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
ORDER BY parity
</select>
<!--
获取字段唯一值的SQL映射
说明:这个查询使用 ${fieldName} 直接拼接字段名因为MyBatis的#{}不支持列名作为参数
安全性通过Service层的白名单验证来确保fieldName的安全性
-->
<select id="selectFieldValues" parameterType="String" resultType="String">
SELECT
DISTINCT ${fieldName} as field_value
FROM
sheep_file
WHERE
<!-- 过滤空值和NULL值确保返回的数据质量 -->
${fieldName} IS NOT NULL
AND ${fieldName} != ''
AND ${fieldName} != 'null'
ORDER BY
<!-- 按字母顺序排序,方便前端显示 -->
${fieldName} ASC
</select>
<select id="selectSheepFileListByCondition" parameterType="map" resultMap="SheepFileResult">
<include refid="selectSheepFileVo"/>
FROM sheep_file
<where>
<!-- 逻辑删除过滤 -->
AND is_delete = 0
<!-- 原有的 SheepFile 条件(保持兼容性) -->
<if test="sheepFile != null">
<if test="sheepFile.bsManageTags != null and sheepFile.bsManageTags != ''">
AND bs_manage_tags LIKE CONCAT('%', #{sheepFile.bsManageTags}, '%')
</if>
<if test="sheepFile.electronicTags != null and sheepFile.electronicTags != ''">
AND electronic_tags LIKE CONCAT('%', #{sheepFile.electronicTags}, '%')
</if>
<if test="sheepFile.drRanch != null and sheepFile.drRanch != ''">
AND dr_ranch LIKE CONCAT('%', #{sheepFile.drRanch}, '%')
</if>
<if test="sheepFile.variety != null and sheepFile.variety != ''">
AND variety LIKE CONCAT('%', #{sheepFile.variety}, '%')
</if>
<if test="sheepFile.name != null and sheepFile.name != ''">
AND name LIKE CONCAT('%', #{sheepFile.name}, '%')
</if>
<if test="sheepFile.gender != null">
AND gender = #{sheepFile.gender}
</if>
<if test="sheepFile.statusId != null">
AND status_id = #{sheepFile.statusId}
</if>
<if test="sheepFile.breed != null and sheepFile.breed != ''">
AND breed LIKE CONCAT('%', #{sheepFile.breed}, '%')
</if>
</if>
<!-- 动态条件处理 - 使用多个if标签代替复杂的choose -->
<if test="params != null and !params.isEmpty()">
<!-- 空值条件 -->
<foreach collection="params.entrySet()" item="value" index="key">
<if test="value == 'IS_NULL'">
AND ${key} IS NULL
</if>
<if test="value == 'NOT_NULL'">
AND ${key} IS NOT NULL
</if>
</foreach>
<!-- 范围条件 -->
<foreach collection="params.entrySet()" item="value" index="key">
<if test="value != null and value.toString().startsWith('GT:')">
AND ${key} &gt; #{value.toString().substring(3)}
</if>
<if test="value != null and value.toString().startsWith('LT:')">
AND ${key} &lt; #{value.toString().substring(3)}
</if>
<if test="value != null and value.toString().startsWith('GE:')">
AND ${key} &gt;= #{value.toString().substring(3)}
</if>
<if test="value != null and value.toString().startsWith('LE:')">
AND ${key} &lt;= #{value.toString().substring(3)}
</if>
</foreach>
<!-- 列表条件 -->
<foreach collection="params.entrySet()" item="value" index="key">
<if test="value != null and value.toString().contains(',')">
AND ${key} IN
<foreach collection="value.toString().split(',')" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</if>
</foreach>
<!-- 模糊查询条件(针对文本字段) -->
<foreach collection="params.entrySet()" item="value" index="key">
<if test="value != null and
(key == 'bs_manage_tags' or key == 'electronic_tags' or
key == 'dr_ranch' or key == 'sheepfold_name' or
key == 'variety' or key == 'family' or
key == 'name' or key == 'breed' or
key == 'father_manage_tags' or key == 'mother_manage_tags' or
key == 'receptor_manage_tags') and
value != 'IS_NULL' and value != 'NOT_NULL' and
!value.toString().startsWith('GT:') and !value.toString().startsWith('LT:') and
!value.toString().startsWith('GE:') and !value.toString().startsWith('LE:') and
!value.toString().contains(',')">
AND ${key} LIKE CONCAT('%', #{value}, '%')
</if>
</foreach>
<!-- 普通等于条件 -->
<foreach collection="params.entrySet()" item="value" index="key">
<if test="value != null and
value != 'IS_NULL' and value != 'NOT_NULL' and
!value.toString().startsWith('GT:') and !value.toString().startsWith('LT:') and
!value.toString().startsWith('GE:') and !value.toString().startsWith('LE:') and
!value.toString().contains(',') and
!(key == 'bs_manage_tags' or key == 'electronic_tags' or
key == 'dr_ranch' or key == 'sheepfold_name' or
key == 'variety' or key == 'family' or
key == 'name' or key == 'breed' or
key == 'father_manage_tags' or key == 'mother_manage_tags' or
key == 'receptor_manage_tags')">
AND ${key} = #{value}
</if>
</foreach>
</if>
</where>
ORDER BY id DESC
</select>
</mapper>

View File

@ -59,8 +59,10 @@
<if test="code != null and code != ''">and code like concat('%', #{code}, '%')</if>
<if test="grade != null and grade != ''">and grade = #{grade}</if>
<if test="status != null and status != ''">and status = #{status}</if>
<if test="tech != null and tech != ''">and tech = #{tech}</if>
<if test="outDate != null "> and out_date = #{outDate}</if>
<if test="tech != null and tech != ''">
AND tech LIKE CONCAT('%', #{tech}, '%')
</if>
<if test="outDate != null ">and out_date = #{outDate}</if>
<if test="params.beginFreezeDate != null and params.endFreezeDate != null">
and freeze_date between #{params.beginFreezeDate} and #{params.endFreezeDate}
</if>
@ -173,8 +175,7 @@
donor_male_no ramId
FROM sc_embryo_flush
WHERE donor_female_no = #{eweNo}
ORDER BY flush_time DESC
LIMIT 1
ORDER BY flush_time DESC LIMIT 1
</select>
<update id="updateDiscard" parameterType="DdFe">
@ -183,4 +184,8 @@
discard_txt = #{discardTxt}
WHERE id = #{id}
</update>
<select id="existsByCode" resultType="int">
SELECT COUNT(*) FROM dd_fe WHERE code = #{code}
</select>
</mapper>