新增密炼物料皮重策略功能,包括相关实体、控制器、服务及接口的实现,支持桌面端免密CRUD操作,优化了打印记录的字段填充逻辑,提升了用户体验。

This commit is contained in:
geht
2026-06-02 16:30:46 +08:00
76 changed files with 4506 additions and 201 deletions

View File

@@ -522,6 +522,71 @@ jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules
-- author:GHT---date:20260529--for: 【QH-MES审批流设计】审批IM消息升级为可跳转业务卡片(biz_record):点击可定位到对应单据,无法定位功能页时退回纯文本 ---
jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/approval/controller/MesXslApprovalLaunchController.java
-- author:cursor---date:20250602--for: 【密炼物料皮重策略】桌面端同步 ---
jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/MesXslStompNotifyService.java
jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslDesktopAnonController.java
jeecg-boot/jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslMixerMaterialTareStrategyController.java
jeecg-boot/jeecg-boot-base-core/src/main/java/org/jeecg/config/shiro/ShiroConfig.java
-- author:cursor---date:20250602--for: 【密炼物料皮重策略】新增物料规格/托盘重量,皮重改名为包装物重量 ---
jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_118__mes_xsl_mixer_material_tare_strategy_fields.sql
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/entity/MesXslMixerMaterialTareStrategy.java
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslMixerMaterialTareStrategyServiceImpl.java
yy-admin-master/YY.Admin.Core/Entity/MesXslMixerMaterialTareStrategy.cs
yy-admin-master/YY.Admin.Services/Service/MixerMaterialTareStrategy/MixerMaterialTareStrategyService.cs
yy-admin-master/YY.Admin/Views/MixerMaterialTareStrategy/MixerMaterialTareStrategyListView.xaml
yy-admin-master/YY.Admin/Views/MixerMaterialTareStrategy/MixerMaterialTareStrategyEditDialogView.xaml
yy-admin-master/YY.Admin/ViewModels/MixerMaterialTareStrategy/MixerMaterialTareStrategyEditDialogViewModel.cs
yy-admin-master/YY.Admin/ViewModels/MixerMaterialTareStrategy/MixerMaterialTareStrategyListViewModel.cs
jeecgboot-vue3/src/views/xslmes/mesXslMixerMaterialTareStrategy/MesXslMixerMaterialTareStrategy.data.ts
jeecgboot-vue3/src/views/xslmes/mesXslMixerMaterialTareStrategy/components/MesXslMixerMaterialTareStrategyModal.vue
-- author:cursor---date:20250602--for: 【原料入场/原材料卡片】皮重字段落库 ---
jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_119__mes_xsl_raw_material_entry_tare_fields.sql
jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_120__mes_xsl_raw_material_card_tare_fields.sql
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/entity/MesXslRawMaterialEntry.java
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/entity/MesXslRawMaterialCard.java
yy-admin-master/YY.Admin.Core/Entity/MesXslRawMaterialEntry.cs
yy-admin-master/YY.Admin.Core/Entity/MesXslRawMaterialCard.cs
yy-admin-master/YY.Admin.Services/Service/RawMaterialEntry/RawMaterialEntryService.cs
yy-admin-master/YY.Admin.Services/Service/RawMaterialCard/RawMaterialCardService.cs
yy-admin-master/YY.Admin/ViewModels/RawMaterialEntry/RawMaterialEntryEditDialogViewModel.cs
yy-admin-master/YY.Admin/ViewModels/RawMaterialEntry/RawMaterialEntryOperationViewModel.cs
yy-admin-master/YY.Admin/ViewModels/RawMaterialCard/RawMaterialCardEditDialogViewModel.cs
-- author:cursor---date:20250602--for: 【原料入场/原材料卡片】列表展示皮重相关字段 ---
yy-admin-master/YY.Admin/Views/RawMaterialEntry/RawMaterialEntryListView.xaml
yy-admin-master/YY.Admin/Views/RawMaterialCard/RawMaterialCardListView.xaml
jeecgboot-vue3/src/views/xslmes/mesXslRawMaterialEntry/MesXslRawMaterialEntry.data.ts
jeecgboot-vue3/src/views/xslmes/mesXslRawMaterialCard/MesXslRawMaterialCard.data.ts
-- author:cursor---date:20250602--for: 【原料入场/原材料卡片】后端列表与详情展示皮重字段 ---
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/entity/MesXslRawMaterialWorkshopRemain.java
jeecgboot-vue3/src/views/xslmes/mesXslRawMaterialEntry/MesXslRawMaterialEntry.data.ts
jeecgboot-vue3/src/views/xslmes/mesXslRawMaterialCard/MesXslRawMaterialCard.data.ts
jeecgboot-vue3/src/views/xslmes/mesXslRawMaterialWorkshopRemain/MesXslRawMaterialWorkshopRemain.data.ts
-- author:cursor---date:20250602--for: 【磅单记录】列表展示货物皮重(关联入场记录托盘及皮重合计,不落库) ---
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/entity/MesXslWeightRecord.java
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/IMesXslRawMaterialEntryService.java
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslRawMaterialEntryServiceImpl.java
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslWeightRecordController.java
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/controller/MesXslDesktopAnonController.java
jeecgboot-vue3/src/views/xslmes/mesXslWeightRecord/MesXslWeightRecord.data.ts
yy-admin-master/YY.Admin.Core/Entity/MesXslWeightRecord.cs
yy-admin-master/YY.Admin.Core/Util/CargoTareWeightCalculator.cs
yy-admin-master/YY.Admin.Services/Service/WeightRecord/WeightRecordService.cs
yy-admin-master/YY.Admin/Views/WeightRecord/WeightRecordListView.xaml
yy-admin-master/YY.Admin/Views/RawMaterialEntry/WeightRecordPickerDialogView.xaml
-- author:cursor---date:20250602--for: 【磅单记录】列表展示原料重量(净重-货物皮重,不落库) ---
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/entity/MesXslWeightRecord.java
jeecg-boot-module/jeecg-module-xslmes/src/main/java/org/jeecg/modules/xslmes/service/impl/MesXslRawMaterialEntryServiceImpl.java
jeecgboot-vue3/src/views/xslmes/mesXslWeightRecord/MesXslWeightRecord.data.ts
yy-admin-master/YY.Admin.Core/Entity/MesXslWeightRecord.cs
yy-admin-master/YY.Admin.Services/Service/WeightRecord/WeightRecordService.cs
yy-admin-master/YY.Admin/Views/WeightRecord/WeightRecordListView.xaml
-- author:jiangxh---date:20250602--for: 【MES】停机记录建表+菜单+CRUD+列表录入维修结果弹窗 ---
jeecg-boot/db/mes-xsl-downtime-record-menu-permission.sql
jeecg-boot/jeecg-module-system/jeecg-system-start/src/main/resources/flyway/sql/mysql/V3.9.2_117__mes_xsl_downtime_record.sql

