更新了配种计划和配种记录

This commit is contained in:
zyk 2025-08-19 00:18:10 +08:00
parent 98ae137a33
commit 8bc26605e0
11 changed files with 985 additions and 95 deletions

View File

@ -3,6 +3,7 @@ package com.zhyc.module.produce.breed.controller;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse;
import com.zhyc.module.produce.breed.domain.ScBreedPlanGenerate;
import com.zhyc.module.produce.breed.service.IScBreedPlanGenerateService;
@ -21,6 +22,7 @@ import com.zhyc.common.core.controller.BaseController;
import com.zhyc.common.core.domain.AjaxResult;
import com.zhyc.common.enums.BusinessType;
import com.zhyc.common.core.page.TableDataInfo;
import com.zhyc.common.utils.poi.ExcelUtil;
/**
* 配种计划生成Controller
@ -78,6 +80,12 @@ public class ScBreedPlanGenerateController extends BaseController
public AjaxResult autoGenerateBreedPlan(@RequestBody Map<String, Object> params)
{
try {
// 获取计划类型
Integer planType = params.get("planType") != null ? (Integer) params.get("planType") : 1;
// 计划名称由系统自动生成不再从前端传入
String planName = null;
// 安全的类型转换
List<?> eweIdsRaw = (List<?>) params.get("eweIds");
List<?> ramIdsRaw = (List<?>) params.get("ramIds");
@ -110,7 +118,7 @@ public class ScBreedPlanGenerateController extends BaseController
})
.collect(Collectors.toList());
ScBreedPlanGenerate planGenerate = scBreedPlanGenerateService.autoGenerateBreedPlan(eweIds, ramIds);
ScBreedPlanGenerate planGenerate = scBreedPlanGenerateService.autoGenerateBreedPlan(planType, planName, eweIds, ramIds);
return success(planGenerate);
} catch (Exception e) {
logger.error("自动生成配种计划失败", e);
@ -151,14 +159,38 @@ public class ScBreedPlanGenerateController extends BaseController
}
/**
* 审批配种计划
* 获取审批配种计划详情
*/
@PreAuthorize("@ss.hasPermi('mating_plan:generate:approve')")
@Log(title = "审批配种计划", businessType = BusinessType.UPDATE)
@PutMapping("/approve/{id}")
public AjaxResult approve(@PathVariable Long id)
@GetMapping("/approve/{id}")
public AjaxResult getApproveInfo(@PathVariable Long id)
{
return toAjax(scBreedPlanGenerateService.approveBreedPlan(id));
Map<String, Object> approveDetails = scBreedPlanGenerateService.getApproveBreedPlanDetails(id);
return success(approveDetails);
}
/**
* 确认审批配种计划
*/
@PreAuthorize("@ss.hasPermi('mating_plan:generate:approve')")
@Log(title = "确认审批配种计划", businessType = BusinessType.UPDATE)
@PutMapping("/approve/confirm")
public AjaxResult confirmApprove(@RequestBody Map<String, Object> params)
{
try {
Long planId = Long.valueOf(params.get("planId").toString());
Integer status = Integer.valueOf(params.get("status").toString());
String approveRemark = params.get("approveRemark") != null ? params.get("approveRemark").toString() : "";
@SuppressWarnings("unchecked")
List<Map<String, Object>> planDetails = (List<Map<String, Object>>) params.get("planDetails");
int result = scBreedPlanGenerateService.confirmApproveBreedPlan(planId, planDetails, status, approveRemark);
return toAjax(result);
} catch (Exception e) {
logger.error("确认审批配种计划失败", e);
return error("确认审批配种计划失败:" + e.getMessage());
}
}
/**
@ -172,6 +204,41 @@ public class ScBreedPlanGenerateController extends BaseController
return success(planDetails);
}
/**
* 导出配种计划列表
*/
@PreAuthorize("@ss.hasPermi('mating_plan:generate:export')")
@Log(title = "导出配种计划列表", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, ScBreedPlanGenerate scBreedPlanGenerate)
{
List<ScBreedPlanGenerate> list = scBreedPlanGenerateService.selectScBreedPlanGenerateList(scBreedPlanGenerate);
ExcelUtil<ScBreedPlanGenerate> util = new ExcelUtil<ScBreedPlanGenerate>(ScBreedPlanGenerate.class);
util.exportExcel(response, list, "配种计划生成数据");
}
/**
* 导出配种计划详情
*/
@PreAuthorize("@ss.hasPermi('mating_plan:generate:export')")
@Log(title = "导出配种计划详情", businessType = BusinessType.EXPORT)
@PostMapping("/export/{id}")
public void exportBreedPlanDetails(HttpServletResponse response, @PathVariable Long id)
{
try {
scBreedPlanGenerateService.exportBreedPlanDetails(response, id);
} catch (Exception e) {
logger.error("导出配种计划详情失败", e);
// 在出错时返回错误信息给前端
try {
response.setContentType("application/json;charset=utf-8");
response.getWriter().write("{\"code\":500,\"msg\":\"导出失败:" + e.getMessage() + "\"}");
} catch (Exception ex) {
logger.error("返回错误信息失败", ex);
}
}
}
/**
* 删除配种计划生成
*/

View File

