生产环节优化
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
package org.jeecg.modules.xslmes.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
import org.jeecg.common.system.base.controller.JeecgController;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslMixingProductionPlan;
|
||||
import org.jeecg.modules.xslmes.service.IMesXslMixingProductionPlanService;
|
||||
import org.jeecg.modules.xslmes.vo.MesXslMixingProductionPlanOrderOptionVO;
|
||||
import org.jeecg.modules.xslmes.vo.MesXslMixingProductionPlanSaveAllVO;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Tag(name = "密炼生产计划维护")
|
||||
@RestController
|
||||
@RequestMapping("/xslmes/mesXslMixingProductionPlan")
|
||||
public class MesXslMixingProductionPlanController
|
||||
extends JeecgController<MesXslMixingProductionPlan, IMesXslMixingProductionPlanService> {
|
||||
|
||||
private final IMesXslMixingProductionPlanService mixingProductionPlanService;
|
||||
|
||||
public MesXslMixingProductionPlanController(
|
||||
IMesXslMixingProductionPlanService mixingProductionPlanService) {
|
||||
this.mixingProductionPlanService = mixingProductionPlanService;
|
||||
}
|
||||
|
||||
@Operation(summary = "密炼生产计划维护-分页列表查询")
|
||||
@GetMapping("/list")
|
||||
public Result<IPage<MesXslMixingProductionPlan>> queryPageList(
|
||||
MesXslMixingProductionPlan model,
|
||||
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "20") Integer pageSize,
|
||||
HttpServletRequest req) {
|
||||
QueryWrapper<MesXslMixingProductionPlan> queryWrapper =
|
||||
QueryGenerator.initQueryWrapper(model, req.getParameterMap());
|
||||
queryWrapper.orderByAsc("sort_no").orderByAsc("create_time");
|
||||
IPage<MesXslMixingProductionPlan> pageList =
|
||||
mixingProductionPlanService.page(new Page<>(pageNo, pageSize), queryWrapper);
|
||||
return Result.OK(pageList);
|
||||
}
|
||||
|
||||
@AutoLog(value = "密炼生产计划维护-整表保存")
|
||||
@Operation(summary = "密炼生产计划维护-整表保存")
|
||||
@RequiresPermissions("xslmes:mes_xsl_mixing_production_plan:saveAll")
|
||||
@PostMapping("/saveAll")
|
||||
public Result<String> saveAll(@RequestBody MesXslMixingProductionPlanSaveAllVO req) {
|
||||
mixingProductionPlanService.saveAllRows(req == null ? null : req.getRows());
|
||||
return Result.OK("保存成功");
|
||||
}
|
||||
|
||||
@Operation(summary = "密炼生产计划维护-班次生产订单候选分页")
|
||||
@GetMapping("/orderOptionPage")
|
||||
public Result<IPage<MesXslMixingProductionPlanOrderOptionVO>> orderOptionPage(
|
||||
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
|
||||
@RequestParam(name = "keyword", required = false) String keyword,
|
||||
@RequestParam(name = "machineId", required = false) String machineId,
|
||||
@RequestParam(name = "machineName", required = false) String machineName) {
|
||||
return Result.OK(
|
||||
mixingProductionPlanService.queryOrderOptions(
|
||||
pageNo, pageSize, keyword, machineId, machineName));
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.aspect.annotation.AutoLog;
|
||||
@@ -97,9 +98,19 @@ public class MesXslProductionOrderController
|
||||
@Operation(summary = "生产订单-拆分生成母胶计划")
|
||||
@RequiresPermissions("xslmes:mes_xsl_production_order:split")
|
||||
@PostMapping("/split")
|
||||
public Result<MesXslMasterBatchPlan> split(@RequestParam(name = "id", required = true) String id) {
|
||||
MesXslMasterBatchPlan plan = mesXslProductionOrderService.splitToMasterBatchPlan(id);
|
||||
return Result.OK("拆分成功", plan);
|
||||
public Result<List<MesXslMasterBatchPlan>> split(@RequestParam(name = "id", required = true) String id) {
|
||||
List<MesXslMasterBatchPlan> plans = mesXslProductionOrderService.splitToMasterBatchPlan(id);
|
||||
return Result.OK("拆分成功", plans);
|
||||
}
|
||||
|
||||
@AutoLog(value = "生产订单-批量拆分生成计划")
|
||||
@Operation(summary = "生产订单-批量拆分生成计划")
|
||||
@RequiresPermissions("xslmes:mes_xsl_production_order:split")
|
||||
@PostMapping("/splitBatch")
|
||||
public Result<Integer> splitBatch(@RequestParam(name = "ids", required = true) String ids) {
|
||||
List<String> idList = Arrays.asList(ids.split(","));
|
||||
int count = mesXslProductionOrderService.splitToMasterBatchPlanBatch(idList);
|
||||
return Result.OK("批量拆分成功", count);
|
||||
}
|
||||
|
||||
@RequiresPermissions("xslmes:mes_xsl_production_order:exportXls")
|
||||
|
||||
@@ -0,0 +1,178 @@
|
||||
package org.jeecg.modules.xslmes.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.shiro.SecurityUtils;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.vo.LoginUser;
|
||||
import org.jeecg.common.util.oConvertUtils;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialDemandPlanSummary;
|
||||
import org.jeecgframework.poi.excel.def.NormalExcelConstants;
|
||||
import org.jeecgframework.poi.excel.entity.ExportParams;
|
||||
import org.jeecgframework.poi.excel.entity.enmus.ExcelType;
|
||||
import org.jeecgframework.poi.excel.view.JeecgEntityExcelView;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.jdbc.core.JdbcTemplate;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
/**
|
||||
* 原材料需求计划(汇总查询)
|
||||
*/
|
||||
@Tag(name = "原材料需求计划")
|
||||
@RestController
|
||||
@RequestMapping("/xslmes/mesXslRawMaterialDemandPlan")
|
||||
public class MesXslRawMaterialDemandPlanController {
|
||||
|
||||
@Autowired private JdbcTemplate jdbcTemplate;
|
||||
|
||||
@Operation(summary = "原材料需求计划-分页列表查询")
|
||||
@GetMapping("/list")
|
||||
public Result<IPage<MesXslRawMaterialDemandPlanSummary>> queryPageList(
|
||||
MesXslRawMaterialDemandPlanSummary query,
|
||||
@RequestParam(name = "groupByMachine", required = false, defaultValue = "0") Integer groupByMachine,
|
||||
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
|
||||
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize) {
|
||||
boolean groupedByMachine = groupByMachine != null && groupByMachine == 1;
|
||||
List<Object> params = new ArrayList<>();
|
||||
String groupedSql = buildGroupedSql(query, groupedByMachine, params);
|
||||
|
||||
String countSql = "SELECT COUNT(1) FROM (" + groupedSql + ") t";
|
||||
Long total = jdbcTemplate.queryForObject(countSql, Long.class, params.toArray());
|
||||
long totalCount = total == null ? 0L : total;
|
||||
|
||||
int offset = Math.max((pageNo - 1) * pageSize, 0);
|
||||
String pageSql = groupedSql + buildOrderBy(groupedByMachine) + " LIMIT ? OFFSET ?";
|
||||
List<Object> pageParams = new ArrayList<>(params);
|
||||
pageParams.add(pageSize);
|
||||
pageParams.add(offset);
|
||||
List<MesXslRawMaterialDemandPlanSummary> rows = queryRows(pageSql, pageParams, groupedByMachine);
|
||||
|
||||
Page<MesXslRawMaterialDemandPlanSummary> page = new Page<>(pageNo, pageSize, totalCount);
|
||||
page.setRecords(rows);
|
||||
return Result.OK(page);
|
||||
}
|
||||
|
||||
@RequiresPermissions("xslmes:mes_xsl_raw_material_demand_plan:exportXls")
|
||||
@RequestMapping("/exportXls")
|
||||
public ModelAndView exportXls(
|
||||
HttpServletRequest request,
|
||||
MesXslRawMaterialDemandPlanSummary query,
|
||||
@RequestParam(name = "groupByMachine", required = false, defaultValue = "0") Integer groupByMachine) {
|
||||
boolean groupedByMachine = groupByMachine != null && groupByMachine == 1;
|
||||
List<Object> params = new ArrayList<>();
|
||||
String groupedSql = buildGroupedSql(query, groupedByMachine, params) + buildOrderBy(groupedByMachine);
|
||||
List<MesXslRawMaterialDemandPlanSummary> exportList = queryRows(groupedSql, params, groupedByMachine);
|
||||
|
||||
LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
|
||||
ModelAndView mv = new ModelAndView(new JeecgEntityExcelView());
|
||||
mv.addObject(NormalExcelConstants.FILE_NAME, "原材料需求计划");
|
||||
mv.addObject(NormalExcelConstants.CLASS, MesXslRawMaterialDemandPlanSummary.class);
|
||||
mv.addObject(
|
||||
NormalExcelConstants.PARAMS,
|
||||
new ExportParams(
|
||||
"原材料需求计划",
|
||||
"导出人:" + (sysUser == null ? "admin" : sysUser.getRealname()),
|
||||
"原材料需求计划",
|
||||
ExcelType.XSSF));
|
||||
mv.addObject(NormalExcelConstants.DATA_LIST, exportList);
|
||||
String exportFields = request.getParameter(NormalExcelConstants.EXPORT_FIELDS);
|
||||
if (oConvertUtils.isNotEmpty(exportFields)) {
|
||||
mv.addObject(NormalExcelConstants.EXPORT_FIELDS, exportFields);
|
||||
}
|
||||
return mv;
|
||||
}
|
||||
|
||||
private String buildGroupedSql(
|
||||
MesXslRawMaterialDemandPlanSummary query, boolean groupedByMachine, List<Object> params) {
|
||||
String machineExpr = "COALESCE(NULLIF(TRIM(t.machine_name),''), '')";
|
||||
String erpCodeExpr = "COALESCE(NULLIF(TRIM(t.erp_code),''), '')";
|
||||
String rawMaterialExpr = "COALESCE(NULLIF(TRIM(t.raw_material_name),''), '')";
|
||||
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.append("SELECT ");
|
||||
if (groupedByMachine) {
|
||||
sql.append(machineExpr).append(" AS machineName, ");
|
||||
} else {
|
||||
sql.append("'' AS machineName, ");
|
||||
}
|
||||
sql.append(erpCodeExpr)
|
||||
.append(" AS erpCode, ")
|
||||
.append(rawMaterialExpr)
|
||||
.append(" AS rawMaterialName, ")
|
||||
.append("SUM(COALESCE(t.demand_weight,0)) AS demandWeight, ")
|
||||
.append("SUM(COALESCE(t.standard_weight,0)) AS standardWeight, ")
|
||||
.append("SUM(COALESCE(t.actual_weight,0)) AS actualWeight ")
|
||||
.append("FROM mes_xsl_raw_material_demand_plan t ")
|
||||
.append("WHERE (t.del_flag = 0 OR t.del_flag IS NULL) ");
|
||||
|
||||
if (query != null && StringUtils.isNotBlank(query.getErpCode())) {
|
||||
sql.append("AND ").append(erpCodeExpr).append(" LIKE ? ");
|
||||
params.add("%" + query.getErpCode().trim() + "%");
|
||||
}
|
||||
if (query != null && StringUtils.isNotBlank(query.getRawMaterialName())) {
|
||||
sql.append("AND ").append(rawMaterialExpr).append(" LIKE ? ");
|
||||
params.add("%" + query.getRawMaterialName().trim() + "%");
|
||||
}
|
||||
if (groupedByMachine && query != null && StringUtils.isNotBlank(query.getMachineName())) {
|
||||
sql.append("AND ").append(machineExpr).append(" LIKE ? ");
|
||||
params.add("%" + query.getMachineName().trim() + "%");
|
||||
}
|
||||
|
||||
sql.append("GROUP BY ");
|
||||
if (groupedByMachine) {
|
||||
sql.append(machineExpr).append(", ");
|
||||
}
|
||||
sql.append(erpCodeExpr).append(", ").append(rawMaterialExpr);
|
||||
return sql.toString();
|
||||
}
|
||||
|
||||
private List<MesXslRawMaterialDemandPlanSummary> queryRows(
|
||||
String sql, List<Object> params, boolean groupedByMachine) {
|
||||
return jdbcTemplate.query(
|
||||
sql,
|
||||
rs -> {
|
||||
List<MesXslRawMaterialDemandPlanSummary> list = new ArrayList<>();
|
||||
int seq = 1;
|
||||
while (rs.next()) {
|
||||
MesXslRawMaterialDemandPlanSummary row = new MesXslRawMaterialDemandPlanSummary();
|
||||
row.setMachineName(groupedByMachine ? trim(rs.getString("machineName")) : "");
|
||||
row.setErpCode(trim(rs.getString("erpCode")));
|
||||
row.setRawMaterialName(trim(rs.getString("rawMaterialName")));
|
||||
row.setDemandWeight(rs.getBigDecimal("demandWeight"));
|
||||
row.setStandardWeight(rs.getBigDecimal("standardWeight"));
|
||||
row.setActualWeight(rs.getBigDecimal("actualWeight"));
|
||||
row.setId(buildRowId(row, groupedByMachine, seq++));
|
||||
list.add(row);
|
||||
}
|
||||
return list;
|
||||
},
|
||||
params.toArray());
|
||||
}
|
||||
|
||||
private String buildOrderBy(boolean groupedByMachine) {
|
||||
if (groupedByMachine) {
|
||||
return " ORDER BY machineName, rawMaterialName, erpCode";
|
||||
}
|
||||
return " ORDER BY rawMaterialName, erpCode";
|
||||
}
|
||||
|
||||
private String buildRowId(MesXslRawMaterialDemandPlanSummary row, boolean groupedByMachine, int seq) {
|
||||
String machine = groupedByMachine ? StringUtils.defaultString(row.getMachineName()) : "ALL";
|
||||
return machine + "_" + StringUtils.defaultString(row.getErpCode()) + "_" + seq;
|
||||
}
|
||||
|
||||
private String trim(String value) {
|
||||
return value == null ? "" : value.trim();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,132 @@
|
||||
package org.jeecg.modules.xslmes.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.experimental.Accessors;
|
||||
import org.jeecg.common.aspect.annotation.Dict;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
/**
|
||||
* 密炼生产计划维护
|
||||
*/
|
||||
@Data
|
||||
@TableName("mes_xsl_mixing_production_plan")
|
||||
@Accessors(chain = true)
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
@Schema(description = "密炼生产计划维护")
|
||||
public class MesXslMixingProductionPlan implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@TableId(type = IdType.ASSIGN_ID)
|
||||
private String id;
|
||||
|
||||
@Excel(name = "排序号", width = 10)
|
||||
@Schema(description = "排序号")
|
||||
private Integer sortNo;
|
||||
|
||||
@Excel(name = "机台", width = 20, dictTable = "mes_xsl_equipment_ledger", dicText = "equipment_name", dicCode = "id")
|
||||
@Dict(dictTable = "mes_xsl_equipment_ledger", dicText = "equipment_name", dicCode = "id")
|
||||
@Schema(description = "机台ID")
|
||||
private String machineId;
|
||||
|
||||
@Excel(name = "机台", width = 20)
|
||||
@Schema(description = "机台名称")
|
||||
private String machineName;
|
||||
|
||||
@Schema(description = "早班计划ID")
|
||||
private String morningPlanId;
|
||||
@Schema(description = "早班计划类型 M母胶/F终胶")
|
||||
private String morningPlanType;
|
||||
@Excel(name = "早班生产订单", width = 20)
|
||||
private String morningOrderNo;
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
@Schema(description = "早班订单日期")
|
||||
private Date morningOrderDate;
|
||||
@Excel(name = "早班配方名称", width = 20)
|
||||
private String morningFormulaName;
|
||||
@Excel(name = "早班计划重量", width = 15)
|
||||
private BigDecimal morningPlanWeight;
|
||||
@Excel(name = "早班计划车数", width = 12)
|
||||
private Integer morningPlannedCarCount;
|
||||
@Excel(name = "早班已排产车数", width = 12)
|
||||
private Integer morningScheduledCarCount;
|
||||
@Excel(name = "早班完成车数", width = 12)
|
||||
private Integer morningFinishedCarCount;
|
||||
@Excel(name = "早班计划", width = 12)
|
||||
private Integer morningPlanCount;
|
||||
@Excel(name = "早班备注", width = 20)
|
||||
private String morningRemark;
|
||||
|
||||
@Schema(description = "中班计划ID")
|
||||
private String noonPlanId;
|
||||
@Schema(description = "中班计划类型 M母胶/F终胶")
|
||||
private String noonPlanType;
|
||||
@Excel(name = "中班生产订单", width = 20)
|
||||
private String noonOrderNo;
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
@Schema(description = "中班订单日期")
|
||||
private Date noonOrderDate;
|
||||
@Excel(name = "中班配方名称", width = 20)
|
||||
private String noonFormulaName;
|
||||
@Excel(name = "中班计划重量", width = 15)
|
||||
private BigDecimal noonPlanWeight;
|
||||
@Excel(name = "中班计划车数", width = 12)
|
||||
private Integer noonPlannedCarCount;
|
||||
@Excel(name = "中班已排产车数", width = 12)
|
||||
private Integer noonScheduledCarCount;
|
||||
@Excel(name = "中班完成车数", width = 12)
|
||||
private Integer noonFinishedCarCount;
|
||||
@Excel(name = "中班计划", width = 12)
|
||||
private Integer noonPlanCount;
|
||||
@Excel(name = "中班备注", width = 20)
|
||||
private String noonRemark;
|
||||
|
||||
@Schema(description = "晚班计划ID")
|
||||
private String nightPlanId;
|
||||
@Schema(description = "晚班计划类型 M母胶/F终胶")
|
||||
private String nightPlanType;
|
||||
@Excel(name = "晚班生产订单", width = 20)
|
||||
private String nightOrderNo;
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
@Schema(description = "晚班订单日期")
|
||||
private Date nightOrderDate;
|
||||
@Excel(name = "晚班配方名称", width = 20)
|
||||
private String nightFormulaName;
|
||||
@Excel(name = "晚班计划重量", width = 15)
|
||||
private BigDecimal nightPlanWeight;
|
||||
@Excel(name = "晚班计划车数", width = 12)
|
||||
private Integer nightPlannedCarCount;
|
||||
@Excel(name = "晚班已排产车数", width = 12)
|
||||
private Integer nightScheduledCarCount;
|
||||
@Excel(name = "晚班完成车数", width = 12)
|
||||
private Integer nightFinishedCarCount;
|
||||
@Excel(name = "晚班计划", width = 12)
|
||||
private Integer nightPlanCount;
|
||||
@Excel(name = "晚班备注", width = 20)
|
||||
private String nightRemark;
|
||||
|
||||
private Integer tenantId;
|
||||
private String sysOrgCode;
|
||||
private String createBy;
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
private String updateBy;
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date updateTime;
|
||||
private Integer delFlag;
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
package org.jeecg.modules.xslmes.entity;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigDecimal;
|
||||
import lombok.Data;
|
||||
import org.jeecgframework.poi.excel.annotation.Excel;
|
||||
|
||||
/**
|
||||
* 原材料需求计划汇总(按原材料或按机台+原材料)
|
||||
*/
|
||||
@Data
|
||||
@Schema(description = "原材料需求计划汇总")
|
||||
public class MesXslRawMaterialDemandPlanSummary implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Schema(description = "主键")
|
||||
private String id;
|
||||
|
||||
@Excel(name = "机台", width = 20)
|
||||
@Schema(description = "机台")
|
||||
private String machineName;
|
||||
|
||||
@Excel(name = "ERP编号", width = 18)
|
||||
@Schema(description = "ERP编号")
|
||||
private String erpCode;
|
||||
|
||||
@Excel(name = "原材料名称", width = 24)
|
||||
@Schema(description = "原材料名称")
|
||||
private String rawMaterialName;
|
||||
|
||||
@Excel(name = "需求重量", width = 15)
|
||||
@Schema(description = "需求重量")
|
||||
private BigDecimal demandWeight;
|
||||
|
||||
@Excel(name = "标准重量", width = 15)
|
||||
@Schema(description = "标准重量")
|
||||
private BigDecimal standardWeight;
|
||||
|
||||
@Excel(name = "实际重量", width = 15)
|
||||
@Schema(description = "实际重量")
|
||||
private BigDecimal actualWeight;
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package org.jeecg.modules.xslmes.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslMixingProductionPlan;
|
||||
|
||||
public interface MesXslMixingProductionPlanMapper extends BaseMapper<MesXslMixingProductionPlan> {}
|
||||
@@ -1,10 +1,13 @@
|
||||
package org.jeecg.modules.xslmes.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import java.util.List;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslMasterBatchPlan;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslProductionOrder;
|
||||
|
||||
public interface IMesXslMasterBatchPlanService extends IService<MesXslMasterBatchPlan> {
|
||||
|
||||
List<MesXslMasterBatchPlan> generateBatchFromProductionOrder(MesXslProductionOrder productionOrder);
|
||||
|
||||
MesXslMasterBatchPlan generateFromProductionOrder(MesXslProductionOrder productionOrder);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package org.jeecg.modules.xslmes.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import java.util.List;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslMixingProductionPlan;
|
||||
import org.jeecg.modules.xslmes.vo.MesXslMixingProductionPlanOrderOptionVO;
|
||||
|
||||
public interface IMesXslMixingProductionPlanService extends IService<MesXslMixingProductionPlan> {
|
||||
void saveAllRows(List<MesXslMixingProductionPlan> rows);
|
||||
|
||||
IPage<MesXslMixingProductionPlanOrderOptionVO> queryOrderOptions(
|
||||
Integer pageNo, Integer pageSize, String keyword, String machineId, String machineName);
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
package org.jeecg.modules.xslmes.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import java.util.List;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslMasterBatchPlan;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslProductionOrder;
|
||||
|
||||
public interface IMesXslProductionOrderService extends IService<MesXslProductionOrder> {
|
||||
|
||||
MesXslMasterBatchPlan splitToMasterBatchPlan(String id);
|
||||
List<MesXslMasterBatchPlan> splitToMasterBatchPlan(String id);
|
||||
|
||||
int splitToMasterBatchPlanBatch(List<String> ids);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,10 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.modules.mes.material.entity.MesMaterial;
|
||||
@@ -33,7 +37,7 @@ public class MesXslFinalBatchPlanServiceImpl
|
||||
return exists;
|
||||
}
|
||||
|
||||
MesMaterial finalMaterial = resolveFinalMaterial(productionOrder.getMaterialCode());
|
||||
MesMaterial finalMaterial = resolveFinalMaterial(productionOrder);
|
||||
if (finalMaterial == null) {
|
||||
throw new JeecgBootException("未找到对应终胶物料,请确认MES物料编码");
|
||||
}
|
||||
@@ -60,16 +64,67 @@ public class MesXslFinalBatchPlanServiceImpl
|
||||
return plan;
|
||||
}
|
||||
|
||||
private MesMaterial resolveFinalMaterial(String mesMaterialCode) {
|
||||
if (StringUtils.isBlank(mesMaterialCode)) {
|
||||
private MesMaterial resolveFinalMaterial(MesXslProductionOrder productionOrder) {
|
||||
for (String seedCode : resolveSplitSeedCodes(productionOrder)) {
|
||||
for (String candidateCode : buildFinalCandidates(seedCode)) {
|
||||
MesMaterial matched = resolveMaterialByBaseCode(candidateCode);
|
||||
if (matched != null) {
|
||||
MesMaterial resolved = new MesMaterial();
|
||||
resolved.setMaterialCode(candidateCode);
|
||||
resolved.setMaterialName(StringUtils.defaultIfBlank(matched.getMaterialName(), candidateCode));
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private MesMaterial resolveMaterialByBaseCode(String baseCode) {
|
||||
if (StringUtils.isBlank(baseCode)) {
|
||||
return null;
|
||||
}
|
||||
MesMaterial exact =
|
||||
mesMaterialMapper.selectOne(
|
||||
new LambdaQueryWrapper<MesMaterial>()
|
||||
.eq(MesMaterial::getMaterialCode, baseCode)
|
||||
.last("LIMIT 1"));
|
||||
if (exact != null) {
|
||||
return exact;
|
||||
}
|
||||
return mesMaterialMapper.selectOne(
|
||||
new LambdaQueryWrapper<MesMaterial>()
|
||||
.eq(MesMaterial::getMaterialCode, mesMaterialCode.trim())
|
||||
.likeRight(MesMaterial::getMaterialCode, baseCode)
|
||||
.last("LIMIT 1"));
|
||||
}
|
||||
|
||||
private List<String> resolveSplitSeedCodes(MesXslProductionOrder productionOrder) {
|
||||
Set<String> seeds = new LinkedHashSet<>();
|
||||
if (productionOrder != null) {
|
||||
if (StringUtils.isNotBlank(productionOrder.getMesMaterialName())) {
|
||||
seeds.add(productionOrder.getMesMaterialName().trim());
|
||||
}
|
||||
if (StringUtils.isNotBlank(productionOrder.getMaterialCode())) {
|
||||
seeds.add(productionOrder.getMaterialCode().trim());
|
||||
}
|
||||
}
|
||||
return new ArrayList<>(seeds);
|
||||
}
|
||||
|
||||
private List<String> buildFinalCandidates(String code) {
|
||||
List<String> candidates = new ArrayList<>(2);
|
||||
if (StringUtils.isBlank(code)) {
|
||||
return candidates;
|
||||
}
|
||||
String trimmed = code.trim();
|
||||
if (trimmed.length() > 0 && (trimmed.startsWith("F") || trimmed.startsWith("f"))) {
|
||||
candidates.add(trimmed);
|
||||
return candidates;
|
||||
}
|
||||
candidates.add("F" + trimmed);
|
||||
candidates.add(trimmed);
|
||||
return candidates;
|
||||
}
|
||||
|
||||
private String buildOrderSerialNo(MesXslProductionOrder productionOrder) {
|
||||
String orderNo = StringUtils.defaultIfBlank(productionOrder.getProductionOrderNo(), productionOrder.getId());
|
||||
return orderNo + "-F-" + System.currentTimeMillis();
|
||||
|
||||
@@ -5,7 +5,9 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.modules.mes.material.entity.MesMaterial;
|
||||
@@ -25,28 +27,55 @@ public class MesXslMasterBatchPlanServiceImpl
|
||||
@Autowired private MesMaterialMapper mesMaterialMapper;
|
||||
|
||||
@Override
|
||||
public MesXslMasterBatchPlan generateFromProductionOrder(MesXslProductionOrder productionOrder) {
|
||||
public List<MesXslMasterBatchPlan> generateBatchFromProductionOrder(MesXslProductionOrder productionOrder) {
|
||||
if (productionOrder == null || StringUtils.isBlank(productionOrder.getId())) {
|
||||
throw new JeecgBootException("生产订单不存在,无法拆分");
|
||||
}
|
||||
MesMaterial motherMaterial = resolveMotherMaterial(productionOrder.getMaterialCode());
|
||||
if (motherMaterial == null) {
|
||||
throw new JeecgBootException("未找到对应母胶物料(优先B1,其次B2)");
|
||||
int totalSegments = normalizeSegmentCount(productionOrder.getProcessSegmentCount());
|
||||
int motherSegments = Math.max(totalSegments - 1, 0);
|
||||
if (motherSegments <= 0) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
MesXslMasterBatchPlan exists =
|
||||
this.getOne(new LambdaQueryWrapper<MesXslMasterBatchPlan>().eq(MesXslMasterBatchPlan::getSourceOrderId, productionOrder.getId()));
|
||||
if (exists != null) {
|
||||
return exists;
|
||||
List<MesXslMasterBatchPlan> existingPlans =
|
||||
this.list(
|
||||
new LambdaQueryWrapper<MesXslMasterBatchPlan>()
|
||||
.eq(MesXslMasterBatchPlan::getSourceOrderId, productionOrder.getId())
|
||||
.orderByAsc(MesXslMasterBatchPlan::getCreateTime)
|
||||
.orderByAsc(MesXslMasterBatchPlan::getId));
|
||||
List<MesXslMasterBatchPlan> result = new ArrayList<>();
|
||||
for (int stageIndex = 1; stageIndex <= motherSegments; stageIndex++) {
|
||||
MesMaterial motherMaterial = resolveMotherMaterialByStage(productionOrder, stageIndex);
|
||||
if (motherMaterial == null) {
|
||||
throw new JeecgBootException("未找到对应母胶物料(第" + stageIndex + "段,编码前缀B" + stageIndex + ")");
|
||||
}
|
||||
MesXslMasterBatchPlan matched = findExistingByMaterialCode(existingPlans, motherMaterial.getMaterialCode());
|
||||
if (matched != null) {
|
||||
result.add(matched);
|
||||
continue;
|
||||
}
|
||||
MesXslMasterBatchPlan plan = buildMotherPlan(productionOrder, motherMaterial, stageIndex);
|
||||
this.save(plan);
|
||||
result.add(plan);
|
||||
existingPlans.add(plan);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MesXslMasterBatchPlan generateFromProductionOrder(MesXslProductionOrder productionOrder) {
|
||||
List<MesXslMasterBatchPlan> plans = generateBatchFromProductionOrder(productionOrder);
|
||||
return plans.isEmpty() ? null : plans.get(0);
|
||||
}
|
||||
|
||||
private MesXslMasterBatchPlan buildMotherPlan(
|
||||
MesXslProductionOrder productionOrder, MesMaterial motherMaterial, int stageIndex) {
|
||||
BigDecimal planWeight = productionOrder.getPlanQty() == null ? BigDecimal.ZERO : productionOrder.getPlanQty();
|
||||
BigDecimal perCarWeight = BigDecimal.ZERO;
|
||||
int planCarCount = calcPlanCarCount(planWeight, perCarWeight);
|
||||
|
||||
MesXslMasterBatchPlan plan = new MesXslMasterBatchPlan();
|
||||
plan.setSourceOrderId(productionOrder.getId());
|
||||
plan.setOrderSerialNo(buildOrderSerialNo(productionOrder));
|
||||
plan.setOrderSerialNo(buildOrderSerialNo(productionOrder, stageIndex));
|
||||
plan.setOrderNo(productionOrder.getProductionOrderNo());
|
||||
plan.setProductionSegmentCount(productionOrder.getProcessSegmentCount());
|
||||
plan.setOrderDate(productionOrder.getOrderDate());
|
||||
@@ -58,45 +87,93 @@ public class MesXslMasterBatchPlanServiceImpl
|
||||
plan.setScheduledCarCount(0);
|
||||
plan.setFinishedCarCount(0);
|
||||
plan.setStatus(0);
|
||||
this.save(plan);
|
||||
return plan;
|
||||
}
|
||||
|
||||
private MesMaterial resolveMotherMaterial(String mesMaterialCode) {
|
||||
if (StringUtils.isBlank(mesMaterialCode)) {
|
||||
private MesXslMasterBatchPlan findExistingByMaterialCode(
|
||||
List<MesXslMasterBatchPlan> existingPlans, String materialCode) {
|
||||
if (StringUtils.isBlank(materialCode) || existingPlans == null || existingPlans.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
String code = mesMaterialCode.trim();
|
||||
List<String> candidates = buildMotherCandidates(code);
|
||||
for (String c : candidates) {
|
||||
MesMaterial found =
|
||||
mesMaterialMapper.selectOne(
|
||||
new LambdaQueryWrapper<MesMaterial>()
|
||||
.eq(MesMaterial::getMaterialCode, c)
|
||||
.last("LIMIT 1"));
|
||||
if (found != null) {
|
||||
return found;
|
||||
for (MesXslMasterBatchPlan plan : existingPlans) {
|
||||
if (plan != null && materialCode.equalsIgnoreCase(StringUtils.trimToEmpty(plan.getMaterialCode()))) {
|
||||
return plan;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private List<String> buildMotherCandidates(String code) {
|
||||
List<String> list = new ArrayList<>(2);
|
||||
private MesMaterial resolveMotherMaterialByStage(MesXslProductionOrder productionOrder, int stageIndex) {
|
||||
for (String seedCode : resolveSplitSeedCodes(productionOrder)) {
|
||||
List<String> candidates = buildMotherCandidates(seedCode, stageIndex);
|
||||
for (String candidateCode : candidates) {
|
||||
MesMaterial matched = resolveMaterialByBaseCode(candidateCode);
|
||||
if (matched != null) {
|
||||
MesMaterial resolved = new MesMaterial();
|
||||
resolved.setMaterialCode(candidateCode);
|
||||
resolved.setMaterialName(StringUtils.defaultIfBlank(matched.getMaterialName(), candidateCode));
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private MesMaterial resolveMaterialByBaseCode(String baseCode) {
|
||||
if (StringUtils.isBlank(baseCode)) {
|
||||
return null;
|
||||
}
|
||||
MesMaterial exact =
|
||||
mesMaterialMapper.selectOne(
|
||||
new LambdaQueryWrapper<MesMaterial>()
|
||||
.eq(MesMaterial::getMaterialCode, baseCode)
|
||||
.last("LIMIT 1"));
|
||||
if (exact != null) {
|
||||
return exact;
|
||||
}
|
||||
return mesMaterialMapper.selectOne(
|
||||
new LambdaQueryWrapper<MesMaterial>()
|
||||
.likeRight(MesMaterial::getMaterialCode, baseCode)
|
||||
.last("LIMIT 1"));
|
||||
}
|
||||
|
||||
private List<String> resolveSplitSeedCodes(MesXslProductionOrder productionOrder) {
|
||||
Set<String> seeds = new LinkedHashSet<>();
|
||||
if (productionOrder != null) {
|
||||
if (StringUtils.isNotBlank(productionOrder.getMesMaterialName())) {
|
||||
seeds.add(productionOrder.getMesMaterialName().trim());
|
||||
}
|
||||
if (StringUtils.isNotBlank(productionOrder.getMaterialCode())) {
|
||||
seeds.add(productionOrder.getMaterialCode().trim());
|
||||
}
|
||||
}
|
||||
return new ArrayList<>(seeds);
|
||||
}
|
||||
|
||||
private List<String> buildMotherCandidates(String code, int stageIndex) {
|
||||
List<String> list = new ArrayList<>(1);
|
||||
if (StringUtils.isBlank(code) || stageIndex <= 0) {
|
||||
return list;
|
||||
}
|
||||
if (code.length() > 1 && (code.startsWith("F") || code.startsWith("f"))) {
|
||||
String suffix = code.substring(1);
|
||||
list.add("B1" + suffix);
|
||||
list.add("B2" + suffix);
|
||||
list.add("B" + stageIndex + suffix);
|
||||
} else {
|
||||
list.add("B1" + code);
|
||||
list.add("B2" + code);
|
||||
list.add("B" + stageIndex + code);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private String buildOrderSerialNo(MesXslProductionOrder productionOrder) {
|
||||
private int normalizeSegmentCount(Integer segmentCount) {
|
||||
if (segmentCount == null || segmentCount <= 0) {
|
||||
return 1;
|
||||
}
|
||||
return segmentCount;
|
||||
}
|
||||
|
||||
private String buildOrderSerialNo(MesXslProductionOrder productionOrder, int stageIndex) {
|
||||
String orderNo = StringUtils.defaultIfBlank(productionOrder.getProductionOrderNo(), productionOrder.getId());
|
||||
return orderNo + "-" + System.currentTimeMillis();
|
||||
return orderNo + "-B" + stageIndex + "-" + System.currentTimeMillis();
|
||||
}
|
||||
|
||||
private int calcPlanCarCount(BigDecimal planWeight, BigDecimal perCarWeight) {
|
||||
|
||||
@@ -0,0 +1,416 @@
|
||||
package org.jeecg.modules.xslmes.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jeecg.common.constant.CommonConstant;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslEquipmentLedger;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslFinalBatchPlan;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslMasterBatchPlan;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslMixingSpec;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslMixingProductionPlan;
|
||||
import org.jeecg.modules.xslmes.mapper.MesXslEquipmentLedgerMapper;
|
||||
import org.jeecg.modules.xslmes.mapper.MesXslFinalBatchPlanMapper;
|
||||
import org.jeecg.modules.xslmes.mapper.MesXslMasterBatchPlanMapper;
|
||||
import org.jeecg.modules.xslmes.mapper.MesXslMixingSpecMapper;
|
||||
import org.jeecg.modules.xslmes.mapper.MesXslMixingProductionPlanMapper;
|
||||
import org.jeecg.modules.xslmes.service.IMesXslMixingProductionPlanService;
|
||||
import org.jeecg.modules.xslmes.vo.MesXslMixingProductionPlanOrderOptionVO;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
@Service
|
||||
public class MesXslMixingProductionPlanServiceImpl
|
||||
extends ServiceImpl<MesXslMixingProductionPlanMapper, MesXslMixingProductionPlan>
|
||||
implements IMesXslMixingProductionPlanService {
|
||||
|
||||
private final MesXslEquipmentLedgerMapper equipmentLedgerMapper;
|
||||
private final MesXslMasterBatchPlanMapper masterBatchPlanMapper;
|
||||
private final MesXslFinalBatchPlanMapper finalBatchPlanMapper;
|
||||
private final MesXslMixingSpecMapper mixingSpecMapper;
|
||||
|
||||
public MesXslMixingProductionPlanServiceImpl(
|
||||
MesXslEquipmentLedgerMapper equipmentLedgerMapper,
|
||||
MesXslMasterBatchPlanMapper masterBatchPlanMapper,
|
||||
MesXslFinalBatchPlanMapper finalBatchPlanMapper,
|
||||
MesXslMixingSpecMapper mixingSpecMapper) {
|
||||
this.equipmentLedgerMapper = equipmentLedgerMapper;
|
||||
this.masterBatchPlanMapper = masterBatchPlanMapper;
|
||||
this.finalBatchPlanMapper = finalBatchPlanMapper;
|
||||
this.mixingSpecMapper = mixingSpecMapper;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void saveAllRows(List<MesXslMixingProductionPlan> rows) {
|
||||
this.remove(new LambdaQueryWrapper<>());
|
||||
if (CollectionUtils.isEmpty(rows)) {
|
||||
return;
|
||||
}
|
||||
Map<String, String> machineNameCache = new HashMap<>();
|
||||
List<MesXslMixingProductionPlan> saveList = new ArrayList<>();
|
||||
int sort = 1;
|
||||
for (MesXslMixingProductionPlan row : rows) {
|
||||
if (row == null || !hasBusinessData(row)) {
|
||||
continue;
|
||||
}
|
||||
normalizeRow(row, machineNameCache);
|
||||
row.setSortNo(sort++);
|
||||
saveList.add(row);
|
||||
}
|
||||
if (!saveList.isEmpty()) {
|
||||
this.saveBatch(saveList, 200);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean hasBusinessData(MesXslMixingProductionPlan row) {
|
||||
return StringUtils.isNotBlank(row.getMachineId())
|
||||
|| StringUtils.isNotBlank(row.getMorningPlanId())
|
||||
|| StringUtils.isNotBlank(row.getNoonPlanId())
|
||||
|| StringUtils.isNotBlank(row.getNightPlanId())
|
||||
|| StringUtils.isNotBlank(row.getMorningRemark())
|
||||
|| StringUtils.isNotBlank(row.getNoonRemark())
|
||||
|| StringUtils.isNotBlank(row.getNightRemark())
|
||||
|| row.getMorningPlanCount() != null
|
||||
|| row.getNoonPlanCount() != null
|
||||
|| row.getNightPlanCount() != null;
|
||||
}
|
||||
|
||||
private void normalizeRow(
|
||||
MesXslMixingProductionPlan row, Map<String, String> machineNameCache) {
|
||||
row.setId(null);
|
||||
row.setMachineId(StringUtils.trimToNull(row.getMachineId()));
|
||||
row.setMachineName(resolveMachineName(row.getMachineId(), machineNameCache));
|
||||
fillShiftFromPlan(row, "morning");
|
||||
fillShiftFromPlan(row, "noon");
|
||||
fillShiftFromPlan(row, "night");
|
||||
Date now = new Date();
|
||||
if (row.getCreateTime() == null) {
|
||||
row.setCreateTime(now);
|
||||
}
|
||||
row.setUpdateTime(now);
|
||||
if (row.getDelFlag() == null) {
|
||||
row.setDelFlag(CommonConstant.DEL_FLAG_0);
|
||||
}
|
||||
}
|
||||
|
||||
private String resolveMachineName(String machineId, Map<String, String> cache) {
|
||||
if (StringUtils.isBlank(machineId)) {
|
||||
return null;
|
||||
}
|
||||
return cache.computeIfAbsent(
|
||||
machineId,
|
||||
id -> {
|
||||
MesXslEquipmentLedger ledger = equipmentLedgerMapper.selectById(id);
|
||||
return ledger == null ? null : ledger.getEquipmentName();
|
||||
});
|
||||
}
|
||||
|
||||
private void fillShiftFromPlan(MesXslMixingProductionPlan row, String shift) {
|
||||
String planId = getPlanId(row, shift);
|
||||
String planType = StringUtils.upperCase(StringUtils.trimToEmpty(getPlanType(row, shift)));
|
||||
if (StringUtils.isBlank(planId)) {
|
||||
clearShiftPlanFields(row, shift);
|
||||
return;
|
||||
}
|
||||
if ("M".equals(planType)) {
|
||||
MesXslMasterBatchPlan plan = masterBatchPlanMapper.selectById(planId);
|
||||
if (plan == null) {
|
||||
clearShiftPlanFields(row, shift);
|
||||
return;
|
||||
}
|
||||
setShiftFromMasterPlan(row, shift, plan);
|
||||
return;
|
||||
}
|
||||
MesXslFinalBatchPlan finalPlan = finalBatchPlanMapper.selectById(planId);
|
||||
if (finalPlan == null) {
|
||||
clearShiftPlanFields(row, shift);
|
||||
return;
|
||||
}
|
||||
setShiftFromFinalPlan(row, shift, finalPlan);
|
||||
}
|
||||
|
||||
private String getPlanId(MesXslMixingProductionPlan row, String shift) {
|
||||
return switch (shift) {
|
||||
case "morning" -> StringUtils.trimToNull(row.getMorningPlanId());
|
||||
case "noon" -> StringUtils.trimToNull(row.getNoonPlanId());
|
||||
default -> StringUtils.trimToNull(row.getNightPlanId());
|
||||
};
|
||||
}
|
||||
|
||||
private String getPlanType(MesXslMixingProductionPlan row, String shift) {
|
||||
return switch (shift) {
|
||||
case "morning" -> row.getMorningPlanType();
|
||||
case "noon" -> row.getNoonPlanType();
|
||||
default -> row.getNightPlanType();
|
||||
};
|
||||
}
|
||||
|
||||
private void setShiftFromMasterPlan(
|
||||
MesXslMixingProductionPlan row, String shift, MesXslMasterBatchPlan plan) {
|
||||
setShiftPlanType(row, shift, "M");
|
||||
setShiftOrderNo(row, shift, plan.getOrderNo());
|
||||
setShiftOrderDate(row, shift, plan.getOrderDate());
|
||||
setShiftFormulaName(
|
||||
row,
|
||||
shift,
|
||||
resolveFormulaNameByMachineAndMaterial(
|
||||
row.getMachineId(), row.getMachineName(), plan.getMaterialCode(), plan.getMesMaterialName()));
|
||||
setShiftPlanWeight(row, shift, plan.getPlanWeight());
|
||||
setShiftPlannedCarCount(row, shift, plan.getPlannedCarCount());
|
||||
setShiftScheduledCarCount(row, shift, plan.getScheduledCarCount());
|
||||
setShiftFinishedCarCount(row, shift, plan.getFinishedCarCount());
|
||||
}
|
||||
|
||||
private void setShiftFromFinalPlan(
|
||||
MesXslMixingProductionPlan row, String shift, MesXslFinalBatchPlan plan) {
|
||||
setShiftPlanType(row, shift, "F");
|
||||
setShiftOrderNo(row, shift, plan.getOrderNo());
|
||||
setShiftOrderDate(row, shift, plan.getOrderDate());
|
||||
setShiftFormulaName(
|
||||
row,
|
||||
shift,
|
||||
resolveFormulaNameByMachineAndMaterial(
|
||||
row.getMachineId(), row.getMachineName(), plan.getMaterialCode(), plan.getMesMaterialName()));
|
||||
setShiftPlanWeight(row, shift, plan.getPlanWeight());
|
||||
setShiftPlannedCarCount(row, shift, plan.getPlannedCarCount());
|
||||
setShiftScheduledCarCount(row, shift, plan.getScheduledCarCount());
|
||||
setShiftFinishedCarCount(row, shift, plan.getFinishedCarCount());
|
||||
}
|
||||
|
||||
private void clearShiftPlanFields(MesXslMixingProductionPlan row, String shift) {
|
||||
setShiftPlanType(row, shift, null);
|
||||
setShiftOrderNo(row, shift, null);
|
||||
setShiftOrderDate(row, shift, null);
|
||||
setShiftFormulaName(row, shift, null);
|
||||
setShiftPlanWeight(row, shift, null);
|
||||
setShiftPlannedCarCount(row, shift, null);
|
||||
setShiftScheduledCarCount(row, shift, null);
|
||||
setShiftFinishedCarCount(row, shift, null);
|
||||
}
|
||||
|
||||
private void setShiftPlanType(MesXslMixingProductionPlan row, String shift, String value) {
|
||||
switch (shift) {
|
||||
case "morning" -> row.setMorningPlanType(value);
|
||||
case "noon" -> row.setNoonPlanType(value);
|
||||
default -> row.setNightPlanType(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void setShiftOrderNo(MesXslMixingProductionPlan row, String shift, String value) {
|
||||
switch (shift) {
|
||||
case "morning" -> row.setMorningOrderNo(value);
|
||||
case "noon" -> row.setNoonOrderNo(value);
|
||||
default -> row.setNightOrderNo(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void setShiftOrderDate(MesXslMixingProductionPlan row, String shift, Date value) {
|
||||
switch (shift) {
|
||||
case "morning" -> row.setMorningOrderDate(value);
|
||||
case "noon" -> row.setNoonOrderDate(value);
|
||||
default -> row.setNightOrderDate(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void setShiftFormulaName(MesXslMixingProductionPlan row, String shift, String value) {
|
||||
switch (shift) {
|
||||
case "morning" -> row.setMorningFormulaName(value);
|
||||
case "noon" -> row.setNoonFormulaName(value);
|
||||
default -> row.setNightFormulaName(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void setShiftPlanWeight(
|
||||
MesXslMixingProductionPlan row, String shift, java.math.BigDecimal value) {
|
||||
switch (shift) {
|
||||
case "morning" -> row.setMorningPlanWeight(value);
|
||||
case "noon" -> row.setNoonPlanWeight(value);
|
||||
default -> row.setNightPlanWeight(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void setShiftPlannedCarCount(MesXslMixingProductionPlan row, String shift, Integer value) {
|
||||
switch (shift) {
|
||||
case "morning" -> row.setMorningPlannedCarCount(value);
|
||||
case "noon" -> row.setNoonPlannedCarCount(value);
|
||||
default -> row.setNightPlannedCarCount(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void setShiftScheduledCarCount(MesXslMixingProductionPlan row, String shift, Integer value) {
|
||||
switch (shift) {
|
||||
case "morning" -> row.setMorningScheduledCarCount(value);
|
||||
case "noon" -> row.setNoonScheduledCarCount(value);
|
||||
default -> row.setNightScheduledCarCount(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void setShiftFinishedCarCount(MesXslMixingProductionPlan row, String shift, Integer value) {
|
||||
switch (shift) {
|
||||
case "morning" -> row.setMorningFinishedCarCount(value);
|
||||
case "noon" -> row.setNoonFinishedCarCount(value);
|
||||
default -> row.setNightFinishedCarCount(value);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPage<MesXslMixingProductionPlanOrderOptionVO> queryOrderOptions(
|
||||
Integer pageNo, Integer pageSize, String keyword, String machineId, String machineName) {
|
||||
String machineIdTrimmed = StringUtils.trimToNull(machineId);
|
||||
String machineNameTrimmed = StringUtils.trimToNull(machineName);
|
||||
List<MesXslMixingProductionPlanOrderOptionVO> all = new ArrayList<>();
|
||||
LambdaQueryWrapper<MesXslMasterBatchPlan> masterWrapper =
|
||||
new LambdaQueryWrapper<MesXslMasterBatchPlan>()
|
||||
.and(w -> w.eq(MesXslMasterBatchPlan::getDelFlag, CommonConstant.DEL_FLAG_0).or().isNull(MesXslMasterBatchPlan::getDelFlag));
|
||||
LambdaQueryWrapper<MesXslFinalBatchPlan> finalWrapper =
|
||||
new LambdaQueryWrapper<MesXslFinalBatchPlan>()
|
||||
.and(w -> w.eq(MesXslFinalBatchPlan::getDelFlag, CommonConstant.DEL_FLAG_0).or().isNull(MesXslFinalBatchPlan::getDelFlag));
|
||||
if (StringUtils.isNotBlank(keyword)) {
|
||||
masterWrapper.and(
|
||||
w ->
|
||||
w.like(MesXslMasterBatchPlan::getOrderNo, keyword)
|
||||
.or()
|
||||
.like(MesXslMasterBatchPlan::getMesMaterialName, keyword));
|
||||
finalWrapper.and(
|
||||
w ->
|
||||
w.like(MesXslFinalBatchPlan::getOrderNo, keyword)
|
||||
.or()
|
||||
.like(MesXslFinalBatchPlan::getMesMaterialName, keyword));
|
||||
}
|
||||
List<MesXslMasterBatchPlan> masters = masterBatchPlanMapper.selectList(masterWrapper);
|
||||
for (MesXslMasterBatchPlan m : masters) {
|
||||
MesXslMixingProductionPlanOrderOptionVO vo = new MesXslMixingProductionPlanOrderOptionVO();
|
||||
vo.setPlanId(m.getId());
|
||||
vo.setPlanType("M");
|
||||
vo.setOrderNo(m.getOrderNo());
|
||||
vo.setOrderDate(m.getOrderDate());
|
||||
vo.setFormulaName(
|
||||
resolveFormulaNameByMachineAndMaterial(
|
||||
machineIdTrimmed, machineNameTrimmed, m.getMaterialCode(), m.getMesMaterialName()));
|
||||
vo.setPlanWeight(m.getPlanWeight());
|
||||
vo.setPlannedCarCount(m.getPlannedCarCount());
|
||||
vo.setScheduledCarCount(m.getScheduledCarCount());
|
||||
vo.setFinishedCarCount(m.getFinishedCarCount());
|
||||
all.add(vo);
|
||||
}
|
||||
List<MesXslFinalBatchPlan> finals = finalBatchPlanMapper.selectList(finalWrapper);
|
||||
for (MesXslFinalBatchPlan f : finals) {
|
||||
MesXslMixingProductionPlanOrderOptionVO vo = new MesXslMixingProductionPlanOrderOptionVO();
|
||||
vo.setPlanId(f.getId());
|
||||
vo.setPlanType("F");
|
||||
vo.setOrderNo(f.getOrderNo());
|
||||
vo.setOrderDate(f.getOrderDate());
|
||||
vo.setFormulaName(
|
||||
resolveFormulaNameByMachineAndMaterial(
|
||||
machineIdTrimmed, machineNameTrimmed, f.getMaterialCode(), f.getMesMaterialName()));
|
||||
vo.setPlanWeight(f.getPlanWeight());
|
||||
vo.setPlannedCarCount(f.getPlannedCarCount());
|
||||
vo.setScheduledCarCount(f.getScheduledCarCount());
|
||||
vo.setFinishedCarCount(f.getFinishedCarCount());
|
||||
all.add(vo);
|
||||
}
|
||||
all.sort(
|
||||
Comparator.comparing(
|
||||
MesXslMixingProductionPlanOrderOptionVO::getOrderDate,
|
||||
Comparator.nullsLast(Comparator.reverseOrder()))
|
||||
.thenComparing(
|
||||
MesXslMixingProductionPlanOrderOptionVO::getOrderNo,
|
||||
Comparator.nullsLast(Comparator.reverseOrder()))
|
||||
.thenComparing(
|
||||
MesXslMixingProductionPlanOrderOptionVO::getPlanId,
|
||||
Comparator.nullsLast(Comparator.reverseOrder())));
|
||||
long current = pageNo == null || pageNo < 1 ? 1 : pageNo;
|
||||
long size = pageSize == null || pageSize < 1 ? 20 : pageSize;
|
||||
int from = (int) ((current - 1) * size);
|
||||
int to = (int) Math.min(from + size, all.size());
|
||||
List<MesXslMixingProductionPlanOrderOptionVO> pageRecords =
|
||||
from >= all.size() ? Collections.emptyList() : all.subList(from, to);
|
||||
Page<MesXslMixingProductionPlanOrderOptionVO> page = new Page<>(current, size);
|
||||
page.setTotal(all.size());
|
||||
page.setRecords(
|
||||
pageRecords.stream().filter(Objects::nonNull).collect(Collectors.toList()));
|
||||
return page;
|
||||
}
|
||||
|
||||
private String resolveFormulaNameByMachineAndMaterial(
|
||||
String machineId, String machineName, String materialCode, String fallbackName) {
|
||||
String code = StringUtils.trimToEmpty(materialCode);
|
||||
if (StringUtils.isBlank(code)) {
|
||||
return StringUtils.defaultString(fallbackName);
|
||||
}
|
||||
String targetSpec = buildTargetSpecName(code);
|
||||
LambdaQueryWrapper<MesXslMixingSpec> exactWrapper =
|
||||
new LambdaQueryWrapper<MesXslMixingSpec>()
|
||||
.eq(MesXslMixingSpec::getSpecName, targetSpec)
|
||||
.and(
|
||||
w ->
|
||||
w.eq(MesXslMixingSpec::getDelFlag, CommonConstant.DEL_FLAG_0)
|
||||
.or()
|
||||
.isNull(MesXslMixingSpec::getDelFlag))
|
||||
.last("LIMIT 1");
|
||||
appendMachineCondition(exactWrapper, machineId, machineName);
|
||||
MesXslMixingSpec exact = mixingSpecMapper.selectOne(exactWrapper);
|
||||
if (exact != null && StringUtils.isNotBlank(exact.getSpecName())) {
|
||||
return exact.getSpecName().trim();
|
||||
}
|
||||
|
||||
LambdaQueryWrapper<MesXslMixingSpec> prefixWrapper =
|
||||
new LambdaQueryWrapper<MesXslMixingSpec>()
|
||||
.likeRight(MesXslMixingSpec::getSpecName, code)
|
||||
.and(
|
||||
w ->
|
||||
w.eq(MesXslMixingSpec::getDelFlag, CommonConstant.DEL_FLAG_0)
|
||||
.or()
|
||||
.isNull(MesXslMixingSpec::getDelFlag))
|
||||
.orderByAsc(MesXslMixingSpec::getSpecName)
|
||||
.last("LIMIT 1");
|
||||
appendMachineCondition(prefixWrapper, machineId, machineName);
|
||||
MesXslMixingSpec prefix = mixingSpecMapper.selectOne(prefixWrapper);
|
||||
if (prefix != null && StringUtils.isNotBlank(prefix.getSpecName())) {
|
||||
return prefix.getSpecName().trim();
|
||||
}
|
||||
return StringUtils.defaultIfBlank(fallbackName, targetSpec);
|
||||
}
|
||||
|
||||
private String buildTargetSpecName(String materialCode) {
|
||||
String code = StringUtils.trimToEmpty(materialCode).toUpperCase();
|
||||
if (code.matches(".*SA\\d{2}$")) {
|
||||
return code;
|
||||
}
|
||||
return code + "SA01";
|
||||
}
|
||||
|
||||
private void appendMachineCondition(
|
||||
LambdaQueryWrapper<MesXslMixingSpec> wrapper, String machineId, String machineName) {
|
||||
String machineIdTrimmed = StringUtils.trimToNull(machineId);
|
||||
String machineNameTrimmed = StringUtils.trimToNull(machineName);
|
||||
if (machineIdTrimmed != null && machineNameTrimmed != null) {
|
||||
wrapper.and(
|
||||
w ->
|
||||
w.eq(MesXslMixingSpec::getMachineId, machineIdTrimmed)
|
||||
.or()
|
||||
.eq(MesXslMixingSpec::getMachineName, machineNameTrimmed));
|
||||
return;
|
||||
}
|
||||
if (machineIdTrimmed != null) {
|
||||
wrapper.eq(MesXslMixingSpec::getMachineId, machineIdTrimmed);
|
||||
return;
|
||||
}
|
||||
if (machineNameTrimmed != null) {
|
||||
wrapper.eq(MesXslMixingSpec::getMachineName, machineNameTrimmed);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +1,17 @@
|
||||
package org.jeecg.modules.xslmes.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.jeecg.common.exception.JeecgBootException;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslFinalBatchPlan;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslMixingSpec;
|
||||
import org.jeecg.modules.xslmes.service.IMesXslFinalBatchPlanService;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslMasterBatchPlan;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslProductionOrder;
|
||||
import org.jeecg.modules.xslmes.mapper.MesXslMixingSpecMapper;
|
||||
import org.jeecg.modules.xslmes.mapper.MesXslProductionOrderMapper;
|
||||
import org.jeecg.modules.xslmes.service.IMesXslMasterBatchPlanService;
|
||||
import org.jeecg.modules.xslmes.service.IMesXslProductionOrderService;
|
||||
@@ -20,10 +26,11 @@ public class MesXslProductionOrderServiceImpl
|
||||
|
||||
@Autowired private IMesXslMasterBatchPlanService masterBatchPlanService;
|
||||
@Autowired private IMesXslFinalBatchPlanService finalBatchPlanService;
|
||||
@Autowired private MesXslMixingSpecMapper mixingSpecMapper;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public MesXslMasterBatchPlan splitToMasterBatchPlan(String id) {
|
||||
public List<MesXslMasterBatchPlan> splitToMasterBatchPlan(String id) {
|
||||
if (StringUtils.isBlank(id)) {
|
||||
throw new JeecgBootException("生产订单ID不能为空");
|
||||
}
|
||||
@@ -34,12 +41,67 @@ public class MesXslProductionOrderServiceImpl
|
||||
if (order.getSplitStatus() != null && order.getSplitStatus() == 1) {
|
||||
throw new JeecgBootException("该生产订单已拆分,无需重复操作");
|
||||
}
|
||||
MesXslMasterBatchPlan plan = masterBatchPlanService.generateFromProductionOrder(order);
|
||||
finalBatchPlanService.generateFromProductionOrder(order);
|
||||
List<MesXslMasterBatchPlan> plans = masterBatchPlanService.generateBatchFromProductionOrder(order);
|
||||
MesXslFinalBatchPlan finalPlan = finalBatchPlanService.generateFromProductionOrder(order);
|
||||
validateMixingSpecExists(plans, finalPlan);
|
||||
MesXslProductionOrder update = new MesXslProductionOrder();
|
||||
update.setId(order.getId());
|
||||
update.setSplitStatus(1);
|
||||
this.updateById(update);
|
||||
return plan;
|
||||
return plans;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public int splitToMasterBatchPlanBatch(List<String> ids) {
|
||||
if (ids == null || ids.isEmpty()) {
|
||||
throw new JeecgBootException("请至少选择一条生产订单");
|
||||
}
|
||||
int successCount = 0;
|
||||
for (String id : ids) {
|
||||
if (StringUtils.isBlank(id)) {
|
||||
continue;
|
||||
}
|
||||
splitToMasterBatchPlan(id.trim());
|
||||
successCount++;
|
||||
}
|
||||
return successCount;
|
||||
}
|
||||
|
||||
private void validateMixingSpecExists(
|
||||
List<MesXslMasterBatchPlan> masterPlans, MesXslFinalBatchPlan finalPlan) {
|
||||
List<String> requiredSpecs = new ArrayList<>();
|
||||
if (masterPlans != null) {
|
||||
for (MesXslMasterBatchPlan plan : masterPlans) {
|
||||
if (plan != null && StringUtils.isNotBlank(plan.getMaterialCode())) {
|
||||
requiredSpecs.add(plan.getMaterialCode().trim() + "SA01");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (finalPlan != null && StringUtils.isNotBlank(finalPlan.getMaterialCode())) {
|
||||
requiredSpecs.add(finalPlan.getMaterialCode().trim() + "SA01");
|
||||
}
|
||||
if (requiredSpecs.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<String> missingSpecs = new ArrayList<>();
|
||||
for (String specName : requiredSpecs) {
|
||||
MesXslMixingSpec found =
|
||||
mixingSpecMapper.selectOne(
|
||||
new LambdaQueryWrapper<MesXslMixingSpec>()
|
||||
.eq(MesXslMixingSpec::getSpecName, specName)
|
||||
.and(
|
||||
w ->
|
||||
w.eq(MesXslMixingSpec::getDelFlag, 0)
|
||||
.or()
|
||||
.isNull(MesXslMixingSpec::getDelFlag))
|
||||
.last("LIMIT 1"));
|
||||
if (found == null) {
|
||||
missingSpecs.add(specName);
|
||||
}
|
||||
}
|
||||
if (!missingSpecs.isEmpty()) {
|
||||
throw new JeecgBootException("对应物料的混炼示方不存在,请先生成混炼示方!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package org.jeecg.modules.xslmes.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Date;
|
||||
import lombok.Data;
|
||||
import org.springframework.format.annotation.DateTimeFormat;
|
||||
|
||||
@Data
|
||||
@Schema(description = "密炼生产计划-班次生产订单候选")
|
||||
public class MesXslMixingProductionPlanOrderOptionVO {
|
||||
@Schema(description = "计划ID")
|
||||
private String planId;
|
||||
|
||||
@Schema(description = "计划类型 M母胶/F终胶")
|
||||
private String planType;
|
||||
|
||||
@Schema(description = "订单编号")
|
||||
private String orderNo;
|
||||
|
||||
@Schema(description = "订单日期")
|
||||
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
|
||||
@DateTimeFormat(pattern = "yyyy-MM-dd")
|
||||
private Date orderDate;
|
||||
|
||||
@Schema(description = "胶料名称")
|
||||
private String formulaName;
|
||||
|
||||
@Schema(description = "计划重量")
|
||||
private BigDecimal planWeight;
|
||||
|
||||
@Schema(description = "计划车数")
|
||||
private Integer plannedCarCount;
|
||||
|
||||
@Schema(description = "已排产车数")
|
||||
private Integer scheduledCarCount;
|
||||
|
||||
@Schema(description = "完成车数")
|
||||
private Integer finishedCarCount;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
package org.jeecg.modules.xslmes.vo;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
import org.jeecg.modules.xslmes.entity.MesXslMixingProductionPlan;
|
||||
|
||||
@Data
|
||||
public class MesXslMixingProductionPlanSaveAllVO {
|
||||
private List<MesXslMixingProductionPlan> rows;
|
||||
}
|
||||
Reference in New Issue
Block a user