View File

@@ -27,6 +27,8 @@ import org.jeecg.modules.xslmes.entity.MesXslCustomer;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialCard;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialEntry;
import org.jeecg.modules.xslmes.entity.MesXslSupplier;
import org.jeecg.modules.xslmes.entity.MesXslMixerMaterialTareStrategy;
import org.jeecg.modules.xslmes.entity.MesXslUnit;
import org.jeecg.modules.xslmes.entity.MesXslVehicle;
import org.jeecg.modules.xslmes.entity.MesXslWarehouse;
import org.jeecg.modules.xslmes.entity.MesXslWarehouseArea;
@@ -35,6 +37,8 @@ import org.jeecg.modules.xslmes.service.IMesXslCustomerService;
import org.jeecg.modules.xslmes.service.IMesXslRawMaterialCardService;
import org.jeecg.modules.xslmes.service.IMesXslRawMaterialEntryService;
import org.jeecg.modules.xslmes.service.IMesXslSupplierService;
import org.jeecg.modules.xslmes.service.IMesXslMixerMaterialTareStrategyService;
import org.jeecg.modules.xslmes.service.IMesXslUnitService;
import org.jeecg.modules.xslmes.service.IMesXslVehicleService;
import org.jeecg.modules.xslmes.service.IMesXslWarehouseAreaService;
import org.jeecg.modules.xslmes.service.IMesXslWarehouseService;
@@ -60,6 +64,8 @@ import org.apache.commons.lang3.StringUtils;
* ShiroConfig 白名单:
* /xslmes/mesXslVehicle/anon/**
* /xslmes/mesXslCustomer/anon/**
* /xslmes/mesXslMixerMaterialTareStrategy/anon/**
* /xslmes/mesXslUnit/anon/**
*/
@Tag(name = "桌面端免密接口")
@RestController
@@ -75,6 +81,8 @@ public class MesXslDesktopAnonController {
private final IMesXslRawMaterialCardService rawMaterialCardService;
private final IMesXslWarehouseService warehouseService;
private final IMesXslWarehouseAreaService warehouseAreaService;
private final IMesXslMixerMaterialTareStrategyService tareStrategyService;
private final IMesXslUnitService unitService;
private final MesXslStompNotifyService stompNotify;
private final IPrintBizTemplateBindService printBizTemplateBindService;
private final IPrintTemplateService printTemplateService;
@@ -390,6 +398,7 @@ public class MesXslDesktopAnonController {
QueryWrapper<MesXslWeightRecord> qw = QueryGenerator.initQueryWrapper(mesXslWeightRecord, req.getParameterMap());
qw.orderByDesc("create_time");
IPage<MesXslWeightRecord> page = weightRecordService.page(new Page<>(pageNo, pageSize), qw);
rawMaterialEntryService.fillWeightRecordDerivedFields(page.getRecords());
return Result.OK(page);
}
@@ -397,7 +406,11 @@ public class MesXslDesktopAnonController {
@GetMapping("/xslmes/mesXslWeightRecord/anon/queryById")
public Result<MesXslWeightRecord> weightRecordAnonQueryById(@RequestParam(name = "id") String id) {
MesXslWeightRecord entity = weightRecordService.getById(id);
return entity != null ? Result.OK(entity) : Result.error("未找到对应数据");
if (entity == null) {
return Result.error("未找到对应数据");
}
rawMaterialEntryService.fillWeightRecordDerivedFields(Collections.singletonList(entity));
return Result.OK(entity);
}
@Operation(summary = "磅单-免密添加")
@@ -828,6 +841,90 @@ public class MesXslDesktopAnonController {
return Result.OK("该值可用!");
}
// ═══════════════════════════ 密炼物料皮重策略 ═══════════════════════════
//update-begin---author:cursor ---date:20250602 for【密炼物料皮重策略】桌面端免密CRUD-----------
@Operation(summary = "密炼物料皮重策略-免密分页列表查询")
@GetMapping("/xslmes/mesXslMixerMaterialTareStrategy/anon/list")
public Result<IPage<MesXslMixerMaterialTareStrategy>> tareStrategyAnonList(
MesXslMixerMaterialTareStrategy model,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<MesXslMixerMaterialTareStrategy> qw = QueryGenerator.initQueryWrapper(model, req.getParameterMap());
qw.orderByDesc("effective_start_date", "create_time");
IPage<MesXslMixerMaterialTareStrategy> page = tareStrategyService.page(new Page<>(pageNo, pageSize), qw);
return Result.OK(page);
}
@Operation(summary = "密炼物料皮重策略-免密通过id查询")
@GetMapping("/xslmes/mesXslMixerMaterialTareStrategy/anon/queryById")
public Result<MesXslMixerMaterialTareStrategy> tareStrategyAnonQueryById(@RequestParam(name = "id") String id) {
MesXslMixerMaterialTareStrategy entity = tareStrategyService.getById(id);
return entity != null ? Result.OK(entity) : Result.error("未找到对应数据");
}
@Operation(summary = "密炼物料皮重策略-免密添加")
@PostMapping("/xslmes/mesXslMixerMaterialTareStrategy/anon/add")
public Result<String> tareStrategyAnonAdd(@RequestBody MesXslMixerMaterialTareStrategy model) {
String err = tareStrategyService.validateBeforeSave(model, false);
if (err != null) {
return Result.error(err);
}
tareStrategyService.save(model);
stompNotify.publishMixerMaterialTareStrategyChanged("add", model.getId());
return Result.OK("添加成功!");
}
@Operation(summary = "密炼物料皮重策略-免密编辑")
@RequestMapping(value = "/xslmes/mesXslMixerMaterialTareStrategy/anon/edit", method = {RequestMethod.PUT, RequestMethod.POST})
public Result<String> tareStrategyAnonEdit(@RequestBody MesXslMixerMaterialTareStrategy model) {
if (oConvertUtils.isEmpty(model.getId())) {
return Result.error("主键不能为空");
}
String err = tareStrategyService.validateBeforeSave(model, true);
if (err != null) {
return Result.error(err);
}
boolean ok = tareStrategyService.updateById(model);
if (!ok) {
return Result.error("数据已被他人修改,请刷新后重试");
}
stompNotify.publishMixerMaterialTareStrategyChanged("edit", model.getId());
return Result.OK("编辑成功!");
}
@Operation(summary = "密炼物料皮重策略-免密删除")
@DeleteMapping("/xslmes/mesXslMixerMaterialTareStrategy/anon/delete")
public Result<String> tareStrategyAnonDelete(@RequestParam(name = "id") String id) {
tareStrategyService.removeById(id);
stompNotify.publishMixerMaterialTareStrategyChanged("delete", id);
return Result.OK("删除成功!");
}
@Operation(summary = "密炼物料皮重策略-免密批量删除")
@DeleteMapping("/xslmes/mesXslMixerMaterialTareStrategy/anon/deleteBatch")
public Result<String> tareStrategyAnonDeleteBatch(@RequestParam(name = "ids") String ids) {
tareStrategyService.removeByIds(Arrays.asList(ids.split(",")));
stompNotify.publishMixerMaterialTareStrategyChanged("batchDelete", ids);
return Result.OK("批量删除成功!");
}
//update-end---author:cursor ---date:20250602 for【密炼物料皮重策略】桌面端免密CRUD-----------
//update-begin---author:cursor ---date:20250602 for【密炼物料皮重策略】桌面端单位下拉只读-----------
@Operation(summary = "单位-免密分页列表查询(供桌面端单位下拉)")
@GetMapping("/xslmes/mesXslUnit/anon/list")
public Result<IPage<MesXslUnit>> unitAnonList(
MesXslUnit mesXslUnit,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "1000") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<MesXslUnit> qw = QueryGenerator.initQueryWrapper(mesXslUnit, req.getParameterMap());
IPage<MesXslUnit> page = unitService.page(new Page<>(pageNo, pageSize), qw);
return Result.OK(page);
}
//update-end---author:cursor ---date:20250602 for【密炼物料皮重策略】桌面端单位下拉只读-----------
// ─────────────────────────── 车辆私有辅助 ────────────────────────────
private void applyWeightNetAndBillType(MesXslWeightRecord record) {

View File

@@ -0,0 +1,151 @@
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 jakarta.servlet.http.HttpServletResponse;
import java.util.Arrays;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
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.common.system.vo.LoginUser;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.xslmes.entity.MesXslMixerMaterialTareStrategy;
import org.jeecg.modules.xslmes.service.IMesXslMixerMaterialTareStrategyService;
import org.jeecg.modules.xslmes.service.MesXslStompNotifyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;
/**
* MES 密炼物料皮重策略
*/
@Tag(name = "MES密炼物料皮重策略")
@RestController
@RequestMapping("/xslmes/mesXslMixerMaterialTareStrategy")
@Slf4j
public class MesXslMixerMaterialTareStrategyController
extends JeecgController<MesXslMixerMaterialTareStrategy, IMesXslMixerMaterialTareStrategyService> {
@Autowired
private IMesXslMixerMaterialTareStrategyService mesXslMixerMaterialTareStrategyService;
@Autowired
private MesXslStompNotifyService stompNotify;
@Operation(summary = "MES密炼物料皮重策略-分页列表查询")
@GetMapping(value = "/list")
public Result<IPage<MesXslMixerMaterialTareStrategy>> queryPageList(
MesXslMixerMaterialTareStrategy model,
@RequestParam(name = "pageNo", defaultValue = "1") Integer pageNo,
@RequestParam(name = "pageSize", defaultValue = "10") Integer pageSize,
HttpServletRequest req) {
QueryWrapper<MesXslMixerMaterialTareStrategy> queryWrapper =
QueryGenerator.initQueryWrapper(model, req.getParameterMap());
queryWrapper.orderByDesc("effective_start_date", "create_time");
Page<MesXslMixerMaterialTareStrategy> page = new Page<>(pageNo, pageSize);
IPage<MesXslMixerMaterialTareStrategy> pageList = mesXslMixerMaterialTareStrategyService.page(page, queryWrapper);
return Result.OK(pageList);
}
@AutoLog(value = "MES密炼物料皮重策略-添加")
@Operation(summary = "MES密炼物料皮重策略-添加")
@RequiresPermissions("xslmes:mes_xsl_mixer_material_tare_strategy:add")
@PostMapping(value = "/add")
public Result<String> add(@RequestBody MesXslMixerMaterialTareStrategy model) {
fillMaintainBy(model);
String err = mesXslMixerMaterialTareStrategyService.validateBeforeSave(model, false);
if (err != null) {
return Result.error(err);
}
mesXslMixerMaterialTareStrategyService.save(model);
//update-begin---author:cursor ---date:20250602 for【密炼物料皮重策略】桌面端同步-----------
stompNotify.publishMixerMaterialTareStrategyChanged("add", model.getId());
//update-end---author:cursor ---date:20250602 for【密炼物料皮重策略】桌面端同步-----------
return Result.OK("添加成功!");
}
@AutoLog(value = "MES密炼物料皮重策略-编辑")
@Operation(summary = "MES密炼物料皮重策略-编辑")
@RequiresPermissions("xslmes:mes_xsl_mixer_material_tare_strategy:edit")
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
public Result<String> edit(@RequestBody MesXslMixerMaterialTareStrategy model) {
fillMaintainBy(model);
String err = mesXslMixerMaterialTareStrategyService.validateBeforeSave(model, true);
if (err != null) {
return Result.error(err);
}
mesXslMixerMaterialTareStrategyService.updateById(model);
//update-begin---author:cursor ---date:20250602 for【密炼物料皮重策略】桌面端同步-----------
stompNotify.publishMixerMaterialTareStrategyChanged("edit", model.getId());
//update-end---author:cursor ---date:20250602 for【密炼物料皮重策略】桌面端同步-----------
return Result.OK("编辑成功!");
}
@AutoLog(value = "MES密炼物料皮重策略-删除")
@Operation(summary = "MES密炼物料皮重策略-通过id删除")
@RequiresPermissions("xslmes:mes_xsl_mixer_material_tare_strategy:delete")
@DeleteMapping(value = "/delete")
public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
mesXslMixerMaterialTareStrategyService.removeById(id);
//update-begin---author:cursor ---date:20250602 for【密炼物料皮重策略】桌面端同步-----------
stompNotify.publishMixerMaterialTareStrategyChanged("delete", id);
//update-end---author:cursor ---date:20250602 for【密炼物料皮重策略】桌面端同步-----------
return Result.OK("删除成功!");
}
@AutoLog(value = "MES密炼物料皮重策略-批量删除")
@Operation(summary = "MES密炼物料皮重策略-批量删除")
@RequiresPermissions("xslmes:mes_xsl_mixer_material_tare_strategy:deleteBatch")
@DeleteMapping(value = "/deleteBatch")
public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
mesXslMixerMaterialTareStrategyService.removeByIds(Arrays.asList(ids.split(",")));
//update-begin---author:cursor ---date:20250602 for【密炼物料皮重策略】桌面端同步-----------
stompNotify.publishMixerMaterialTareStrategyChanged("batchDelete", ids);
//update-end---author:cursor ---date:20250602 for【密炼物料皮重策略】桌面端同步-----------
return Result.OK("批量删除成功!");
}
@Operation(summary = "MES密炼物料皮重策略-通过id查询")
@GetMapping(value = "/queryById")
public Result<MesXslMixerMaterialTareStrategy> queryById(@RequestParam(name = "id", required = true) String id) {
MesXslMixerMaterialTareStrategy entity = mesXslMixerMaterialTareStrategyService.getById(id);
if (entity == null) {
return Result.error("未找到对应数据");
}
return Result.OK(entity);
}
@RequiresPermissions("xslmes:mes_xsl_mixer_material_tare_strategy:exportXls")
@RequestMapping(value = "/exportXls")
public ModelAndView exportXls(HttpServletRequest request, MesXslMixerMaterialTareStrategy model) {
return super.exportXls(request, model, MesXslMixerMaterialTareStrategy.class, "密炼物料皮重策略");
}
@RequiresPermissions("xslmes:mes_xsl_mixer_material_tare_strategy:importExcel")
@RequestMapping(value = "/importExcel", method = RequestMethod.POST)
public Result<?> importExcel(HttpServletRequest request, HttpServletResponse response) {
return super.importExcel(request, response, MesXslMixerMaterialTareStrategy.class);
}
//update-begin---author:cursor ---date:20250602 for【密炼物料皮重策略】维护人自动回填当前登录用户-----------
private void fillMaintainBy(MesXslMixerMaterialTareStrategy model) {
LoginUser loginUser = null;
try {
loginUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
} catch (Exception e) {
log.debug("获取登录用户失败", e);
}
if (loginUser != null && oConvertUtils.isNotEmpty(loginUser.getUsername())) {
model.setMaintainBy(loginUser.getUsername());
}
}
//update-end---author:cursor ---date:20250602 for【密炼物料皮重策略】维护人自动回填当前登录用户-----------
}