@ -1,6 +1,7 @@
package com.zhyc.module.produce.breed.controller;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
@ -76,7 +77,11 @@ public class ScBreedRecordController extends BaseController
@GetMapping(value = "/getSheepByTags/{manageTags}")
public AjaxResult getSheepInfoByTags(@PathVariable("manageTags") String manageTags)
{
return success(scBreedRecordService.getSheepInfoByTags(manageTags));
Map<String, Object> sheepInfo = scBreedRecordService.getSheepInfoByTags(manageTags);
if (sheepInfo == null || sheepInfo.isEmpty()) {
return error("未找到耳号为 " + manageTags + " 的羊只信息");
}
return success(sheepInfo);
}
/**
@ -86,7 +91,25 @@ public class ScBreedRecordController extends BaseController
@GetMapping(value = "/getBreedPlan/{manageTags}")
public AjaxResult getBreedPlanByEweTags(@PathVariable("manageTags") String manageTags)
{
return success(scBreedRecordService.getBreedPlanByEweTags(manageTags));
Map<String, Object> breedPlan = scBreedRecordService.getBreedPlanByEweTags(manageTags);
if (breedPlan == null || breedPlan.isEmpty()) {
return error("未找到耳号为 " + manageTags + " 的母羊配种计划");
}
return success(breedPlan);
}
/**
* 根据母羊耳号获取最新配种计划信息优先从配种计划生成表获取
*/
@PreAuthorize("@ss.hasPermi('Breeding_records:Breeding_records:query')")
@GetMapping(value = "/getLatestBreedPlan/{manageTags}")
public AjaxResult getLatestBreedPlanByEweTags(@PathVariable("manageTags") String manageTags)
{
Map<String, Object> breedPlan = scBreedRecordService.getLatestBreedPlanByEweTags(manageTags);
if (breedPlan == null || breedPlan.isEmpty()) {
return error("未找到耳号为 " + manageTags + " 的母羊配种计划");
}
return success(breedPlan);
}
/**
@ -97,24 +120,43 @@ public class ScBreedRecordController extends BaseController
@PostMapping
public AjaxResult add(@RequestBody ScBreedRecord scBreedRecord)
{
// 如果传入的是耳号需要转换为羊只ID
// 处理母羊耳号转换
if (scBreedRecord.getEweManageTags() != null && !scBreedRecord.getEweManageTags().isEmpty()) {
Long eweId = scBreedRecordService.getSheepIdByTags(scBreedRecord.getEweManageTags());
if (eweId == null) {
return error("未找到母羊耳号对应的羊只信息");
return error("未找到母羊耳号 " + scBreedRecord.getEweManageTags() + " 对应的羊只信息");
}
scBreedRecord.setEweId(eweId.toString());
scBreedRecord.setSheepId(eweId); // 设置羊只ID为母羊ID
}
// 处理公羊耳号转换
if (scBreedRecord.getRamManageTags() != null && !scBreedRecord.getRamManageTags().isEmpty()) {
Long ramId = scBreedRecordService.getRamIdByTags(scBreedRecord.getRamManageTags());
if (ramId == null) {
return error("未找到公羊耳号对应的羊只信息");
return error("未找到公羊耳号 " + scBreedRecord.getRamManageTags() + " 对应的羊只信息");
}
scBreedRecord.setRamId(ramId.toString());
}
return toAjax(scBreedRecordService.insertScBreedRecord(scBreedRecord));
// 验证配种方式
if (scBreedRecord.getBreedType() == null) {
return error("配种方式不能为空");
}
if (scBreedRecord.getBreedType() != 1 && scBreedRecord.getBreedType() != 2) {
return error("配种方式只能是1-同期发情 或 2-本交");
}
// 验证技术员
if (scBreedRecord.getTechnician() == null || scBreedRecord.getTechnician().trim().isEmpty()) {
return error("技术员不能为空");
}
int result = scBreedRecordService.insertScBreedRecord(scBreedRecord);
if (result > 0) {
return success("配种记录新增成功");
}
return error("配种记录新增失败");
}
/**
@ -125,23 +167,32 @@ public class ScBreedRecordController extends BaseController
@PutMapping
public AjaxResult edit(@RequestBody ScBreedRecord scBreedRecord)
{
// 如果传入的是耳号需要转换为羊只ID
// 处理母羊耳号转换
if (scBreedRecord.getEweManageTags() != null && !scBreedRecord.getEweManageTags().isEmpty()) {
Long eweId = scBreedRecordService.getSheepIdByTags(scBreedRecord.getEweManageTags());
if (eweId == null) {
return error("未找到母羊耳号对应的羊只信息");
return error("未找到母羊耳号 " + scBreedRecord.getEweManageTags() + " 对应的羊只信息");
}
scBreedRecord.setEweId(eweId.toString());
scBreedRecord.setSheepId(eweId); // 设置羊只ID为母羊ID
}
// 处理公羊耳号转换
if (scBreedRecord.getRamManageTags() != null && !scBreedRecord.getRamManageTags().isEmpty()) {
Long ramId = scBreedRecordService.getRamIdByTags(scBreedRecord.getRamManageTags());
if (ramId == null) {
return error("未找到公羊耳号对应的羊只信息");
return error("未找到公羊耳号 " + scBreedRecord.getRamManageTags() + " 对应的羊只信息");
}
scBreedRecord.setRamId(ramId.toString());
}
// 验证配种方式
if (scBreedRecord.getBreedType() != null) {
if (scBreedRecord.getBreedType() != 1 && scBreedRecord.getBreedType() != 2) {
return error("配种方式只能是1-同期发情 或 2-本交");
}
}
return toAjax(scBreedRecordService.updateScBreedRecord(scBreedRecord));
}
@ -155,4 +206,37 @@ public class ScBreedRecordController extends BaseController
{
return toAjax(scBreedRecordService.deleteScBreedRecordByIds(ids));
}
/**
* 同步孕检结果到配种记录
*/
@PreAuthorize("@ss.hasPermi('Breeding_records:Breeding_records:edit')")
@Log(title = "同步孕检结果", businessType = BusinessType.UPDATE)
@PostMapping("/syncPregnancyResult")
public AjaxResult syncPregnancyResult(@RequestBody Map<String, Object> params)
{
Long pregnancyRecordId = Long.valueOf(params.get("pregnancyRecordId").toString());
Long sheepId = Long.valueOf(params.get("sheepId").toString());
String pregnancyCheckDate = params.get("pregnancyCheckDate").toString();
int result = scBreedRecordService.syncPregnancyResult(pregnancyRecordId, sheepId, pregnancyCheckDate);
if (result > 0) {
return success("孕检结果同步成功");
} else {
return error("孕检结果同步失败,可能未找到对应的配种记录");
}
}
/**
* 根据羊只ID和时间范围查询配种记录
*/
@PreAuthorize("@ss.hasPermi('Breeding_records:Breeding_records:query')")
@GetMapping("/getByTimeRange/{sheepId}/{startDate}/{endDate}")
public AjaxResult getBreedRecordsByTimeRange(@PathVariable("sheepId") Long sheepId,
@PathVariable("startDate") String startDate,
@PathVariable("endDate") String endDate)
{
List<ScBreedRecord> records = scBreedRecordService.getBreedRecordsByTimeRange(sheepId, startDate, endDate);
return success(records);
}
}

View File

@ -5,6 +5,7 @@ import lombok.Data;
import lombok.NoArgsConstructor;
import com.zhyc.common.annotation.Excel;
import com.zhyc.common.core.domain.BaseEntity;
import java.util.Date;
/**
* 配种记录对象 sc_breed_record
@ -42,6 +43,10 @@ public class ScBreedRecord extends BaseEntity
@Excel(name = "耗精量")
private String breedDrugs;
/** 配种方式 1-同期发情 2-本交 */
@Excel(name = "配种方式", readConverterExp = "1=同期发情,2=本交")
private Integer breedType;
// ============ 显示字段 ============
/** 母羊耳号 */
@ -88,7 +93,7 @@ public class ScBreedRecord extends BaseEntity
@Excel(name = "所在牧场")
private String ranchName;
/** 配种方式 */
/** 配种方式显示 */
@Excel(name = "配种方式")
private String matingType;
@ -107,5 +112,43 @@ public class ScBreedRecord extends BaseEntity
/** 牧场ID */
private Long ranchId;
/** 配种计划ID */
private Long planId;
// ============ 新增孕检相关字段 ============
/** 孕检日期 */
@Excel(name = "孕检日期")
private Date pregnancyCheckDate;
/** 孕检结果 */
@Excel(name = "孕检结果")
private String pregnancyResult;
/** 孕检方式 */
@Excel(name = "孕检方式")
private String pregnancyWay;
/** 胎数 */
@Excel(name = "胎数")
private Integer fetusCount;
/** 孕检技术员 */
@Excel(name = "孕检技术员")
private String pregnancyTechnician;
/** 孕检备注 */
@Excel(name = "孕检备注")
private String pregnancyRemark;
/** 孕检记录ID */
private Long pregnancyRecordId;
/** 配种到孕检间隔天数 */
@Excel(name = "配种到孕检间隔(天)")
private Integer daysToPregnancyCheck;
/** 是否已孕检 */
@Excel(name = "是否已孕检", readConverterExp = "0=否,1=是")
private Integer isPregnancyChecked;
}

View File

@ -89,6 +89,22 @@ public interface ScBreedPlanGenerateMapper
*/
public List<Map<String, Object>> selectBreedPlanDetails(Long planGenerateId);
/**
* 获取审批配种计划详情
*
* @param planGenerateId 配种计划生成ID
* @return 审批配种计划详情列表
*/
public List<Map<String, Object>> selectApproveBreedPlanDetails(Long planGenerateId);
/**
* 更新临时配种计划
*
* @param params 更新参数
* @return 结果
*/
public int updateTempBreedPlan(Map<String, Object> params);
/**
* 删除配种计划生成
*
@ -104,4 +120,12 @@ public interface ScBreedPlanGenerateMapper
* @return 结果
*/
public int deleteScBreedPlanGenerateByIds(Long[] ids);
/**
* 删除临时配种计划
*
* @param planGenerateId 配种计划生成ID
* @return 结果
*/
public int deleteTempBreedPlanByPlanId(Long planGenerateId);
}

