Merge remote-tracking branch 'origin/main'
This commit is contained in:
@@ -84,6 +84,9 @@ public class DdSaleController extends BaseController {
|
|||||||
@Log(title = "销售主单", businessType = BusinessType.INSERT)
|
@Log(title = "销售主单", businessType = BusinessType.INSERT)
|
||||||
@PostMapping
|
@PostMapping
|
||||||
public AjaxResult add(@RequestBody DdSale ddSale) {
|
public AjaxResult add(@RequestBody DdSale ddSale) {
|
||||||
|
// 适配数据分离
|
||||||
|
ddSale.setDeptId(getDeptId());
|
||||||
|
ddSale.setUserId(getUserId());
|
||||||
return toAjax(ddSaleService.insertDdSale(ddSale));
|
return toAjax(ddSaleService.insertDdSale(ddSale));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,10 @@ import java.math.BigDecimal;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
import org.apache.commons.lang3.builder.ToStringBuilder;
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
import org.apache.commons.lang3.builder.ToStringStyle;
|
import org.apache.commons.lang3.builder.ToStringStyle;
|
||||||
import com.zhyc.common.annotation.Excel;
|
import com.zhyc.common.annotation.Excel;
|
||||||
@@ -11,10 +15,12 @@ import com.zhyc.common.core.domain.BaseEntity;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 销售主单对象 dd_sl
|
* 销售主单对象 dd_sl
|
||||||
*
|
*
|
||||||
* @author HashMap
|
* @author HashMap
|
||||||
* @date 2025-12-01
|
* @date 2025-12-01
|
||||||
*/
|
*/
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
public class DdSale extends BaseEntity
|
public class DdSale extends BaseEntity
|
||||||
{
|
{
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
@@ -59,119 +65,11 @@ public class DdSale extends BaseEntity
|
|||||||
@Excel(name = "技术员")
|
@Excel(name = "技术员")
|
||||||
private String tech;
|
private String tech;
|
||||||
|
|
||||||
|
private Long userId;
|
||||||
|
private Long deptId;
|
||||||
|
|
||||||
/** 销售明细信息 */
|
/** 销售明细信息 */
|
||||||
private List<DdSaleItem> ddSaleItemList;
|
private List<DdSaleItem> ddSaleItemList;
|
||||||
|
|
||||||
public void setId(Long id)
|
|
||||||
{
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Long getId()
|
|
||||||
{
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSaleDate(Date saleDate)
|
|
||||||
{
|
|
||||||
this.saleDate = saleDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Date getSaleDate()
|
|
||||||
{
|
|
||||||
return saleDate;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCustName(String custName)
|
|
||||||
{
|
|
||||||
this.custName = custName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCustName()
|
|
||||||
{
|
|
||||||
return custName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCustPhone(String custPhone)
|
|
||||||
{
|
|
||||||
this.custPhone = custPhone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCustPhone()
|
|
||||||
{
|
|
||||||
return custPhone;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setCustAddr(String custAddr)
|
|
||||||
{
|
|
||||||
this.custAddr = custAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getCustAddr()
|
|
||||||
{
|
|
||||||
return custAddr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSalesper(String salesper)
|
|
||||||
{
|
|
||||||
this.salesper = salesper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSalesper()
|
|
||||||
{
|
|
||||||
return salesper;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setQuaranNo(String quaranNo)
|
|
||||||
{
|
|
||||||
this.quaranNo = quaranNo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getQuaranNo()
|
|
||||||
{
|
|
||||||
return quaranNo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setApprNo(String apprNo)
|
|
||||||
{
|
|
||||||
this.apprNo = apprNo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getApprNo()
|
|
||||||
{
|
|
||||||
return apprNo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPrice(BigDecimal price)
|
|
||||||
{
|
|
||||||
this.price = price;
|
|
||||||
}
|
|
||||||
|
|
||||||
public BigDecimal getPrice()
|
|
||||||
{
|
|
||||||
return price;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTech(String tech)
|
|
||||||
{
|
|
||||||
this.tech = tech;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTech()
|
|
||||||
{
|
|
||||||
return tech;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<DdSaleItem> getDdSaleItemList()
|
|
||||||
{
|
|
||||||
return ddSaleItemList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setDdSaleItemList(List<DdSaleItem> ddSaleItemList)
|
|
||||||
{
|
|
||||||
this.ddSaleItemList = ddSaleItemList;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.zhyc.module.frozen.service.impl;
|
|||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.zhyc.common.annotation.DataScope;
|
||||||
import com.zhyc.common.utils.DateUtils;
|
import com.zhyc.common.utils.DateUtils;
|
||||||
import com.zhyc.module.frozen.domain.DdFe;
|
import com.zhyc.module.frozen.domain.DdFe;
|
||||||
import com.zhyc.module.frozen.domain.DdFs;
|
import com.zhyc.module.frozen.domain.DdFs;
|
||||||
@@ -58,6 +59,7 @@ public class DdSaleServiceImpl implements IDdSaleService {
|
|||||||
* @return 销售主单
|
* @return 销售主单
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@DataScope(deptAlias = "dd_sl_alias" , userAlias = "dd_sl_alias")
|
||||||
public List<DdSale> selectDdSaleList(DdSale ddSale) {
|
public List<DdSale> selectDdSaleList(DdSale ddSale) {
|
||||||
return ddSaleMapper.selectDdSaleList(ddSale);
|
return ddSaleMapper.selectDdSaleList(ddSale);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import com.zhyc.module.produce.breed.service.IScBreedPlanGenerateService;
|
|||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import com.zhyc.common.annotation.Log;
|
import com.zhyc.common.annotation.Log;
|
||||||
import com.zhyc.common.core.controller.BaseController;
|
import com.zhyc.common.core.controller.BaseController;
|
||||||
import com.zhyc.common.core.domain.AjaxResult;
|
import com.zhyc.common.core.domain.AjaxResult;
|
||||||
@@ -65,7 +66,89 @@ public class ScBreedPlanGenerateController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自动生成配种计划
|
* 导出已选母羊公羊配对表(供用户下载后手动填写/确认配对)
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('mating_plan:generate:export')")
|
||||||
|
@Log(title = "导出配对模板", businessType = BusinessType.EXPORT)
|
||||||
|
@PostMapping("/exportPairs")
|
||||||
|
public void exportSelectedPairs(HttpServletResponse response, @RequestBody Map<String, Object> params)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
List<?> eweIdsRaw = (List<?>) params.get("eweIds");
|
||||||
|
List<?> ramIdsRaw = (List<?>) params.get("ramIds");
|
||||||
|
|
||||||
|
if (eweIdsRaw == null || ramIdsRaw == null) {
|
||||||
|
response.setContentType("application/json;charset=utf-8");
|
||||||
|
response.getWriter().write("{\"code\":500,\"msg\":\"参数不能为空\"}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Long> eweIds = eweIdsRaw.stream()
|
||||||
|
.map(obj -> obj instanceof Integer ? ((Integer) obj).longValue()
|
||||||
|
: obj instanceof Long ? (Long) obj : Long.valueOf(obj.toString()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
List<Long> ramIds = ramIdsRaw.stream()
|
||||||
|
.map(obj -> obj instanceof Integer ? ((Integer) obj).longValue()
|
||||||
|
: obj instanceof Long ? (Long) obj : Long.valueOf(obj.toString()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
scBreedPlanGenerateService.exportSelectedPairs(response, eweIds, ramIds);
|
||||||
|
} 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析导入的配对Excel,返回配对预览数据(不生成计划)
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('mating_plan:generate:add')")
|
||||||
|
@PostMapping("/parsePairs")
|
||||||
|
public AjaxResult parsePairsFromExcel(@RequestParam("file") MultipartFile file)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
List<Map<String, Object>> pairs = scBreedPlanGenerateService.parsePairsFromExcel(file);
|
||||||
|
return success(pairs);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("解析配对Excel失败", e);
|
||||||
|
return error("解析失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据导入的配对数据生成配种计划
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('mating_plan:generate:auto')")
|
||||||
|
@PostMapping("/generateFromPairs")
|
||||||
|
@Log(title = "导入生成配种计划", businessType = BusinessType.INSERT)
|
||||||
|
public AjaxResult generateBreedPlanFromPairs(@RequestBody Map<String, Object> params)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
Integer planType = params.get("planType") != null ? (Integer) params.get("planType") : 1;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
List<Map<String, Object>> pairs = (List<Map<String, Object>>) params.get("pairs");
|
||||||
|
|
||||||
|
if (pairs == null || pairs.isEmpty()) {
|
||||||
|
return error("配对数据不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
ScBreedPlanGenerate planGenerate = scBreedPlanGenerateService.autoGenerateBreedPlanFromPairs(planType, pairs);
|
||||||
|
return success(planGenerate);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("导入生成配种计划失败", e);
|
||||||
|
return error("生成失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动生成配种计划(原有逻辑保留,按比例自动分配)
|
||||||
*/
|
*/
|
||||||
@PreAuthorize("@ss.hasPermi('mating_plan:generate:auto')")
|
@PreAuthorize("@ss.hasPermi('mating_plan:generate:auto')")
|
||||||
@PostMapping("/auto")
|
@PostMapping("/auto")
|
||||||
@@ -73,13 +156,9 @@ public class ScBreedPlanGenerateController extends BaseController
|
|||||||
public AjaxResult autoGenerateBreedPlan(@RequestBody Map<String, Object> params)
|
public AjaxResult autoGenerateBreedPlan(@RequestBody Map<String, Object> params)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
// 获取计划类型
|
|
||||||
Integer planType = params.get("planType") != null ? (Integer) params.get("planType") : 1;
|
Integer planType = params.get("planType") != null ? (Integer) params.get("planType") : 1;
|
||||||
|
|
||||||
// 计划名称由系统自动生成,不再从前端传入
|
|
||||||
String planName = null;
|
String planName = null;
|
||||||
|
|
||||||
// 安全的类型转换
|
|
||||||
List<?> eweIdsRaw = (List<?>) params.get("eweIds");
|
List<?> eweIdsRaw = (List<?>) params.get("eweIds");
|
||||||
List<?> ramIdsRaw = (List<?>) params.get("ramIds");
|
List<?> ramIdsRaw = (List<?>) params.get("ramIds");
|
||||||
|
|
||||||
@@ -88,27 +167,13 @@ public class ScBreedPlanGenerateController extends BaseController
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<Long> eweIds = eweIdsRaw.stream()
|
List<Long> eweIds = eweIdsRaw.stream()
|
||||||
.map(obj -> {
|
.map(obj -> obj instanceof Integer ? ((Integer) obj).longValue()
|
||||||
if (obj instanceof Integer) {
|
: obj instanceof Long ? (Long) obj : Long.valueOf(obj.toString()))
|
||||||
return ((Integer) obj).longValue();
|
|
||||||
} else if (obj instanceof Long) {
|
|
||||||
return (Long) obj;
|
|
||||||
} else {
|
|
||||||
return Long.valueOf(obj.toString());
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
List<Long> ramIds = ramIdsRaw.stream()
|
List<Long> ramIds = ramIdsRaw.stream()
|
||||||
.map(obj -> {
|
.map(obj -> obj instanceof Integer ? ((Integer) obj).longValue()
|
||||||
if (obj instanceof Integer) {
|
: obj instanceof Long ? (Long) obj : Long.valueOf(obj.toString()))
|
||||||
return ((Integer) obj).longValue();
|
|
||||||
} else if (obj instanceof Long) {
|
|
||||||
return (Long) obj;
|
|
||||||
} else {
|
|
||||||
return Long.valueOf(obj.toString());
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
ScBreedPlanGenerate planGenerate = scBreedPlanGenerateService.autoGenerateBreedPlan(planType, planName, eweIds, ramIds);
|
ScBreedPlanGenerate planGenerate = scBreedPlanGenerateService.autoGenerateBreedPlan(planType, planName, eweIds, ramIds);
|
||||||
@@ -222,7 +287,6 @@ public class ScBreedPlanGenerateController extends BaseController
|
|||||||
scBreedPlanGenerateService.exportBreedPlanDetails(response, id);
|
scBreedPlanGenerateService.exportBreedPlanDetails(response, id);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
logger.error("导出配种计划详情失败", e);
|
logger.error("导出配种计划详情失败", e);
|
||||||
// 在出错时返回错误信息给前端
|
|
||||||
try {
|
try {
|
||||||
response.setContentType("application/json;charset=utf-8");
|
response.setContentType("application/json;charset=utf-8");
|
||||||
response.getWriter().write("{\"code\":500,\"msg\":\"导出失败:" + e.getMessage() + "\"}");
|
response.getWriter().write("{\"code\":500,\"msg\":\"导出失败:" + e.getMessage() + "\"}");
|
||||||
@@ -246,7 +310,7 @@ public class ScBreedPlanGenerateController extends BaseController
|
|||||||
/**
|
/**
|
||||||
* 模糊查询母羊耳号列表
|
* 模糊查询母羊耳号列表
|
||||||
*/
|
*/
|
||||||
@PreAuthorize("@ss.hasPermi('mating_plan:generate:query')") // 根据实际权限修改
|
@PreAuthorize("@ss.hasPermi('mating_plan:generate:query')")
|
||||||
@GetMapping("/search_ear_numbers")
|
@GetMapping("/search_ear_numbers")
|
||||||
public AjaxResult searchEarNumbers(@RequestParam("query") String query) {
|
public AjaxResult searchEarNumbers(@RequestParam("query") String query) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -79,14 +79,20 @@ public class ScDryMilkController extends BaseController
|
|||||||
/**
|
/**
|
||||||
* 远程搜索耳号列表
|
* 远程搜索耳号列表
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* 模糊查询母羊耳号列表
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('drymilk:drymilk:query')") // 根据实际权限修改
|
||||||
@GetMapping("/searchEarNumbers")
|
@GetMapping("/searchEarNumbers")
|
||||||
public AjaxResult searchEarNumbers(@RequestParam(value = "query", required = false) String query)
|
public AjaxResult searchEarNumbers(@RequestParam("query") String query) {
|
||||||
{
|
try {
|
||||||
if (query == null) query = "";
|
List<String> earNumbers = scDryMilkService.searchEarNumbers(query);
|
||||||
List<String> list = scDryMilkService.selectSheepEarNumberList(query);
|
return success(earNumbers);
|
||||||
return AjaxResult.success(list);
|
} catch (Exception e) {
|
||||||
|
logger.error("搜索耳号异常", e);
|
||||||
|
return error("搜索耳号失败:" + e.getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 远程搜索技术员列表
|
* 远程搜索技术员列表
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ public class ScEmbryoFlushController extends BaseController
|
|||||||
return getDataTable(list);
|
return getDataTable(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出冲胚记录列表
|
* 导出冲胚记录列表
|
||||||
*/
|
*/
|
||||||
@@ -126,4 +127,35 @@ public class ScEmbryoFlushController extends BaseController
|
|||||||
List<Map<String, Object>> list = scEmbryoFlushService.selectDonorFemaleList();
|
List<Map<String, Object>> list = scEmbryoFlushService.selectDonorFemaleList();
|
||||||
return success(list);
|
return success(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取供体公羊下拉列表
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('embryo:flush:query')")
|
||||||
|
@GetMapping("/donorMaleList")
|
||||||
|
public AjaxResult getDonorMaleList()
|
||||||
|
{
|
||||||
|
List<Map<String, Object>> list = scEmbryoFlushService.selectDonorMaleList();
|
||||||
|
return success(list);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 根据耳号获取羊只基础信息
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('embryo:flush:query')")
|
||||||
|
@GetMapping("/getSheepInfo")
|
||||||
|
public AjaxResult getSheepInfo(@RequestParam("manageTag") String manageTag) {
|
||||||
|
return success(scEmbryoFlushService.getSheepInfoByTag(manageTag));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据父母品种实时计算胚胎品种
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('embryo:flush:query')")
|
||||||
|
@GetMapping("/calculateVariety")
|
||||||
|
public AjaxResult calculateVariety(@RequestParam("maleVariety") String maleVariety,
|
||||||
|
@RequestParam("femaleVariety") String femaleVariety) {
|
||||||
|
String result = scEmbryoFlushService.calculateEmbryoVariety(maleVariety, femaleVariety);
|
||||||
|
return success(result);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,8 +1,14 @@
|
|||||||
package com.zhyc.module.produce.breed.controller;
|
package com.zhyc.module.produce.breed.controller;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.apache.poi.ss.usermodel.*;
|
||||||
|
import org.apache.poi.ss.util.CellRangeAddress;
|
||||||
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
@@ -13,7 +19,6 @@ import com.zhyc.common.enums.BusinessType;
|
|||||||
import com.zhyc.module.produce.breed.domain.ScLambingRecord;
|
import com.zhyc.module.produce.breed.domain.ScLambingRecord;
|
||||||
import com.zhyc.module.produce.breed.domain.ScLambDetail;
|
import com.zhyc.module.produce.breed.domain.ScLambDetail;
|
||||||
import com.zhyc.module.produce.breed.service.IScLambingRecordService;
|
import com.zhyc.module.produce.breed.service.IScLambingRecordService;
|
||||||
import com.zhyc.common.utils.poi.ExcelUtil;
|
|
||||||
import com.zhyc.common.core.page.TableDataInfo;
|
import com.zhyc.common.core.page.TableDataInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -55,6 +60,7 @@ public class ScLambingRecordController extends BaseController {
|
|||||||
return error("查询配种信息失败:" + e.getMessage());
|
return error("查询配种信息失败:" + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@PreAuthorize("@ss.hasPermi('breed:lambing_records:query')")
|
@PreAuthorize("@ss.hasPermi('breed:lambing_records:query')")
|
||||||
@GetMapping("/search_ear_numbers")
|
@GetMapping("/search_ear_numbers")
|
||||||
public AjaxResult searchEarNumbers(@RequestParam("query") String query) {
|
public AjaxResult searchEarNumbers(@RequestParam("query") String query) {
|
||||||
@@ -66,25 +72,217 @@ public class ScLambingRecordController extends BaseController {
|
|||||||
return error("搜索耳号失败:" + e.getMessage());
|
return error("搜索耳号失败:" + e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出产羔记录列表
|
* 导出产羔记录列表(多Sheet:Sheet1=产羔记录,Sheet2=羔羊详情)
|
||||||
*/
|
*/
|
||||||
@PreAuthorize("@ss.hasPermi('breed:lambing_records:export')")
|
@PreAuthorize("@ss.hasPermi('breed:lambing_records:export')")
|
||||||
@Log(title = "产羔记录", businessType = BusinessType.EXPORT)
|
@Log(title = "产羔记录", businessType = BusinessType.EXPORT)
|
||||||
@PostMapping("/export")
|
@PostMapping("/export")
|
||||||
public void export(HttpServletResponse response, ScLambingRecord scLambingRecord) {
|
public void export(HttpServletResponse response, ScLambingRecord scLambingRecord) throws IOException {
|
||||||
|
// 不分页,查全量
|
||||||
List<ScLambingRecord> list = scLambingRecordService.selectScLambingRecordList(scLambingRecord);
|
List<ScLambingRecord> list = scLambingRecordService.selectScLambingRecordList(scLambingRecord);
|
||||||
ExcelUtil<ScLambingRecord> util = new ExcelUtil<ScLambingRecord>(ScLambingRecord.class);
|
|
||||||
util.exportExcel(response, list, "产羔记录数据");
|
// 为每条记录补充羔羊详情
|
||||||
|
for (ScLambingRecord record : list) {
|
||||||
|
List<ScLambDetail> details = scLambingRecordService.selectLambDetailByLambingRecordId(record.getId());
|
||||||
|
record.setLambDetails(details);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建多Sheet工作簿
|
||||||
|
XSSFWorkbook workbook = buildExportWorkbook(list);
|
||||||
|
|
||||||
|
// 写出响应
|
||||||
|
String filename = java.net.URLEncoder.encode("产羔记录_" + new java.text.SimpleDateFormat("yyyyMMddHHmmss").format(new java.util.Date()), "UTF-8");
|
||||||
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
|
response.setCharacterEncoding("utf-8");
|
||||||
|
response.setHeader("Content-Disposition", "attachment;filename=" + filename + ".xlsx");
|
||||||
|
workbook.write(response.getOutputStream());
|
||||||
|
workbook.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取产羔记录详细信息(修改:改为获取包含关联信息的详细数据)
|
* 构建导出工作簿(两个Sheet)
|
||||||
|
*/
|
||||||
|
private XSSFWorkbook buildExportWorkbook(List<ScLambingRecord> list) {
|
||||||
|
XSSFWorkbook workbook = new XSSFWorkbook();
|
||||||
|
SimpleDateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
|
||||||
|
// ==================== Sheet1:产羔记录 ====================
|
||||||
|
Sheet sheet1 = workbook.createSheet("产羔记录");
|
||||||
|
|
||||||
|
// 标题样式
|
||||||
|
CellStyle headerStyle = createHeaderStyle(workbook);
|
||||||
|
// 普通单元格样式
|
||||||
|
CellStyle dataStyle = createDataStyle(workbook);
|
||||||
|
|
||||||
|
// 产羔记录表头(与界面完全一致)
|
||||||
|
String[] headers1 = {
|
||||||
|
"母羊耳号", "母羊品种", "配种日期", "胎次", "公羊耳号", "公羊品种",
|
||||||
|
"产羔数量", "活羔数量", "折损数", "技术员", "月龄", "产羔评分",
|
||||||
|
"公羔数量", "母羔数量", "留养公羔数量", "留养母羔数量",
|
||||||
|
"未留养公羔数量", "未留养母羔数量", "产羔时怀孕天数",
|
||||||
|
"当前羊舍", "创建人", "创建日期", "所在牧场", "备注"
|
||||||
|
};
|
||||||
|
|
||||||
|
// 列宽(字符数 * 256)
|
||||||
|
int[] colWidths1 = {
|
||||||
|
14, 12, 13, 8, 14, 12,
|
||||||
|
10, 10, 8, 10, 8, 10,
|
||||||
|
10, 10, 14, 14,
|
||||||
|
16, 16, 16,
|
||||||
|
12, 10, 12, 12, 20
|
||||||
|
};
|
||||||
|
|
||||||
|
Row headerRow1 = sheet1.createRow(0);
|
||||||
|
headerRow1.setHeightInPoints(22);
|
||||||
|
for (int i = 0; i < headers1.length; i++) {
|
||||||
|
sheet1.setColumnWidth(i, colWidths1[i] * 256);
|
||||||
|
Cell cell = headerRow1.createCell(i);
|
||||||
|
cell.setCellValue(headers1[i]);
|
||||||
|
cell.setCellStyle(headerStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 产羔记录数据行
|
||||||
|
int rowNum1 = 1;
|
||||||
|
for (ScLambingRecord r : list) {
|
||||||
|
Row row = sheet1.createRow(rowNum1++);
|
||||||
|
row.setHeightInPoints(18);
|
||||||
|
int col = 0;
|
||||||
|
setCellValue(row, col++, r.getFemaleEarNumber(), dataStyle);
|
||||||
|
setCellValue(row, col++, r.getFemaleBreed(), dataStyle);
|
||||||
|
setCellValue(row, col++, r.getBreedingDate() != null ? dateFmt.format(r.getBreedingDate()) : "", dataStyle);
|
||||||
|
setCellValue(row, col++, r.getParity(), dataStyle);
|
||||||
|
setCellValue(row, col++, r.getMaleEarNumber(), dataStyle);
|
||||||
|
setCellValue(row, col++, r.getMaleBreed(), dataStyle);
|
||||||
|
setCellValue(row, col++, r.getLambsBorn(), dataStyle);
|
||||||
|
setCellValue(row, col++, r.getSurvival(), dataStyle);
|
||||||
|
// 折损数 = 产羔数 - 活羔数
|
||||||
|
int loss = (int) ((r.getLambsBorn() != null ? r.getLambsBorn() : 0)
|
||||||
|
- (r.getSurvival() != null ? r.getSurvival() : 0));
|
||||||
|
setCellValue(row, col++, loss, dataStyle);
|
||||||
|
setCellValue(row, col++, r.getTechnician(), dataStyle);
|
||||||
|
setCellValue(row, col++, r.getMonthAge(), dataStyle);
|
||||||
|
setCellValue(row, col++, r.getScore(), dataStyle);
|
||||||
|
setCellValue(row, col++, r.getMaleCount(), dataStyle);
|
||||||
|
setCellValue(row, col++, r.getFemaleCount(), dataStyle);
|
||||||
|
setCellValue(row, col++, r.getRetainedMaleCount(), dataStyle);
|
||||||
|
setCellValue(row, col++, r.getRetainedFemaleCount(), dataStyle);
|
||||||
|
setCellValue(row, col++, r.getUnretainedMaleCount(), dataStyle);
|
||||||
|
setCellValue(row, col++, r.getUnretainedFemaleCount(), dataStyle);
|
||||||
|
setCellValue(row, col++, r.getPregnancyDays(), dataStyle);
|
||||||
|
setCellValue(row, col++, r.getCurrentShed(), dataStyle);
|
||||||
|
setCellValue(row, col++, r.getCreateBy(), dataStyle);
|
||||||
|
setCellValue(row, col++, r.getCreateTime() != null ? dateFmt.format(r.getCreateTime()) : "", dataStyle);
|
||||||
|
setCellValue(row, col++, r.getFarm(), dataStyle);
|
||||||
|
setCellValue(row, col++, r.getComment(), dataStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ==================== Sheet2:羔羊详情 ====================
|
||||||
|
Sheet sheet2 = workbook.createSheet("羔羊详情");
|
||||||
|
|
||||||
|
String[] headers2 = {
|
||||||
|
"母羊耳号", "胎次", "羔羊耳号", "性别", "出生体重(kg)",
|
||||||
|
"是否留养", "家系", "出生日期"
|
||||||
|
};
|
||||||
|
int[] colWidths2 = { 14, 8, 14, 8, 14, 10, 16, 13 };
|
||||||
|
|
||||||
|
Row headerRow2 = sheet2.createRow(0);
|
||||||
|
headerRow2.setHeightInPoints(22);
|
||||||
|
for (int i = 0; i < headers2.length; i++) {
|
||||||
|
sheet2.setColumnWidth(i, colWidths2[i] * 256);
|
||||||
|
Cell cell = headerRow2.createCell(i);
|
||||||
|
cell.setCellValue(headers2[i]);
|
||||||
|
cell.setCellStyle(headerStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
int rowNum2 = 1;
|
||||||
|
for (ScLambingRecord r : list) {
|
||||||
|
if (r.getLambDetails() == null || r.getLambDetails().isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (ScLambDetail d : r.getLambDetails()) {
|
||||||
|
Row row = sheet2.createRow(rowNum2++);
|
||||||
|
row.setHeightInPoints(18);
|
||||||
|
int col = 0;
|
||||||
|
setCellValue(row, col++, r.getFemaleEarNumber(), dataStyle);
|
||||||
|
setCellValue(row, col++, r.getParity(), dataStyle);
|
||||||
|
setCellValue(row, col++, d.getLambEarNumber(), dataStyle);
|
||||||
|
// 性别:1=公,0=母,2=阉羊,3=兼性(参照后端校验逻辑)
|
||||||
|
String genderLabel = "";
|
||||||
|
if (d.getGender() != null) {
|
||||||
|
switch (d.getGender()) {
|
||||||
|
case 0: genderLabel = "母"; break;
|
||||||
|
case 1: genderLabel = "公"; break;
|
||||||
|
case 2: genderLabel = "阉羊"; break;
|
||||||
|
case 3: genderLabel = "兼性"; break;
|
||||||
|
default: genderLabel = String.valueOf(d.getGender());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setCellValue(row, col++, genderLabel, dataStyle);
|
||||||
|
setCellValue(row, col++, d.getBirthWeight() != null ? d.getBirthWeight().toPlainString() : "", dataStyle);
|
||||||
|
setCellValue(row, col++, Boolean.TRUE.equals(d.getIsRetained()) ? "是" : "否", dataStyle);
|
||||||
|
setCellValue(row, col++, d.getLineage(), dataStyle);
|
||||||
|
setCellValue(row, col++, d.getBirthday() != null ? dateFmt.format(d.getBirthday()) : "", dataStyle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return workbook;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 创建表头样式 */
|
||||||
|
private CellStyle createHeaderStyle(XSSFWorkbook workbook) {
|
||||||
|
CellStyle style = workbook.createCellStyle();
|
||||||
|
Font font = workbook.createFont();
|
||||||
|
font.setBold(true);
|
||||||
|
font.setFontHeightInPoints((short) 11);
|
||||||
|
style.setFont(font);
|
||||||
|
style.setFillForegroundColor(IndexedColors.LIGHT_CORNFLOWER_BLUE.getIndex());
|
||||||
|
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||||
|
style.setAlignment(HorizontalAlignment.CENTER);
|
||||||
|
style.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||||
|
style.setBorderBottom(BorderStyle.THIN);
|
||||||
|
style.setBorderTop(BorderStyle.THIN);
|
||||||
|
style.setBorderLeft(BorderStyle.THIN);
|
||||||
|
style.setBorderRight(BorderStyle.THIN);
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 创建数据行样式 */
|
||||||
|
private CellStyle createDataStyle(XSSFWorkbook workbook) {
|
||||||
|
CellStyle style = workbook.createCellStyle();
|
||||||
|
style.setAlignment(HorizontalAlignment.CENTER);
|
||||||
|
style.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||||
|
style.setBorderBottom(BorderStyle.THIN);
|
||||||
|
style.setBorderTop(BorderStyle.THIN);
|
||||||
|
style.setBorderLeft(BorderStyle.THIN);
|
||||||
|
style.setBorderRight(BorderStyle.THIN);
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 统一设置单元格值 */
|
||||||
|
private void setCellValue(Row row, int col, Object value, CellStyle style) {
|
||||||
|
Cell cell = row.createCell(col);
|
||||||
|
if (value == null) {
|
||||||
|
cell.setCellValue("");
|
||||||
|
} else if (value instanceof Integer) {
|
||||||
|
cell.setCellValue((Integer) value);
|
||||||
|
} else if (value instanceof Long) {
|
||||||
|
cell.setCellValue((Long) value);
|
||||||
|
} else if (value instanceof Double) {
|
||||||
|
cell.setCellValue((Double) value);
|
||||||
|
} else {
|
||||||
|
cell.setCellValue(value.toString());
|
||||||
|
}
|
||||||
|
cell.setCellStyle(style);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取产羔记录详细信息
|
||||||
*/
|
*/
|
||||||
@PreAuthorize("@ss.hasPermi('breed:lambing_records:query')")
|
@PreAuthorize("@ss.hasPermi('breed:lambing_records:query')")
|
||||||
@GetMapping(value = "/{id}")
|
@GetMapping(value = "/{id}")
|
||||||
public AjaxResult getInfo(@PathVariable("id") Long id) {
|
public AjaxResult getInfo(@PathVariable("id") Long id) {
|
||||||
// 修改:改为调用详细查询方法,获取包含母羊耳号、公羊耳号等关联信息
|
|
||||||
return success(scLambingRecordService.selectScLambingRecordDetailById(id));
|
return success(scLambingRecordService.selectScLambingRecordDetailById(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,16 +294,11 @@ public class ScLambingRecordController extends BaseController {
|
|||||||
@PostMapping
|
@PostMapping
|
||||||
public AjaxResult add(@RequestBody ScLambingRecord scLambingRecord) {
|
public AjaxResult add(@RequestBody ScLambingRecord scLambingRecord) {
|
||||||
try {
|
try {
|
||||||
// 设置创建人
|
|
||||||
scLambingRecord.setCreateBy(getUsername());
|
scLambingRecord.setCreateBy(getUsername());
|
||||||
|
|
||||||
// 如果没有设置创建时间,使用当前时间
|
|
||||||
if (scLambingRecord.getCreateTime() == null) {
|
if (scLambingRecord.getCreateTime() == null) {
|
||||||
scLambingRecord.setCreateTime(new java.util.Date());
|
scLambingRecord.setCreateTime(new java.util.Date());
|
||||||
}
|
}
|
||||||
|
|
||||||
int result = scLambingRecordService.insertScLambingRecord(scLambingRecord);
|
int result = scLambingRecordService.insertScLambingRecord(scLambingRecord);
|
||||||
|
|
||||||
if (result > 0) {
|
if (result > 0) {
|
||||||
String message = "新增产羔记录成功";
|
String message = "新增产羔记录成功";
|
||||||
if (scLambingRecord.getLambDetails() != null && !scLambingRecord.getLambDetails().isEmpty()) {
|
if (scLambingRecord.getLambDetails() != null && !scLambingRecord.getLambDetails().isEmpty()) {
|
||||||
|
|||||||
@@ -41,6 +41,20 @@ public class ScSheepDeathController extends BaseController
|
|||||||
@Autowired
|
@Autowired
|
||||||
private ISwDiseaseService swDiseaseService;
|
private ISwDiseaseService swDiseaseService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模糊查询母羊耳号列表
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('/sheep_death/death:query')") // 根据实际权限修改
|
||||||
|
@GetMapping("/search_ear_numbers")
|
||||||
|
public AjaxResult searchEarNumbers(@RequestParam("query") String query) {
|
||||||
|
try {
|
||||||
|
List<String> earNumbers = scSheepDeathService.searchEarNumbers(query);
|
||||||
|
return success(earNumbers);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("搜索耳号异常", e);
|
||||||
|
return error("搜索耳号失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* 查询羊只死淘记录列表
|
* 查询羊只死淘记录列表
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -36,15 +36,6 @@ public class ScWeanRecordController extends BaseController {
|
|||||||
return getDataTable(list);
|
return getDataTable(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 【新增】模糊查询耳号列表 (用于前端下拉框远程搜索)
|
|
||||||
*/
|
|
||||||
@PreAuthorize("@ss.hasPermi('Weaning:weaning_record:list')")
|
|
||||||
@GetMapping("/search_ear_numbers")
|
|
||||||
public AjaxResult searchEarNumbers(@RequestParam("query") String query) {
|
|
||||||
List<String> list = scWeanRecordService.searchEarNumbers(query);
|
|
||||||
return success(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出断奶记录列表
|
* 导出断奶记录列表
|
||||||
@@ -129,5 +120,19 @@ public class ScWeanRecordController extends BaseController {
|
|||||||
return toAjax(scWeanRecordService.deleteScWeanRecordByIds(ids));
|
return toAjax(scWeanRecordService.deleteScWeanRecordByIds(ids));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模糊查询母羊耳号列表
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('breed:lambing_records:query')") // 根据实际权限修改
|
||||||
|
@GetMapping("/search_ear_numbers")
|
||||||
|
public AjaxResult searchEarNumbers(@RequestParam("query") String query) {
|
||||||
|
try {
|
||||||
|
List<String> earNumbers = scWeanRecordService.searchEarNumbers(query);
|
||||||
|
return success(earNumbers);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error("搜索耳号异常", e);
|
||||||
|
return error("搜索耳号失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -18,6 +18,16 @@ public class ScDryMilk extends BaseEntity
|
|||||||
{
|
{
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
/** 全部羊耳号列表(用于多耳号查询) */
|
||||||
|
private List<String> allEarNumbers;
|
||||||
|
|
||||||
|
public List<String> getAllEarNumbers() {
|
||||||
|
return allEarNumbers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllEarNumbers(List<String> allEarNumbers) {
|
||||||
|
this.allEarNumbers = allEarNumbers;
|
||||||
|
}
|
||||||
/** 主键id */
|
/** 主键id */
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ public class ScSheepDeath extends BaseEntity
|
|||||||
{
|
{
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
|
||||||
/** 主键ID */
|
/** 主键ID */
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,17 @@ public class ScWeanRecord extends BaseEntity {
|
|||||||
/** 主键ID */
|
/** 主键ID */
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
/** 全部羊耳号列表(用于多耳号查询) */
|
||||||
|
private List<String> allEarNumbers;
|
||||||
|
|
||||||
|
public List<String> getAllEarNumbers() {
|
||||||
|
return allEarNumbers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAllEarNumbers(List<String> allEarNumbers) {
|
||||||
|
this.allEarNumbers = allEarNumbers;
|
||||||
|
}
|
||||||
|
|
||||||
/** 羊只ID */
|
/** 羊只ID */
|
||||||
@Excel(name = "羊只ID")
|
@Excel(name = "羊只ID")
|
||||||
private Long sheepId;
|
private Long sheepId;
|
||||||
@@ -51,10 +62,6 @@ public class ScWeanRecord extends BaseEntity {
|
|||||||
@Excel(name = "电子耳号")
|
@Excel(name = "电子耳号")
|
||||||
private String electronicTags;
|
private String electronicTags;
|
||||||
|
|
||||||
// --- 新增查询字段 ---
|
|
||||||
|
|
||||||
/** 多耳号查询列表 */
|
|
||||||
private List<String> allEarNumbers;
|
|
||||||
|
|
||||||
/** 是否在群 (1是 0否) */
|
/** 是否在群 (1是 0否) */
|
||||||
private String isInHerd;
|
private String isInHerd;
|
||||||
|
|||||||
@@ -136,4 +136,26 @@ public interface ScBreedPlanGenerateMapper
|
|||||||
* @return 耳号列表
|
* @return 耳号列表
|
||||||
*/
|
*/
|
||||||
List<String> searchEarNumbers(@Param("query") String query);
|
List<String> searchEarNumbers(@Param("query") String query);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据ID列表查询羊只耳号
|
||||||
|
*
|
||||||
|
* @param ids 羊只ID列表
|
||||||
|
* @param gender 性别:1=母羊,2=公羊
|
||||||
|
* @return 包含 id、manage_tags 的 Map 列表
|
||||||
|
*/
|
||||||
|
List<Map<String, Object>> selectEarNumbersByIds(
|
||||||
|
@Param("ids") List<Long> ids,
|
||||||
|
@Param("gender") int gender);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据管理耳号查询羊只ID
|
||||||
|
*
|
||||||
|
* @param manageTags 管理耳号
|
||||||
|
* @param gender 性别:1=母羊,2=公羊
|
||||||
|
* @return 羊只ID
|
||||||
|
*/
|
||||||
|
Long selectSheepIdByManageTags(
|
||||||
|
@Param("manageTags") String manageTags,
|
||||||
|
@Param("gender") int gender);
|
||||||
}
|
}
|
||||||
@@ -69,4 +69,11 @@ public interface ScDryMilkMapper
|
|||||||
* 远程搜索技术员列表
|
* 远程搜索技术员列表
|
||||||
*/
|
*/
|
||||||
public List<String> searchTechnicianList(@Param("query") String query);
|
public List<String> searchTechnicianList(@Param("query") String query);
|
||||||
|
/**
|
||||||
|
* 模糊查询母羊耳号列表
|
||||||
|
*
|
||||||
|
* @param query 查询关键字
|
||||||
|
* @return 耳号列表
|
||||||
|
*/
|
||||||
|
List<String> searchEarNumbers(@Param("query") String query);
|
||||||
}
|
}
|
||||||
@@ -83,4 +83,11 @@ public interface ScEmbryoFlushMapper
|
|||||||
* @return 母羊列表
|
* @return 母羊列表
|
||||||
*/
|
*/
|
||||||
public List<Map<String, Object>> selectDonorFemaleList();
|
public List<Map<String, Object>> selectDonorFemaleList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询所有公羊列表(用于下拉选择)
|
||||||
|
*
|
||||||
|
* @return 公羊列表
|
||||||
|
*/
|
||||||
|
public List<Map<String, Object>> selectDonorMaleList();
|
||||||
}
|
}
|
||||||
@@ -85,4 +85,12 @@ public interface ScSheepDeathMapper
|
|||||||
* 远程搜索:处理人
|
* 远程搜索:处理人
|
||||||
*/
|
*/
|
||||||
public List<String> selectDistinctHandler(@Param("query") String query);
|
public List<String> selectDistinctHandler(@Param("query") String query);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模糊查询母羊耳号列表
|
||||||
|
*
|
||||||
|
* @param query 查询关键字
|
||||||
|
* @return 耳号列表
|
||||||
|
*/
|
||||||
|
List<String> searchEarNumbers(@Param("query") String query);
|
||||||
}
|
}
|
||||||
@@ -68,9 +68,10 @@ public interface ScWeanRecordMapper
|
|||||||
public int updateBasSheepWeaningInfo(ScWeanRecord scWeanRecord);
|
public int updateBasSheepWeaningInfo(ScWeanRecord scWeanRecord);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 【新增】模糊查询耳号列表 (用于前端远程搜索)
|
* 模糊查询母羊耳号列表
|
||||||
|
*
|
||||||
* @param query 查询关键字
|
* @param query 查询关键字
|
||||||
* @return 耳号列表
|
* @return 耳号列表
|
||||||
*/
|
*/
|
||||||
public List<String> searchEarNumbers(@Param("query") String query);
|
List<String> searchEarNumbers(@Param("query") String query);
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,9 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import com.zhyc.module.produce.breed.domain.ScBreedPlanGenerate;
|
import com.zhyc.module.produce.breed.domain.ScBreedPlanGenerate;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 配种计划生成Service接口
|
* 配种计划生成Service接口
|
||||||
@@ -44,6 +46,13 @@ public interface IScBreedPlanGenerateService
|
|||||||
*/
|
*/
|
||||||
public List<Map<String, Object>> selectEligibleRam(@RequestParam(value = "manageTags", required = false) String manageTags);
|
public List<Map<String, Object>> selectEligibleRam(@RequestParam(value = "manageTags", required = false) String manageTags);
|
||||||
|
|
||||||
|
void exportSelectedPairs(HttpServletResponse response, List<Long> eweIds, List<Long> ramIds);
|
||||||
|
|
||||||
|
List<Map<String, Object>> parsePairsFromExcel(MultipartFile file);
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
ScBreedPlanGenerate autoGenerateBreedPlanFromPairs(Integer planType, List<Map<String, Object>> pairs);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自动生成配种计划
|
* 自动生成配种计划
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -66,4 +66,12 @@ public interface IScDryMilkService
|
|||||||
* 远程搜索技术员列表
|
* 远程搜索技术员列表
|
||||||
*/
|
*/
|
||||||
public List<String> selectTechnicianList(String query);
|
public List<String> selectTechnicianList(String query);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模糊查询母羊耳号列表
|
||||||
|
*
|
||||||
|
* @param query 查询关键字
|
||||||
|
* @return 耳号列表
|
||||||
|
*/
|
||||||
|
public List<String> searchEarNumbers(String query);
|
||||||
}
|
}
|
||||||
@@ -83,4 +83,13 @@ public interface IScEmbryoFlushService
|
|||||||
* @return 母羊列表
|
* @return 母羊列表
|
||||||
*/
|
*/
|
||||||
public List<Map<String, Object>> selectDonorFemaleList();
|
public List<Map<String, Object>> selectDonorFemaleList();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询所有供体公羊列表(用于下拉选择)
|
||||||
|
*
|
||||||
|
* @return 公羊列表
|
||||||
|
*/
|
||||||
|
public List<Map<String, Object>> selectDonorMaleList();
|
||||||
|
|
||||||
|
public Map<String, Object> getSheepInfoByTag(String manageTag);
|
||||||
}
|
}
|
||||||
@@ -82,4 +82,12 @@ public interface IScSheepDeathService
|
|||||||
* 远程搜索:处理人
|
* 远程搜索:处理人
|
||||||
*/
|
*/
|
||||||
public List<String> selectDistinctHandler(String query);
|
public List<String> selectDistinctHandler(String query);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 模糊查询母羊耳号列表
|
||||||
|
*
|
||||||
|
* @param query 查询关键字
|
||||||
|
* @return 耳号列表
|
||||||
|
*/
|
||||||
|
public List<String> searchEarNumbers(String query);
|
||||||
}
|
}
|
||||||
@@ -61,7 +61,8 @@ public interface IScWeanRecordService
|
|||||||
public Long selectSheepIdByEarNumber(String earNumber);
|
public Long selectSheepIdByEarNumber(String earNumber);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 【新增】模糊查询耳号列表
|
* 模糊查询母羊耳号列表
|
||||||
|
*
|
||||||
* @param query 查询关键字
|
* @param query 查询关键字
|
||||||
* @return 耳号列表
|
* @return 耳号列表
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -3,9 +3,11 @@ package com.zhyc.module.produce.breed.service.impl;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import com.zhyc.module.produce.breed.domain.ScBreedPlan;
|
import com.zhyc.module.produce.breed.domain.ScBreedPlan;
|
||||||
@@ -16,6 +18,7 @@ import com.zhyc.module.produce.breed.service.IScBreedPlanGenerateService;
|
|||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
import com.zhyc.common.utils.SecurityUtils;
|
import com.zhyc.common.utils.SecurityUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||||
@@ -40,9 +43,6 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询配种计划生成
|
* 查询配种计划生成
|
||||||
*
|
|
||||||
* @param id 配种计划生成主键
|
|
||||||
* @return 配种计划生成
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ScBreedPlanGenerate selectScBreedPlanGenerateById(Long id)
|
public ScBreedPlanGenerate selectScBreedPlanGenerateById(Long id)
|
||||||
@@ -52,9 +52,6 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询配种计划生成列表
|
* 查询配种计划生成列表
|
||||||
*
|
|
||||||
* @param scBreedPlanGenerate 配种计划生成
|
|
||||||
* @return 配种计划生成
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<ScBreedPlanGenerate> selectScBreedPlanGenerateList(ScBreedPlanGenerate scBreedPlanGenerate)
|
public List<ScBreedPlanGenerate> selectScBreedPlanGenerateList(ScBreedPlanGenerate scBreedPlanGenerate)
|
||||||
@@ -64,8 +61,6 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 筛选符合条件的母羊
|
* 筛选符合条件的母羊
|
||||||
*
|
|
||||||
* @return 符合条件的母羊列表
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<Map<String, Object>> selectEligibleEwe(@RequestParam(value = "manageTags", required = false) String manageTags)
|
public List<Map<String, Object>> selectEligibleEwe(@RequestParam(value = "manageTags", required = false) String manageTags)
|
||||||
@@ -75,8 +70,6 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 筛选符合条件的公羊
|
* 筛选符合条件的公羊
|
||||||
*
|
|
||||||
* @return 符合条件的公羊列表
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<Map<String, Object>> selectEligibleRam(@RequestParam(value = "manageTags", required = false) String manageTags)
|
public List<Map<String, Object>> selectEligibleRam(@RequestParam(value = "manageTags", required = false) String manageTags)
|
||||||
@@ -85,26 +78,302 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自动生成配种计划
|
* 导出已选母羊公羊配对表
|
||||||
|
* 按轮询方式将母羊分配给公羊,导出Excel,两列:母羊耳号、公羊耳号
|
||||||
|
*
|
||||||
|
* @param response HTTP响应
|
||||||
|
* @param eweIds 已选母羊ID列表
|
||||||
|
* @param ramIds 已选公羊ID列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void exportSelectedPairs(HttpServletResponse response, List<Long> eweIds, List<Long> ramIds)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// 查询母羊耳号(gender=1)
|
||||||
|
List<Map<String, Object>> eweList = scBreedPlanGenerateMapper.selectEarNumbersByIds(eweIds, 1);
|
||||||
|
// 查询公羊耳号(gender=2)
|
||||||
|
List<Map<String, Object>> ramList = scBreedPlanGenerateMapper.selectEarNumbersByIds(ramIds, 2);
|
||||||
|
|
||||||
|
// 建立ID->耳号 的快速查找
|
||||||
|
Map<Long, String> eweEarMap = new HashMap<>();
|
||||||
|
for (Map<String, Object> e : eweList) {
|
||||||
|
eweEarMap.put(Long.valueOf(e.get("id").toString()), e.get("manage_tags").toString());
|
||||||
|
}
|
||||||
|
Map<Long, String> ramEarMap = new HashMap<>();
|
||||||
|
for (Map<String, Object> r : ramList) {
|
||||||
|
ramEarMap.put(Long.valueOf(r.get("id").toString()), r.get("manage_tags").toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 母羊列、公羊列各自独立写入,行数取两者最大值,不做轮询配对
|
||||||
|
Workbook workbook = new XSSFWorkbook();
|
||||||
|
Sheet sheet = workbook.createSheet("配种配对表");
|
||||||
|
|
||||||
|
// 母羊表头样式(粉色)
|
||||||
|
CellStyle eweHeaderStyle = workbook.createCellStyle();
|
||||||
|
Font eweFont = workbook.createFont();
|
||||||
|
eweFont.setBold(true);
|
||||||
|
eweFont.setFontHeightInPoints((short) 12);
|
||||||
|
eweHeaderStyle.setFont(eweFont);
|
||||||
|
eweHeaderStyle.setAlignment(HorizontalAlignment.CENTER);
|
||||||
|
eweHeaderStyle.setFillForegroundColor(IndexedColors.ROSE.getIndex());
|
||||||
|
eweHeaderStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||||
|
setBorder(eweHeaderStyle);
|
||||||
|
|
||||||
|
// 公羊表头样式(浅蓝)
|
||||||
|
CellStyle ramHeaderStyle = workbook.createCellStyle();
|
||||||
|
Font ramFont = workbook.createFont();
|
||||||
|
ramFont.setBold(true);
|
||||||
|
ramFont.setFontHeightInPoints((short) 12);
|
||||||
|
ramHeaderStyle.setFont(ramFont);
|
||||||
|
ramHeaderStyle.setAlignment(HorizontalAlignment.CENTER);
|
||||||
|
ramHeaderStyle.setFillForegroundColor(IndexedColors.LIGHT_BLUE.getIndex());
|
||||||
|
ramHeaderStyle.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||||
|
setBorder(ramHeaderStyle);
|
||||||
|
|
||||||
|
CellStyle dataStyle = workbook.createCellStyle();
|
||||||
|
dataStyle.setAlignment(HorizontalAlignment.CENTER);
|
||||||
|
setBorder(dataStyle);
|
||||||
|
|
||||||
|
// 写入表头
|
||||||
|
Row headerRow = sheet.createRow(0);
|
||||||
|
Cell c1 = headerRow.createCell(0);
|
||||||
|
c1.setCellValue("母羊耳号");
|
||||||
|
c1.setCellStyle(eweHeaderStyle);
|
||||||
|
Cell c2 = headerRow.createCell(1);
|
||||||
|
c2.setCellValue("公羊耳号");
|
||||||
|
c2.setCellStyle(ramHeaderStyle);
|
||||||
|
|
||||||
|
// 母羊列和公羊列各自独立写入,行数取两者最大值
|
||||||
|
int maxRows = Math.max(eweIds.size(), ramIds.size());
|
||||||
|
for (int i = 0; i < maxRows; i++) {
|
||||||
|
Row row = sheet.createRow(i + 1);
|
||||||
|
Cell dc1 = row.createCell(0);
|
||||||
|
if (i < eweIds.size()) {
|
||||||
|
dc1.setCellValue(eweEarMap.getOrDefault(eweIds.get(i), ""));
|
||||||
|
}
|
||||||
|
dc1.setCellStyle(dataStyle);
|
||||||
|
Cell dc2 = row.createCell(1);
|
||||||
|
if (i < ramIds.size()) {
|
||||||
|
dc2.setCellValue(ramEarMap.getOrDefault(ramIds.get(i), ""));
|
||||||
|
}
|
||||||
|
dc2.setCellStyle(dataStyle);
|
||||||
|
}
|
||||||
|
|
||||||
|
sheet.setColumnWidth(0, 5000);
|
||||||
|
sheet.setColumnWidth(1, 5000);
|
||||||
|
|
||||||
|
// 响应头
|
||||||
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
|
response.setCharacterEncoding("utf-8");
|
||||||
|
String fileName = java.net.URLEncoder.encode("配种配对表", "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("导出配对表失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 给样式设置边框 */
|
||||||
|
private void setBorder(CellStyle style) {
|
||||||
|
style.setBorderTop(BorderStyle.THIN);
|
||||||
|
style.setBorderBottom(BorderStyle.THIN);
|
||||||
|
style.setBorderLeft(BorderStyle.THIN);
|
||||||
|
style.setBorderRight(BorderStyle.THIN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析导入的配对Excel,返回配对预览列表
|
||||||
|
* Excel格式:第一列=母羊耳号,第二列=公羊耳号,第一行为表头(跳过)
|
||||||
|
*
|
||||||
|
* @param file 上传的Excel文件
|
||||||
|
* @return 配对列表,每项包含 eweEarNo、ramEarNo、eweId(可能null)、ramId(可能null)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<Map<String, Object>> parsePairsFromExcel(MultipartFile file)
|
||||||
|
{
|
||||||
|
List<Map<String, Object>> result = new ArrayList<>();
|
||||||
|
try (InputStream is = file.getInputStream();
|
||||||
|
Workbook workbook = WorkbookFactory.create(is)) {
|
||||||
|
|
||||||
|
Sheet sheet = workbook.getSheetAt(0);
|
||||||
|
int lastRow = sheet.getLastRowNum();
|
||||||
|
|
||||||
|
// 从第2行(index=1)开始,跳过表头
|
||||||
|
for (int i = 1; i <= lastRow; i++) {
|
||||||
|
Row row = sheet.getRow(i);
|
||||||
|
if (row == null) continue;
|
||||||
|
|
||||||
|
String eweEarNo = getCellStringValue(row.getCell(0));
|
||||||
|
String ramEarNo = getCellStringValue(row.getCell(1));
|
||||||
|
|
||||||
|
if (eweEarNo.isEmpty() && ramEarNo.isEmpty()) continue;
|
||||||
|
|
||||||
|
Map<String, Object> pair = new HashMap<>();
|
||||||
|
pair.put("eweEarNo", eweEarNo);
|
||||||
|
pair.put("ramEarNo", ramEarNo);
|
||||||
|
pair.put("rowIndex", i);
|
||||||
|
|
||||||
|
// 尝试查找对应的ID(用于校验)
|
||||||
|
Long eweId = null;
|
||||||
|
Long ramId = null;
|
||||||
|
if (!eweEarNo.isEmpty()) {
|
||||||
|
eweId = scBreedPlanGenerateMapper.selectSheepIdByManageTags(eweEarNo, 1); // 母羊 gender=1
|
||||||
|
}
|
||||||
|
if (!ramEarNo.isEmpty()) {
|
||||||
|
ramId = scBreedPlanGenerateMapper.selectSheepIdByManageTags(ramEarNo, 2); // 公羊 gender=2
|
||||||
|
}
|
||||||
|
|
||||||
|
pair.put("eweId", eweId);
|
||||||
|
pair.put("ramId", ramId);
|
||||||
|
// 校验状态
|
||||||
|
if (eweEarNo.isEmpty()) {
|
||||||
|
pair.put("valid", false);
|
||||||
|
pair.put("error", "母羊耳号不能为空");
|
||||||
|
} else if (ramEarNo.isEmpty()) {
|
||||||
|
pair.put("valid", false);
|
||||||
|
pair.put("error", "公羊耳号不能为空");
|
||||||
|
} else if (eweId == null) {
|
||||||
|
pair.put("valid", false);
|
||||||
|
pair.put("error", "母羊耳号[" + eweEarNo + "]未找到");
|
||||||
|
} else if (ramId == null) {
|
||||||
|
pair.put("valid", false);
|
||||||
|
pair.put("error", "公羊耳号[" + ramEarNo + "]未找到");
|
||||||
|
} else {
|
||||||
|
pair.put("valid", true);
|
||||||
|
pair.put("error", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
result.add(pair);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException("解析Excel失败:" + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 安全读取单元格字符串值 */
|
||||||
|
private String getCellStringValue(Cell cell) {
|
||||||
|
if (cell == null) return "";
|
||||||
|
switch (cell.getCellType()) {
|
||||||
|
case STRING: return cell.getStringCellValue().trim();
|
||||||
|
case NUMERIC: return String.valueOf((long) cell.getNumericCellValue());
|
||||||
|
default: return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据导入的配对数据(耳号列表)生成配种计划
|
||||||
|
* pairs 中每项包含 eweEarNo 和 ramEarNo(或 eweId/ramId)
|
||||||
*
|
*
|
||||||
* @param planType 计划类型
|
* @param planType 计划类型
|
||||||
* @param planName 计划名称
|
* @param pairs 配对数据列表
|
||||||
* @param eweIds 母羊ID列表
|
|
||||||
* @param ramIds 公羊ID列表
|
|
||||||
* @return 生成的配种计划
|
* @return 生成的配种计划
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
|
public ScBreedPlanGenerate autoGenerateBreedPlanFromPairs(Integer planType, List<Map<String, Object>> pairs)
|
||||||
|
{
|
||||||
|
// 收集所有有效的 eweId / ramId(去重统计用)
|
||||||
|
List<Long> eweIds = new ArrayList<>();
|
||||||
|
List<Long> ramIds = new ArrayList<>();
|
||||||
|
|
||||||
|
for (Map<String, Object> pair : pairs) {
|
||||||
|
Long eweId = null;
|
||||||
|
Long ramId = null;
|
||||||
|
|
||||||
|
// 优先用已解析的 ID;其次用耳号现查
|
||||||
|
if (pair.get("eweId") != null) {
|
||||||
|
eweId = Long.valueOf(pair.get("eweId").toString());
|
||||||
|
} else if (pair.get("eweEarNo") != null) {
|
||||||
|
eweId = scBreedPlanGenerateMapper.selectSheepIdByManageTags(pair.get("eweEarNo").toString(), 1); // 母羊 gender=1
|
||||||
|
}
|
||||||
|
if (pair.get("ramId") != null) {
|
||||||
|
ramId = Long.valueOf(pair.get("ramId").toString());
|
||||||
|
} else if (pair.get("ramEarNo") != null) {
|
||||||
|
ramId = scBreedPlanGenerateMapper.selectSheepIdByManageTags(pair.get("ramEarNo").toString(), 2); // 公羊 gender=2
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eweId == null || ramId == null) continue; // 跳过无效行
|
||||||
|
|
||||||
|
eweIds.add(eweId);
|
||||||
|
if (!ramIds.contains(ramId)) ramIds.add(ramId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eweIds.isEmpty()) {
|
||||||
|
throw new RuntimeException("没有有效的配对数据,请检查耳号是否存在");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 创建计划汇总记录
|
||||||
|
ScBreedPlanGenerate planGenerate = new ScBreedPlanGenerate();
|
||||||
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
|
String dateStr = sdf.format(new Date());
|
||||||
|
|
||||||
|
String planTypeName;
|
||||||
|
switch (planType) {
|
||||||
|
case 1: planTypeName = "供体母羊配种计划"; break;
|
||||||
|
case 2: planTypeName = "同期发情人工授精计划"; break;
|
||||||
|
case 3: planTypeName = "本交配种计划"; break;
|
||||||
|
case 4: planTypeName = "自然发情人工授精计划"; break;
|
||||||
|
default: planTypeName = "配种计划"; break;
|
||||||
|
}
|
||||||
|
|
||||||
|
planGenerate.setPlanName(dateStr + planTypeName);
|
||||||
|
planGenerate.setPlanType(planType);
|
||||||
|
planGenerate.setPlanDate(new Date());
|
||||||
|
planGenerate.setTotalEweCount(eweIds.size());
|
||||||
|
planGenerate.setTotalRamCount(ramIds.size());
|
||||||
|
double ratio = ramIds.isEmpty() ? 0 : (double) eweIds.size() / ramIds.size();
|
||||||
|
planGenerate.setBreedRatio(String.format("%.1f:1", ratio));
|
||||||
|
planGenerate.setStatus(0); // 待审批
|
||||||
|
planGenerate.setCreateBy(SecurityUtils.getUsername());
|
||||||
|
planGenerate.setCreateTime(new Date());
|
||||||
|
|
||||||
|
scBreedPlanGenerateMapper.insertScBreedPlanGenerate(planGenerate);
|
||||||
|
|
||||||
|
// 按导入的配对逐条插入临时计划(保留用户指定的配对关系)
|
||||||
|
for (Map<String, Object> pair : pairs) {
|
||||||
|
Long eweId = null;
|
||||||
|
Long ramId = null;
|
||||||
|
|
||||||
|
if (pair.get("eweId") != null) {
|
||||||
|
eweId = Long.valueOf(pair.get("eweId").toString());
|
||||||
|
} else if (pair.get("eweEarNo") != null) {
|
||||||
|
eweId = scBreedPlanGenerateMapper.selectSheepIdByManageTags(pair.get("eweEarNo").toString(), 1); // 母羊 gender=1
|
||||||
|
}
|
||||||
|
if (pair.get("ramId") != null) {
|
||||||
|
ramId = Long.valueOf(pair.get("ramId").toString());
|
||||||
|
} else if (pair.get("ramEarNo") != null) {
|
||||||
|
ramId = scBreedPlanGenerateMapper.selectSheepIdByManageTags(pair.get("ramEarNo").toString(), 2); // 公羊 gender=2
|
||||||
|
}
|
||||||
|
|
||||||
|
if (eweId == null || ramId == null) continue;
|
||||||
|
|
||||||
|
ScBreedPlan breedPlan = new ScBreedPlan();
|
||||||
|
breedPlan.setRamId(ramId.toString());
|
||||||
|
breedPlan.setEweId(eweId.toString());
|
||||||
|
breedPlan.setBreedType(Long.valueOf(planType));
|
||||||
|
scBreedPlanGenerateMapper.insertTempBreedPlan(planGenerate.getId(), breedPlan);
|
||||||
|
}
|
||||||
|
|
||||||
|
return planGenerate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自动生成配种计划(按比例自动分配,原有逻辑不变)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional
|
||||||
public ScBreedPlanGenerate autoGenerateBreedPlan(Integer planType, String planName, List<Long> eweIds, List<Long> ramIds)
|
public ScBreedPlanGenerate autoGenerateBreedPlan(Integer planType, String planName, List<Long> eweIds, List<Long> ramIds)
|
||||||
{
|
{
|
||||||
// 创建配种计划生成记录
|
|
||||||
ScBreedPlanGenerate planGenerate = new ScBreedPlanGenerate();
|
ScBreedPlanGenerate planGenerate = new ScBreedPlanGenerate();
|
||||||
|
|
||||||
// 自动生成计划名称:日期+计划类型
|
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||||
String dateStr = sdf.format(new Date());
|
String dateStr = sdf.format(new Date());
|
||||||
String planTypeName = "";
|
String planTypeName;
|
||||||
|
|
||||||
switch (planType) {
|
switch (planType) {
|
||||||
case 1: planTypeName = "供体母羊配种计划"; break;
|
case 1: planTypeName = "供体母羊配种计划"; break;
|
||||||
case 2: planTypeName = "同期发情人工授精计划"; break;
|
case 2: planTypeName = "同期发情人工授精计划"; break;
|
||||||
@@ -112,7 +381,6 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
|||||||
case 4: planTypeName = "自然发情人工授精计划"; break;
|
case 4: planTypeName = "自然发情人工授精计划"; break;
|
||||||
default: planTypeName = "未知配种计划"; break;
|
default: planTypeName = "未知配种计划"; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
planName = dateStr + planTypeName;
|
planName = dateStr + planTypeName;
|
||||||
|
|
||||||
planGenerate.setPlanName(planName);
|
planGenerate.setPlanName(planName);
|
||||||
@@ -120,26 +388,18 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
|||||||
planGenerate.setPlanDate(new Date());
|
planGenerate.setPlanDate(new Date());
|
||||||
planGenerate.setTotalEweCount(eweIds.size());
|
planGenerate.setTotalEweCount(eweIds.size());
|
||||||
planGenerate.setTotalRamCount(ramIds.size());
|
planGenerate.setTotalRamCount(ramIds.size());
|
||||||
|
|
||||||
// 计算配种比例
|
|
||||||
double ratio = (double) eweIds.size() / ramIds.size();
|
double ratio = (double) eweIds.size() / ramIds.size();
|
||||||
planGenerate.setBreedRatio(String.format("%.1f:1", ratio));
|
planGenerate.setBreedRatio(String.format("%.1f:1", ratio));
|
||||||
planGenerate.setStatus(0); // 待审批
|
planGenerate.setStatus(0);
|
||||||
planGenerate.setCreateBy(SecurityUtils.getUsername());
|
planGenerate.setCreateBy(SecurityUtils.getUsername());
|
||||||
planGenerate.setCreateTime(new Date());
|
planGenerate.setCreateTime(new Date());
|
||||||
|
|
||||||
// 保存配种计划生成记录
|
|
||||||
scBreedPlanGenerateMapper.insertScBreedPlanGenerate(planGenerate);
|
scBreedPlanGenerateMapper.insertScBreedPlanGenerate(planGenerate);
|
||||||
|
|
||||||
// 生成具体的配种计划
|
|
||||||
generateBreedPlanDetails(planGenerate.getId(), eweIds, ramIds, planType);
|
generateBreedPlanDetails(planGenerate.getId(), eweIds, ramIds, planType);
|
||||||
|
|
||||||
return planGenerate;
|
return planGenerate;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 生成具体的配种计划详情
|
|
||||||
*/
|
|
||||||
private void generateBreedPlanDetails(Long planGenerateId, List<Long> eweIds, List<Long> ramIds, Integer planType)
|
private void generateBreedPlanDetails(Long planGenerateId, List<Long> eweIds, List<Long> ramIds, Integer planType)
|
||||||
{
|
{
|
||||||
int ramIndex = 0;
|
int ramIndex = 0;
|
||||||
@@ -149,9 +409,6 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
|||||||
ScBreedPlan breedPlan = new ScBreedPlan();
|
ScBreedPlan breedPlan = new ScBreedPlan();
|
||||||
breedPlan.setRamId(ramIds.get(ramIndex).toString());
|
breedPlan.setRamId(ramIds.get(ramIndex).toString());
|
||||||
breedPlan.setEweId(eweIds.get(i).toString());
|
breedPlan.setEweId(eweIds.get(i).toString());
|
||||||
|
|
||||||
// 2. 修改:直接使用 planType 作为 breedType (假设一一对应)
|
|
||||||
// 1=供体母羊配种, 2=同期发情人工授精, 3=本交, 4=自然发情人工授精
|
|
||||||
breedPlan.setBreedType(Long.valueOf(planType));
|
breedPlan.setBreedType(Long.valueOf(planType));
|
||||||
|
|
||||||
scBreedPlanGenerateMapper.insertTempBreedPlan(planGenerateId, breedPlan);
|
scBreedPlanGenerateMapper.insertTempBreedPlan(planGenerateId, breedPlan);
|
||||||
@@ -164,9 +421,6 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增配种计划生成
|
* 新增配种计划生成
|
||||||
*
|
|
||||||
* @param scBreedPlanGenerate 配种计划生成
|
|
||||||
* @return 结果
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int insertScBreedPlanGenerate(ScBreedPlanGenerate scBreedPlanGenerate)
|
public int insertScBreedPlanGenerate(ScBreedPlanGenerate scBreedPlanGenerate)
|
||||||
@@ -177,9 +431,6 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改配种计划生成
|
* 修改配种计划生成
|
||||||
*
|
|
||||||
* @param scBreedPlanGenerate 配种计划生成
|
|
||||||
* @return 结果
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public int updateScBreedPlanGenerate(ScBreedPlanGenerate scBreedPlanGenerate)
|
public int updateScBreedPlanGenerate(ScBreedPlanGenerate scBreedPlanGenerate)
|
||||||
@@ -190,44 +441,27 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取审批配种计划详情
|
* 获取审批配种计划详情
|
||||||
*
|
|
||||||
* @param id 配种计划ID
|
|
||||||
* @return 审批配种计划详情
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> getApproveBreedPlanDetails(Long id)
|
public Map<String, Object> getApproveBreedPlanDetails(Long id)
|
||||||
{
|
{
|
||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
// 获取配种计划基本信息
|
|
||||||
ScBreedPlanGenerate planGenerate = scBreedPlanGenerateMapper.selectScBreedPlanGenerateById(id);
|
ScBreedPlanGenerate planGenerate = scBreedPlanGenerateMapper.selectScBreedPlanGenerateById(id);
|
||||||
result.put("planInfo", planGenerate);
|
result.put("planInfo", planGenerate);
|
||||||
|
|
||||||
// 获取详细的配种计划信息
|
|
||||||
List<Map<String, Object>> planDetails = scBreedPlanGenerateMapper.selectApproveBreedPlanDetails(id);
|
List<Map<String, Object>> planDetails = scBreedPlanGenerateMapper.selectApproveBreedPlanDetails(id);
|
||||||
result.put("planDetails", planDetails);
|
result.put("planDetails", planDetails);
|
||||||
|
|
||||||
// 获取可选择的公羊列表
|
|
||||||
List<Map<String, Object>> availableRams = scBreedPlanGenerateMapper.selectEligibleRam();
|
List<Map<String, Object>> availableRams = scBreedPlanGenerateMapper.selectEligibleRam();
|
||||||
result.put("availableRams", availableRams);
|
result.put("availableRams", availableRams);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 确认审批配种计划
|
* 确认审批配种计划
|
||||||
*
|
|
||||||
* @param planId 配种计划ID
|
|
||||||
* @param planDetails 配种计划详情
|
|
||||||
* @param status 审批状态
|
|
||||||
* @param approveRemark 审批意见
|
|
||||||
* @return 结果
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public int confirmApproveBreedPlan(Long planId, List<Map<String, Object>> planDetails, Integer status, String approveRemark)
|
public int confirmApproveBreedPlan(Long planId, List<Map<String, Object>> planDetails, Integer status, String approveRemark)
|
||||||
{
|
{
|
||||||
// 更新审批状态
|
|
||||||
ScBreedPlanGenerate planGenerate = new ScBreedPlanGenerate();
|
ScBreedPlanGenerate planGenerate = new ScBreedPlanGenerate();
|
||||||
planGenerate.setId(planId);
|
planGenerate.setId(planId);
|
||||||
planGenerate.setStatus(status);
|
planGenerate.setStatus(status);
|
||||||
@@ -238,16 +472,13 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
|||||||
|
|
||||||
int result = scBreedPlanGenerateMapper.updateScBreedPlanGenerate(planGenerate);
|
int result = scBreedPlanGenerateMapper.updateScBreedPlanGenerate(planGenerate);
|
||||||
|
|
||||||
// 如果审批通过,更新临时配种计划并转为正式计划
|
|
||||||
if (result > 0 && status == 1) {
|
if (result > 0 && status == 1) {
|
||||||
// 更新临时配种计划中的公羊分配
|
|
||||||
if (planDetails != null && !planDetails.isEmpty()) {
|
if (planDetails != null && !planDetails.isEmpty()) {
|
||||||
for (Map<String, Object> detail : planDetails) {
|
for (Map<String, Object> detail : planDetails) {
|
||||||
Long tempId = Long.valueOf(detail.get("id").toString());
|
Long tempId = Long.valueOf(detail.get("id").toString());
|
||||||
Long ramId = Long.valueOf(detail.get("ram_id").toString());
|
Long ramId = Long.valueOf(detail.get("ram_id").toString());
|
||||||
Long breedType = Long.valueOf(detail.get("breed_type").toString());
|
Long breedType = Long.valueOf(detail.get("breed_type").toString());
|
||||||
|
|
||||||
// 更新临时配种计划
|
|
||||||
Map<String, Object> updateParams = new HashMap<>();
|
Map<String, Object> updateParams = new HashMap<>();
|
||||||
updateParams.put("id", tempId);
|
updateParams.put("id", tempId);
|
||||||
updateParams.put("ramId", ramId);
|
updateParams.put("ramId", ramId);
|
||||||
@@ -255,65 +486,41 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
|||||||
scBreedPlanGenerateMapper.updateTempBreedPlan(updateParams);
|
scBreedPlanGenerateMapper.updateTempBreedPlan(updateParams);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 将临时配种计划转为正式配种计划
|
|
||||||
scBreedPlanGenerateMapper.transferTempToFormal(planId);
|
scBreedPlanGenerateMapper.transferTempToFormal(planId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取配种计划详情
|
* 获取配种计划详情
|
||||||
*
|
|
||||||
* @param id 配种计划ID
|
|
||||||
* @return 配种计划详情
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Object> getBreedPlanDetails(Long id)
|
public Map<String, Object> getBreedPlanDetails(Long id)
|
||||||
{
|
{
|
||||||
Map<String, Object> result = new HashMap<>();
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
// 获取配种计划基本信息
|
|
||||||
ScBreedPlanGenerate planGenerate = scBreedPlanGenerateMapper.selectScBreedPlanGenerateById(id);
|
ScBreedPlanGenerate planGenerate = scBreedPlanGenerateMapper.selectScBreedPlanGenerateById(id);
|
||||||
result.put("planInfo", planGenerate);
|
result.put("planInfo", planGenerate);
|
||||||
|
|
||||||
// 获取配种计划详情列表
|
|
||||||
List<Map<String, Object>> planDetails = scBreedPlanGenerateMapper.selectBreedPlanDetails(id);
|
List<Map<String, Object>> planDetails = scBreedPlanGenerateMapper.selectBreedPlanDetails(id);
|
||||||
result.put("planDetails", planDetails);
|
result.put("planDetails", planDetails);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出配种计划详情
|
* 导出配种计划详情(已审批)
|
||||||
*
|
|
||||||
* @param response HTTP响应
|
|
||||||
* @param id 配种计划ID
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void exportBreedPlanDetails(HttpServletResponse response, Long id)
|
public void exportBreedPlanDetails(HttpServletResponse response, Long id)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
// 获取配种计划基本信息
|
|
||||||
ScBreedPlanGenerate planGenerate = scBreedPlanGenerateMapper.selectScBreedPlanGenerateById(id);
|
ScBreedPlanGenerate planGenerate = scBreedPlanGenerateMapper.selectScBreedPlanGenerateById(id);
|
||||||
if (planGenerate == null) {
|
if (planGenerate == null) throw new RuntimeException("配种计划不存在");
|
||||||
throw new RuntimeException("配种计划不存在");
|
if (planGenerate.getStatus() != 1) throw new RuntimeException("只有已审批的配种计划才能导出");
|
||||||
}
|
|
||||||
|
|
||||||
// 检查是否已审批
|
|
||||||
if (planGenerate.getStatus() != 1) {
|
|
||||||
throw new RuntimeException("只有已审批的配种计划才能导出");
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获取配种计划详情
|
|
||||||
List<Map<String, Object>> planDetails = scBreedPlanGenerateMapper.selectBreedPlanDetails(id);
|
List<Map<String, Object>> planDetails = scBreedPlanGenerateMapper.selectBreedPlanDetails(id);
|
||||||
|
|
||||||
// 创建工作簿
|
|
||||||
Workbook workbook = new XSSFWorkbook();
|
Workbook workbook = new XSSFWorkbook();
|
||||||
Sheet sheet = workbook.createSheet("配种计划详情");
|
Sheet sheet = workbook.createSheet("配种计划详情");
|
||||||
|
|
||||||
// 创建样式
|
|
||||||
CellStyle titleStyle = workbook.createCellStyle();
|
CellStyle titleStyle = workbook.createCellStyle();
|
||||||
Font titleFont = workbook.createFont();
|
Font titleFont = workbook.createFont();
|
||||||
titleFont.setBold(true);
|
titleFont.setBold(true);
|
||||||
@@ -350,28 +557,14 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
|||||||
|
|
||||||
int rowNum = 0;
|
int rowNum = 0;
|
||||||
|
|
||||||
// 标题
|
|
||||||
Row titleRow = sheet.createRow(rowNum++);
|
Row titleRow = sheet.createRow(rowNum++);
|
||||||
Cell titleCell = titleRow.createCell(0);
|
Cell titleCell = titleRow.createCell(0);
|
||||||
titleCell.setCellValue(planGenerate.getPlanName() + " - 配种计划详情");
|
titleCell.setCellValue(planGenerate.getPlanName() + " - 配种计划详情");
|
||||||
titleCell.setCellStyle(titleStyle);
|
titleCell.setCellStyle(titleStyle);
|
||||||
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 19));
|
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 19));
|
||||||
|
|
||||||
// 空行
|
|
||||||
rowNum++;
|
rowNum++;
|
||||||
|
|
||||||
String typeName = "";
|
|
||||||
switch (planGenerate.getPlanType()) {
|
|
||||||
case 1: typeName = "供体母羊配种计划"; break;
|
|
||||||
case 2: typeName = "同期发情人工授精计划"; break;
|
|
||||||
case 3: typeName = "本交配种计划"; break;
|
|
||||||
case 4: typeName = "自然发情人工授精计划"; break;
|
|
||||||
default: typeName = "未知"; break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 基本信息
|
|
||||||
Row infoRow1 = sheet.createRow(rowNum++);
|
|
||||||
infoRow1.createCell(0).setCellValue("计划类型:");
|
|
||||||
String planTypeNameStr;
|
String planTypeNameStr;
|
||||||
Integer type = planGenerate.getPlanType();
|
Integer type = planGenerate.getPlanType();
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
@@ -385,6 +578,9 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
|||||||
} else {
|
} else {
|
||||||
planTypeNameStr = "";
|
planTypeNameStr = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Row infoRow1 = sheet.createRow(rowNum++);
|
||||||
|
infoRow1.createCell(0).setCellValue("计划类型:");
|
||||||
infoRow1.createCell(1).setCellValue(planTypeNameStr);
|
infoRow1.createCell(1).setCellValue(planTypeNameStr);
|
||||||
infoRow1.createCell(3).setCellValue("计划日期:");
|
infoRow1.createCell(3).setCellValue("计划日期:");
|
||||||
infoRow1.createCell(4).setCellValue(new SimpleDateFormat("yyyy-MM-dd").format(planGenerate.getPlanDate()));
|
infoRow1.createCell(4).setCellValue(new SimpleDateFormat("yyyy-MM-dd").format(planGenerate.getPlanDate()));
|
||||||
@@ -401,55 +597,39 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
|||||||
infoRow3.createCell(3).setCellValue("创建人:");
|
infoRow3.createCell(3).setCellValue("创建人:");
|
||||||
infoRow3.createCell(4).setCellValue(planGenerate.getCreateBy());
|
infoRow3.createCell(4).setCellValue(planGenerate.getCreateBy());
|
||||||
|
|
||||||
// 空行
|
|
||||||
rowNum++;
|
rowNum++;
|
||||||
|
|
||||||
// 分组表头
|
|
||||||
Row groupHeaderRow = sheet.createRow(rowNum++);
|
Row groupHeaderRow = sheet.createRow(rowNum++);
|
||||||
Cell groupHeaderCell1 = groupHeaderRow.createCell(1);
|
Cell gc1 = groupHeaderRow.createCell(1);
|
||||||
groupHeaderCell1.setCellValue("母羊信息");
|
gc1.setCellValue("母羊信息");
|
||||||
groupHeaderCell1.setCellStyle(eweHeaderStyle);
|
gc1.setCellStyle(eweHeaderStyle);
|
||||||
sheet.addMergedRegion(new CellRangeAddress(rowNum-1, rowNum-1, 1, 12));
|
sheet.addMergedRegion(new CellRangeAddress(rowNum - 1, rowNum - 1, 1, 12));
|
||||||
|
Cell gc2 = groupHeaderRow.createCell(13);
|
||||||
|
gc2.setCellValue("公羊信息");
|
||||||
|
gc2.setCellStyle(ramHeaderStyle);
|
||||||
|
sheet.addMergedRegion(new CellRangeAddress(rowNum - 1, rowNum - 1, 13, 19));
|
||||||
|
|
||||||
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++);
|
Row headerRow = sheet.createRow(rowNum++);
|
||||||
String[] headers = {
|
String[] headers = {
|
||||||
"序号",
|
"序号",
|
||||||
// 母羊信息
|
|
||||||
"母羊耳号", "母羊品种", "母羊家系", "母羊类别", "繁育状态", "胎次", "月龄", "体重", "核心羊群", "是否种用", "羊舍", "备注",
|
"母羊耳号", "母羊品种", "母羊家系", "母羊类别", "繁育状态", "胎次", "月龄", "体重", "核心羊群", "是否种用", "羊舍", "备注",
|
||||||
// 公羊信息
|
|
||||||
"公羊耳号", "公羊品种", "公羊家系", "公羊类别", "生日", "月龄", "体重",
|
"公羊耳号", "公羊品种", "公羊家系", "公羊类别", "生日", "月龄", "体重",
|
||||||
// 配种信息
|
|
||||||
"配种类型"
|
"配种类型"
|
||||||
};
|
};
|
||||||
|
|
||||||
for (int i = 0; i < headers.length; i++) {
|
for (int i = 0; i < headers.length; i++) {
|
||||||
Cell cell = headerRow.createCell(i);
|
Cell cell = headerRow.createCell(i);
|
||||||
cell.setCellValue(headers[i]);
|
cell.setCellValue(headers[i]);
|
||||||
if (i == 0 || i == headers.length - 1) {
|
if (i == 0 || i == headers.length - 1) cell.setCellStyle(headerStyle);
|
||||||
cell.setCellStyle(headerStyle);
|
else if (i <= 12) cell.setCellStyle(eweHeaderStyle);
|
||||||
} else if (i <= 12) {
|
else cell.setCellStyle(ramHeaderStyle);
|
||||||
cell.setCellStyle(eweHeaderStyle);
|
|
||||||
} else {
|
|
||||||
cell.setCellStyle(ramHeaderStyle);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 数据行
|
|
||||||
for (int i = 0; i < planDetails.size(); i++) {
|
for (int i = 0; i < planDetails.size(); i++) {
|
||||||
Map<String, Object> detail = planDetails.get(i);
|
Map<String, Object> detail = planDetails.get(i);
|
||||||
Row dataRow = sheet.createRow(rowNum++);
|
Row dataRow = sheet.createRow(rowNum++);
|
||||||
int colNum = 0;
|
int colNum = 0;
|
||||||
|
|
||||||
// 序号
|
|
||||||
dataRow.createCell(colNum++).setCellValue(i + 1);
|
dataRow.createCell(colNum++).setCellValue(i + 1);
|
||||||
|
|
||||||
// 母羊信息
|
|
||||||
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_manage_tags"));
|
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_manage_tags"));
|
||||||
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_variety"));
|
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_variety"));
|
||||||
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_family"));
|
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_family"));
|
||||||
@@ -462,8 +642,6 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
|||||||
dataRow.createCell(colNum++).setCellValue(getBooleanValue(detail, "ewe_is_breeding") ? "是" : "否");
|
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_sheepfold_name"));
|
||||||
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_comment"));
|
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_comment"));
|
||||||
|
|
||||||
// 公羊信息
|
|
||||||
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_manage_tags"));
|
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_manage_tags"));
|
||||||
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_variety"));
|
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_variety"));
|
||||||
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_family"));
|
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_family"));
|
||||||
@@ -472,48 +650,36 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
|||||||
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_month_age"));
|
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_month_age"));
|
||||||
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_current_weight"));
|
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_current_weight"));
|
||||||
|
|
||||||
// 配种类型
|
|
||||||
Object breedTypeObj = detail.get("breed_type");
|
Object breedTypeObj = detail.get("breed_type");
|
||||||
String breedTypeName = "未知类型";
|
String breedTypeName = "未知类型";
|
||||||
if (breedTypeObj != null) {
|
if (breedTypeObj != null) {
|
||||||
try {
|
try {
|
||||||
int typeValue = Integer.parseInt(breedTypeObj.toString());
|
int tv = Integer.parseInt(breedTypeObj.toString());
|
||||||
switch (typeValue) {
|
switch (tv) {
|
||||||
case 1: breedTypeName = "供体母羊配种"; break;
|
case 1: breedTypeName = "供体母羊配种"; break;
|
||||||
case 2: breedTypeName = "同期发情人工授精"; break;
|
case 2: breedTypeName = "同期发情人工授精"; break;
|
||||||
case 3: breedTypeName = "本交"; break;
|
case 3: breedTypeName = "本交"; break;
|
||||||
case 4: breedTypeName = "自然发情人工授精"; break;
|
case 4: breedTypeName = "自然发情人工授精"; break;
|
||||||
default: breedTypeName = "未知类型";
|
|
||||||
}
|
}
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException ignored) {}
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
dataRow.createCell(colNum++).setCellValue(breedTypeName);
|
dataRow.createCell(colNum).setCellValue(breedTypeName);
|
||||||
// 应用数据样式
|
|
||||||
for (int j = 0; j < headers.length; j++) {
|
for (int j = 0; j < headers.length; j++) {
|
||||||
if (dataRow.getCell(j) != null) {
|
if (dataRow.getCell(j) != null) dataRow.getCell(j).setCellStyle(dataStyle);
|
||||||
dataRow.getCell(j).setCellStyle(dataStyle);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 自动调整列宽
|
|
||||||
for (int i = 0; i < headers.length; i++) {
|
for (int i = 0; i < headers.length; i++) {
|
||||||
sheet.autoSizeColumn(i);
|
sheet.autoSizeColumn(i);
|
||||||
// 设置最小宽度
|
if (sheet.getColumnWidth(i) < 2000) sheet.setColumnWidth(i, 2000);
|
||||||
if (sheet.getColumnWidth(i) < 2000) {
|
|
||||||
sheet.setColumnWidth(i, 2000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置响应头
|
|
||||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
response.setCharacterEncoding("utf-8");
|
response.setCharacterEncoding("utf-8");
|
||||||
String fileName = java.net.URLEncoder.encode(planGenerate.getPlanName() + "_配种计划详情", "UTF-8").replaceAll("\\+", "%20");
|
String fileName = java.net.URLEncoder.encode(planGenerate.getPlanName() + "_配种计划详情", "UTF-8").replaceAll("\\+", "%20");
|
||||||
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
|
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
|
||||||
|
|
||||||
// 输出到响应流
|
|
||||||
workbook.write(response.getOutputStream());
|
workbook.write(response.getOutputStream());
|
||||||
workbook.close();
|
workbook.close();
|
||||||
|
|
||||||
@@ -522,17 +688,11 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 安全获取字符串值
|
|
||||||
*/
|
|
||||||
private String getStringValue(Map<String, Object> map, String key) {
|
private String getStringValue(Map<String, Object> map, String key) {
|
||||||
Object value = map.get(key);
|
Object value = map.get(key);
|
||||||
return value != null ? value.toString() : "";
|
return value != null ? value.toString() : "";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 安全获取布尔值
|
|
||||||
*/
|
|
||||||
private boolean getBooleanValue(Map<String, Object> map, String key) {
|
private boolean getBooleanValue(Map<String, Object> map, String key) {
|
||||||
Object value = map.get(key);
|
Object value = map.get(key);
|
||||||
if (value == null) return false;
|
if (value == null) return false;
|
||||||
@@ -543,15 +703,11 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量删除配种计划生成
|
* 批量删除配种计划生成
|
||||||
*
|
|
||||||
* @param ids 需要删除的配种计划生成主键
|
|
||||||
* @return 结果
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public int deleteScBreedPlanGenerateByIds(Long[] ids)
|
public int deleteScBreedPlanGenerateByIds(Long[] ids)
|
||||||
{
|
{
|
||||||
// 删除相关的临时配种计划
|
|
||||||
for (Long id : ids) {
|
for (Long id : ids) {
|
||||||
scBreedPlanGenerateMapper.deleteTempBreedPlanByPlanId(id);
|
scBreedPlanGenerateMapper.deleteTempBreedPlanByPlanId(id);
|
||||||
}
|
}
|
||||||
@@ -560,18 +716,15 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除配种计划生成信息
|
* 删除配种计划生成信息
|
||||||
*
|
|
||||||
* @param id 配种计划生成主键
|
|
||||||
* @return 结果
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public int deleteScBreedPlanGenerateById(Long id)
|
public int deleteScBreedPlanGenerateById(Long id)
|
||||||
{
|
{
|
||||||
// 先删除相关的临时配种计划
|
|
||||||
scBreedPlanGenerateMapper.deleteTempBreedPlanByPlanId(id);
|
scBreedPlanGenerateMapper.deleteTempBreedPlanByPlanId(id);
|
||||||
return scBreedPlanGenerateMapper.deleteScBreedPlanGenerateById(id);
|
return scBreedPlanGenerateMapper.deleteScBreedPlanGenerateById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> searchEarNumbers(String query) {
|
public List<String> searchEarNumbers(String query) {
|
||||||
return scBreedPlanGenerateMapper.searchEarNumbers(query);
|
return scBreedPlanGenerateMapper.searchEarNumbers(query);
|
||||||
|
|||||||
@@ -104,4 +104,9 @@ public class ScDryMilkServiceImpl implements IScDryMilkService
|
|||||||
public List<String> selectTechnicianList(String query) {
|
public List<String> selectTechnicianList(String query) {
|
||||||
return scDryMilkMapper.searchTechnicianList(query);
|
return scDryMilkMapper.searchTechnicianList(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<String> searchEarNumbers(String query) {
|
||||||
|
return scDryMilkMapper.searchEarNumbers(query);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -105,7 +105,7 @@ public class ScEmbryoFlushServiceImpl implements IScEmbryoFlushService
|
|||||||
int unfertilized = flush.getUnfertilized() != null ? flush.getUnfertilized() : 0;
|
int unfertilized = flush.getUnfertilized() != null ? flush.getUnfertilized() : 0;
|
||||||
int degenerated = flush.getDegenerated() != null ? flush.getDegenerated() : 0;
|
int degenerated = flush.getDegenerated() != null ? flush.getDegenerated() : 0;
|
||||||
|
|
||||||
// 有效胚 = A+ + A + B + C + D
|
// 有效胚 = A+ + A + B + C + D(16细胞D级) + 16细胞期
|
||||||
flush.setValidEmbryo(gradeAPlus + gradeA + gradeB + gradeC + gradeD);
|
flush.setValidEmbryo(gradeAPlus + gradeA + gradeB + gradeC + gradeD);
|
||||||
|
|
||||||
// 冲胚数 = 所有数量求和
|
// 冲胚数 = 所有数量求和
|
||||||
@@ -220,6 +220,14 @@ public class ScEmbryoFlushServiceImpl implements IScEmbryoFlushService
|
|||||||
return calculateEmbryoVarietyById(maleId, femaleId);
|
return calculateEmbryoVarietyById(maleId, femaleId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getSheepInfoByTag(String manageTag) {
|
||||||
|
if (manageTag == null || manageTag.trim().isEmpty()) {
|
||||||
|
return new HashMap<>();
|
||||||
|
}
|
||||||
|
return scEmbryoFlushMapper.selectSheepInfoByManageTag(manageTag);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据父母品种ID计算胚胎品种(核心计算方法)
|
* 根据父母品种ID计算胚胎品种(核心计算方法)
|
||||||
*
|
*
|
||||||
@@ -324,4 +332,10 @@ public class ScEmbryoFlushServiceImpl implements IScEmbryoFlushService
|
|||||||
{
|
{
|
||||||
return scEmbryoFlushMapper.selectDonorFemaleList();
|
return scEmbryoFlushMapper.selectDonorFemaleList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Map<String, Object>> selectDonorMaleList()
|
||||||
|
{
|
||||||
|
return scEmbryoFlushMapper.selectDonorMaleList();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -49,6 +49,10 @@ public class ScSheepDeathServiceImpl implements IScSheepDeathService
|
|||||||
{
|
{
|
||||||
return scSheepDeathMapper.selectSheepFileByManageTags(manageTags);
|
return scSheepDeathMapper.selectSheepFileByManageTags(manageTags);
|
||||||
}
|
}
|
||||||
|
@Override
|
||||||
|
public List<String> searchEarNumbers(String query) {
|
||||||
|
return scSheepDeathMapper.searchEarNumbers(query);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
|
|||||||
@@ -114,11 +114,6 @@ public class ScWeanRecordServiceImpl implements IScWeanRecordService
|
|||||||
return scWeanRecordMapper.selectSheepIdByEarNumber(earNumber);
|
return scWeanRecordMapper.selectSheepIdByEarNumber(earNumber);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 【新增】模糊查询耳号列表 (用于前端远程搜索)
|
|
||||||
* @param query 查询关键字
|
|
||||||
* @return 耳号列表
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> searchEarNumbers(String query) {
|
public List<String> searchEarNumbers(String query) {
|
||||||
return scWeanRecordMapper.searchEarNumbers(query);
|
return scWeanRecordMapper.searchEarNumbers(query);
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
</resultMap>
|
</resultMap>
|
||||||
|
|
||||||
<sql id="selectDdSaleVo">
|
<sql id="selectDdSaleVo">
|
||||||
select id, sale_date, cust_name, cust_phone, cust_addr, salesper, quaran_no, appr_no, price, tech, remark, create_by, create_time from dd_sl
|
select id, sale_date, cust_name, cust_phone, cust_addr, salesper, quaran_no, appr_no, price, tech, remark, create_by, create_time from dd_sl dd_sl_alias
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<select id="selectDdSaleList" parameterType="DdSale" resultMap="DdSaleResult">
|
<select id="selectDdSaleList" parameterType="DdSale" resultMap="DdSaleResult">
|
||||||
@@ -53,6 +53,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="apprNo != null and apprNo != ''"> and appr_no = #{apprNo}</if>
|
<if test="apprNo != null and apprNo != ''"> and appr_no = #{apprNo}</if>
|
||||||
<if test="price != null "> and price = #{price}</if>
|
<if test="price != null "> and price = #{price}</if>
|
||||||
<if test="tech != null and tech != ''"> and tech = #{tech}</if>
|
<if test="tech != null and tech != ''"> and tech = #{tech}</if>
|
||||||
|
${params.dataScope}
|
||||||
</where>
|
</where>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
@@ -83,7 +84,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="remark != null">remark,</if>
|
<if test="remark != null">remark,</if>
|
||||||
<if test="createBy != null">create_by,</if>
|
<if test="createBy != null">create_by,</if>
|
||||||
<if test="createTime != null">create_time,</if>
|
<if test="createTime != null">create_time,</if>
|
||||||
</trim>
|
<if test="userId != null">user_id,</if>
|
||||||
|
<if test="deptId != null">dept_id,</if>
|
||||||
|
</trim>
|
||||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||||
<if test="saleDate != null">#{saleDate},</if>
|
<if test="saleDate != null">#{saleDate},</if>
|
||||||
<if test="custName != null and custName != ''">#{custName},</if>
|
<if test="custName != null and custName != ''">#{custName},</if>
|
||||||
@@ -97,7 +100,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
<if test="remark != null">#{remark},</if>
|
<if test="remark != null">#{remark},</if>
|
||||||
<if test="createBy != null">#{createBy},</if>
|
<if test="createBy != null">#{createBy},</if>
|
||||||
<if test="createTime != null">#{createTime},</if>
|
<if test="createTime != null">#{createTime},</if>
|
||||||
</trim>
|
<if test="userId != null">#{userId},</if>
|
||||||
|
<if test="deptId != null">#{deptId},</if>
|
||||||
|
</trim>
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
<update id="updateDdSale" parameterType="DdSale">
|
<update id="updateDdSale" parameterType="DdSale">
|
||||||
|
|||||||
@@ -54,77 +54,77 @@
|
|||||||
<!-- 筛选符合条件的母羊 -->
|
<!-- 筛选符合条件的母羊 -->
|
||||||
<select id="selectEligibleEwe" resultType="Map">
|
<select id="selectEligibleEwe" resultType="Map">
|
||||||
select
|
select
|
||||||
bs.id,
|
bs.id,
|
||||||
bs.manage_tags as bs_manage_tags,
|
bs.manage_tags as bs_manage_tags,
|
||||||
bv.variety as variety,
|
bv.variety as variety,
|
||||||
bs.family,
|
bs.family,
|
||||||
bst.name as sheep_type,
|
bst.name as sheep_type,
|
||||||
bs.gender,
|
bs.gender,
|
||||||
TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) as month_age,
|
TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) as month_age,
|
||||||
bs.current_weight,
|
bs.current_weight,
|
||||||
bs.post_lambing_day,
|
bs.post_lambing_day,
|
||||||
bbs.breed as breed,
|
bbs.breed as breed,
|
||||||
bs.parity,
|
bs.parity,
|
||||||
dsf.sheepfold_name,
|
dsf.sheepfold_name,
|
||||||
bs.comment,
|
bs.comment,
|
||||||
CASE WHEN bs.is_core = 1 THEN '是' ELSE '否' END as is_core,
|
CASE WHEN bs.is_core = 1 THEN '是' ELSE '否' END as is_core,
|
||||||
CASE WHEN bs.is_breeding = 1 THEN '是' ELSE '否' END as is_breeding,
|
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
|
CONCAT('胎次:', IFNULL(bs.parity, 0), ' 配种次数:', IFNULL(bs.mating_counts, 0)) as reproduction_info
|
||||||
from bas_sheep bs
|
from bas_sheep bs
|
||||||
left join bas_sheep_variety bv on bs.variety_id = bv.id
|
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_sheep_type bst on bs.type_id = bst.id
|
||||||
left join bas_breed_status bbs on bs.breed_status_id = bbs.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
|
left join da_sheepfold dsf on bs.sheepfold_id = dsf.id
|
||||||
where bs.gender = 1
|
where bs.gender = 1
|
||||||
and bs.is_delete = 0
|
and bs.is_delete = 0
|
||||||
<if test="manageTags != null and manageTags != ''">
|
<if test="manageTags != null and manageTags != ''">
|
||||||
and bs.manage_tags like concat('%', #{manageTags}, '%')
|
and bs.manage_tags like concat('%', #{manageTags}, '%')
|
||||||
</if>
|
</if>
|
||||||
and (bs.status_id = 1 or bs.status_id is null)
|
and (bs.status_id = 1 or bs.status_id is null)
|
||||||
and (
|
and (
|
||||||
(bst.name in ('青年羊', '超龄羊') and (
|
(bst.name in ('青年羊', '超龄羊') and (
|
||||||
(bv.variety = '湖羊' and TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) >= 7.5 and bs.current_weight >= 33) or
|
(bv.variety = '湖羊' and TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) >= 7.5 and bs.current_weight >= 33) or
|
||||||
(bv.variety = '东佛里生' and TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) >= 9 and bs.current_weight >= 50) or
|
(bv.variety = '东佛里生' and TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) >= 9 and bs.current_weight >= 50) or
|
||||||
(bv.variety not in ('湖羊', '东佛里生') and TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) >= 9 and bs.current_weight >= 50)
|
(bv.variety not in ('湖羊', '东佛里生') and TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) >= 9 and bs.current_weight >= 50)
|
||||||
))
|
))
|
||||||
or
|
or
|
||||||
(bst.name in ('泌乳羊', '种母羊') and bs.post_lambing_day > 45 and bs.current_weight > 0)
|
(bst.name in ('泌乳羊', '种母羊') and bs.post_lambing_day > 45 and bs.current_weight > 0)
|
||||||
)
|
)
|
||||||
order by bv.variety, TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) desc
|
order by bv.variety, TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) desc
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
<!-- 筛选符合条件的公羊 -->
|
<!-- 筛选符合条件的公羊 -->
|
||||||
<select id="selectEligibleRam" resultType="Map">
|
<select id="selectEligibleRam" resultType="Map">
|
||||||
select
|
select
|
||||||
bs.id,
|
bs.id,
|
||||||
bs.manage_tags as bs_manage_tags,
|
bs.manage_tags as bs_manage_tags,
|
||||||
bv.variety as variety,
|
bv.variety as variety,
|
||||||
bs.family,
|
bs.family,
|
||||||
bst.name as sheep_type,
|
bst.name as sheep_type,
|
||||||
bs.gender,
|
bs.gender,
|
||||||
bs.birthday,
|
bs.birthday,
|
||||||
TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) as month_age,
|
TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) as month_age,
|
||||||
bs.current_weight,
|
bs.current_weight,
|
||||||
bbs.breed as breed
|
bbs.breed as breed
|
||||||
from bas_sheep bs
|
from bas_sheep bs
|
||||||
left join bas_sheep_variety bv on bs.variety_id = bv.id
|
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_sheep_type bst on bs.type_id = bst.id
|
||||||
left join bas_breed_status bbs on bs.breed_status_id = bbs.id
|
left join bas_breed_status bbs on bs.breed_status_id = bbs.id
|
||||||
where bs.gender = 2
|
where bs.gender = 2
|
||||||
and bs.is_delete = 0
|
and bs.is_delete = 0
|
||||||
<if test="manageTags != null and manageTags != ''">
|
<if test="manageTags != null and manageTags != ''">
|
||||||
and bs.manage_tags like concat('%', #{manageTags}, '%')
|
and bs.manage_tags like concat('%', #{manageTags}, '%')
|
||||||
</if>
|
</if>
|
||||||
and bs.status_id = 1
|
and bs.status_id = 1
|
||||||
and (
|
and (
|
||||||
(bst.name in ('青年羊', '超龄羊') and (
|
(bst.name in ('青年羊', '超龄羊') and (
|
||||||
(bv.variety = '湖羊' and TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) >= 7.5 and bs.current_weight >= 33) or
|
(bv.variety = '湖羊' and TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) >= 7.5 and bs.current_weight >= 33) or
|
||||||
(bv.variety = '东佛里生' and TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) >= 9 and bs.current_weight >= 50) or
|
(bv.variety = '东佛里生' and TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) >= 9 and bs.current_weight >= 50) or
|
||||||
(bv.variety not in ('湖羊', '东佛里生') and TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) >= 9 and bs.current_weight >= 50)
|
(bv.variety not in ('湖羊', '东佛里生') and TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) >= 9 and bs.current_weight >= 50)
|
||||||
))
|
))
|
||||||
or
|
or
|
||||||
bst.name not in ('青年羊', '超龄羊')
|
bst.name not in ('青年羊', '超龄羊')
|
||||||
)
|
)
|
||||||
order by bv.variety, TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) desc
|
order by bv.variety, TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) desc
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
@@ -325,4 +325,35 @@
|
|||||||
ORDER BY sf.bs_manage_tags
|
ORDER BY sf.bs_manage_tags
|
||||||
LIMIT 50
|
LIMIT 50
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<!-- ========== 导出配对表 / 导入配对表 相关查询 ========== -->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
根据ID列表查询羊只耳号
|
||||||
|
gender: 1=母羊 2=公羊
|
||||||
|
-->
|
||||||
|
<select id="selectEarNumbersByIds" resultType="java.util.Map">
|
||||||
|
SELECT id, manage_tags
|
||||||
|
FROM bas_sheep
|
||||||
|
WHERE gender = #{gender}
|
||||||
|
AND is_delete = 0
|
||||||
|
AND id IN
|
||||||
|
<foreach item="id" collection="ids" open="(" separator="," close=")">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
根据管理耳号查询羊只ID
|
||||||
|
gender: 1=母羊 2=公羊
|
||||||
|
-->
|
||||||
|
<select id="selectSheepIdByManageTags" resultType="java.lang.Long">
|
||||||
|
SELECT id
|
||||||
|
FROM bas_sheep
|
||||||
|
WHERE manage_tags = #{manageTags}
|
||||||
|
AND gender = #{gender}
|
||||||
|
AND is_delete = 0
|
||||||
|
LIMIT 1
|
||||||
|
</select>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
@@ -33,6 +33,16 @@
|
|||||||
<select id="selectScDryMilkList" parameterType="ScDryMilk" resultMap="ScDryMilkResult">
|
<select id="selectScDryMilkList" parameterType="ScDryMilk" resultMap="ScDryMilkResult">
|
||||||
<include refid="selectScDryMilkVo"/>
|
<include refid="selectScDryMilkVo"/>
|
||||||
<where>
|
<where>
|
||||||
|
<!-- 全部羊多耳号查询 -->
|
||||||
|
<if test="allEarNumbers != null and allEarNumbers.size() > 0">
|
||||||
|
AND (
|
||||||
|
<!-- 注意:s 代表 sheep_file 表的别名,根据实际 SQL 别名修改 -->
|
||||||
|
s.bs_manage_tags IN
|
||||||
|
<foreach collection="allEarNumbers" item="earNumber" open="(" separator="," close=")">
|
||||||
|
#{earNumber}
|
||||||
|
</foreach>
|
||||||
|
)
|
||||||
|
</if>
|
||||||
<if test="manageTagsList != null and manageTagsList.size() > 0">
|
<if test="manageTagsList != null and manageTagsList.size() > 0">
|
||||||
AND s.bs_manage_tags IN
|
AND s.bs_manage_tags IN
|
||||||
<foreach collection="manageTagsList" item="tag" open="(" separator="," close=")">
|
<foreach collection="manageTagsList" item="tag" open="(" separator="," close=")">
|
||||||
@@ -147,8 +157,8 @@
|
|||||||
SELECT DISTINCT sf.bs_manage_tags
|
SELECT DISTINCT sf.bs_manage_tags
|
||||||
FROM sheep_file sf
|
FROM sheep_file sf
|
||||||
WHERE sf.bs_manage_tags LIKE CONCAT(#{query}, '%')
|
WHERE sf.bs_manage_tags LIKE CONCAT(#{query}, '%')
|
||||||
AND sf.is_delete = 0
|
AND sf.is_delete = 0
|
||||||
ORDER BY sf.bs_manage_tags
|
ORDER BY sf.bs_manage_tags
|
||||||
LIMIT 50
|
LIMIT 50
|
||||||
</select>
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
@@ -222,4 +222,18 @@
|
|||||||
AND (sf.is_delete = 0 OR sf.is_delete IS NULL)
|
AND (sf.is_delete = 0 OR sf.is_delete IS NULL)
|
||||||
ORDER BY sf.bs_manage_tags
|
ORDER BY sf.bs_manage_tags
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<!-- 查询所有公羊列表(用于下拉选择) -->
|
||||||
|
<select id="selectDonorMaleList" resultType="java.util.Map">
|
||||||
|
SELECT DISTINCT
|
||||||
|
sf.bs_manage_tags AS manageTag,
|
||||||
|
sf.variety,
|
||||||
|
sf.variety_id AS varietyId,
|
||||||
|
sf.ranch_id AS ranchId,
|
||||||
|
sf.dr_ranch AS ranchName
|
||||||
|
FROM sheep_file sf
|
||||||
|
WHERE sf.gender = 2
|
||||||
|
AND (sf.is_delete = 0 OR sf.is_delete IS NULL)
|
||||||
|
ORDER BY sf.bs_manage_tags
|
||||||
|
</select>
|
||||||
</mapper>
|
</mapper>
|
||||||
@@ -159,6 +159,7 @@
|
|||||||
br.ram_id as ram_id,
|
br.ram_id as ram_id,
|
||||||
ram.bs_manage_tags as male_ear_number,
|
ram.bs_manage_tags as male_ear_number,
|
||||||
ram.variety as male_breed,
|
ram.variety as male_breed,
|
||||||
|
ram.family as male_lineage,
|
||||||
br.create_time as breeding_date,
|
br.create_time as breeding_date,
|
||||||
DATEDIFF(CURDATE(), br.create_time) as pregnancy_days,
|
DATEDIFF(CURDATE(), br.create_time) as pregnancy_days,
|
||||||
br.technician as technician
|
br.technician as technician
|
||||||
@@ -212,8 +213,6 @@
|
|||||||
<if test="technician != null">technician = #{technician},</if>
|
<if test="technician != null">technician = #{technician},</if>
|
||||||
<if test="score != null">score = #{score},</if>
|
<if test="score != null">score = #{score},</if>
|
||||||
<if test="comment != null">comment = #{comment},</if>
|
<if test="comment != null">comment = #{comment},</if>
|
||||||
<if test="updateBy != null">update_by = #{updateBy},</if>
|
|
||||||
<if test="updateTime != null">update_time = #{updateTime},</if>
|
|
||||||
</trim>
|
</trim>
|
||||||
where id = #{id}
|
where id = #{id}
|
||||||
</update>
|
</update>
|
||||||
|
|||||||
@@ -39,15 +39,52 @@
|
|||||||
select d.id, d.sheep_id, d.manage_tags, d.event_type, d.death_date, d.disease_type_id, d.disease_subtype_id,
|
select d.id, d.sheep_id, d.manage_tags, d.event_type, d.death_date, d.disease_type_id, d.disease_subtype_id,
|
||||||
d.disposal_direction, d.technician, d.handler, d.work_group, d.create_by, d.create_time, d.comment,
|
d.disposal_direction, d.technician, d.handler, d.work_group, d.create_by, d.create_time, d.comment,
|
||||||
d.update_by, d.update_time, d.is_delete,
|
d.update_by, d.update_time, d.is_delete,
|
||||||
s.variety, s.name as sheep_type_name, s.gender, s.day_age, s.parity, s.sheepfold_name,
|
|
||||||
s.breed as breed_status, s.post_lambing_day, s.lactation_day, s.gestation_day
|
/* --- 关联数据获取 --- */
|
||||||
|
/* 1. 品种名称 (假设品种表是 bas_variety) */
|
||||||
|
(SELECT variety FROM bas_sheep_variety WHERE id = s.variety_id) as variety,
|
||||||
|
|
||||||
|
/* 2. 羊只类型名称 (从字典表获取) */
|
||||||
|
(SELECT dict_label FROM sys_dict_data WHERE dict_type = 'sys_sheep_type' AND dict_value = s.type_id) as sheep_type_name,
|
||||||
|
|
||||||
|
/* 3. 性别直接获取 */
|
||||||
|
s.gender,
|
||||||
|
|
||||||
|
/* 4. 计算日龄 (当前日期 - 出生日期) */
|
||||||
|
DATEDIFF(NOW(), s.birthday) as day_age,
|
||||||
|
|
||||||
|
/* 5. 胎次 */
|
||||||
|
s.parity,
|
||||||
|
|
||||||
|
/* 6. 羊舍名称 (假设羊舍表是 bas_sheepfold) */
|
||||||
|
(SELECT sheepfold_name FROM da_sheepfold WHERE id = s.sheepfold_id) as sheepfold_name,
|
||||||
|
|
||||||
|
/* 7. 繁育状态 (从字典表获取) */
|
||||||
|
(SELECT breed FROM bas_breed_status WHERE id = s.status_id) as breed,
|
||||||
|
|
||||||
|
/* 8. 其他数值字段 */
|
||||||
|
s.post_lambing_day,
|
||||||
|
s.lactation_day,
|
||||||
|
s.gestation_day
|
||||||
|
|
||||||
from sc_sheep_death d
|
from sc_sheep_death d
|
||||||
left join sheep_file s on d.manage_tags = s.bs_manage_tags
|
/* 关键修改:直接关联 bas_sheep 表,而不是视图 */
|
||||||
|
/* 同时只通过 manage_tags 关联,忽略 status_id 的限制 */
|
||||||
|
left join bas_sheep s on d.manage_tags = s.manage_tags AND s.is_delete = 0
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
<select id="selectScSheepDeathList" parameterType="ScSheepDeath" resultMap="ScSheepDeathResult">
|
<select id="selectScSheepDeathList" parameterType="ScSheepDeath" resultMap="ScSheepDeathResult">
|
||||||
<include refid="selectScSheepDeathVo"/>
|
<include refid="selectScSheepDeathVo"/>
|
||||||
<where>
|
<where>
|
||||||
|
<if test="allEarNumbers != null and allEarNumbers.size() > 0">
|
||||||
|
AND (
|
||||||
|
s.manage_tags IN
|
||||||
|
<foreach collection="allEarNumbers" item="earNumber" open="(" separator="," close=")">
|
||||||
|
#{earNumber}
|
||||||
|
</foreach>
|
||||||
|
)
|
||||||
|
</if>
|
||||||
|
|
||||||
<if test="sheepId != null "> and d.sheep_id = #{sheepId}</if>
|
<if test="sheepId != null "> and d.sheep_id = #{sheepId}</if>
|
||||||
|
|
||||||
<if test="manageTagsList != null and manageTagsList.size() > 0">
|
<if test="manageTagsList != null and manageTagsList.size() > 0">
|
||||||
@@ -99,16 +136,28 @@
|
|||||||
and d.work_group = #{workGroup}
|
and d.work_group = #{workGroup}
|
||||||
</if>
|
</if>
|
||||||
|
|
||||||
<if test="variety != null and variety != ''"> and s.variety like concat('%', #{variety}, '%')</if>
|
<if test="variety != null and variety != ''">
|
||||||
|
AND s.variety_id IN (
|
||||||
|
SELECT id FROM bas_sheep_variety WHERE variety LIKE concat('%', #{variety}, '%')
|
||||||
|
)
|
||||||
|
</if>
|
||||||
|
|
||||||
<if test="sheepTypeList != null and sheepTypeList.size() > 0">
|
<if test="sheepTypeList != null and sheepTypeList.size() > 0">
|
||||||
AND s.name IN
|
AND s.type_id IN (
|
||||||
|
SELECT dict_value FROM sys_dict_data
|
||||||
|
WHERE dict_type = 'sys_sheep_type'
|
||||||
|
AND dict_label IN
|
||||||
<foreach collection="sheepTypeList" item="sType" open="(" separator="," close=")">
|
<foreach collection="sheepTypeList" item="sType" open="(" separator="," close=")">
|
||||||
#{sType}
|
#{sType}
|
||||||
</foreach>
|
</foreach>
|
||||||
|
)
|
||||||
</if>
|
</if>
|
||||||
<if test="(sheepTypeList == null or sheepTypeList.size() == 0) and sheepType != null and sheepType != ''">
|
<if test="(sheepTypeList == null or sheepTypeList.size() == 0) and sheepType != null and sheepType != ''">
|
||||||
and s.name like concat('%', #{sheepType}, '%')
|
AND s.type_id IN (
|
||||||
|
SELECT dict_value FROM sys_dict_data
|
||||||
|
WHERE dict_type = 'sys_sheep_type'
|
||||||
|
AND dict_label LIKE concat('%', #{sheepType}, '%')
|
||||||
|
)
|
||||||
</if>
|
</if>
|
||||||
</where>
|
</where>
|
||||||
order by d.create_time desc
|
order by d.create_time desc
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="com.zhyc.module.produce.breed.mapper.ScWeanRecordMapper">
|
<mapper namespace="com.zhyc.module.produce.breed.mapper.ScWeanRecordMapper">
|
||||||
|
|
||||||
<resultMap type="com.zhyc.module.produce.breed.domain.ScWeanRecord" id="ScWeanRecordResult">
|
<resultMap type="ScWeanRecord" id="ScWeanRecordResult">
|
||||||
<result property="id" column="id" />
|
<result property="id" column="id" />
|
||||||
<result property="sheepId" column="sheep_id" />
|
<result property="sheepId" column="sheep_id" />
|
||||||
<result property="datetime" column="datetime" />
|
<result property="datetime" column="datetime" />
|
||||||
@@ -44,8 +44,11 @@
|
|||||||
<where>
|
<where>
|
||||||
<!-- 全部羊多耳号查询 -->
|
<!-- 全部羊多耳号查询 -->
|
||||||
<!-- 正确:sf.bs_manage_tags,sf是sheep_file的别名 -->
|
<!-- 正确:sf.bs_manage_tags,sf是sheep_file的别名 -->
|
||||||
|
<!-- 全部羊多耳号查询 -->
|
||||||
<if test="allEarNumbers != null and allEarNumbers.size() > 0">
|
<if test="allEarNumbers != null and allEarNumbers.size() > 0">
|
||||||
AND (sf.bs_manage_tags IN
|
AND (
|
||||||
|
<!-- 注意:s 代表 sheep_file 表的别名,根据实际 SQL 别名修改 -->
|
||||||
|
sf.bs_manage_tags IN
|
||||||
<foreach collection="allEarNumbers" item="earNumber" open="(" separator="," close=")">
|
<foreach collection="allEarNumbers" item="earNumber" open="(" separator="," close=")">
|
||||||
#{earNumber}
|
#{earNumber}
|
||||||
</foreach>
|
</foreach>
|
||||||
@@ -94,6 +97,15 @@
|
|||||||
order by wr.create_time desc
|
order by wr.create_time desc
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<!-- 模糊查询耳号列表 -->
|
||||||
|
<select id="searchEarNumbers" resultType="java.lang.String">
|
||||||
|
SELECT DISTINCT sf.bs_manage_tags
|
||||||
|
FROM sheep_file sf
|
||||||
|
WHERE sf.bs_manage_tags LIKE CONCAT(#{query}, '%')
|
||||||
|
AND sf.is_delete = 0
|
||||||
|
ORDER BY sf.bs_manage_tags
|
||||||
|
LIMIT 50
|
||||||
|
</select>
|
||||||
|
|
||||||
<select id="selectScWeanRecordById" parameterType="Long" resultMap="ScWeanRecordResult">
|
<select id="selectScWeanRecordById" parameterType="Long" resultMap="ScWeanRecordResult">
|
||||||
<include refid="selectScWeanRecordVo"/>
|
<include refid="selectScWeanRecordVo"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user