View File

@@ -27,9 +27,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.stream.Collectors;
/**
* 地磅数据记录
@@ -57,7 +55,7 @@ public class MesXslWeightRecordController extends JeecgController<MesXslWeightRe
queryWrapper.orderByDesc("create_time");
Page<MesXslWeightRecord> page = new Page<>(pageNo, pageSize);
IPage<MesXslWeightRecord> pageList = mesXslWeightRecordService.page(page, queryWrapper);
fillEnteredWeight(pageList.getRecords());
rawMaterialEntryService.fillWeightRecordDerivedFields(pageList.getRecords());
return Result.OK(pageList);
}
@@ -120,7 +118,7 @@ public class MesXslWeightRecordController extends JeecgController<MesXslWeightRe
if (record == null) {
return Result.error("未找到对应数据");
}
fillEnteredWeight(Collections.singletonList(record));
fillWeightRecordDerivedFields(Collections.singletonList(record));
return Result.OK(record);
}
@@ -187,27 +185,7 @@ public class MesXslWeightRecordController extends JeecgController<MesXslWeightRe
}
}
/**
* 给一批磅单记录批量填充「已入场重量」transient 字段,不入库)。
* 数据来源所有引用本榜单bill_no 匹配)的原料入场记录的拆码明细的 (份数×每份重量) 累计。
* 实现上为避免 N+1先收集所有 billNo再一次 IN 查询累计。
*/
private void fillEnteredWeight(List<MesXslWeightRecord> records) {
if (records == null || records.isEmpty()) {
return;
}
List<String> billNos = records.stream()
.map(MesXslWeightRecord::getBillNo)
.filter(s -> s != null && !s.isBlank())
.distinct()
.collect(Collectors.toList());
if (billNos.isEmpty()) {
return;
}
Map<String, BigDecimal> sumMap = rawMaterialEntryService.sumEnteredWeightByBillNos(billNos);
for (MesXslWeightRecord r : records) {
BigDecimal v = (r.getBillNo() == null) ? null : sumMap.get(r.getBillNo());
r.setEnteredWeight(v != null ? v : BigDecimal.ZERO);
}
private void fillWeightRecordDerivedFields(List<MesXslWeightRecord> records) {
rawMaterialEntryService.fillWeightRecordDerivedFields(records);
}
}