View File

@ -3,6 +3,8 @@ package com.zhyc.module.produce.breed.mapper;
import java.util.List;
import java.util.Map;
import com.zhyc.module.produce.breed.domain.ScBreedRecord;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
/**
* 配种记录Mapper接口
@ -10,6 +12,7 @@ import com.zhyc.module.produce.breed.domain.ScBreedRecord;
* @author ruoyi
* @date 2025-07-23
*/
@Mapper
public interface ScBreedRecordMapper
{
/**
@ -61,7 +64,7 @@ public interface ScBreedRecordMapper
public int deleteScBreedRecordByIds(Long[] ids);
/**
* 根据耳号查询羊只ID
* 根据管理耳号查询羊只ID
*
* @param manageTags 管理耳号
* @return 羊只ID
@ -69,7 +72,7 @@ public interface ScBreedRecordMapper
public Long getSheepIdByManageTags(String manageTags);
/**
* 根据公羊耳号查询羊只ID
* 根据公羊管理耳号查询羊只ID
*
* @param manageTags 管理耳号
* @return 羊只ID
@ -91,4 +94,34 @@ public interface ScBreedRecordMapper
* @return 配种计划信息
*/
public Map<String, Object> getBreedPlanByEweTags(String manageTags);
/**
* 根据母羊耳号获取最新的配种计划信息从配种计划生成表
*
* @param manageTags 母羊管理耳号
* @return 配种计划信息
*/
public Map<String, Object> getLatestBreedPlanByEweTags(String manageTags);
/**
* 根据配种记录ID更新孕检信息
*
* @param breedRecordId 配种记录ID
* @param pregnancyRecordId 孕检记录ID
* @return 结果
*/
public int updatePregnancyInfo(@Param("breedRecordId") Long breedRecordId,
@Param("pregnancyRecordId") Long pregnancyRecordId);
/**
* 根据羊只ID和配种时间查询配种记录
*
* @param sheepId 羊只ID
* @param matingDateStart 配种开始时间
* @param matingDateEnd 配种结束时间
* @return 配种记录集合
*/
public List<ScBreedRecord> selectBreedRecordByMatingTime(@Param("sheepId") Long sheepId,
@Param("matingDateStart") String matingDateStart,
@Param("matingDateEnd") String matingDateEnd);
}

View File

@ -2,6 +2,7 @@ package com.zhyc.module.produce.breed.service;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import com.zhyc.module.produce.breed.domain.ScBreedPlanGenerate;
/**
@ -45,11 +46,13 @@ public interface IScBreedPlanGenerateService
/**
* 自动生成配种计划
*
* @param planType 计划类型
* @param planName 计划名称
* @param eweIds 母羊ID列表
* @param ramIds 公羊ID列表
* @return 生成的配种计划
*/
public ScBreedPlanGenerate autoGenerateBreedPlan(List<Long> eweIds, List<Long> ramIds);
public ScBreedPlanGenerate autoGenerateBreedPlan(Integer planType, String planName, List<Long> eweIds, List<Long> ramIds);
/**
* 新增配种计划生成
@ -68,12 +71,23 @@ public interface IScBreedPlanGenerateService
public int updateScBreedPlanGenerate(ScBreedPlanGenerate scBreedPlanGenerate);
/**
* 审批配种计划
* 获取审批配种计划详情
*
* @param id 配种计划ID
* @return 审批配种计划详情
*/
public Map<String, Object> getApproveBreedPlanDetails(Long id);
/**
* 确认审批配种计划
*
* @param planId 配种计划ID
* @param planDetails 配种计划详情
* @param status 审批状态
* @param approveRemark 审批意见
* @return 结果
*/
public int approveBreedPlan(Long id);
public int confirmApproveBreedPlan(Long planId, List<Map<String, Object>> planDetails, Integer status, String approveRemark);
/**
* 获取配种计划详情
@ -91,6 +105,14 @@ public interface IScBreedPlanGenerateService
*/
public int deleteScBreedPlanGenerateByIds(Long[] ids);
/**
* 导出配种计划详情
*
* @param response HTTP响应
* @param id 配种计划ID
*/
public void exportBreedPlanDetails(HttpServletResponse response, Long id);
/**
* 删除配种计划生成信息
*

View File

@ -91,4 +91,32 @@ public interface IScBreedRecordService
* @return 配种计划信息
*/
public Map<String, Object> getBreedPlanByEweTags(String manageTags);
/**
* 根据母羊耳号获取最新的配种计划信息优先从配种计划生成表获取
*
* @param manageTags 母羊管理耳号
* @return 配种计划信息
*/
public Map<String, Object> getLatestBreedPlanByEweTags(String manageTags);
/**
* 同步孕检结果到配种记录
*
* @param pregnancyRecordId 孕检记录ID
* @param sheepId 羊只ID
* @param pregnancyCheckDate 孕检日期
* @return 结果
*/
public int syncPregnancyResult(Long pregnancyRecordId, Long sheepId, String pregnancyCheckDate);
/**
* 根据羊只ID和时间范围查询配种记录
*
* @param sheepId 羊只ID
* @param startDate 开始时间
* @param endDate 结束时间
* @return 配种记录集合
*/
public List<ScBreedRecord> getBreedRecordsByTimeRange(Long sheepId, String startDate, String endDate);
}

View File

