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)
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody DdSale ddSale) {
|
||||
// 适配数据分离
|
||||
ddSale.setDeptId(getDeptId());
|
||||
ddSale.setUserId(getUserId());
|
||||
return toAjax(ddSaleService.insertDdSale(ddSale));
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,10 @@ import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
import java.util.Date;
|
||||
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.ToStringStyle;
|
||||
import com.zhyc.common.annotation.Excel;
|
||||
@@ -15,6 +19,8 @@ import com.zhyc.common.core.domain.BaseEntity;
|
||||
* @author HashMap
|
||||
* @date 2025-12-01
|
||||
*/
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
public class DdSale extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
@@ -59,119 +65,11 @@ public class DdSale extends BaseEntity
|
||||
@Excel(name = "技术员")
|
||||
private String tech;
|
||||
|
||||
private Long userId;
|
||||
private Long deptId;
|
||||
|
||||
/** 销售明细信息 */
|
||||
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
|
||||
public String toString() {
|
||||
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.List;
|
||||
|
||||
import com.zhyc.common.annotation.DataScope;
|
||||
import com.zhyc.common.utils.DateUtils;
|
||||
import com.zhyc.module.frozen.domain.DdFe;
|
||||
import com.zhyc.module.frozen.domain.DdFs;
|
||||
@@ -58,6 +59,7 @@ public class DdSaleServiceImpl implements IDdSaleService {
|
||||
* @return 销售主单
|
||||
*/
|
||||
@Override
|
||||
@DataScope(deptAlias = "dd_sl_alias" , userAlias = "dd_sl_alias")
|
||||
public List<DdSale> selectDdSaleList(DdSale 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.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.zhyc.common.annotation.Log;
|
||||
import com.zhyc.common.core.controller.BaseController;
|
||||
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')")
|
||||
@PostMapping("/auto")
|
||||
@@ -73,13 +156,9 @@ public class ScBreedPlanGenerateController extends BaseController
|
||||
public AjaxResult autoGenerateBreedPlan(@RequestBody Map<String, Object> params)
|
||||
{
|
||||
try {
|
||||
// 获取计划类型
|
||||
Integer planType = params.get("planType") != null ? (Integer) params.get("planType") : 1;
|
||||
|
||||
// 计划名称由系统自动生成,不再从前端传入
|
||||
String planName = null;
|
||||
|
||||
// 安全的类型转换
|
||||
List<?> eweIdsRaw = (List<?>) params.get("eweIds");
|
||||
List<?> ramIdsRaw = (List<?>) params.get("ramIds");
|
||||
|
||||
@@ -88,27 +167,13 @@ public class ScBreedPlanGenerateController extends BaseController
|
||||
}
|
||||
|
||||
List<Long> eweIds = eweIdsRaw.stream()
|
||||
.map(obj -> {
|
||||
if (obj instanceof Integer) {
|
||||
return ((Integer) obj).longValue();
|
||||
} else if (obj instanceof Long) {
|
||||
return (Long) obj;
|
||||
} else {
|
||||
return Long.valueOf(obj.toString());
|
||||
}
|
||||
})
|
||||
.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 -> {
|
||||
if (obj instanceof Integer) {
|
||||
return ((Integer) obj).longValue();
|
||||
} else if (obj instanceof Long) {
|
||||
return (Long) obj;
|
||||
} else {
|
||||
return Long.valueOf(obj.toString());
|
||||
}
|
||||
})
|
||||
.map(obj -> obj instanceof Integer ? ((Integer) obj).longValue()
|
||||
: obj instanceof Long ? (Long) obj : Long.valueOf(obj.toString()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
ScBreedPlanGenerate planGenerate = scBreedPlanGenerateService.autoGenerateBreedPlan(planType, planName, eweIds, ramIds);
|
||||
@@ -222,7 +287,6 @@ public class ScBreedPlanGenerateController extends BaseController
|
||||
scBreedPlanGenerateService.exportBreedPlanDetails(response, id);
|
||||
} catch (Exception e) {
|
||||
logger.error("导出配种计划详情失败", e);
|
||||
// 在出错时返回错误信息给前端
|
||||
try {
|
||||
response.setContentType("application/json;charset=utf-8");
|
||||
response.getWriter().write("{\"code\":500,\"msg\":\"导出失败:" + e.getMessage() + "\"}");
|
||||
@@ -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")
|
||||
public AjaxResult searchEarNumbers(@RequestParam("query") String query) {
|
||||
try {
|
||||
|
||||
@@ -79,14 +79,20 @@ public class ScDryMilkController extends BaseController
|
||||
/**
|
||||
* 远程搜索耳号列表
|
||||
*/
|
||||
/**
|
||||
* 模糊查询母羊耳号列表
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('drymilk:drymilk:query')") // 根据实际权限修改
|
||||
@GetMapping("/searchEarNumbers")
|
||||
public AjaxResult searchEarNumbers(@RequestParam(value = "query", required = false) String query)
|
||||
{
|
||||
if (query == null) query = "";
|
||||
List<String> list = scDryMilkService.selectSheepEarNumberList(query);
|
||||
return AjaxResult.success(list);
|
||||
public AjaxResult searchEarNumbers(@RequestParam("query") String query) {
|
||||
try {
|
||||
List<String> earNumbers = scDryMilkService.searchEarNumbers(query);
|
||||
return success(earNumbers);
|
||||
} catch (Exception e) {
|
||||
logger.error("搜索耳号异常", e);
|
||||
return error("搜索耳号失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 远程搜索技术员列表
|
||||
*/
|
||||
|
||||
@@ -48,6 +48,7 @@ public class ScEmbryoFlushController extends BaseController
|
||||
return getDataTable(list);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 导出冲胚记录列表
|
||||
*/
|
||||
@@ -126,4 +127,35 @@ public class ScEmbryoFlushController extends BaseController
|
||||
List<Map<String, Object>> list = scEmbryoFlushService.selectDonorFemaleList();
|
||||
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;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
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.beans.factory.annotation.Autowired;
|
||||
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.ScLambDetail;
|
||||
import com.zhyc.module.produce.breed.service.IScLambingRecordService;
|
||||
import com.zhyc.common.utils.poi.ExcelUtil;
|
||||
import com.zhyc.common.core.page.TableDataInfo;
|
||||
|
||||
/**
|
||||
@@ -55,6 +60,7 @@ public class ScLambingRecordController extends BaseController {
|
||||
return error("查询配种信息失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@PreAuthorize("@ss.hasPermi('breed:lambing_records:query')")
|
||||
@GetMapping("/search_ear_numbers")
|
||||
public AjaxResult searchEarNumbers(@RequestParam("query") String query) {
|
||||
@@ -66,25 +72,217 @@ public class ScLambingRecordController extends BaseController {
|
||||
return error("搜索耳号失败:" + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出产羔记录列表
|
||||
* 导出产羔记录列表(多Sheet:Sheet1=产羔记录,Sheet2=羔羊详情)
|
||||
*/
|
||||
@PreAuthorize("@ss.hasPermi('breed:lambing_records:export')")
|
||||
@Log(title = "产羔记录", businessType = BusinessType.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);
|
||||
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')")
|
||||
@GetMapping(value = "/{id}")
|
||||
public AjaxResult getInfo(@PathVariable("id") Long id) {
|
||||
// 修改:改为调用详细查询方法,获取包含母羊耳号、公羊耳号等关联信息
|
||||
return success(scLambingRecordService.selectScLambingRecordDetailById(id));
|
||||
}
|
||||
|
||||
@@ -96,16 +294,11 @@ public class ScLambingRecordController extends BaseController {
|
||||
@PostMapping
|
||||
public AjaxResult add(@RequestBody ScLambingRecord scLambingRecord) {
|
||||
try {
|
||||
// 设置创建人
|
||||
scLambingRecord.setCreateBy(getUsername());
|
||||
|
||||
// 如果没有设置创建时间,使用当前时间
|
||||
if (scLambingRecord.getCreateTime() == null) {
|
||||
scLambingRecord.setCreateTime(new java.util.Date());
|
||||
}
|
||||
|
||||
int result = scLambingRecordService.insertScLambingRecord(scLambingRecord);
|
||||
|
||||
if (result > 0) {
|
||||
String message = "新增产羔记录成功";
|
||||
if (scLambingRecord.getLambDetails() != null && !scLambingRecord.getLambDetails().isEmpty()) {
|
||||
|
||||
@@ -41,6 +41,20 @@ public class ScSheepDeathController extends BaseController
|
||||
@Autowired
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 【新增】模糊查询耳号列表 (用于前端下拉框远程搜索)
|
||||
*/
|
||||
@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));
|
||||
}
|
||||
|
||||
/**
|
||||
* 模糊查询母羊耳号列表
|
||||
*/
|
||||
@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 List<String> allEarNumbers;
|
||||
|
||||
public List<String> getAllEarNumbers() {
|
||||
return allEarNumbers;
|
||||
}
|
||||
|
||||
public void setAllEarNumbers(List<String> allEarNumbers) {
|
||||
this.allEarNumbers = allEarNumbers;
|
||||
}
|
||||
/** 主键id */
|
||||
private Long id;
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@ public class ScSheepDeath extends BaseEntity
|
||||
{
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
|
||||
/** 主键ID */
|
||||
private Long id;
|
||||
|
||||
|
||||
@@ -22,6 +22,17 @@ public class ScWeanRecord extends BaseEntity {
|
||||
/** 主键ID */
|
||||
private Long id;
|
||||
|
||||
/** 全部羊耳号列表(用于多耳号查询) */
|
||||
private List<String> allEarNumbers;
|
||||
|
||||
public List<String> getAllEarNumbers() {
|
||||
return allEarNumbers;
|
||||
}
|
||||
|
||||
public void setAllEarNumbers(List<String> allEarNumbers) {
|
||||
this.allEarNumbers = allEarNumbers;
|
||||
}
|
||||
|
||||
/** 羊只ID */
|
||||
@Excel(name = "羊只ID")
|
||||
private Long sheepId;
|
||||
@@ -51,10 +62,6 @@ public class ScWeanRecord extends BaseEntity {
|
||||
@Excel(name = "电子耳号")
|
||||
private String electronicTags;
|
||||
|
||||
// --- 新增查询字段 ---
|
||||
|
||||
/** 多耳号查询列表 */
|
||||
private List<String> allEarNumbers;
|
||||
|
||||
/** 是否在群 (1是 0否) */
|
||||
private String isInHerd;
|
||||
|
||||
@@ -136,4 +136,26 @@ public interface ScBreedPlanGenerateMapper
|
||||
* @return 耳号列表
|
||||
*/
|
||||
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);
|
||||
/**
|
||||
* 模糊查询母羊耳号列表
|
||||
*
|
||||
* @param query 查询关键字
|
||||
* @return 耳号列表
|
||||
*/
|
||||
List<String> searchEarNumbers(@Param("query") String query);
|
||||
}
|
||||
@@ -83,4 +83,11 @@ public interface ScEmbryoFlushMapper
|
||||
* @return 母羊列表
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* 模糊查询母羊耳号列表
|
||||
*
|
||||
* @param query 查询关键字
|
||||
* @return 耳号列表
|
||||
*/
|
||||
List<String> searchEarNumbers(@Param("query") String query);
|
||||
}
|
||||
@@ -68,9 +68,10 @@ public interface ScWeanRecordMapper
|
||||
public int updateBasSheepWeaningInfo(ScWeanRecord scWeanRecord);
|
||||
|
||||
/**
|
||||
* 【新增】模糊查询耳号列表 (用于前端远程搜索)
|
||||
* 模糊查询母羊耳号列表
|
||||
*
|
||||
* @param query 查询关键字
|
||||
* @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 javax.servlet.http.HttpServletResponse;
|
||||
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.multipart.MultipartFile;
|
||||
|
||||
/**
|
||||
* 配种计划生成Service接口
|
||||
@@ -44,6 +46,13 @@ public interface IScBreedPlanGenerateService
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* 模糊查询母羊耳号列表
|
||||
*
|
||||
* @param query 查询关键字
|
||||
* @return 耳号列表
|
||||
*/
|
||||
public List<String> searchEarNumbers(String query);
|
||||
}
|
||||
@@ -83,4 +83,13 @@ public interface IScEmbryoFlushService
|
||||
* @return 母羊列表
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* 模糊查询母羊耳号列表
|
||||
*
|
||||
* @param query 查询关键字
|
||||
* @return 耳号列表
|
||||
*/
|
||||
public List<String> searchEarNumbers(String query);
|
||||
}
|
||||
@@ -61,7 +61,8 @@ public interface IScWeanRecordService
|
||||
public Long selectSheepIdByEarNumber(String earNumber);
|
||||
|
||||
/**
|
||||
* 【新增】模糊查询耳号列表
|
||||
* 模糊查询母羊耳号列表
|
||||
*
|
||||
* @param query 查询关键字
|
||||
* @return 耳号列表
|
||||
*/
|
||||
|
||||
@@ -3,9 +3,11 @@ package com.zhyc.module.produce.breed.service.impl;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
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.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.zhyc.common.utils.SecurityUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
|
||||
@@ -40,9 +43,6 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
||||
|
||||
/**
|
||||
* 查询配种计划生成
|
||||
*
|
||||
* @param id 配种计划生成主键
|
||||
* @return 配种计划生成
|
||||
*/
|
||||
@Override
|
||||
public ScBreedPlanGenerate selectScBreedPlanGenerateById(Long id)
|
||||
@@ -52,9 +52,6 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
||||
|
||||
/**
|
||||
* 查询配种计划生成列表
|
||||
*
|
||||
* @param scBreedPlanGenerate 配种计划生成
|
||||
* @return 配种计划生成
|
||||
*/
|
||||
@Override
|
||||
public List<ScBreedPlanGenerate> selectScBreedPlanGenerateList(ScBreedPlanGenerate scBreedPlanGenerate)
|
||||
@@ -64,8 +61,6 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
||||
|
||||
/**
|
||||
* 筛选符合条件的母羊
|
||||
*
|
||||
* @return 符合条件的母羊列表
|
||||
*/
|
||||
@Override
|
||||
public List<Map<String, Object>> selectEligibleEwe(@RequestParam(value = "manageTags", required = false) String manageTags)
|
||||
@@ -75,8 +70,6 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
||||
|
||||
/**
|
||||
* 筛选符合条件的公羊
|
||||
*
|
||||
* @return 符合条件的公羊列表
|
||||
*/
|
||||
@Override
|
||||
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 planName 计划名称
|
||||
* @param eweIds 母羊ID列表
|
||||
* @param ramIds 公羊ID列表
|
||||
* @param pairs 配对数据列表
|
||||
* @return 生成的配种计划
|
||||
*/
|
||||
@Override
|
||||
@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)
|
||||
{
|
||||
// 创建配种计划生成记录
|
||||
ScBreedPlanGenerate planGenerate = new ScBreedPlanGenerate();
|
||||
|
||||
// 自动生成计划名称:日期+计划类型
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
String dateStr = sdf.format(new Date());
|
||||
String planTypeName = "";
|
||||
|
||||
String planTypeName;
|
||||
switch (planType) {
|
||||
case 1: planTypeName = "供体母羊配种计划"; break;
|
||||
case 2: planTypeName = "同期发情人工授精计划"; break;
|
||||
@@ -112,7 +381,6 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
||||
case 4: planTypeName = "自然发情人工授精计划"; break;
|
||||
default: planTypeName = "未知配种计划"; break;
|
||||
}
|
||||
|
||||
planName = dateStr + planTypeName;
|
||||
|
||||
planGenerate.setPlanName(planName);
|
||||
@@ -120,26 +388,18 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
||||
planGenerate.setPlanDate(new Date());
|
||||
planGenerate.setTotalEweCount(eweIds.size());
|
||||
planGenerate.setTotalRamCount(ramIds.size());
|
||||
|
||||
// 计算配种比例
|
||||
double ratio = (double) eweIds.size() / ramIds.size();
|
||||
planGenerate.setBreedRatio(String.format("%.1f:1", ratio));
|
||||
planGenerate.setStatus(0); // 待审批
|
||||
planGenerate.setStatus(0);
|
||||
planGenerate.setCreateBy(SecurityUtils.getUsername());
|
||||
planGenerate.setCreateTime(new Date());
|
||||
|
||||
// 保存配种计划生成记录
|
||||
scBreedPlanGenerateMapper.insertScBreedPlanGenerate(planGenerate);
|
||||
|
||||
// 生成具体的配种计划
|
||||
generateBreedPlanDetails(planGenerate.getId(), eweIds, ramIds, planType);
|
||||
|
||||
return planGenerate;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成具体的配种计划详情
|
||||
*/
|
||||
private void generateBreedPlanDetails(Long planGenerateId, List<Long> eweIds, List<Long> ramIds, Integer planType)
|
||||
{
|
||||
int ramIndex = 0;
|
||||
@@ -149,9 +409,6 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
||||
ScBreedPlan breedPlan = new ScBreedPlan();
|
||||
breedPlan.setRamId(ramIds.get(ramIndex).toString());
|
||||
breedPlan.setEweId(eweIds.get(i).toString());
|
||||
|
||||
// 2. 修改:直接使用 planType 作为 breedType (假设一一对应)
|
||||
// 1=供体母羊配种, 2=同期发情人工授精, 3=本交, 4=自然发情人工授精
|
||||
breedPlan.setBreedType(Long.valueOf(planType));
|
||||
|
||||
scBreedPlanGenerateMapper.insertTempBreedPlan(planGenerateId, breedPlan);
|
||||
@@ -164,9 +421,6 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
||||
|
||||
/**
|
||||
* 新增配种计划生成
|
||||
*
|
||||
* @param scBreedPlanGenerate 配种计划生成
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int insertScBreedPlanGenerate(ScBreedPlanGenerate scBreedPlanGenerate)
|
||||
@@ -177,9 +431,6 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
||||
|
||||
/**
|
||||
* 修改配种计划生成
|
||||
*
|
||||
* @param scBreedPlanGenerate 配种计划生成
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public int updateScBreedPlanGenerate(ScBreedPlanGenerate scBreedPlanGenerate)
|
||||
@@ -190,44 +441,27 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
||||
|
||||
/**
|
||||
* 获取审批配种计划详情
|
||||
*
|
||||
* @param id 配种计划ID
|
||||
* @return 审批配种计划详情
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> getApproveBreedPlanDetails(Long id)
|
||||
{
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
|
||||
// 获取配种计划基本信息
|
||||
ScBreedPlanGenerate planGenerate = scBreedPlanGenerateMapper.selectScBreedPlanGenerateById(id);
|
||||
result.put("planInfo", planGenerate);
|
||||
|
||||
// 获取详细的配种计划信息
|
||||
List<Map<String, Object>> planDetails = scBreedPlanGenerateMapper.selectApproveBreedPlanDetails(id);
|
||||
result.put("planDetails", planDetails);
|
||||
|
||||
// 获取可选择的公羊列表
|
||||
List<Map<String, Object>> availableRams = scBreedPlanGenerateMapper.selectEligibleRam();
|
||||
result.put("availableRams", availableRams);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认审批配种计划
|
||||
*
|
||||
* @param planId 配种计划ID
|
||||
* @param planDetails 配种计划详情
|
||||
* @param status 审批状态
|
||||
* @param approveRemark 审批意见
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public int confirmApproveBreedPlan(Long planId, List<Map<String, Object>> planDetails, Integer status, String approveRemark)
|
||||
{
|
||||
// 更新审批状态
|
||||
ScBreedPlanGenerate planGenerate = new ScBreedPlanGenerate();
|
||||
planGenerate.setId(planId);
|
||||
planGenerate.setStatus(status);
|
||||
@@ -238,16 +472,13 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
||||
|
||||
int result = scBreedPlanGenerateMapper.updateScBreedPlanGenerate(planGenerate);
|
||||
|
||||
// 如果审批通过,更新临时配种计划并转为正式计划
|
||||
if (result > 0 && status == 1) {
|
||||
// 更新临时配种计划中的公羊分配
|
||||
if (planDetails != null && !planDetails.isEmpty()) {
|
||||
for (Map<String, Object> detail : planDetails) {
|
||||
Long tempId = Long.valueOf(detail.get("id").toString());
|
||||
Long ramId = Long.valueOf(detail.get("ram_id").toString());
|
||||
Long breedType = Long.valueOf(detail.get("breed_type").toString());
|
||||
|
||||
// 更新临时配种计划
|
||||
Map<String, Object> updateParams = new HashMap<>();
|
||||
updateParams.put("id", tempId);
|
||||
updateParams.put("ramId", ramId);
|
||||
@@ -255,65 +486,41 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
||||
scBreedPlanGenerateMapper.updateTempBreedPlan(updateParams);
|
||||
}
|
||||
}
|
||||
|
||||
// 将临时配种计划转为正式配种计划
|
||||
scBreedPlanGenerateMapper.transferTempToFormal(planId);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配种计划详情
|
||||
*
|
||||
* @param id 配种计划ID
|
||||
* @return 配种计划详情
|
||||
*/
|
||||
@Override
|
||||
public Map<String, Object> getBreedPlanDetails(Long id)
|
||||
{
|
||||
Map<String, Object> result = new HashMap<>();
|
||||
|
||||
// 获取配种计划基本信息
|
||||
ScBreedPlanGenerate planGenerate = scBreedPlanGenerateMapper.selectScBreedPlanGenerateById(id);
|
||||
result.put("planInfo", planGenerate);
|
||||
|
||||
// 获取配种计划详情列表
|
||||
List<Map<String, Object>> planDetails = scBreedPlanGenerateMapper.selectBreedPlanDetails(id);
|
||||
result.put("planDetails", planDetails);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出配种计划详情
|
||||
*
|
||||
* @param response HTTP响应
|
||||
* @param id 配种计划ID
|
||||
* 导出配种计划详情(已审批)
|
||||
*/
|
||||
@Override
|
||||
public void exportBreedPlanDetails(HttpServletResponse response, Long id)
|
||||
{
|
||||
try {
|
||||
// 获取配种计划基本信息
|
||||
ScBreedPlanGenerate planGenerate = scBreedPlanGenerateMapper.selectScBreedPlanGenerateById(id);
|
||||
if (planGenerate == null) {
|
||||
throw new RuntimeException("配种计划不存在");
|
||||
}
|
||||
if (planGenerate == null) 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);
|
||||
|
||||
// 创建工作簿
|
||||
Workbook workbook = new XSSFWorkbook();
|
||||
Sheet sheet = workbook.createSheet("配种计划详情");
|
||||
|
||||
// 创建样式
|
||||
CellStyle titleStyle = workbook.createCellStyle();
|
||||
Font titleFont = workbook.createFont();
|
||||
titleFont.setBold(true);
|
||||
@@ -350,28 +557,14 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
||||
|
||||
int rowNum = 0;
|
||||
|
||||
// 标题
|
||||
Row titleRow = sheet.createRow(rowNum++);
|
||||
Cell titleCell = titleRow.createCell(0);
|
||||
titleCell.setCellValue(planGenerate.getPlanName() + " - 配种计划详情");
|
||||
titleCell.setCellStyle(titleStyle);
|
||||
sheet.addMergedRegion(new CellRangeAddress(0, 0, 0, 19));
|
||||
|
||||
// 空行
|
||||
rowNum++;
|
||||
|
||||
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;
|
||||
Integer type = planGenerate.getPlanType();
|
||||
if (type != null) {
|
||||
@@ -385,6 +578,9 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
||||
} else {
|
||||
planTypeNameStr = "";
|
||||
}
|
||||
|
||||
Row infoRow1 = sheet.createRow(rowNum++);
|
||||
infoRow1.createCell(0).setCellValue("计划类型:");
|
||||
infoRow1.createCell(1).setCellValue(planTypeNameStr);
|
||||
infoRow1.createCell(3).setCellValue("计划日期:");
|
||||
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(4).setCellValue(planGenerate.getCreateBy());
|
||||
|
||||
// 空行
|
||||
rowNum++;
|
||||
|
||||
// 分组表头
|
||||
Row groupHeaderRow = sheet.createRow(rowNum++);
|
||||
Cell groupHeaderCell1 = groupHeaderRow.createCell(1);
|
||||
groupHeaderCell1.setCellValue("母羊信息");
|
||||
groupHeaderCell1.setCellStyle(eweHeaderStyle);
|
||||
sheet.addMergedRegion(new CellRangeAddress(rowNum-1, rowNum-1, 1, 12));
|
||||
Cell gc1 = groupHeaderRow.createCell(1);
|
||||
gc1.setCellValue("母羊信息");
|
||||
gc1.setCellStyle(eweHeaderStyle);
|
||||
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++);
|
||||
String[] headers = {
|
||||
"序号",
|
||||
// 母羊信息
|
||||
"母羊耳号", "母羊品种", "母羊家系", "母羊类别", "繁育状态", "胎次", "月龄", "体重", "核心羊群", "是否种用", "羊舍", "备注",
|
||||
// 公羊信息
|
||||
"公羊耳号", "公羊品种", "公羊家系", "公羊类别", "生日", "月龄", "体重",
|
||||
// 配种信息
|
||||
"配种类型"
|
||||
};
|
||||
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
Cell cell = headerRow.createCell(i);
|
||||
cell.setCellValue(headers[i]);
|
||||
if (i == 0 || i == headers.length - 1) {
|
||||
cell.setCellStyle(headerStyle);
|
||||
} else if (i <= 12) {
|
||||
cell.setCellStyle(eweHeaderStyle);
|
||||
} else {
|
||||
cell.setCellStyle(ramHeaderStyle);
|
||||
}
|
||||
if (i == 0 || i == headers.length - 1) cell.setCellStyle(headerStyle);
|
||||
else if (i <= 12) cell.setCellStyle(eweHeaderStyle);
|
||||
else cell.setCellStyle(ramHeaderStyle);
|
||||
}
|
||||
|
||||
// 数据行
|
||||
for (int i = 0; i < planDetails.size(); i++) {
|
||||
Map<String, Object> detail = planDetails.get(i);
|
||||
Row dataRow = sheet.createRow(rowNum++);
|
||||
int colNum = 0;
|
||||
|
||||
// 序号
|
||||
dataRow.createCell(colNum++).setCellValue(i + 1);
|
||||
|
||||
// 母羊信息
|
||||
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_manage_tags"));
|
||||
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_variety"));
|
||||
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_family"));
|
||||
@@ -462,8 +642,6 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
||||
dataRow.createCell(colNum++).setCellValue(getBooleanValue(detail, "ewe_is_breeding") ? "是" : "否");
|
||||
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_sheepfold_name"));
|
||||
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ewe_comment"));
|
||||
|
||||
// 公羊信息
|
||||
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_manage_tags"));
|
||||
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_variety"));
|
||||
dataRow.createCell(colNum++).setCellValue(getStringValue(detail, "ram_family"));
|
||||
@@ -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_current_weight"));
|
||||
|
||||
// 配种类型
|
||||
Object breedTypeObj = detail.get("breed_type");
|
||||
String breedTypeName = "未知类型";
|
||||
if (breedTypeObj != null) {
|
||||
try {
|
||||
int typeValue = Integer.parseInt(breedTypeObj.toString());
|
||||
switch (typeValue) {
|
||||
int tv = Integer.parseInt(breedTypeObj.toString());
|
||||
switch (tv) {
|
||||
case 1: breedTypeName = "供体母羊配种"; break;
|
||||
case 2: breedTypeName = "同期发情人工授精"; break;
|
||||
case 3: breedTypeName = "本交"; break;
|
||||
case 4: breedTypeName = "自然发情人工授精"; break;
|
||||
default: breedTypeName = "未知类型";
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
// ignore
|
||||
}
|
||||
} catch (NumberFormatException ignored) {}
|
||||
}
|
||||
dataRow.createCell(colNum++).setCellValue(breedTypeName);
|
||||
// 应用数据样式
|
||||
dataRow.createCell(colNum).setCellValue(breedTypeName);
|
||||
|
||||
for (int j = 0; j < headers.length; j++) {
|
||||
if (dataRow.getCell(j) != null) {
|
||||
dataRow.getCell(j).setCellStyle(dataStyle);
|
||||
}
|
||||
if (dataRow.getCell(j) != null) dataRow.getCell(j).setCellStyle(dataStyle);
|
||||
}
|
||||
}
|
||||
|
||||
// 自动调整列宽
|
||||
for (int i = 0; i < headers.length; i++) {
|
||||
sheet.autoSizeColumn(i);
|
||||
// 设置最小宽度
|
||||
if (sheet.getColumnWidth(i) < 2000) {
|
||||
sheet.setColumnWidth(i, 2000);
|
||||
}
|
||||
if (sheet.getColumnWidth(i) < 2000) sheet.setColumnWidth(i, 2000);
|
||||
}
|
||||
|
||||
// 设置响应头
|
||||
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||
response.setCharacterEncoding("utf-8");
|
||||
String fileName = java.net.URLEncoder.encode(planGenerate.getPlanName() + "_配种计划详情", "UTF-8").replaceAll("\\+", "%20");
|
||||
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
|
||||
|
||||
// 输出到响应流
|
||||
workbook.write(response.getOutputStream());
|
||||
workbook.close();
|
||||
|
||||
@@ -522,17 +688,11 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全获取字符串值
|
||||
*/
|
||||
private String getStringValue(Map<String, Object> map, String key) {
|
||||
Object value = map.get(key);
|
||||
return value != null ? value.toString() : "";
|
||||
}
|
||||
|
||||
/**
|
||||
* 安全获取布尔值
|
||||
*/
|
||||
private boolean getBooleanValue(Map<String, Object> map, String key) {
|
||||
Object value = map.get(key);
|
||||
if (value == null) return false;
|
||||
@@ -543,15 +703,11 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
||||
|
||||
/**
|
||||
* 批量删除配种计划生成
|
||||
*
|
||||
* @param ids 需要删除的配种计划生成主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public int deleteScBreedPlanGenerateByIds(Long[] ids)
|
||||
{
|
||||
// 删除相关的临时配种计划
|
||||
for (Long id : ids) {
|
||||
scBreedPlanGenerateMapper.deleteTempBreedPlanByPlanId(id);
|
||||
}
|
||||
@@ -560,18 +716,15 @@ public class ScBreedPlanGenerateServiceImpl implements IScBreedPlanGenerateServi
|
||||
|
||||
/**
|
||||
* 删除配种计划生成信息
|
||||
*
|
||||
* @param id 配种计划生成主键
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional
|
||||
public int deleteScBreedPlanGenerateById(Long id)
|
||||
{
|
||||
// 先删除相关的临时配种计划
|
||||
scBreedPlanGenerateMapper.deleteTempBreedPlanByPlanId(id);
|
||||
return scBreedPlanGenerateMapper.deleteScBreedPlanGenerateById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> searchEarNumbers(String query) {
|
||||
return scBreedPlanGenerateMapper.searchEarNumbers(query);
|
||||
|
||||
@@ -104,4 +104,9 @@ public class ScDryMilkServiceImpl implements IScDryMilkService
|
||||
public List<String> selectTechnicianList(String 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 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);
|
||||
|
||||
// 冲胚数 = 所有数量求和
|
||||
@@ -220,6 +220,14 @@ public class ScEmbryoFlushServiceImpl implements IScEmbryoFlushService
|
||||
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计算胚胎品种(核心计算方法)
|
||||
*
|
||||
@@ -324,4 +332,10 @@ public class ScEmbryoFlushServiceImpl implements IScEmbryoFlushService
|
||||
{
|
||||
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);
|
||||
}
|
||||
@Override
|
||||
public List<String> searchEarNumbers(String query) {
|
||||
return scSheepDeathMapper.searchEarNumbers(query);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional
|
||||
|
||||
@@ -114,11 +114,6 @@ public class ScWeanRecordServiceImpl implements IScWeanRecordService
|
||||
return scWeanRecordMapper.selectSheepIdByEarNumber(earNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* 【新增】模糊查询耳号列表 (用于前端远程搜索)
|
||||
* @param query 查询关键字
|
||||
* @return 耳号列表
|
||||
*/
|
||||
@Override
|
||||
public List<String> searchEarNumbers(String query) {
|
||||
return scWeanRecordMapper.searchEarNumbers(query);
|
||||
|
||||
@@ -38,7 +38,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</resultMap>
|
||||
|
||||
<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>
|
||||
|
||||
<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="price != null "> and price = #{price}</if>
|
||||
<if test="tech != null and tech != ''"> and tech = #{tech}</if>
|
||||
${params.dataScope}
|
||||
</where>
|
||||
</select>
|
||||
|
||||
@@ -83,7 +84,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="remark != null">remark,</if>
|
||||
<if test="createBy != null">create_by,</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=",">
|
||||
<if test="saleDate != null">#{saleDate},</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="createBy != null">#{createBy},</if>
|
||||
<if test="createTime != null">#{createTime},</if>
|
||||
</trim>
|
||||
<if test="userId != null">#{userId},</if>
|
||||
<if test="deptId != null">#{deptId},</if>
|
||||
</trim>
|
||||
</insert>
|
||||
|
||||
<update id="updateDdSale" parameterType="DdSale">
|
||||
|
||||
@@ -54,77 +54,77 @@
|
||||
<!-- 筛选符合条件的母羊 -->
|
||||
<select id="selectEligibleEwe" resultType="Map">
|
||||
select
|
||||
bs.id,
|
||||
bs.manage_tags as bs_manage_tags,
|
||||
bv.variety as variety,
|
||||
bs.family,
|
||||
bst.name as sheep_type,
|
||||
bs.gender,
|
||||
TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) as month_age,
|
||||
bs.current_weight,
|
||||
bs.post_lambing_day,
|
||||
bbs.breed as breed,
|
||||
bs.parity,
|
||||
dsf.sheepfold_name,
|
||||
bs.comment,
|
||||
CASE WHEN bs.is_core = 1 THEN '是' ELSE '否' END as is_core,
|
||||
CASE WHEN bs.is_breeding = 1 THEN '是' ELSE '否' END as is_breeding,
|
||||
CONCAT('胎次:', IFNULL(bs.parity, 0), ' 配种次数:', IFNULL(bs.mating_counts, 0)) as reproduction_info
|
||||
bs.id,
|
||||
bs.manage_tags as bs_manage_tags,
|
||||
bv.variety as variety,
|
||||
bs.family,
|
||||
bst.name as sheep_type,
|
||||
bs.gender,
|
||||
TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) as month_age,
|
||||
bs.current_weight,
|
||||
bs.post_lambing_day,
|
||||
bbs.breed as breed,
|
||||
bs.parity,
|
||||
dsf.sheepfold_name,
|
||||
bs.comment,
|
||||
CASE WHEN bs.is_core = 1 THEN '是' ELSE '否' END as is_core,
|
||||
CASE WHEN bs.is_breeding = 1 THEN '是' ELSE '否' END as is_breeding,
|
||||
CONCAT('胎次:', IFNULL(bs.parity, 0), ' 配种次数:', IFNULL(bs.mating_counts, 0)) as reproduction_info
|
||||
from bas_sheep bs
|
||||
left join bas_sheep_variety bv on bs.variety_id = bv.id
|
||||
left join bas_sheep_type bst on bs.type_id = bst.id
|
||||
left join bas_breed_status bbs on bs.breed_status_id = bbs.id
|
||||
left join da_sheepfold dsf on bs.sheepfold_id = dsf.id
|
||||
left join bas_sheep_variety bv on bs.variety_id = bv.id
|
||||
left join bas_sheep_type bst on bs.type_id = bst.id
|
||||
left join bas_breed_status bbs on bs.breed_status_id = bbs.id
|
||||
left join da_sheepfold dsf on bs.sheepfold_id = dsf.id
|
||||
where bs.gender = 1
|
||||
and bs.is_delete = 0
|
||||
and bs.is_delete = 0
|
||||
<if test="manageTags != null and manageTags != ''">
|
||||
and bs.manage_tags like concat('%', #{manageTags}, '%')
|
||||
</if>
|
||||
and (bs.status_id = 1 or bs.status_id is null)
|
||||
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()) >= 9 and bs.current_weight >= 50) or
|
||||
(bv.variety not in ('湖羊', '东佛里生') and TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) >= 9 and bs.current_weight >= 50)
|
||||
))
|
||||
or
|
||||
(bst.name in ('泌乳羊', '种母羊') and bs.post_lambing_day > 45 and bs.current_weight > 0)
|
||||
)
|
||||
and (bs.status_id = 1 or bs.status_id is null)
|
||||
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()) >= 9 and bs.current_weight >= 50) or
|
||||
(bv.variety not in ('湖羊', '东佛里生') and TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) >= 9 and bs.current_weight >= 50)
|
||||
))
|
||||
or
|
||||
(bst.name in ('泌乳羊', '种母羊') and bs.post_lambing_day > 45 and bs.current_weight > 0)
|
||||
)
|
||||
order by bv.variety, TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) desc
|
||||
</select>
|
||||
|
||||
<!-- 筛选符合条件的公羊 -->
|
||||
<select id="selectEligibleRam" resultType="Map">
|
||||
select
|
||||
bs.id,
|
||||
bs.manage_tags as bs_manage_tags,
|
||||
bv.variety as variety,
|
||||
bs.family,
|
||||
bst.name as sheep_type,
|
||||
bs.gender,
|
||||
bs.birthday,
|
||||
TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) as month_age,
|
||||
bs.current_weight,
|
||||
bbs.breed as breed
|
||||
bs.id,
|
||||
bs.manage_tags as bs_manage_tags,
|
||||
bv.variety as variety,
|
||||
bs.family,
|
||||
bst.name as sheep_type,
|
||||
bs.gender,
|
||||
bs.birthday,
|
||||
TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) as month_age,
|
||||
bs.current_weight,
|
||||
bbs.breed as breed
|
||||
from bas_sheep bs
|
||||
left join bas_sheep_variety bv on bs.variety_id = bv.id
|
||||
left join bas_sheep_type bst on bs.type_id = bst.id
|
||||
left join bas_breed_status bbs on bs.breed_status_id = bbs.id
|
||||
left join bas_sheep_variety bv on bs.variety_id = bv.id
|
||||
left join bas_sheep_type bst on bs.type_id = bst.id
|
||||
left join bas_breed_status bbs on bs.breed_status_id = bbs.id
|
||||
where bs.gender = 2
|
||||
and bs.is_delete = 0
|
||||
and bs.is_delete = 0
|
||||
<if test="manageTags != null and manageTags != ''">
|
||||
and bs.manage_tags like concat('%', #{manageTags}, '%')
|
||||
</if>
|
||||
and bs.status_id = 1
|
||||
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()) >= 9 and bs.current_weight >= 50) or
|
||||
(bv.variety not in ('湖羊', '东佛里生') and TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) >= 9 and bs.current_weight >= 50)
|
||||
))
|
||||
or
|
||||
bst.name not in ('青年羊', '超龄羊')
|
||||
)
|
||||
and bs.status_id = 1
|
||||
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()) >= 9 and bs.current_weight >= 50) or
|
||||
(bv.variety not in ('湖羊', '东佛里生') and TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) >= 9 and bs.current_weight >= 50)
|
||||
))
|
||||
or
|
||||
bst.name not in ('青年羊', '超龄羊')
|
||||
)
|
||||
order by bv.variety, TIMESTAMPDIFF(MONTH, bs.birthday, NOW()) desc
|
||||
</select>
|
||||
|
||||
@@ -325,4 +325,35 @@
|
||||
ORDER BY sf.bs_manage_tags
|
||||
LIMIT 50
|
||||
</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>
|
||||
@@ -33,6 +33,16 @@
|
||||
<select id="selectScDryMilkList" parameterType="ScDryMilk" resultMap="ScDryMilkResult">
|
||||
<include refid="selectScDryMilkVo"/>
|
||||
<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">
|
||||
AND s.bs_manage_tags IN
|
||||
<foreach collection="manageTagsList" item="tag" open="(" separator="," close=")">
|
||||
@@ -147,8 +157,8 @@
|
||||
SELECT DISTINCT sf.bs_manage_tags
|
||||
FROM sheep_file sf
|
||||
WHERE sf.bs_manage_tags LIKE CONCAT(#{query}, '%')
|
||||
AND sf.is_delete = 0
|
||||
AND sf.is_delete = 0
|
||||
ORDER BY sf.bs_manage_tags
|
||||
LIMIT 50
|
||||
LIMIT 50
|
||||
</select>
|
||||
</mapper>
|
||||
@@ -222,4 +222,18 @@
|
||||
AND (sf.is_delete = 0 OR sf.is_delete IS NULL)
|
||||
ORDER BY sf.bs_manage_tags
|
||||
</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>
|
||||
@@ -159,6 +159,7 @@
|
||||
br.ram_id as ram_id,
|
||||
ram.bs_manage_tags as male_ear_number,
|
||||
ram.variety as male_breed,
|
||||
ram.family as male_lineage,
|
||||
br.create_time as breeding_date,
|
||||
DATEDIFF(CURDATE(), br.create_time) as pregnancy_days,
|
||||
br.technician as technician
|
||||
@@ -212,8 +213,6 @@
|
||||
<if test="technician != null">technician = #{technician},</if>
|
||||
<if test="score != null">score = #{score},</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>
|
||||
where id = #{id}
|
||||
</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,
|
||||
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,
|
||||
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
|
||||
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>
|
||||
|
||||
<select id="selectScSheepDeathList" parameterType="ScSheepDeath" resultMap="ScSheepDeathResult">
|
||||
<include refid="selectScSheepDeathVo"/>
|
||||
<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="manageTagsList != null and manageTagsList.size() > 0">
|
||||
@@ -99,16 +136,28 @@
|
||||
and d.work_group = #{workGroup}
|
||||
</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">
|
||||
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=")">
|
||||
#{sType}
|
||||
</foreach>
|
||||
)
|
||||
</if>
|
||||
<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>
|
||||
</where>
|
||||
order by d.create_time desc
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<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="sheepId" column="sheep_id" />
|
||||
<result property="datetime" column="datetime" />
|
||||
@@ -44,8 +44,11 @@
|
||||
<where>
|
||||
<!-- 全部羊多耳号查询 -->
|
||||
<!-- 正确:sf.bs_manage_tags,sf是sheep_file的别名 -->
|
||||
<!-- 全部羊多耳号查询 -->
|
||||
<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=")">
|
||||
#{earNumber}
|
||||
</foreach>
|
||||
@@ -94,6 +97,15 @@
|
||||
order by wr.create_time desc
|
||||
</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">
|
||||
<include refid="selectScWeanRecordVo"/>
|
||||
|
||||
Reference in New Issue
Block a user