View File

@@ -0,0 +1,107 @@
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;
/**
* MES 密炼物料皮重策略
*/
@Data
@TableName("mes_xsl_mixer_material_tare_strategy")
@Accessors(chain = true)
@EqualsAndHashCode(callSuper = false)
@Schema(description = "MES密炼物料皮重策略")
public class MesXslMixerMaterialTareStrategy implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(type = IdType.ASSIGN_ID)
private String id;
@Schema(description = "租户ID")
private Integer tenantId;
@Excel(name = "密炼物料", width = 18, dictTable = "mes_mixer_material", dicText = "material_name", dicCode = "id")
@Dict(dictTable = "mes_mixer_material", dicText = "material_name", dicCode = "id")
@Schema(description = "密炼物料ID关联 mes_mixer_material.id")
private String mixerMaterialId;
@Excel(name = "密炼物料名称", width = 20)
@Schema(description = "密炼物料名称冗余")
private String mixerMaterialName;
@Excel(name = "供应商", width = 18, dictTable = "mes_xsl_supplier", dicText = "supplier_name", dicCode = "id")
@Dict(dictTable = "mes_xsl_supplier", dicText = "supplier_name", dicCode = "id")
@Schema(description = "供应商ID关联 mes_xsl_supplier.id")
private String supplierId;
@Excel(name = "供应商名称", width = 20)
@Schema(description = "供应商名称冗余")
private String supplierName;
@Excel(name = "物料规格", width = 16)
@Schema(description = "物料规格(与密炼物料、供应商、生效日期共同参与唯一性校验,不同规格可分别维护)")
private String materialSpec;
@Excel(name = "包装物重量", width = 12)
@Schema(description = "包装物重量")
private BigDecimal tareWeight;
@Excel(name = "托盘重量", width = 12)
@Schema(description = "托盘重量")
private BigDecimal palletWeight;
@Schema(description = "单位ID关联 mes_xsl_unit.id")
private String unitId;
@Excel(name = "单位", width = 10)
@Schema(description = "单位名称冗余")
private String unitName;
@Excel(name = "生效开始日期", width = 14, format = "yyyy-MM-dd")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
@Schema(description = "生效开始日期")
private Date effectiveStartDate;
@Excel(name = "生效截止日期", width = 14, format = "yyyy-MM-dd")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd")
@DateTimeFormat(pattern = "yyyy-MM-dd")
@Schema(description = "生效截止日期")
private Date effectiveEndDate;
@Excel(name = "维护人", width = 12, dictTable = "sys_user", dicText = "realname", dicCode = "username")
@Dict(dictTable = "sys_user", dicText = "realname", dicCode = "username")
@Schema(description = "维护人(登录账号)")
private String maintainBy;
@Excel(name = "创建人", width = 12)
private String createBy;
@Excel(name = "创建时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime;
@Excel(name = "修改人", width = 12)
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 String sysOrgCode;
private Integer delFlag;
}