@ -5,6 +5,8 @@ import java.util.Map;
import java.util.HashMap;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import com.zhyc.module.produce.breed.domain.ScBreedPlan;
import com.zhyc.module.produce.breed.domain.ScBreedPlanGenerate;
@ -15,6 +17,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.zhyc.common.utils.SecurityUtils;
import org.springframework.util.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
/**
* 配种计划生成Service业务层处理
@ -80,20 +86,27 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
/**
* 自动生成配种计划
*
* @param planType 计划类型
* @param planName 计划名称
* @param eweIds 母羊ID列表
* @param ramIds 公羊ID列表
* @return 生成的配种计划
*/
@Override
@Transactional
public ScBreedPlanGenerate autoGenerateBreedPlan(List<Long> eweIds, List<Long> ramIds)
public ScBreedPlanGenerate autoGenerateBreedPlan(Integer planType, String planName, List<Long> eweIds, List<Long> ramIds)
{
// 创建配种计划生成记录
ScBreedPlanGenerate planGenerate = new ScBreedPlanGenerate();
// 自动生成计划名称日期+计划类型
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String dateStr = sdf.format(new Date());
planGenerate.setPlanName(dateStr + "同期发情配种计划");
planGenerate.setPlanType(1);
String planTypeName = (planType == 1) ? "同期发情配种计划" : "本交配种计划";
planName = dateStr + planTypeName;
planGenerate.setPlanName(planName);
planGenerate.setPlanType(planType);
planGenerate.setPlanDate(new Date());
planGenerate.setTotalEweCount(eweIds.size());
planGenerate.setTotalRamCount(ramIds.size());
@ -109,7 +122,7 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
scBreedPlanGenerateMapper.insertScBreedPlanGenerate(planGenerate);
// 生成具体的配种计划
generateBreedPlanDetails(planGenerate.getId(), eweIds, ramIds);
generateBreedPlanDetails(planGenerate.getId(), eweIds, ramIds, planType);
return planGenerate;
}
@ -117,16 +130,23 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
/**
* 生成具体的配种计划详情
*/
private void generateBreedPlanDetails(Long planGenerateId, List<Long> eweIds, List<Long> ramIds)
private void generateBreedPlanDetails(Long planGenerateId, List<Long> eweIds, List<Long> ramIds, Integer planType)
{
int ramIndex = 0;
int ewesPerRam = (int) Math.ceil((double) eweIds.size() / ramIds.size());
for (int i = 0; i < eweIds.size(); i++) {
ScBreedPlan breedPlan = new ScBreedPlan();
// 存储公羊ID而不是字符串
breedPlan.setRamId(ramIds.get(ramIndex).toString());
breedPlan.setEweId(eweIds.get(i).toString());
breedPlan.setBreedType(1L); // 默认配种类型
// 根据计划类型设置配种类型同期发情配种计划->同期发情本交配种计划->本交
if (planType == 1) {
breedPlan.setBreedType(1L); // 同期发情
} else {
breedPlan.setBreedType(2L); // 本交
}
// 插入临时配种计划关联到生成记录
scBreedPlanGenerateMapper.insertTempBreedPlan(planGenerateId, breedPlan);
@ -165,28 +185,75 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
}
/**
* 审批配种计划
* 获取审批配种计划详情
*
* @param id 配种计划ID
* @return 审批配种计划详情
*/
@Override
public Map<String, Object> getApproveBreedPlanDetails(Long id)
{
Map<String, Object> result = new HashMap<>();
// 获取配种计划基本信息
ScBreedPlanGenerate planGenerate = scBreedPlanGenerateMapper.selectScBreedPlanGenerateById(id);
result.put("planInfo", planGenerate);
// 获取详细的配种计划信息
List<Map<String, Object>> planDetails = scBreedPlanGenerateMapper.selectApproveBreedPlanDetails(id);
result.put("planDetails", planDetails);
// 获取可选择的公羊列表
List<Map<String, Object>> availableRams = scBreedPlanGenerateMapper.selectEligibleRam();
result.put("availableRams", availableRams);
return result;
}
/**
* 确认审批配种计划
*
* @param planId 配种计划ID
* @param planDetails 配种计划详情
* @param status 审批状态
* @param approveRemark 审批意见
* @return 结果
*/
@Override
@Transactional
public int approveBreedPlan(Long id)
public int confirmApproveBreedPlan(Long planId, List<Map<String, Object>> planDetails, Integer status, String approveRemark)
{
// 更新审批状态
ScBreedPlanGenerate planGenerate = new ScBreedPlanGenerate();
planGenerate.setId(id);
planGenerate.setStatus(1); // 已审批
planGenerate.setId(planId);
planGenerate.setStatus(status);
planGenerate.setApprover(SecurityUtils.getUsername());
planGenerate.setApproveTime(new Date());
planGenerate.setApproveRemark(approveRemark);
planGenerate.setUpdateTime(new Date());
int result = scBreedPlanGenerateMapper.updateScBreedPlanGenerate(planGenerate);
// 将临时配种计划转为正式配种计划
if (result > 0) {
scBreedPlanGenerateMapper.transferTempToFormal(id);
// 如果审批通过更新临时配种计划并转为正式计划
if (result > 0 && status == 1) {
// 更新临时配种计划中的公羊分配
if (planDetails != null && !planDetails.isEmpty()) {
for (Map<String, Object> detail : planDetails) {
Long tempId = Long.valueOf(detail.get("id").toString());
Long ramId = Long.valueOf(detail.get("ram_id").toString());
Long breedType = Long.valueOf(detail.get("breed_type").toString());
// 更新临时配种计划
Map<String, Object> updateParams = new HashMap<>();
updateParams.put("id", tempId);
updateParams.put("ramId", ramId);
updateParams.put("breedType", breedType);
scBreedPlanGenerateMapper.updateTempBreedPlan(updateParams);
}
}
// 将临时配种计划转为正式配种计划
scBreedPlanGenerateMapper.transferTempToFormal(planId);
}
return result;
@ -214,6 +281,231 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
return result;
}
/**
* 导出配种计划详情
*
* @param response HTTP响应
* @param id 配种计划ID
*/
@Override
public void exportBreedPlanDetails(HttpServletResponse response, Long id)
{
try {
// 获取配种计划基本信息
ScBreedPlanGenerate planGenerate = scBreedPlanGenerateMapper.selectScBreedPlanGenerateById(id);
if (planGenerate == null) {
throw new RuntimeException("配种计划不存在");
}
// 检查是否已审批
if (planGenerate.getStatus() != 1) {
throw new RuntimeException("只有已审批的配种计划才能导出");
}
// 获取配种计划详情
List<Map<String, Object>> planDetails = scBreedPlanGenerateMapper.selectBreedPlanDetails(id);
// 创建工作簿
Workbook workbook = new XSSFWorkbook();
Sheet sheet = workbook.createSheet("配种计划详情");
// 创建样式
CellStyle titleStyle = workbook.createCellStyle();
Font titleFont = workbook.createFont();
titleFont.setBold(true);
titleFont.setFontHeightInPoints((short) 16);
titleStyle.setFont(titleFont);
titleStyle.setAlignment(HorizontalAlignment.CENTER);
CellStyle headerStyle = workbook.createCellStyle();
Font headerFont = workbook.createFont();
headerFont.setBold(true);
headerStyle.setFont(headerFont);
headerStyle.setAlignment(HorizontalAlignment.CENTER);
headerStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
headerStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
CellStyle dataStyle = workbook.createCellStyle();
dataStyle.setAlignment(HorizontalAlignment.CENTER);
CellStyle eweHeaderStyle = workbook.createCellStyle();
Font eweHeaderFont = workbook.createFont();
eweHeaderFont.setBold(true);
eweHeaderStyle.setFont(eweHeaderFont);
eweHeaderStyle.setAlignment(HorizontalAlignment.CENTER);
eweHeaderStyle.setFillForegroundColor(IndexedColors.ROSE.getIndex());
eweHeaderStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
CellStyle ramHeaderStyle = workbook.createCellStyle();
Font ramHeaderFont = workbook.createFont();
ramHeaderFont.setBold(true);
ramHeaderStyle.setFont(ramHeaderFont);
ramHeaderStyle.setAlignment(HorizontalAlignment.CENTER);
ramHeaderStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex());
ramHeaderStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
int rowNum = 0;
// 标题
Row titleRow = sheet.createRow(rowNum++);
Cell titleCell = titleRow.createCell(0);
titleCell.setCellValue(planGenerate.getPlanName() + " - 配种计划详情");
titleCell.setCellStyle(titleStyle);
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 19));
// 空行
rowNum++;
// 基本信息
Row infoRow1 = sheet.createRow(rowNum++);
infoRow1.createCell(0).setCellValue("计划类型:");
infoRow1.createCell(1).setCellValue(planGenerate.getPlanType() == 1 ? "同期发情配种计划" : "本交配种计划");
infoRow1.createCell(3).setCellValue("计划日期:");
infoRow1.createCell(4).setCellValue(new SimpleDateFormat("yyyy-MM-dd").format(planGenerate.getPlanDate()));
Row infoRow2 = sheet.createRow(rowNum++);
infoRow2.createCell(0).setCellValue("母羊数量:");
infoRow2.createCell(1).setCellValue(planGenerate.getTotalEweCount());
infoRow2.createCell(3).setCellValue("公羊数量:");
infoRow2.createCell(4).setCellValue(planGenerate.getTotalRamCount());
Row infoRow3 = sheet.createRow(rowNum++);
infoRow3.createCell(0).setCellValue("配种比例:");
infoRow3.createCell(1).setCellValue(planGenerate.getBreedRatio());
infoRow3.createCell(3).setCellValue("创建人:");
infoRow3.createCell(4).setCellValue(planGenerate.getCreateBy());
// 空行
rowNum++;
// 分组表头
Row groupHeaderRow = sheet.createRow(rowNum++);
Cell groupHeaderCell1 = groupHeaderRow.createCell(1);
groupHeaderCell1.setCellValue("母羊信息");
groupHeaderCell1.setCellStyle(eweHeaderStyle);
sheet.addMergedRegion(new CellRangeAddress(rowNum-1, rowNum-1, 1, 12));
Cell groupHeaderCell2 = groupHeaderRow.createCell(13);
groupHeaderCell2.setCellValue("公羊信息");
groupHeaderCell2.setCellStyle(ramHeaderStyle);
sheet.addMergedRegion(new CellRangeAddress(rowNum-1, rowNum-1, 13, 19));
// 详细表头
Row headerRow = sheet.createRow(rowNum++);
String[] headers = {
"序号",
// 母羊信息
"母羊耳号", "母羊品种", "母羊家系", "母羊类别", "繁育状态", "胎次", "月龄", "体重", "核心羊群", "是否种用", "羊舍", "备注",
// 公羊信息
"公羊耳号", "公羊品种", "公羊家系", "公羊类别", "生日", "月龄", "体重",
// 配种信息
"配种类型"
};
for (int i = 0; i < headers.length; i++) {
Cell cell = headerRow.createCell(i);
cell.setCellValue(headers[i]);
if (i == 0 || i == headers.length - 1) {
cell.setCellStyle(headerStyle);
} else if (i <= 12) {
cell.setCellStyle(eweHeaderStyle);
} else {
cell.setCellStyle(ramHeaderStyle);
}
}
// 数据行
for (int i = 0; i < planDetails.size(); i++) {
Map<String, Object> detail = planDetails.get(i);
Row dataRow = sheet.createRow(rowNum++);
int colNum = 0;
// 序号
dataRow.createCell(colNum++).setCellValue(i + 1);
// 母羊信息
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_manage_tags"));
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_variety"));
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_family"));
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_sheep_type"));
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_breed_status"));
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_parity"));
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_month_age"));
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_current_weight"));
dataRow.createCell(colNum++).setCellValue(getBooleanValue(detail, "ewe_is_core") ? "" : "");
dataRow.createCell(colNum++).setCellValue(getBooleanValue(detail, "ewe_is_breeding") ? "" : "");
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_sheepfold_name"));
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_comment"));
// 公羊信息
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_manage_tags"));
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_variety"));
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_family"));
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_sheep_type"));
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_birthday"));
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_month_age"));
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_current_weight"));
// 配种类型
Object breedType = detail.get("breed_type");
String breedTypeName = "未知类型";
if (breedType != null) {
int typeValue = Integer.parseInt(breedType.toString());
breedTypeName = typeValue == 1 ? "同期发情" : (typeValue == 2 ? "本交" : "未知类型");
}
dataRow.createCell(colNum++).setCellValue(breedTypeName);
// 应用数据样式
for (int j = 0; j < headers.length; j++) {
if (dataRow.getCell(j) != null) {
dataRow.getCell(j).setCellStyle(dataStyle);
}
}
}
// 自动调整列宽
for (int i = 0; i < headers.length; i++) {
sheet.autoSizeColumn(i);
// 设置最小宽度
if (sheet.getColumnWidth(i) < 2000) {
sheet.setColumnWidth(i, 2000);
}
}
// 设置响应头
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
response.setCharacterEncoding("utf-8");
String fileName = java.net.URLEncoder.encode(planGenerate.getPlanName() + "_配种计划详情", "UTF-8").replaceAll("\\+", "%20");
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
// 输出到响应流
workbook.write(response.getOutputStream());
workbook.close();
} catch (IOException e) {
throw new RuntimeException("导出Excel失败", e);
}
}
/**
* 安全获取字符串值
*/
private String getStringValue(Map<String, Object> map, String key) {
Object value = map.get(key);
return value != null ? value.toString() : "";
}
/**
* 安全获取布尔值
*/
private boolean getBooleanValue(Map<String, Object> map, String key) {
Object value = map.get(key);
if (value == null) return false;
if (value instanceof Boolean) return (Boolean) value;
if (value instanceof Number) return ((Number) value).intValue() == 1;
return "1".equals(value.toString()) || "true".equalsIgnoreCase(value.toString());
}
/**
* 批量删除配种计划生成
*
@ -221,8 +513,13 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
* @return 结果
*/
@Override
@Transactional
public int deleteScBreedPlanGenerateByIds(Long[] ids)
{
// 删除相关的临时配种计划
for (Long id : ids) {
scBreedPlanGenerateMapper.deleteTempBreedPlanByPlanId(id);
}
return scBreedPlanGenerateMapper.deleteScBreedPlanGenerateByIds(ids);
}
@ -233,8 +530,11 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
* @return 结果
*/
@Override
@Transactional
public int deleteScBreedPlanGenerateById(Long id)
{
// 先删除相关的临时配种计划
scBreedPlanGenerateMapper.deleteTempBreedPlanByPlanId(id);
return scBreedPlanGenerateMapper.deleteScBreedPlanGenerateById(id);
}
}

View File

@ -4,6 +4,8 @@ import java.util.List;
import java.util.Map;
import com.zhyc.common.utils.DateUtils;
import com.zhyc.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zhyc.module.produce.breed.mapper.ScBreedRecordMapper;
@ -19,6 +21,8 @@ import com.zhyc.module.produce.breed.service.IScBreedRecordService;
@Service
public class ScBreedRecordServiceImpl implements IScBreedRecordService
{
private static final Logger log = LoggerFactory.getLogger(ScBreedRecordServiceImpl.class);
@Autowired
private ScBreedRecordMapper scBreedRecordMapper;
@ -161,4 +165,84 @@ public class ScBreedRecordServiceImpl implements IScBreedRecordService
{
return scBreedRecordMapper.getBreedPlanByEweTags(manageTags);
}
/**
* 根据母羊耳号获取最新的配种计划信息优先从配种计划生成表获取
*
* @param manageTags 母羊管理耳号
* @return 配种计划信息
*/
@Override
public Map<String, Object> getLatestBreedPlanByEweTags(String manageTags)
{
try {
// 优先从配种计划生成表获取最新计划
Map<String, Object> latestPlan = scBreedRecordMapper.getLatestBreedPlanByEweTags(manageTags);
if (latestPlan != null && !latestPlan.isEmpty()) {
log.info("从配种计划生成表获取到配种计划: {}", latestPlan);
return latestPlan;
}
// 如果生成表中没有则从普通配种计划表获取
Map<String, Object> normalPlan = scBreedRecordMapper.getBreedPlanByEweTags(manageTags);
if (normalPlan != null && !normalPlan.isEmpty()) {
log.info("从配种计划表获取到配种计划: {}", normalPlan);
return normalPlan;
}
log.warn("未找到母羊耳号 {} 的配种计划信息", manageTags);
return null;
} catch (Exception e) {
log.error("获取配种计划信息时发生异常,母羊耳号: {}", manageTags, e);
return null;
}
}
/**
* 同步孕检结果到配种记录
*
* @param pregnancyRecordId 孕检记录ID
* @param sheepId 羊只ID
* @param pregnancyCheckDate 孕检日期
* @return 结果
*/
@Override
public int syncPregnancyResult(Long pregnancyRecordId, Long sheepId, String pregnancyCheckDate)
{
try {
// 查找孕检日期前最近的配种记录
List<ScBreedRecord> breedRecords = scBreedRecordMapper.selectBreedRecordByMatingTime(
sheepId, null, pregnancyCheckDate);
if (breedRecords != null && !breedRecords.isEmpty()) {
// 取最近的一次配种记录
ScBreedRecord latestBreedRecord = breedRecords.get(0);
// 更新配种记录中的孕检信息
return scBreedRecordMapper.updatePregnancyInfo(latestBreedRecord.getId(), pregnancyRecordId);
} else {
log.warn("未找到羊只ID {} 在孕检日期 {} 前的配种记录", sheepId, pregnancyCheckDate);
return 0;
}
} catch (Exception e) {
log.error("同步孕检结果到配种记录时发生异常", e);
return 0;
}
}
/**
* 根据羊只ID和时间范围查询配种记录
*
* @param sheepId 羊只ID
* @param startDate 开始时间
* @param endDate 结束时间
* @return 配种记录集合
*/
@Override
public List<ScBreedRecord> getBreedRecordsByTimeRange(Long sheepId, String startDate, String endDate)
{
return scBreedRecordMapper.selectBreedRecordByMatingTime(sheepId, startDate, endDate);
}
}