View File

@@ -86,6 +86,14 @@ public class MesXslRawMaterialCard implements Serializable {
@Schema(description = "总重")
private BigDecimal totalWeight;
@Excel(name = "包装物皮重", width = 12)
@Schema(description = "包装物皮重(KG)")
private BigDecimal packagingTare;
@Excel(name = "托盘重量", width = 12)
@Schema(description = "托盘重量(KG)")
private BigDecimal palletWeight;
@Excel(name = "剩余重量", width = 12)
@Schema(description = "剩余重量")
private BigDecimal remainingWeight;

View File

@@ -89,6 +89,10 @@ public class MesXslRawMaterialEntry implements Serializable {
@Schema(description = "总重(KG)")
private BigDecimal totalWeight;
@Excel(name = "托盘及皮重合计", width = 14)
@Schema(description = "托盘及皮重(合计)")
private BigDecimal palletTareTotal;
// 总份数 / 每份总重 / 每份包数:从 数值类型 升级为 字符串类型,
// 支持桌面端「拆码明细」多行拼接保存(如 20/1/ 与 100/200/)。
@Excel(name = "总份数", width = 12)
@@ -99,6 +103,17 @@ public class MesXslRawMaterialEntry implements Serializable {
@Schema(description = "每份总重(KG)(支持多行拆码明细拼接,如 100/200/")
private String portionWeight;
@Excel(name = "包装物皮重", width = 14)
@Schema(description = "拆码明细包装物皮重拼接(以 / 分隔,末尾带 /")
private String portionPackagingTare;
@Excel(name = "托盘重量", width = 14)
@Schema(description = "拆码明细托盘重量拼接(以 / 分隔,末尾带 /")
private String portionPalletWeight;
@Schema(description = "拆码明细皮重策略ID拼接以 / 分隔,末尾带 /")
private String portionTareStrategyIds;
@Excel(name = "每份包数", width = 12)
@Schema(description = "每份包数(支持多行拆码明细拼接)")
private String portionPackages;

View File

@@ -56,6 +56,14 @@ public class MesXslRawMaterialWorkshopRemain extends JeecgEntity {
@Schema(description = "总重")
private BigDecimal totalWeight;
@Excel(name = "包装物皮重", width = 12)
@Schema(description = "包装物皮重(KG)")
private BigDecimal packagingTare;
@Excel(name = "托盘重量", width = 12)
@Schema(description = "托盘重量(KG)")
private BigDecimal palletWeight;
@Excel(name = "剩余重量", width = 12)
@Schema(description = "剩余重量")
private BigDecimal remainingWeight;

View File

@@ -43,7 +43,10 @@ import java.util.Date;
"driverName",
"driverPhone",
"billType",
"tenantId"
"tenantId",
"enteredWeight",
"cargoTareWeight",
"rawMaterialWeight"
})
public class MesXslWeightRecord extends JeecgEntity implements Serializable {
@@ -129,4 +132,20 @@ public class MesXslWeightRecord extends JeecgEntity implements Serializable {
@TableField(exist = false)
@Schema(description = "已入场重量(KG),由原料入场记录的拆码明细实时累计")
private BigDecimal enteredWeight;
/**
* 货物皮重KG—— 实时计算,不落库。
* 数据来源所有引用本榜单bill_no 匹配)的原料入场记录的 pallet_tare_total托盘及皮重合计累加。
*/
@TableField(exist = false)
@Schema(description = "货物皮重(KG),关联原料入场记录的托盘及皮重合计累计")
private BigDecimal cargoTareWeight;
/**
* 原料重量KG—— 实时计算,不落库。
* 公式:净重(KG) - 货物皮重(KG)。
*/
@TableField(exist = false)
@Schema(description = "原料重量(KG)=净重-货物皮重")
private BigDecimal rawMaterialWeight;
}

View File

@@ -0,0 +1,11 @@
package org.jeecg.modules.xslmes.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import org.jeecg.modules.xslmes.entity.MesXslMixerMaterialTareStrategy;
/**
* MES 密炼物料皮重策略 Mapper
*/
@Mapper
public interface MesXslMixerMaterialTareStrategyMapper extends BaseMapper<MesXslMixerMaterialTareStrategy> {}

View File

@@ -0,0 +1,22 @@
package org.jeecg.modules.xslmes.service;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.xslmes.entity.MesXslMixerMaterialTareStrategy;
/**
* MES 密炼物料皮重策略
*/
public interface IMesXslMixerMaterialTareStrategyService extends IService<MesXslMixerMaterialTareStrategy> {
//update-begin---author:cursor ---date:20250602 for【密炼物料皮重策略】保存前校验生效日期重叠含物料规格-----------
/**
* 校验同一租户、同一供应商、同一密炼物料、同一物料规格在生效日期内是否已存在记录。
* 同一密炼物料不同规格可分别维护;仅规格相同且生效日期重叠时不允许重复。
*
* @param entity 待保存实体
* @param isUpdate 是否编辑
* @return 错误信息null 表示通过
*/
String validateBeforeSave(MesXslMixerMaterialTareStrategy entity, boolean isUpdate);
//update-end---author:cursor ---date:20250602 for【密炼物料皮重策略】保存前校验生效日期重叠含物料规格-----------
}

View File

@@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialEntry;
import org.jeecg.modules.xslmes.entity.MesXslWeightRecord;
import org.jeecg.modules.xslmes.vo.MesXslRawMaterialCardBriefVO;
import org.jeecg.modules.xslmes.vo.MesXslRawMaterialEntryDeleteLogVO;
@@ -62,6 +63,19 @@ public interface IMesXslRawMaterialEntryService extends IService<MesXslRawMateri
*/
Map<String, BigDecimal> sumEnteredWeightByBillNos(Collection<String> billNos);
/**
* 按榜单号批量统计「货物皮重」(托盘及皮重合计累加)。
*
* @param billNos 榜单号集合
* @return billNo -&gt; 累计货物皮重;查不到的 billNo 不会出现在 map 中
*/
Map<String, BigDecimal> sumCargoTareByBillNos(Collection<String> billNos);
/**
* 给磅单列表/详情填充由原料入场记录衍生的 transient 字段(已入场重量、货物皮重)。
*/
void fillWeightRecordDerivedFields(List<MesXslWeightRecord> records);
/**
* 结存入库并汇总原材料库存。
* <p>

View File

@@ -75,6 +75,14 @@ public class MesXslStompNotifyService {
publish("/topic/sync/print-templates", "PRINT_TEMPLATE_CHANGED", "templateId", templateId, action);
}
//update-begin---author:cursor ---date:20250602 for【密炼物料皮重策略】桌面端同步-----------
/** 广播密炼物料皮重策略变更事件到 /topic/sync/mes-mixer-material-tare-strategies */
public void publishMixerMaterialTareStrategyChanged(String action, String tareStrategyId) {
publish("/topic/sync/mes-mixer-material-tare-strategies", "MES_MIXER_MATERIAL_TARE_STRATEGY_CHANGED",
"tareStrategyId", tareStrategyId, action);
}
//update-end---author:cursor ---date:20250602 for【密炼物料皮重策略】桌面端同步-----------
// ─────────────────────────── 私有辅助 ────────────────────────────
private void publish(String topic, String cmd, String idKey, String idValue, String action) {

View File

@@ -773,7 +773,7 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
//update-begin---author:cursor ---date:20260601 for【XSLMES-20260601-A62】生成混炼示方改为同步B/F段胶至胶料信息-----------
/**
* 生成混炼示方时,将 B 段/F 段胶料同步写入「胶料信息」(mes_material)
* 胶料类别取配合示方所选胶料代号」对应胶料的类别;不再写入密炼物料,也不再维护比重
* 除 ERP 编号留空、编码/名称为示方编号外,其余字段按配合示方所选胶料信息赋值
*/
private void syncGeneratedRubberMixerMaterial(
MesXslFormulaMixingGenerateRowVO row,
@@ -785,60 +785,128 @@ public class MesXslFormulaSpecServiceImpl extends ServiceImpl<MesXslFormulaSpecM
}
String specCode = row.getSpecCode().trim();
boolean isFinalStage = "Q".equalsIgnoreCase(resolveMixingMaterialStep(row));
String categoryId = resolveGeneratedRubberCategoryId(formula);
String rubberName = resolveRubberName(formula);
MesMaterial sourceRubber = resolveSourceRubberMaterial(formula);
MesMaterial existing = findRubberMaterialByCodeOrName(specCode);
Date now = new Date();
if (existing != null) {
if (StringUtils.isNotBlank(categoryId)) {
existing.setCategoryId(categoryId);
//update-begin---author:cursor ---date:20260601 for【XSLMES-20260601-A62】更新已生成胶料时按原胶料复制字段-----------
if (sourceRubber != null) {
fillGeneratedRubberFromSource(existing, sourceRubber, specCode, now, true);
} else {
applyGeneratedRubberFallback(existing, formula, specCode, now);
}
if (StringUtils.isBlank(existing.getMaterialCode())) {
existing.setMaterialCode(specCode);
}
if (StringUtils.isBlank(existing.getMaterialName())) {
existing.setMaterialName(specCode);
}
if (StringUtils.isBlank(existing.getAliasName()) && StringUtils.isNotBlank(rubberName)) {
existing.setAliasName(rubberName);
}
existing.setEnableFlag(existing.getEnableFlag() == null ? 1 : existing.getEnableFlag());
existing.setUpdateTime(now);
//update-end---author:cursor ---date:20260601 for【XSLMES-20260601-A62】更新已生成胶料时按原胶料复制字段-----------
mesMaterialService.updateById(existing);
log.info(
"[混炼示方生成] 更新胶料信息 id={}, code={}, categoryId={}, isFinal={}",
"[混炼示方生成] 更新胶料信息 id={}, code={}, sourceId={}, isFinal={}",
existing.getId(),
specCode,
categoryId,
sourceRubber != null ? sourceRubber.getId() : null,
isFinalStage);
return;
}
MesMaterial material = new MesMaterial();
material.setMaterialCode(specCode);
material.setMaterialName(specCode);
material.setAliasName(StringUtils.isNotBlank(rubberName) ? rubberName : null);
material.setCategoryId(categoryId);
material.setEnableFlag(1);
material.setIsSpecialRubber(0);
material.setDelFlag(CommonConstant.DEL_FLAG_0);
material.setCreateTime(now);
material.setUpdateTime(now);
//update-begin---author:cursor ---date:20260601 for【XSLMES-20260601-A62】新增B/F段胶料按原胶料复制字段-----------
if (sourceRubber != null) {
fillGeneratedRubberFromSource(material, sourceRubber, specCode, now, false);
} else {
applyGeneratedRubberFallback(material, formula, specCode, now);
}
//update-end---author:cursor ---date:20260601 for【XSLMES-20260601-A62】新增B/F段胶料按原胶料复制字段-----------
mesMaterialService.save(material);
log.info(
"[混炼示方生成] 新增胶料信息 id={}, code={}, categoryId={}, isFinal={}",
"[混炼示方生成] 新增胶料信息 id={}, code={}, sourceId={}, isFinal={}",
material.getId(),
specCode,
categoryId,
sourceRubber != null ? sourceRubber.getId() : null,
isFinalStage);
}
/** 生成的 B/F 段胶料类别:取配合示方所选「胶料代号」对应胶料(mes_material)的类别 */
private String resolveGeneratedRubberCategoryId(MesXslFormulaSpec formula) {
/** 配合示方所选「胶料代号」对应的原胶料信息 */
private MesMaterial resolveSourceRubberMaterial(MesXslFormulaSpec formula) {
if (formula == null || StringUtils.isBlank(formula.getRubberMaterialId())) {
return null;
}
MesMaterial rubber = mesMaterialService.getById(formula.getRubberMaterialId());
if (rubber == null) {
return null;
}
if (rubber.getDelFlag() != null && rubber.getDelFlag().equals(CommonConstant.DEL_FLAG_1)) {
return null;
}
return rubber;
}
/**
* 将原胶料字段复制到生成的 B/F 段胶料:编码/名称=示方编号ERP 编号留空,不复制主键与审计字段。
*/
private void fillGeneratedRubberFromSource(
MesMaterial target, MesMaterial source, String specCode, Date now, boolean isUpdate) {
if (target == null || source == null || StringUtils.isBlank(specCode)) {
return;
}
String code = specCode.trim();
target.setMaterialCode(code);
target.setMaterialName(code);
target.setAliasName(source.getAliasName());
target.setShortName(source.getShortName());
target.setCategoryId(source.getCategoryId());
target.setMaterialGrade(source.getMaterialGrade());
target.setPlanPrice(source.getPlanPrice());
target.setMinStock(source.getMinStock());
target.setMaxStock(source.getMaxStock());
target.setBaseUnitId(source.getBaseUnitId());
target.setStatUnitId(source.getStatUnitId());
target.setUnitConvertRate(source.getUnitConvertRate());
target.setErpCode(null);
target.setFinalShelfLifeDays(source.getFinalShelfLifeDays());
target.setMasterShelfLifeDays(source.getMasterShelfLifeDays());
target.setMinStandingHours(source.getMinStandingHours());
target.setStandardCode(source.getStandardCode());
target.setOriginPlace(source.getOriginPlace());
target.setSupplierId(source.getSupplierId());
target.setCustomerId(source.getCustomerId());
target.setEnableFlag(source.getEnableFlag() != null ? source.getEnableFlag() : 1);
target.setIsSpecialRubber(source.getIsSpecialRubber() != null ? source.getIsSpecialRubber() : 0);
target.setSyncFromErpFlag(0);
target.setLastErpSyncTime(null);
target.setRemark(source.getRemark());
target.setTenantId(source.getTenantId());
target.setSysOrgCode(source.getSysOrgCode());
target.setUpdateTime(now);
if (!isUpdate) {
target.setDelFlag(CommonConstant.DEL_FLAG_0);
target.setCreateTime(now);
}
}
/** 未选择原胶料时的最小兜底(仅类别/状态) */
private void applyGeneratedRubberFallback(MesMaterial target, MesXslFormulaSpec formula, String specCode, Date now) {
if (target == null || StringUtils.isBlank(specCode)) {
return;
}
String code = specCode.trim();
target.setMaterialCode(code);
target.setMaterialName(code);
target.setCategoryId(resolveGeneratedRubberCategoryId(formula));
String rubberName = resolveRubberName(formula);
if (StringUtils.isNotBlank(rubberName)) {
target.setAliasName(rubberName);
}
target.setErpCode(null);
target.setEnableFlag(target.getEnableFlag() != null ? target.getEnableFlag() : 1);
target.setIsSpecialRubber(target.getIsSpecialRubber() != null ? target.getIsSpecialRubber() : 0);
target.setDelFlag(target.getDelFlag() != null ? target.getDelFlag() : CommonConstant.DEL_FLAG_0);
target.setUpdateTime(now);
if (target.getCreateTime() == null) {
target.setCreateTime(now);
}
}
/** 生成的 B/F 段胶料类别:取配合示方所选「胶料代号」对应胶料(mes_material)的类别 */
private String resolveGeneratedRubberCategoryId(MesXslFormulaSpec formula) {
MesMaterial rubber = resolveSourceRubberMaterial(formula);
return rubber != null ? rubber.getCategoryId() : null;
}

View File

@@ -0,0 +1,107 @@
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.Date;
import org.jeecg.common.util.oConvertUtils;
import org.jeecg.modules.mes.material.entity.MesMixerMaterial;
import org.jeecg.modules.mes.material.service.IMesMixerMaterialService;
import org.jeecg.modules.xslmes.entity.MesXslMixerMaterialTareStrategy;
import org.jeecg.modules.xslmes.entity.MesXslSupplier;
import org.jeecg.modules.xslmes.entity.MesXslUnit;
import org.jeecg.modules.xslmes.mapper.MesXslMixerMaterialTareStrategyMapper;
import org.jeecg.modules.xslmes.service.IMesXslMixerMaterialTareStrategyService;
import org.jeecg.modules.xslmes.service.IMesXslSupplierService;
import org.jeecg.modules.xslmes.service.IMesXslUnitService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* MES 密炼物料皮重策略
*/
@Service
public class MesXslMixerMaterialTareStrategyServiceImpl
extends ServiceImpl<MesXslMixerMaterialTareStrategyMapper, MesXslMixerMaterialTareStrategy>
implements IMesXslMixerMaterialTareStrategyService {
@Autowired
private IMesMixerMaterialService mesMixerMaterialService;
@Autowired
private IMesXslSupplierService mesXslSupplierService;
@Autowired
private IMesXslUnitService mesXslUnitService;
//update-begin---author:cursor ---date:20250602 for【密炼物料皮重策略】保存前校验与冗余回填-----------
@Override
public String validateBeforeSave(MesXslMixerMaterialTareStrategy entity, boolean isUpdate) {
if (oConvertUtils.isEmpty(entity.getMixerMaterialId())) {
return "请选择密炼物料";
}
if (oConvertUtils.isEmpty(entity.getSupplierId())) {
return "请选择供应商";
}
if (entity.getTareWeight() == null) {
return "请填写包装物重量";
}
if (entity.getPalletWeight() != null && entity.getPalletWeight().signum() < 0) {
return "托盘重量不能为负数";
}
if (oConvertUtils.isEmpty(entity.getUnitId())) {
return "请选择单位";
}
Date startDate = entity.getEffectiveStartDate();
Date endDate = entity.getEffectiveEndDate();
if (startDate == null || endDate == null) {
return "请填写完整的生效日期";
}
if (startDate.after(endDate)) {
return "生效开始日期不能晚于截止日期";
}
MesMixerMaterial mixerMaterial = mesMixerMaterialService.getById(entity.getMixerMaterialId());
if (mixerMaterial == null) {
return "所选密炼物料不存在,请重新选择";
}
MesXslSupplier supplier = mesXslSupplierService.getById(entity.getSupplierId());
if (supplier == null) {
return "所选供应商不存在,请重新选择";
}
MesXslUnit unit = mesXslUnitService.getById(entity.getUnitId());
if (unit == null) {
return "所选单位不存在,请重新选择";
}
entity.setMixerMaterialName(mixerMaterial.getMaterialName());
entity.setSupplierName(supplier.getSupplierName());
entity.setUnitName(unit.getUnitName());
//update-begin---author:cursor ---date:20250602 for【密炼物料皮重策略】重叠校验增加物料规格维度-----------
if (entity.getMaterialSpec() != null) {
entity.setMaterialSpec(entity.getMaterialSpec().trim());
}
if (oConvertUtils.isEmpty(entity.getMaterialSpec())) {
entity.setMaterialSpec(null);
}
String normalizedSpec = oConvertUtils.isEmpty(entity.getMaterialSpec()) ? "" : entity.getMaterialSpec();
LambdaQueryWrapper<MesXslMixerMaterialTareStrategy> overlapQw = new LambdaQueryWrapper<>();
overlapQw.eq(MesXslMixerMaterialTareStrategy::getMixerMaterialId, entity.getMixerMaterialId())
.eq(MesXslMixerMaterialTareStrategy::getSupplierId, entity.getSupplierId())
.le(MesXslMixerMaterialTareStrategy::getEffectiveStartDate, endDate)
.ge(MesXslMixerMaterialTareStrategy::getEffectiveEndDate, startDate)
.apply("IFNULL(TRIM(material_spec), '') = {0}", normalizedSpec);
//update-end---author:cursor ---date:20250602 for【密炼物料皮重策略】重叠校验增加物料规格维度-----------
if (entity.getTenantId() != null) {
overlapQw.eq(MesXslMixerMaterialTareStrategy::getTenantId, entity.getTenantId());
}
if (isUpdate && oConvertUtils.isNotEmpty(entity.getId())) {
overlapQw.ne(MesXslMixerMaterialTareStrategy::getId, entity.getId());
}
if (count(overlapQw) > 0) {
return "同一租户、同一供应商、同一密炼物料且物料规格相同的时间段内,已存在策略,请勿重复维护";
}
return null;
}
//update-end---author:cursor ---date:20250602 for【密炼物料皮重策略】保存前校验与冗余回填-----------
}

View File

@@ -10,6 +10,7 @@ import org.jeecg.modules.xslmes.entity.MesXslRawMaterialCard;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialInventory;
import org.jeecg.modules.xslmes.entity.MesXslRawMaterialEntry;
import org.jeecg.modules.xslmes.entity.MesXslWarehouseArea;
import org.jeecg.modules.xslmes.entity.MesXslWeightRecord;
import org.jeecg.modules.xslmes.mapper.MesXslRawMaterialEntryMapper;
import org.jeecg.modules.xslmes.service.IMesXslRawMaterialCardService;
import org.jeecg.modules.xslmes.service.IMesXslRawMaterialInventoryService;
@@ -217,6 +218,75 @@ public class MesXslRawMaterialEntryServiceImpl
return result;
}
@Override
public Map<String, BigDecimal> sumCargoTareByBillNos(Collection<String> billNos) {
if (billNos == null || billNos.isEmpty()) {
return Collections.emptyMap();
}
Set<String> distinct = billNos.stream()
.filter(s -> s != null && !s.isBlank())
.collect(Collectors.toCollection(HashSet::new));
if (distinct.isEmpty()) {
return Collections.emptyMap();
}
LambdaQueryWrapper<MesXslRawMaterialEntry> qw = new LambdaQueryWrapper<>();
qw.in(MesXslRawMaterialEntry::getBillNo, distinct)
.select(MesXslRawMaterialEntry::getBillNo, MesXslRawMaterialEntry::getPalletTareTotal);
List<MesXslRawMaterialEntry> rows = this.list(qw);
Map<String, BigDecimal> result = new HashMap<>();
for (MesXslRawMaterialEntry row : rows) {
if (row.getBillNo() == null || row.getPalletTareTotal() == null) {
continue;
}
result.merge(row.getBillNo(), row.getPalletTareTotal(), BigDecimal::add);
}
return result;
}
@Override
public void fillWeightRecordDerivedFields(List<MesXslWeightRecord> records) {
if (records == null || records.isEmpty()) {
return;
}
List<String> billNos = records.stream()
.map(MesXslWeightRecord::getBillNo)
.filter(s -> s != null && !s.isBlank())
.distinct()
.collect(Collectors.toList());
if (billNos.isEmpty()) {
for (MesXslWeightRecord r : records) {
r.setEnteredWeight(BigDecimal.ZERO);
r.setCargoTareWeight(BigDecimal.ZERO);
applyRawMaterialWeight(r);
}
return;
}
Map<String, BigDecimal> enteredMap = sumEnteredWeightByBillNos(billNos);
Map<String, BigDecimal> cargoTareMap = sumCargoTareByBillNos(billNos);
for (MesXslWeightRecord r : records) {
String billNo = r.getBillNo();
if (billNo == null || billNo.isBlank()) {
r.setEnteredWeight(BigDecimal.ZERO);
r.setCargoTareWeight(BigDecimal.ZERO);
} else {
r.setEnteredWeight(enteredMap.getOrDefault(billNo, BigDecimal.ZERO));
r.setCargoTareWeight(cargoTareMap.getOrDefault(billNo, BigDecimal.ZERO));
}
applyRawMaterialWeight(r);
}
}
/** 原料重量 = 净重 - 货物皮重(不落库) */
private static void applyRawMaterialWeight(MesXslWeightRecord record) {
BigDecimal net = record.getNetWeight();
if (net == null) {
record.setRawMaterialWeight(null);
return;
}
BigDecimal cargo = record.getCargoTareWeight() != null ? record.getCargoTareWeight() : BigDecimal.ZERO;
record.setRawMaterialWeight(net.subtract(cargo));
}
@Override
@Transactional(rollbackFor = Exception.class)
public void batchStockInAndSyncInventory(Collection<String> ids) {