View File

@ -34,8 +34,14 @@
<where>
<if test="planName != null and planName != ''"> and plan_name like concat('%', #{planName}, '%')</if>
<if test="planType != null"> and plan_type = #{planType}</if>
<if test="planDate != null"> and plan_date = #{planDate}</if>
<if test="planDate != null"> and DATE(plan_date) = DATE(#{planDate})</if>
<if test="status != null"> and status = #{status}</if>
<if test="params.beginTime != null and params.beginTime != ''">
and DATE(plan_date) &gt;= DATE(#{params.beginTime})
</if>
<if test="params.endTime != null and params.endTime != ''">
and DATE(plan_date) &lt;= DATE(#{params.endTime})
</if>
</where>
order by create_time desc
</select>
@ -48,63 +54,72 @@
<!-- 筛选符合条件的母羊 -->
<select id="selectEligibleEwe" resultType="Map">
select
sf.id,
sf.bs_manage_tags,
sf.variety,
sf.name as sheep_type,
sf.gender,
sf.month_age,
sf.current_weight,
sf.post_lambing_day,
sf.breed
from sheep_file sf
where sf.gender = 1
and sf.is_delete = 0
and (sf.status_id = 1 or sf.status_id is null)
bs.id,
bs.manage_tags as bs_manage_tags,
bv.variety as variety,
bs.family,
bst.name as sheep_type,
bs.gender,
TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) as month_age,
bs.current_weight,
bs.post_lambing_day,
bbs.breed as breed,
bs.parity,
dsf.sheepfold_name,
bs.comment,
CASE WHEN bs.is_core = 1 THEN '是' ELSE '否' END as is_core,
CASE WHEN bs.is_breeding = 1 THEN '是' ELSE '否' END as is_breeding,
CONCAT('胎次:', IFNULL(bs.parity, 0), ' 配种次数:', IFNULL(bs.mating_counts, 0)) as reproduction_info
from bas_sheep bs
left join bas_sheep_variety bv on bs.variety_id = bv.id
left join bas_sheep_type bst on bs.type_id = bst.id
left join bas_breed_status bbs on bs.breed_status_id = bbs.id
left join da_sheepfold dsf on bs.sheepfold_id = dsf.id
where bs.gender = 1
and bs.is_delete = 0
and (bs.status_id = 1 or bs.status_id is null)
and (
-- 青年羊或超龄羊的配种条件
(sf.name in ('青年羊', '超龄羊') and (
(sf.variety = '湖羊' and sf.month_age >= 7.5 and sf.current_weight >= 33) or
(sf.variety = '东佛里生' and sf.month_age >= 9 and sf.current_weight >= 50) or
(sf.variety not in ('湖羊', '东佛里生') and sf.month_age >= 9 and sf.current_weight >= 50)
(bst.name in ('青年羊', '超龄羊') and (
(bv.variety = '湖羊' and TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) &gt;= 7.5 and bs.current_weight &gt;= 33) or
(bv.variety = '东佛里生' and TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) &gt;= 9 and bs.current_weight &gt;= 50) or
(bv.variety not in ('湖羊', '东佛里生') and TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) &gt;= 9 and bs.current_weight &gt;= 50)
))
or
-- 泌乳羊或种母羊的配种条件
(sf.name in ('泌乳羊', '种母羊') and sf.post_lambing_day > 45 and sf.current_weight > 0)
(bst.name in ('泌乳羊', '种母羊') and bs.post_lambing_day &gt; 45 and bs.current_weight &gt; 0)
)
order by sf.variety, sf.month_age desc
order by bv.variety, TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) desc
</select>
<!-- 筛选符合条件的公羊 -->
<select id="selectEligibleRam" resultType="Map">
select
sf.id,
sf.manage_tags as bs_manage_tags,
bs.id,
bs.manage_tags as bs_manage_tags,
bv.variety as variety,
bs.family,
bst.name as sheep_type,
sf.gender,
TIMESTAMPDIFF(MONTH, sf.birthday, NOW()) as month_age,
sf.current_weight,
bs.gender,
bs.birthday,
TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) as month_age,
bs.current_weight,
bbs.breed as breed
from bas_sheep sf
left join bas_sheep_variety bv on sf.variety_id = bv.id
left join bas_sheep_type bst on sf.type_id = bst.id
left join bas_breed_status bbs on sf.breed_status_id = bbs.id
where sf.gender = 2
and sf.is_delete = 0
and sf.status_id = 1
from bas_sheep bs
left join bas_sheep_variety bv on bs.variety_id = bv.id
left join bas_sheep_type bst on bs.type_id = bst.id
left join bas_breed_status bbs on bs.breed_status_id = bbs.id
where bs.gender = 2
and bs.is_delete = 0
and bs.status_id = 1
and (
-- 青年羊或超龄羊的参配条件
(bst.name in ('青年羊', '超龄羊') and (
(bv.variety = '湖羊' and TIMESTAMPDIFF(MONTH, sf.birthday, NOW()) >= 7.5 and sf.current_weight >= 33) or
(bv.variety = '东佛里生' and TIMESTAMPDIFF(MONTH, sf.birthday, NOW()) >= 9 and sf.current_weight >= 50) or
(bv.variety not in ('湖羊', '东佛里生') and TIMESTAMPDIFF(MONTH, sf.birthday, NOW()) >= 9 and sf.current_weight >= 50)
(bv.variety = '湖羊' and TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) &gt;= 7.5 and bs.current_weight &gt;= 33) or
(bv.variety = '东佛里生' and TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) &gt;= 9 and bs.current_weight &gt;= 50) or
(bv.variety not in ('湖羊', '东佛里生') and TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) &gt;= 9 and bs.current_weight &gt;= 50)
))
or
-- 其他类型公羊
bst.name not in ('青年羊', '超龄羊')
)
order by bv.variety, TIMESTAMPDIFF(MONTH, sf.birthday, NOW()) desc
order by bv.variety, TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) desc
</select>
<insert id="insertScBreedPlanGenerate" parameterType="ScBreedPlanGenerate" useGeneratedKeys="true" keyProperty="id">
@ -176,25 +191,110 @@
where plan_generate_id = #{planGenerateId}
</insert>
<!-- 获取配种计划详情 -->
<!-- 获取配种计划详情 - 显示完整字段信息 -->
<select id="selectBreedPlanDetails" parameterType="Long" resultType="Map">
select
temp.id,
temp.ram_id,
temp.ewe_id,
temp.breed_type,
ram.bs_manage_tags as ram_manage_tags,
ram.variety as ram_variety,
ewe.bs_manage_tags as ewe_manage_tags,
ewe.variety as ewe_variety,
ewe.current_weight as ewe_weight
-- 母羊完整信息
ewe.manage_tags as ewe_manage_tags,
ewe_variety.variety as ewe_variety,
ewe.family as ewe_family,
ewe_type.name as ewe_sheep_type,
ewe_breed.breed as ewe_breed_status,
ewe.parity as ewe_parity,
TIMESTAMPDIFF(MONTH, ewe.birthday, NOW()) as ewe_month_age,
ewe.current_weight as ewe_current_weight,
CASE WHEN ewe.is_core = 1 THEN 1 ELSE 0 END as ewe_is_core,
CASE WHEN ewe.is_breeding = 1 THEN 1 ELSE 0 END as ewe_is_breeding,
ewe_sheepfold.sheepfold_name as ewe_sheepfold_name,
ewe.comment as ewe_comment,
CONCAT('胎次:', IFNULL(ewe.parity, 0), ' 配种次数:', IFNULL(ewe.mating_counts, 0)) as ewe_reproduction_info,
-- 公羊完整信息 - 直接关联查询耳号
ram.manage_tags as ram_manage_tags,
ram_variety.variety as ram_variety,
ram.family as ram_family,
ram_type.name as ram_sheep_type,
ram.birthday as ram_birthday,
TIMESTAMPDIFF(MONTH, ram.birthday, NOW()) as ram_month_age,
ram.current_weight as ram_current_weight
from sc_breed_plan_temp temp
left join sheep_file ram on temp.ram_id = ram.id
left join sheep_file ewe on temp.ewe_id = ewe.id
left join bas_sheep ewe on ewe.id = CAST(temp.ewe_id AS UNSIGNED)
left join bas_sheep_variety ewe_variety on ewe.variety_id = ewe_variety.id
left join bas_sheep_type ewe_type on ewe.type_id = ewe_type.id
left join bas_breed_status ewe_breed on ewe.breed_status_id = ewe_breed.id
left join da_sheepfold ewe_sheepfold on ewe.sheepfold_id = ewe_sheepfold.id
left join bas_sheep ram on ram.id = CAST(temp.ram_id AS UNSIGNED)
left join bas_sheep_variety ram_variety on ram.variety_id = ram_variety.id
left join bas_sheep_type ram_type on ram.type_id = ram_type.id
where temp.plan_generate_id = #{planGenerateId}
order by temp.ram_id, temp.ewe_id
order by temp.ewe_id, temp.ram_id
</select>
<!-- 获取审批详情 - 包含完整的母羊和公羊信息 -->
<select id="selectApproveBreedPlanDetails" parameterType="Long" resultType="Map">
select
temp.id,
temp.ram_id,
temp.ewe_id,
temp.breed_type,
-- 母羊信息
ewe.manage_tags as ewe_manage_tags,
ewe_variety.variety as ewe_variety,
ewe.family as ewe_family,
ewe_type.name as ewe_sheep_type,
ewe_breed.breed as ewe_breed_status,
ewe.parity as ewe_parity,
TIMESTAMPDIFF(MONTH, ewe.birthday, NOW()) as ewe_month_age,
ewe.current_weight as ewe_current_weight,
CASE WHEN ewe.is_core = 1 THEN 1 ELSE 0 END as ewe_is_core,
CASE WHEN ewe.is_breeding = 1 THEN 1 ELSE 0 END as ewe_is_breeding,
ewe_sheepfold.sheepfold_name as ewe_sheepfold_name,
ewe.comment as ewe_comment,
CONCAT('胎次:', IFNULL(ewe.parity, 0), ' 配种次数:', IFNULL(ewe.mating_counts, 0)) as ewe_reproduction_info,
-- 公羊信息 - 直接关联查询耳号
ram.manage_tags as ram_manage_tags,
ram_variety.variety as ram_variety,
ram.family as ram_family,
ram_type.name as ram_sheep_type,
ram.birthday as ram_birthday,
TIMESTAMPDIFF(MONTH, ram.birthday, NOW()) as ram_month_age,
ram.current_weight as ram_current_weight
from sc_breed_plan_temp temp
left join bas_sheep ewe on ewe.id = CAST(temp.ewe_id AS UNSIGNED)
left join bas_sheep_variety ewe_variety on ewe.variety_id = ewe_variety.id
left join bas_sheep_type ewe_type on ewe.type_id = ewe_type.id
left join bas_breed_status ewe_breed on ewe.breed_status_id = ewe_breed.id
left join da_sheepfold ewe_sheepfold on ewe.sheepfold_id = ewe_sheepfold.id
left join bas_sheep ram on ram.id = CAST(temp.ram_id AS UNSIGNED)
left join bas_sheep_variety ram_variety on ram.variety_id = ram_variety.id
left join bas_sheep_type ram_type on ram.type_id = ram_type.id
where temp.plan_generate_id = #{planGenerateId}
order by temp.ewe_id, temp.ram_id
</select>
<!-- 更新临时配种计划 -->
<update id="updateTempBreedPlan">
update sc_breed_plan_temp
<set>
<if test="ramId != null">
ram_id = #{ramId},
</if>
<if test="ramId == null">
ram_id = null,
</if>
<if test="breedType != null">
breed_type = #{breedType},
</if>
<if test="breedType == null">
breed_type = null,
</if>
</set>
where id = #{id}
</update>
<delete id="deleteScBreedPlanGenerateById" parameterType="Long">
delete from sc_breed_plan_generate where id = #{id}
</delete>
@ -205,4 +305,9 @@
#{id}
</foreach>
</delete>
<!-- 删除临时配种计划 -->
<delete id="deleteTempBreedPlanByPlanId" parameterType="Long">
delete from sc_breed_plan_temp where plan_generate_id = #{planGenerateId}
</delete>
</mapper>

View File

@ -11,9 +11,10 @@
<result property="eweId" column="ewe_id" />
<result property="technician" column="technician" />
<result property="breedDrugs" column="breed_drugs" />
<result property="breedType" column="breed_type" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<!-- 新增显示字段 -->
<!-- 显示字段 -->
<result property="eweManageTags" column="ewe_manage_tags" />
<result property="eweVariety" column="ewe_variety" />
<result property="ramManageTags" column="ram_manage_tags" />
@ -29,6 +30,16 @@
<result property="sheepType" column="sheep_type" />
<result property="matingCount" column="mating_count" />
<result property="timeSincePlanning" column="time_since_planning" />
<!-- 孕检相关字段 -->
<result property="pregnancyCheckDate" column="pregnancy_check_date" />
<result property="pregnancyResult" column="pregnancy_result" />
<result property="pregnancyWay" column="pregnancy_way" />
<result property="fetusCount" column="fetus_count" />
<result property="pregnancyTechnician" column="pregnancy_technician" />
<result property="pregnancyRemark" column="pregnancy_remark" />
<result property="pregnancyRecordId" column="pregnancy_record_id" />
<result property="daysToPregnancyCheck" column="days_to_pregnancy_check" />
<result property="isPregnancyChecked" column="is_pregnancy_checked" />
</resultMap>
<sql id="selectScBreedRecordVo">
@ -39,6 +50,7 @@
br.ewe_id,
br.technician,
br.breed_drugs,
br.breed_type,
br.create_by,
br.create_time,
-- 母羊信息(从视图获取)
@ -56,13 +68,45 @@
-- 公羊信息(从视图获取)
ram_view.bs_manage_tags as ram_manage_tags,
ram_view.variety as ram_variety,
-- 配种方式(如果视图中没有,设为空或从其他地方获取)
'' as mating_type,
-- 配种方式显示
CASE br.breed_type
WHEN 1 THEN '同期发情'
WHEN 2 THEN '本交'
ELSE '未知'
END as mating_type,
-- 发情后配种时间(小时数)
TIMESTAMPDIFF(HOUR, br.create_time, NOW()) as time_since_planning
TIMESTAMPDIFF(HOUR, br.create_time, NOW()) as time_since_planning,
-- 孕检相关信息
pr.datetime as pregnancy_check_date,
pr.result as pregnancy_result,
pr.way as pregnancy_way,
pr.fetus_count,
pr.technician as pregnancy_technician,
pr.remark as pregnancy_remark,
pr.id as pregnancy_record_id,
-- 配种到孕检间隔天数
CASE
WHEN pr.datetime IS NOT NULL THEN DATEDIFF(pr.datetime, br.create_time)
ELSE NULL
END as days_to_pregnancy_check,
-- 是否已孕检
CASE
WHEN pr.id IS NOT NULL THEN 1
ELSE 0
END as is_pregnancy_checked
from sc_breed_record br
left join sheep_file ewe_view on br.ewe_id = ewe_view.id
left join sheep_file ram_view on br.ram_id = ram_view.id
left join sc_pregnancy_record pr on pr.sheep_id = br.ewe_id
and pr.is_delete = 0
and pr.datetime >= br.create_time
and pr.datetime = (
select min(pr2.datetime)
from sc_pregnancy_record pr2
where pr2.sheep_id = br.ewe_id
and pr2.is_delete = 0
and pr2.datetime >= br.create_time
)
</sql>
<select id="selectScBreedRecordList" parameterType="ScBreedRecord" resultMap="ScBreedRecordResult">
@ -71,6 +115,7 @@
<if test="sheepId != null "> and br.sheep_id = #{sheepId}</if>
<if test="ramId != null and ramId != ''"> and br.ram_id = #{ramId}</if>
<if test="eweId != null and eweId != ''"> and br.ewe_id = #{eweId}</if>
<if test="breedType != null"> and br.breed_type = #{breedType}</if>
<if test="technician != null and technician != ''"> and br.technician like concat('%', #{technician}, '%')</if>
<if test="breedDrugs != null and breedDrugs != ''"> and br.breed_drugs like concat('%', #{breedDrugs}, '%')</if>
<if test="createBy != null and createBy != ''"> and br.create_by like concat('%', #{createBy}, '%')</if>
@ -81,6 +126,12 @@
<if test="eweVariety != null and eweVariety != ''"> and ewe_view.variety like concat('%', #{eweVariety}, '%')</if>
<if test="ramVariety != null and ramVariety != ''"> and ram_view.variety like concat('%', #{ramVariety}, '%')</if>
<if test="ranchId != null"> and ewe_view.ranch_id = #{ranchId}</if>
<!-- 孕检相关查询条件 -->
<if test="pregnancyResult != null and pregnancyResult != ''"> and pr.result like concat('%', #{pregnancyResult}, '%')</if>
<if test="isPregnancyChecked != null">
<if test="isPregnancyChecked == 1"> and pr.id IS NOT NULL</if>
<if test="isPregnancyChecked == 0"> and pr.id IS NULL</if>
</if>
</where>
order by br.create_time desc
</select>
@ -170,19 +221,43 @@
ewe_view.bs_manage_tags as ewe_manage_tags,
bp.ram_id,
ram_view.bs_manage_tags as ram_manage_tags,
bp.plan_date,
bp.breed_type,
bp.technician,
bp.status,
bp.create_time as plan_create_time,
TIMESTAMPDIFF(HOUR, bp.create_time, NOW()) as hours_since_plan
CASE bp.breed_type
WHEN 1 THEN '同期发情'
WHEN 2 THEN '本交'
ELSE '未知'
END as breed_type_name,
TIMESTAMPDIFF(HOUR, NOW(), NOW()) as hours_since_plan
from sc_breed_plan bp
left join sheep_file ewe_view on bp.ewe_id = ewe_view.id
left join sheep_file ram_view on bp.ram_id = ram_view.id
where ewe_view.bs_manage_tags = #{manageTags}
and bp.status = '待配种'
and bp.is_delete = 0
order by bp.create_time desc
order by bp.id desc
limit 1
</select>
<!-- 根据母羊耳号获取最新的配种计划信息(从配种计划生成表) -->
<select id="getLatestBreedPlanByEweTags" parameterType="String" resultType="map">
select
bpg.id as plan_generate_id,
bpt.ewe_id,
ewe_view.bs_manage_tags as ewe_manage_tags,
bpt.ram_id,
ram_view.bs_manage_tags as ram_manage_tags,
bpt.breed_type,
CASE bpt.breed_type
WHEN 1 THEN '同期发情'
WHEN 2 THEN '本交'
ELSE '未知'
END as breed_type_name,
bpg.create_time as plan_create_time
from sc_breed_plan_generate bpg
inner join sc_breed_plan_temp bpt on bpg.id = bpt.plan_generate_id
left join sheep_file ewe_view on bpt.ewe_id = ewe_view.id
left join sheep_file ram_view on bpt.ram_id = ram_view.id
where ewe_view.bs_manage_tags = #{manageTags}
and bpg.status = 1 -- 已审批的计划
order by bpg.create_time desc, bpt.id desc
limit 1
</select>
@ -194,6 +269,7 @@
<if test="eweId != null">ewe_id,</if>
<if test="technician != null">technician,</if>
<if test="breedDrugs != null">breed_drugs,</if>
<if test="breedType != null">breed_type,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
</trim>
@ -203,6 +279,7 @@
<if test="eweId != null">#{eweId},</if>
<if test="technician != null">#{technician},</if>
<if test="breedDrugs != null">#{breedDrugs},</if>
<if test="breedType != null">#{breedType},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
</trim>
@ -216,6 +293,7 @@
<if test="eweId != null">ewe_id = #{eweId},</if>
<if test="technician != null">technician = #{technician},</if>
<if test="breedDrugs != null">breed_drugs = #{breedDrugs},</if>
<if test="breedType != null">breed_type = #{breedType},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
</trim>
@ -232,4 +310,26 @@
#{id}
</foreach>
</delete>
<!-- 根据羊只ID和配种时间查询配种记录 -->
<select id="selectBreedRecordByMatingTime" resultMap="ScBreedRecordResult">
<include refid="selectScBreedRecordVo"/>
<where>
<if test="sheepId != null">and br.ewe_id = #{sheepId}</if>
<if test="matingDateStart != null and matingDateStart != ''">
and br.create_time >= #{matingDateStart}
</if>
<if test="matingDateEnd != null and matingDateEnd != ''">
and br.create_time &lt;= #{matingDateEnd}
</if>
</where>
order by br.create_time desc
</select>
<!-- 更新配种记录的孕检信息 -->
<update id="updatePregnancyInfo">
update sc_breed_record
set pregnancy_record_id = #{pregnancyRecordId}
where id = #{breedRecordId}
</update>
</mapper>