From 143853a87d08a3019ff12f47232dd27b3c50f7e1 Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Thu, 25 Jun 2026 11:34:56 +0800 Subject: [PATCH 01/24] =?UTF-8?q?feat(flow):=20=E6=B7=BB=E5=8A=A0=E6=8E=92?= =?UTF-8?q?=E4=BA=A7=E6=98=8E=E7=BB=86=E9=92=A2=E5=8D=B7=E5=85=B3=E7=B3=BB?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 创建排产明细钢卷关系实体类 SchDetailCoilRel - 定义业务对象 SchDetailCoilRelBo 和视图对象 SchDetailCoilRelVo - 实现排产明细钢卷关系服务接口 ISchDetailCoilRelService - 开发控制器 SchDetailCoilRelController 提供 REST API - 创建数据访问层 SchDetailCoilRelMapper 和 XML 映射文件 - 实现服务层业务逻辑 SchDetailCoilRelServiceImpl - 集成分页查询、新增、修改、删除等基础操作 - 添加 Excel 导出功能和数据验证机制 --- .../SchDetailCoilRelController.java | 99 ++++++++++++++++ .../com/klp/flow/domain/SchDetailCoilRel.java | 45 ++++++++ .../flow/domain/bo/SchDetailCoilRelBo.java | 41 +++++++ .../flow/domain/vo/SchDetailCoilRelVo.java | 49 ++++++++ .../flow/mapper/SchDetailCoilRelMapper.java | 15 +++ .../service/ISchDetailCoilRelService.java | 49 ++++++++ .../impl/SchDetailCoilRelServiceImpl.java | 109 ++++++++++++++++++ .../mapper/flow/SchDetailCoilRelMapper.xml | 20 ++++ 8 files changed, 427 insertions(+) create mode 100644 klp-flow/src/main/java/com/klp/flow/controller/SchDetailCoilRelController.java create mode 100644 klp-flow/src/main/java/com/klp/flow/domain/SchDetailCoilRel.java create mode 100644 klp-flow/src/main/java/com/klp/flow/domain/bo/SchDetailCoilRelBo.java create mode 100644 klp-flow/src/main/java/com/klp/flow/domain/vo/SchDetailCoilRelVo.java create mode 100644 klp-flow/src/main/java/com/klp/flow/mapper/SchDetailCoilRelMapper.java create mode 100644 klp-flow/src/main/java/com/klp/flow/service/ISchDetailCoilRelService.java create mode 100644 klp-flow/src/main/java/com/klp/flow/service/impl/SchDetailCoilRelServiceImpl.java create mode 100644 klp-flow/src/main/resources/mapper/flow/SchDetailCoilRelMapper.xml diff --git a/klp-flow/src/main/java/com/klp/flow/controller/SchDetailCoilRelController.java b/klp-flow/src/main/java/com/klp/flow/controller/SchDetailCoilRelController.java new file mode 100644 index 000000000..8256c50ab --- /dev/null +++ b/klp-flow/src/main/java/com/klp/flow/controller/SchDetailCoilRelController.java @@ -0,0 +1,99 @@ +package com.klp.flow.controller; + +import java.util.List; +import java.util.Arrays; + +import lombok.RequiredArgsConstructor; +import javax.servlet.http.HttpServletResponse; +import javax.validation.constraints.*; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import com.klp.common.annotation.RepeatSubmit; +import com.klp.common.annotation.Log; +import com.klp.common.core.controller.BaseController; +import com.klp.common.core.domain.PageQuery; +import com.klp.common.core.domain.R; +import com.klp.common.core.validate.AddGroup; +import com.klp.common.core.validate.EditGroup; +import com.klp.common.enums.BusinessType; +import com.klp.common.utils.poi.ExcelUtil; +import com.klp.flow.domain.vo.SchDetailCoilRelVo; +import com.klp.flow.domain.bo.SchDetailCoilRelBo; +import com.klp.flow.service.ISchDetailCoilRelService; +import com.klp.common.core.page.TableDataInfo; + +/** + * 排产明细钢卷关系 + * + * @author klp + * @date 2026-06-25 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/flow/detailCoilRel") +public class SchDetailCoilRelController extends BaseController { + + private final ISchDetailCoilRelService iSchDetailCoilRelService; + + /** + * 查询排产明细钢卷关系列表 + */ + @GetMapping("/list") + public TableDataInfo list(SchDetailCoilRelBo bo, PageQuery pageQuery) { + return iSchDetailCoilRelService.queryPageList(bo, pageQuery); + } + + /** + * 导出排产明细钢卷关系列表 + */ + @Log(title = "排产明细钢卷关系", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(SchDetailCoilRelBo bo, HttpServletResponse response) { + List list = iSchDetailCoilRelService.queryList(bo); + ExcelUtil.exportExcel(list, "排产明细钢卷关系", SchDetailCoilRelVo.class, response); + } + + /** + * 获取排产明细钢卷关系详细信息 + * + * @param relId 主键 + */ + @GetMapping("/{relId}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long relId) { + return R.ok(iSchDetailCoilRelService.queryById(relId)); + } + + /** + * 新增排产明细钢卷关系 + */ + @Log(title = "排产明细钢卷关系", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody SchDetailCoilRelBo bo) { + return toAjax(iSchDetailCoilRelService.insertByBo(bo)); + } + + /** + * 修改排产明细钢卷关系 + */ + @Log(title = "排产明细钢卷关系", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody SchDetailCoilRelBo bo) { + return toAjax(iSchDetailCoilRelService.updateByBo(bo)); + } + + /** + * 删除排产明细钢卷关系 + * + * @param relIds 主键串 + */ + @Log(title = "排产明细钢卷关系", businessType = BusinessType.DELETE) + @DeleteMapping("/{relIds}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] relIds) { + return toAjax(iSchDetailCoilRelService.deleteWithValidByIds(Arrays.asList(relIds), true)); + } +} diff --git a/klp-flow/src/main/java/com/klp/flow/domain/SchDetailCoilRel.java b/klp-flow/src/main/java/com/klp/flow/domain/SchDetailCoilRel.java new file mode 100644 index 000000000..34f40e079 --- /dev/null +++ b/klp-flow/src/main/java/com/klp/flow/domain/SchDetailCoilRel.java @@ -0,0 +1,45 @@ +package com.klp.flow.domain; + +import com.baomidou.mybatisplus.annotation.*; +import com.klp.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + + +/** + * 排产明细钢卷关系对象 sch_detail_coil_rel + * + * @author klp + * @date 2026-06-25 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("sch_detail_coil_rel") +public class SchDetailCoilRel extends BaseEntity { + + private static final long serialVersionUID=1L; + + /** + * 主键 + */ + @TableId(value = "rel_id") + private Long relId; + /** + * 排产明细ID(关联 sch_prod_schedule_detail.schedule_detail_id) + */ + private Long scheduleDetailId; + /** + * 钢卷ID(关联 wms_material_coil.coil_id) + */ + private Long coilId; + /** + * 备注 + */ + private String remark; + /** + * 删除标志(0=正常,1=已删除) + */ + @TableLogic + private Integer delFlag; + +} diff --git a/klp-flow/src/main/java/com/klp/flow/domain/bo/SchDetailCoilRelBo.java b/klp-flow/src/main/java/com/klp/flow/domain/bo/SchDetailCoilRelBo.java new file mode 100644 index 000000000..204d334eb --- /dev/null +++ b/klp-flow/src/main/java/com/klp/flow/domain/bo/SchDetailCoilRelBo.java @@ -0,0 +1,41 @@ +package com.klp.flow.domain.bo; + +import com.klp.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; +import javax.validation.constraints.*; + + +/** + * 排产明细钢卷关系业务对象 sch_detail_coil_rel + * + * @author klp + * @date 2026-06-25 + */ + +@Data +@EqualsAndHashCode(callSuper = true) +public class SchDetailCoilRelBo extends BaseEntity { + + /** + * 主键 + */ + private Long relId; + + /** + * 排产明细ID(关联 sch_prod_schedule_detail.schedule_detail_id) + */ + private Long scheduleDetailId; + + /** + * 钢卷ID(关联 wms_material_coil.coil_id) + */ + private Long coilId; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/klp-flow/src/main/java/com/klp/flow/domain/vo/SchDetailCoilRelVo.java b/klp-flow/src/main/java/com/klp/flow/domain/vo/SchDetailCoilRelVo.java new file mode 100644 index 000000000..b92836493 --- /dev/null +++ b/klp-flow/src/main/java/com/klp/flow/domain/vo/SchDetailCoilRelVo.java @@ -0,0 +1,49 @@ +package com.klp.flow.domain.vo; + +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import com.klp.common.annotation.ExcelDictFormat; +import com.klp.common.convert.ExcelDictConvert; +import lombok.Data; + + +/** + * 排产明细钢卷关系视图对象 sch_detail_coil_rel + * + * @author klp + * @date 2026-06-25 + */ +@Data +@ExcelIgnoreUnannotated +public class SchDetailCoilRelVo { + + private static final long serialVersionUID = 1L; + + /** + * 主键 + */ + @ExcelProperty(value = "主键") + private Long relId; + + /** + * 排产明细ID(关联 sch_prod_schedule_detail.schedule_detail_id) + */ + @ExcelProperty(value = "排产明细ID", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "关=联,s=ch_prod_schedule_detail.schedule_detail_id") + private Long scheduleDetailId; + + /** + * 钢卷ID(关联 wms_material_coil.coil_id) + */ + @ExcelProperty(value = "钢卷ID", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "关=联,w=ms_material_coil.coil_id") + private Long coilId; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + +} diff --git a/klp-flow/src/main/java/com/klp/flow/mapper/SchDetailCoilRelMapper.java b/klp-flow/src/main/java/com/klp/flow/mapper/SchDetailCoilRelMapper.java new file mode 100644 index 000000000..371f30b2c --- /dev/null +++ b/klp-flow/src/main/java/com/klp/flow/mapper/SchDetailCoilRelMapper.java @@ -0,0 +1,15 @@ +package com.klp.flow.mapper; + +import com.klp.flow.domain.SchDetailCoilRel; +import com.klp.flow.domain.vo.SchDetailCoilRelVo; +import com.klp.common.core.mapper.BaseMapperPlus; + +/** + * 排产明细钢卷关系Mapper接口 + * + * @author klp + * @date 2026-06-25 + */ +public interface SchDetailCoilRelMapper extends BaseMapperPlus { + +} diff --git a/klp-flow/src/main/java/com/klp/flow/service/ISchDetailCoilRelService.java b/klp-flow/src/main/java/com/klp/flow/service/ISchDetailCoilRelService.java new file mode 100644 index 000000000..d5749f55f --- /dev/null +++ b/klp-flow/src/main/java/com/klp/flow/service/ISchDetailCoilRelService.java @@ -0,0 +1,49 @@ +package com.klp.flow.service; + +import com.klp.flow.domain.SchDetailCoilRel; +import com.klp.flow.domain.vo.SchDetailCoilRelVo; +import com.klp.flow.domain.bo.SchDetailCoilRelBo; +import com.klp.common.core.page.TableDataInfo; +import com.klp.common.core.domain.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 排产明细钢卷关系Service接口 + * + * @author klp + * @date 2026-06-25 + */ +public interface ISchDetailCoilRelService { + + /** + * 查询排产明细钢卷关系 + */ + SchDetailCoilRelVo queryById(Long relId); + + /** + * 查询排产明细钢卷关系列表 + */ + TableDataInfo queryPageList(SchDetailCoilRelBo bo, PageQuery pageQuery); + + /** + * 查询排产明细钢卷关系列表 + */ + List queryList(SchDetailCoilRelBo bo); + + /** + * 新增排产明细钢卷关系 + */ + Boolean insertByBo(SchDetailCoilRelBo bo); + + /** + * 修改排产明细钢卷关系 + */ + Boolean updateByBo(SchDetailCoilRelBo bo); + + /** + * 校验并批量删除排产明细钢卷关系信息 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/klp-flow/src/main/java/com/klp/flow/service/impl/SchDetailCoilRelServiceImpl.java b/klp-flow/src/main/java/com/klp/flow/service/impl/SchDetailCoilRelServiceImpl.java new file mode 100644 index 000000000..87b0b9a2c --- /dev/null +++ b/klp-flow/src/main/java/com/klp/flow/service/impl/SchDetailCoilRelServiceImpl.java @@ -0,0 +1,109 @@ +package com.klp.flow.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.klp.common.core.page.TableDataInfo; +import com.klp.common.core.domain.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import com.klp.flow.domain.bo.SchDetailCoilRelBo; +import com.klp.flow.domain.vo.SchDetailCoilRelVo; +import com.klp.flow.domain.SchDetailCoilRel; +import com.klp.flow.mapper.SchDetailCoilRelMapper; +import com.klp.flow.service.ISchDetailCoilRelService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 排产明细钢卷关系Service业务层处理 + * + * @author klp + * @date 2026-06-25 + */ +@RequiredArgsConstructor +@Service +public class SchDetailCoilRelServiceImpl implements ISchDetailCoilRelService { + + private final SchDetailCoilRelMapper baseMapper; + + /** + * 查询排产明细钢卷关系 + */ + @Override + public SchDetailCoilRelVo queryById(Long relId){ + return baseMapper.selectVoById(relId); + } + + /** + * 查询排产明细钢卷关系列表 + */ + @Override + public TableDataInfo queryPageList(SchDetailCoilRelBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询排产明细钢卷关系列表 + */ + @Override + public List queryList(SchDetailCoilRelBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(SchDetailCoilRelBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(bo.getScheduleDetailId() != null, SchDetailCoilRel::getScheduleDetailId, bo.getScheduleDetailId()); + lqw.eq(bo.getCoilId() != null, SchDetailCoilRel::getCoilId, bo.getCoilId()); + return lqw; + } + + /** + * 新增排产明细钢卷关系 + */ + @Override + public Boolean insertByBo(SchDetailCoilRelBo bo) { + SchDetailCoilRel add = BeanUtil.toBean(bo, SchDetailCoilRel.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setRelId(add.getRelId()); + } + return flag; + } + + /** + * 修改排产明细钢卷关系 + */ + @Override + public Boolean updateByBo(SchDetailCoilRelBo bo) { + SchDetailCoilRel update = BeanUtil.toBean(bo, SchDetailCoilRel.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(SchDetailCoilRel entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 批量删除排产明细钢卷关系 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteBatchIds(ids) > 0; + } +} diff --git a/klp-flow/src/main/resources/mapper/flow/SchDetailCoilRelMapper.xml b/klp-flow/src/main/resources/mapper/flow/SchDetailCoilRelMapper.xml new file mode 100644 index 000000000..4d23596d6 --- /dev/null +++ b/klp-flow/src/main/resources/mapper/flow/SchDetailCoilRelMapper.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + From 3277610ff700009416214b299a8359e591efe103 Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Thu, 25 Jun 2026 13:18:50 +0800 Subject: [PATCH 02/24] =?UTF-8?q?feat(WmsMaterialCoil):=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E6=8E=92=E9=99=A4=E5=B7=B2=E7=BB=91=E5=AE=9A=E6=8E=92?= =?UTF-8?q?=E4=BA=A7=E6=98=8E=E7=BB=86=E9=92=A2=E5=8D=B7=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 WmsMaterialCoilBo 中新增 excludeScheduledDetail 字段 - 实现排产明细绑定钢卷的查询过滤逻辑 - 防止钢卷重复绑定到多个排产单 - 通过子查询优化排产明细关联查询性能 --- .../src/main/java/com/klp/domain/bo/WmsMaterialCoilBo.java | 6 ++++++ .../com/klp/service/impl/WmsMaterialCoilServiceImpl.java | 4 ++++ 2 files changed, 10 insertions(+) diff --git a/klp-wms/src/main/java/com/klp/domain/bo/WmsMaterialCoilBo.java b/klp-wms/src/main/java/com/klp/domain/bo/WmsMaterialCoilBo.java index 477738814..8f9283aad 100644 --- a/klp-wms/src/main/java/com/klp/domain/bo/WmsMaterialCoilBo.java +++ b/klp-wms/src/main/java/com/klp/domain/bo/WmsMaterialCoilBo.java @@ -432,5 +432,11 @@ public class WmsMaterialCoilBo extends BaseEntity { */ @TableField(exist = false) private Boolean excludeAccepted; + + /** + * 是否排除已绑定排产明细的钢卷(true=列表不返回已绑定排产明细的钢卷) + */ + @TableField(exist = false) + private Boolean excludeScheduledDetail; } diff --git a/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java index e2d28f944..962a57abb 100644 --- a/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java +++ b/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java @@ -1128,6 +1128,10 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { if (Boolean.TRUE.equals(bo.getExcludeAccepted())) { qw.apply("NOT EXISTS (SELECT 1 FROM ts_accept_coil_rel acr WHERE acr.del_flag = 0 AND acr.coil_id = mc.coil_id)"); } + // 排除已绑定排产明细的钢卷(防止重复绑定排产单) + if (Boolean.TRUE.equals(bo.getExcludeScheduledDetail())) { + qw.apply("NOT EXISTS (SELECT 1 FROM sch_prod_schedule_detail_coil sdc WHERE sdc.del_flag = 0 AND sdc.coil_id = mc.coil_id)"); + } // 组合 item_id 条件:改为使用 EXISTS 子查询,替代预查询 + IN boolean hasSelectType = StringUtils.isNotBlank(bo.getSelectType()); From 86200d189d2595f972c8fe17218eedcbff8215ee Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Thu, 25 Jun 2026 13:23:30 +0800 Subject: [PATCH 03/24] =?UTF-8?q?feat(schProdSchedule):=20=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E6=8E=92=E4=BA=A7=E5=8D=95=E4=B8=BB=E8=A1=A8=E4=B8=8E?= =?UTF-8?q?=E6=98=8E=E7=BB=86=E8=A1=A8=E7=9A=84=E5=85=B3=E8=81=94=E6=9F=A5?= =?UTF-8?q?=E8=AF=A2=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在SchProdScheduleDetailVo中添加schedule字段用于关联主表信息 - 在SchProdScheduleVo中添加detailList字段用于关联明细列表 - 实现fillSchedule方法批量填充排产单明细中的主表信息 - 实现fillDetailList方法批量填充排产单主表中的明细列表 - 修改queryById、queryPageList、queryList方法以支持关联数据查询 - 添加必要的依赖注入和工具类导入 --- .../domain/vo/SchProdScheduleDetailVo.java | 6 +++ .../klp/flow/domain/vo/SchProdScheduleVo.java | 8 ++++ .../SchProdScheduleDetailServiceImpl.java | 40 ++++++++++++++++- .../impl/SchProdScheduleServiceImpl.java | 45 ++++++++++++++++++- 4 files changed, 95 insertions(+), 4 deletions(-) diff --git a/klp-flow/src/main/java/com/klp/flow/domain/vo/SchProdScheduleDetailVo.java b/klp-flow/src/main/java/com/klp/flow/domain/vo/SchProdScheduleDetailVo.java index c0c9a763c..b5e33912a 100644 --- a/klp-flow/src/main/java/com/klp/flow/domain/vo/SchProdScheduleDetailVo.java +++ b/klp-flow/src/main/java/com/klp/flow/domain/vo/SchProdScheduleDetailVo.java @@ -3,6 +3,7 @@ package com.klp.flow.domain.vo; import java.math.BigDecimal; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; +import com.baomidou.mybatisplus.annotation.TableField; import com.klp.common.annotation.ExcelDictFormat; import com.klp.common.convert.ExcelDictConvert; import lombok.Data; @@ -69,5 +70,10 @@ public class SchProdScheduleDetailVo { @ExcelProperty(value = "单行排产备注") private String remark; + /** + * 关联的排产单主表信息 + */ + @TableField(exist = false) + private SchProdScheduleVo schedule; } diff --git a/klp-flow/src/main/java/com/klp/flow/domain/vo/SchProdScheduleVo.java b/klp-flow/src/main/java/com/klp/flow/domain/vo/SchProdScheduleVo.java index e563dd389..938ec3c31 100644 --- a/klp-flow/src/main/java/com/klp/flow/domain/vo/SchProdScheduleVo.java +++ b/klp-flow/src/main/java/com/klp/flow/domain/vo/SchProdScheduleVo.java @@ -5,10 +5,13 @@ import java.util.Date; import com.fasterxml.jackson.annotation.JsonFormat; import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; import com.alibaba.excel.annotation.ExcelProperty; +import com.baomidou.mybatisplus.annotation.TableField; import com.klp.common.annotation.ExcelDictFormat; import com.klp.common.convert.ExcelDictConvert; import lombok.Data; +import java.util.List; + /** * 排产单主视图对象 sch_prod_schedule @@ -186,5 +189,10 @@ public class SchProdScheduleVo { @ExcelProperty(value = "备注") private String remark; + /** + * 关联的排产明细列表 + */ + @TableField(exist = false) + private List detailList; } diff --git a/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleDetailServiceImpl.java b/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleDetailServiceImpl.java index be3fbf2f0..1d623b884 100644 --- a/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleDetailServiceImpl.java +++ b/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleDetailServiceImpl.java @@ -12,12 +12,17 @@ import org.springframework.stereotype.Service; import com.klp.flow.domain.bo.SchProdScheduleDetailBo; import com.klp.flow.domain.vo.SchProdScheduleDetailVo; import com.klp.flow.domain.SchProdScheduleDetail; +import com.klp.flow.domain.vo.SchProdScheduleVo; import com.klp.flow.mapper.SchProdScheduleDetailMapper; +import com.klp.flow.mapper.SchProdScheduleMapper; import com.klp.flow.service.ISchProdScheduleDetailService; import java.util.List; import java.util.Map; import java.util.Collection; +import java.util.Collections; +import java.util.Set; +import java.util.stream.Collectors; /** * 排产单明细Service业务层处理 @@ -30,13 +35,18 @@ import java.util.Collection; public class SchProdScheduleDetailServiceImpl implements ISchProdScheduleDetailService { private final SchProdScheduleDetailMapper baseMapper; + private final SchProdScheduleMapper scheduleMapper; /** * 查询排产单明细 */ @Override public SchProdScheduleDetailVo queryById(Long scheduleDetailId){ - return baseMapper.selectVoById(scheduleDetailId); + SchProdScheduleDetailVo vo = baseMapper.selectVoById(scheduleDetailId); + if (vo != null) { + fillSchedule(Collections.singletonList(vo)); + } + return vo; } /** @@ -46,6 +56,7 @@ public class SchProdScheduleDetailServiceImpl implements ISchProdScheduleDetailS public TableDataInfo queryPageList(SchProdScheduleDetailBo bo, PageQuery pageQuery) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + fillSchedule(result.getRecords()); return TableDataInfo.build(result); } @@ -55,7 +66,32 @@ public class SchProdScheduleDetailServiceImpl implements ISchProdScheduleDetailS @Override public List queryList(SchProdScheduleDetailBo bo) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); - return baseMapper.selectVoList(lqw); + List list = baseMapper.selectVoList(lqw); + fillSchedule(list); + return list; + } + + /** + * 批量填充主表信息 + */ + private void fillSchedule(List voList) { + if (voList == null || voList.isEmpty()) { + return; + } + Set scheduleIds = voList.stream() + .map(SchProdScheduleDetailVo::getScheduleId) + .filter(id -> id != null) + .collect(Collectors.toSet()); + if (scheduleIds.isEmpty()) { + return; + } + List schedules = scheduleMapper.selectVoBatchIds(scheduleIds); + Map scheduleMap = schedules != null + ? schedules.stream().collect(Collectors.toMap(SchProdScheduleVo::getScheduleId, s -> s, (a, b) -> a)) + : Collections.emptyMap(); + for (SchProdScheduleDetailVo vo : voList) { + vo.setSchedule(scheduleMap.get(vo.getScheduleId())); + } } private LambdaQueryWrapper buildQueryWrapper(SchProdScheduleDetailBo bo) { diff --git a/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleServiceImpl.java b/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleServiceImpl.java index e97631cae..630b7dae2 100644 --- a/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleServiceImpl.java +++ b/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleServiceImpl.java @@ -12,12 +12,17 @@ import org.springframework.stereotype.Service; import com.klp.flow.domain.bo.SchProdScheduleBo; import com.klp.flow.domain.vo.SchProdScheduleVo; import com.klp.flow.domain.SchProdSchedule; +import com.klp.flow.domain.SchProdScheduleDetail; +import com.klp.flow.domain.vo.SchProdScheduleDetailVo; import com.klp.flow.mapper.SchProdScheduleMapper; +import com.klp.flow.mapper.SchProdScheduleDetailMapper; import com.klp.flow.service.ISchProdScheduleService; import java.util.List; import java.util.Map; import java.util.Collection; +import java.util.Collections; +import java.util.stream.Collectors; /** * 排产单主Service业务层处理 @@ -30,13 +35,18 @@ import java.util.Collection; public class SchProdScheduleServiceImpl implements ISchProdScheduleService { private final SchProdScheduleMapper baseMapper; + private final SchProdScheduleDetailMapper detailMapper; /** * 查询排产单主 */ @Override public SchProdScheduleVo queryById(Long scheduleId){ - return baseMapper.selectVoById(scheduleId); + SchProdScheduleVo vo = baseMapper.selectVoById(scheduleId); + if (vo != null) { + fillDetailList(Collections.singletonList(vo)); + } + return vo; } /** @@ -46,6 +56,7 @@ public class SchProdScheduleServiceImpl implements ISchProdScheduleService { public TableDataInfo queryPageList(SchProdScheduleBo bo, PageQuery pageQuery) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + fillDetailList(result.getRecords()); return TableDataInfo.build(result); } @@ -55,7 +66,37 @@ public class SchProdScheduleServiceImpl implements ISchProdScheduleService { @Override public List queryList(SchProdScheduleBo bo) { LambdaQueryWrapper lqw = buildQueryWrapper(bo); - return baseMapper.selectVoList(lqw); + List list = baseMapper.selectVoList(lqw); + fillDetailList(list); + return list; + } + + /** + * 批量填充明细列表 + */ + private void fillDetailList(List voList) { + if (voList == null || voList.isEmpty()) { + return; + } + List scheduleIds = voList.stream() + .map(SchProdScheduleVo::getScheduleId) + .filter(id -> id != null) + .distinct() + .collect(Collectors.toList()); + if (scheduleIds.isEmpty()) { + return; + } + LambdaQueryWrapper detailQw = Wrappers.lambdaQuery(); + detailQw.in(SchProdScheduleDetail::getScheduleId, scheduleIds); + List allDetails = detailMapper.selectVoList(detailQw); + if (allDetails == null || allDetails.isEmpty()) { + return; + } + Map> detailMap = allDetails.stream() + .collect(Collectors.groupingBy(SchProdScheduleDetailVo::getScheduleId)); + for (SchProdScheduleVo vo : voList) { + vo.setDetailList(detailMap.getOrDefault(vo.getScheduleId(), Collections.emptyList())); + } } private LambdaQueryWrapper buildQueryWrapper(SchProdScheduleBo bo) { From 7e9caf9bb7ba8926126b791e6af63786b1e9a893 Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Thu, 25 Jun 2026 13:41:48 +0800 Subject: [PATCH 04/24] =?UTF-8?q?feat(flow):=20=E6=B7=BB=E5=8A=A0=E7=94=9F?= =?UTF-8?q?=E4=BA=A7=E6=8E=92=E7=A8=8B=E5=85=B3=E8=81=94CRM=E8=AE=A2?= =?UTF-8?q?=E5=8D=95=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在生产排程VO中新增orderList字段存储关联的CRM订单列表 - 实现fillOrderList方法批量填充CRM订单数据 - 通过sch_sale_schedule_rel关联表建立排程与订单的关系 - 添加ICrmOrderService依赖注入以查询订单信息 - 在查询排程详情时自动加载相关联的CRM订单数据 - 配置klp-crm模块依赖以支持跨模块服务调用 --- .../crm/service/impl/CrmOrderServiceImpl.java | 12 +++- klp-flow/pom.xml | 4 ++ .../klp/flow/domain/vo/SchProdScheduleVo.java | 7 ++ .../impl/SchProdScheduleServiceImpl.java | 69 +++++++++++++++++++ 4 files changed, 89 insertions(+), 3 deletions(-) diff --git a/klp-crm/src/main/java/com/klp/crm/service/impl/CrmOrderServiceImpl.java b/klp-crm/src/main/java/com/klp/crm/service/impl/CrmOrderServiceImpl.java index bfef5bb9e..e6baee4c8 100644 --- a/klp-crm/src/main/java/com/klp/crm/service/impl/CrmOrderServiceImpl.java +++ b/klp-crm/src/main/java/com/klp/crm/service/impl/CrmOrderServiceImpl.java @@ -107,6 +107,12 @@ public class CrmOrderServiceImpl implements ICrmOrderService { return TableDataInfo.build(result); } + extracted(records); + + return TableDataInfo.build(result); + } + + private void extracted(List records) { Set userNames = records.stream() .flatMap(v -> java.util.stream.Stream.of(v.getCreateBy(), v.getUpdateBy())) .filter(StringUtils::isNotBlank) @@ -178,8 +184,6 @@ public class CrmOrderServiceImpl implements ICrmOrderService { } } } - - return TableDataInfo.build(result); } private QueryWrapper buildQueryWrapperPlus(CrmOrderBo bo) { @@ -262,7 +266,9 @@ public class CrmOrderServiceImpl implements ICrmOrderService { @Override public List queryList(CrmOrderBo bo) { QueryWrapper lqw = buildQueryWrapperPlus(bo); - return baseMapper.selectVoPagePlus(lqw); + List crmOrderVos = baseMapper.selectVoPagePlus(lqw); + extracted(crmOrderVos); + return crmOrderVos; } /** diff --git a/klp-flow/pom.xml b/klp-flow/pom.xml index 9ae00e637..9aab07b11 100644 --- a/klp-flow/pom.xml +++ b/klp-flow/pom.xml @@ -19,5 +19,9 @@ com.klp klp-wms + + com.klp + klp-crm + diff --git a/klp-flow/src/main/java/com/klp/flow/domain/vo/SchProdScheduleVo.java b/klp-flow/src/main/java/com/klp/flow/domain/vo/SchProdScheduleVo.java index 938ec3c31..9a9dab4c9 100644 --- a/klp-flow/src/main/java/com/klp/flow/domain/vo/SchProdScheduleVo.java +++ b/klp-flow/src/main/java/com/klp/flow/domain/vo/SchProdScheduleVo.java @@ -8,6 +8,7 @@ import com.alibaba.excel.annotation.ExcelProperty; import com.baomidou.mybatisplus.annotation.TableField; import com.klp.common.annotation.ExcelDictFormat; import com.klp.common.convert.ExcelDictConvert; +import com.klp.crm.domain.vo.CrmOrderVo; import lombok.Data; import java.util.List; @@ -195,4 +196,10 @@ public class SchProdScheduleVo { @TableField(exist = false) private List detailList; + /** + * 关联的CRM订单列表(通过合同号 relContractNo 匹配 CrmOrder.contractCode) + */ + @TableField(exist = false) + private List orderList; + } diff --git a/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleServiceImpl.java b/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleServiceImpl.java index 630b7dae2..e6a105b6f 100644 --- a/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleServiceImpl.java +++ b/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleServiceImpl.java @@ -16,10 +16,17 @@ import com.klp.flow.domain.SchProdScheduleDetail; import com.klp.flow.domain.vo.SchProdScheduleDetailVo; import com.klp.flow.mapper.SchProdScheduleMapper; import com.klp.flow.mapper.SchProdScheduleDetailMapper; +import com.klp.flow.mapper.SchSaleScheduleRelMapper; +import com.klp.flow.domain.SchSaleScheduleRel; import com.klp.flow.service.ISchProdScheduleService; +import com.klp.crm.service.ICrmOrderService; +import com.klp.crm.domain.bo.CrmOrderBo; +import com.klp.crm.domain.vo.CrmOrderVo; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.Set; import java.util.Collection; import java.util.Collections; import java.util.stream.Collectors; @@ -36,6 +43,8 @@ public class SchProdScheduleServiceImpl implements ISchProdScheduleService { private final SchProdScheduleMapper baseMapper; private final SchProdScheduleDetailMapper detailMapper; + private final SchSaleScheduleRelMapper relMapper; + private final ICrmOrderService crmOrderService; /** * 查询排产单主 @@ -45,6 +54,7 @@ public class SchProdScheduleServiceImpl implements ISchProdScheduleService { SchProdScheduleVo vo = baseMapper.selectVoById(scheduleId); if (vo != null) { fillDetailList(Collections.singletonList(vo)); + fillOrderList(Collections.singletonList(vo)); } return vo; } @@ -57,6 +67,7 @@ public class SchProdScheduleServiceImpl implements ISchProdScheduleService { LambdaQueryWrapper lqw = buildQueryWrapper(bo); Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); fillDetailList(result.getRecords()); + fillOrderList(result.getRecords()); return TableDataInfo.build(result); } @@ -68,6 +79,7 @@ public class SchProdScheduleServiceImpl implements ISchProdScheduleService { LambdaQueryWrapper lqw = buildQueryWrapper(bo); List list = baseMapper.selectVoList(lqw); fillDetailList(list); + fillOrderList(list); return list; } @@ -99,6 +111,63 @@ public class SchProdScheduleServiceImpl implements ISchProdScheduleService { } } + /** + * 批量填充CRM订单列表(通过 sch_sale_schedule_rel 关联表) + */ + private void fillOrderList(List voList) { + if (voList == null || voList.isEmpty()) { + return; + } + // 1. 收集所有 scheduleId + List scheduleIds = voList.stream() + .map(SchProdScheduleVo::getScheduleId) + .filter(id -> id != null) + .distinct() + .collect(Collectors.toList()); + if (scheduleIds.isEmpty()) { + return; + } + // 2. 查关联表,获取 scheduleId → orderId 映射 + LambdaQueryWrapper relQw = Wrappers.lambdaQuery(); + relQw.in(SchSaleScheduleRel::getScheduleId, scheduleIds); + List rels = relMapper.selectList(relQw); + if (rels == null || rels.isEmpty()) { + return; + } + // 收集所有 orderId(去重) + Set orderIdSet = rels.stream() + .map(SchSaleScheduleRel::getOrderId) + .filter(id -> id != null) + .collect(Collectors.toSet()); + // scheduleId → 关联的 orderId 列表 + Map> scheduleOrderIdsMap = rels.stream() + .collect(Collectors.groupingBy( + SchSaleScheduleRel::getScheduleId, + Collectors.mapping(SchSaleScheduleRel::getOrderId, Collectors.toList()) + )); + if (orderIdSet.isEmpty()) { + return; + } + // 3. 批量查 CrmOrder + CrmOrderBo orderBo = new CrmOrderBo(); + orderBo.setOrderIds(new java.util.ArrayList<>(orderIdSet)); + List allOrders = crmOrderService.queryList(orderBo); + Map orderMap = allOrders != null + ? allOrders.stream().collect(Collectors.toMap(CrmOrderVo::getOrderId, o -> o, (a, b) -> a)) + : Collections.emptyMap(); + // 4. 回填到 VO + for (SchProdScheduleVo vo : voList) { + List orderIds = scheduleOrderIdsMap.get(vo.getScheduleId()); + if (orderIds != null) { + List orders = orderIds.stream() + .map(orderMap::get) + .filter(Objects::nonNull) + .collect(Collectors.toList()); + vo.setOrderList(orders); + } + } + } + private LambdaQueryWrapper buildQueryWrapper(SchProdScheduleBo bo) { Map params = bo.getParams(); LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); From 1c0b0da99e10dccf2ca45a07a19a1665822e2555 Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Thu, 25 Jun 2026 15:04:41 +0800 Subject: [PATCH 05/24] =?UTF-8?q?feat(wms):=20=E9=80=80=E7=81=AB=E8=AE=A1?= =?UTF-8?q?=E5=88=92=E9=80=89=E6=8B=A9=E5=90=88=E5=90=8C=E6=8F=90=E5=89=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在退火计划表格中添加合同号选择功能,支持远程搜索和下拉选择 - 更新数据库表结构,在wms_furnace_plan_coil表中新增contract_id字段 - 修改后端实体类将contractNo改为contractId,并更新相关映射配置 - 调整前端页面布局,将左右两列比例从12:12调整为10:14 - 优化退火完成验证逻辑,要求所有钢卷必须绑定合同后才能完成操作 - 修复材料网格布局样式,改为固定2列显示 - 添加订单列表加载和搜索功能,支持按关键词过滤 - 更新完成退火对话框提示文案,明确合同绑定要求 --- .../resources/db/migration/V9__anneal_wip.sql | 3 + klp-ui/src/views/wms/anneal/plan/ctrl.vue | 112 ++++++++++++------ .../com/klp/domain/WmsFurnacePlanCoil.java | 4 +- .../klp/domain/bo/WmsFurnacePlanCoilBo.java | 4 +- .../klp/domain/vo/WmsFurnacePlanCoilVo.java | 4 +- .../impl/WmsFurnacePlanCoilServiceImpl.java | 2 +- .../impl/WmsFurnacePlanServiceImpl.java | 7 +- .../mapper/klp/WmsFurnacePlanCoilMapper.xml | 2 +- script/sql/mysql/klp-oa.sql | 1 + 9 files changed, 97 insertions(+), 42 deletions(-) diff --git a/klp-admin/src/main/resources/db/migration/V9__anneal_wip.sql b/klp-admin/src/main/resources/db/migration/V9__anneal_wip.sql index 43b88727b..fdc0f2197 100644 --- a/klp-admin/src/main/resources/db/migration/V9__anneal_wip.sql +++ b/klp-admin/src/main/resources/db/migration/V9__anneal_wip.sql @@ -36,6 +36,9 @@ CREATE TABLE IF NOT EXISTS wms_furnace_plan_coil ( plan_coil_id BIGINT AUTO_INCREMENT PRIMARY KEY, plan_id BIGINT NOT NULL COMMENT '计划ID', coil_id BIGINT NOT NULL COMMENT '钢卷ID', + logic_warehouse_id BIGINT NULL COMMENT '逻辑库区去向(钢卷退火后目标逻辑库区)', + furnace_level TINYINT(1) NULL COMMENT '炉火层级(1=一层,2=二层,3=三层)', + contract_id BIGINT NULL COMMENT '合同ID', del_flag TINYINT DEFAULT 0 COMMENT '删除标记(0正常 1删除)', create_by VARCHAR(64) NULL, update_by VARCHAR(64) NULL, diff --git a/klp-ui/src/views/wms/anneal/plan/ctrl.vue b/klp-ui/src/views/wms/anneal/plan/ctrl.vue index f6c37c365..05a718992 100644 --- a/klp-ui/src/views/wms/anneal/plan/ctrl.vue +++ b/klp-ui/src/views/wms/anneal/plan/ctrl.vue @@ -52,7 +52,7 @@ @pagination="getList" /> - +
领料列表 @@ -102,7 +102,7 @@
- +
退火计划 @@ -136,8 +136,33 @@ - - + + + + - + @@ -238,6 +261,7 @@ import { listAnnealPlan, updateAnnealPlanCoil, getAnnealPlan, addAnnealPlan, updateAnnealPlan, delAnnealPlan, changeAnnealPlanStatus, inFurnace, completeAnnealPlan, listAnnealPlanCoils, bindAnnealPlanCoils, unbindAnnealPlanCoil } from "@/api/wms/annealPlan"; import { listAnnealFurnace } from "@/api/wms/annealFurnace"; import { listMaterialCoil } from "@/api/wms/coil"; +import { listOrder } from "@/api/crm/order"; import { listCoilContractRel } from '@/api/wms/coilContractRel'; import { listWarehouse } from '@/api/wms/warehouse' import WarehouseSelect from "@/components/KLPService/WarehouseSelect"; @@ -279,6 +303,8 @@ export default { }, currentPlan: {}, coilList: [], + orderList: [], + orderLoading: false, materialLoading: false, materialTotal: 0, materialList: [], @@ -303,6 +329,7 @@ export default { floatLayerConfig: { columns: [ { label: '入场钢卷号', prop: 'enterCoilNo' }, + { label: '合同号', prop: 'contractId' }, { label: '当前钢卷号', prop: 'coil.currentCoilNo' }, { label: '厂家卷号', prop: 'coil.supplierCoilNo' }, { label: '逻辑库位', prop: 'coil.warehouseName' }, @@ -332,6 +359,7 @@ export default { this.loadFurnaces(); this.getMaterialCoils(); this.loadWarehouses(); + this.loadOrderList(); }, methods: { getList() { @@ -363,6 +391,33 @@ export default { this.loadPlanCoils(); }); }, + handleContractIdChange(row) { + updateAnnealPlanCoil(row).then(() => { + this.$message.success('合同号已更新'); + }); + }, + loadOrderList() { + this.orderLoading = true; + listOrder({ pageNum: 1, pageSize: 100 }).then(response => { + this.orderList = response.rows || []; + this.orderLoading = false; + }).catch(() => { + this.orderLoading = false; + }); + }, + remoteSearchOrders(query) { + if (query) { + this.orderLoading = true; + listOrder({ pageNum: 1, pageSize: 20, keyword: query }).then(response => { + this.orderList = response.rows || []; + this.orderLoading = false; + }).catch(() => { + this.orderLoading = false; + }); + } else { + this.loadOrderList(); + } + }, getMaterialCoils() { this.materialLoading = true; listMaterialCoil(this.materialQueryParams).then(response => { @@ -397,17 +452,10 @@ export default { ...item, coilId: item.coilId, enterCoilNo: item.enterCoilNo, - warehouseId: item.logicWarehouseId || null + warehouseId: item.logicWarehouseId || null, + contractId: item.contractId || null, + contractCode: (this.orderList.find(o => o.orderId === item.contractId) || {}).contractCode || null, })); - // 查询每个钢卷绑定的合同号作为默认值 - for (const coil of this.completeCoils) { - listCoilContractRel({ coilId: coil.coilId }).then(res => { - const rows = res.rows || [] - if (rows.length > 0 && rows[0].contractId) { - this.$set(coil, 'contractId', rows[0].contractId) - } - }) - } this.completeLoading = false; }).catch(() => { this.completeLoading = false; @@ -585,9 +633,14 @@ export default { warehouseId: item.warehouseId, contractId: item.contractId, })); - const missing = locations.filter(item => !item.warehouseId || !item.contractId); - if (missing.length > 0) { - this.$message.warning('请先为所有钢卷分配实际库位和关联合同'); + const missingWarehouse = locations.filter(item => !item.warehouseId); + if (missingWarehouse.length > 0) { + this.$message.warning('请先为所有钢卷分配实际库位'); + return; + } + const missingContract = locations.filter(item => !item.contractId); + if (missingContract.length > 0) { + this.$message.warning('请先在明细中为所有钢卷绑定合同后再完成退火'); return; } this.completeLoading = true; @@ -703,8 +756,7 @@ export default { /* ========== 修复在这里 ========== */ .material-grid { display: grid; - /* 核心修复:去掉固定 4 列,改用自动填充,实现真正自适应 */ - grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); + grid-template-columns: repeat(2, 1fr); gap: 12px; min-height: 120px; /* 必须加,让 grid 不受父级弹性压缩影响 */ @@ -712,15 +764,6 @@ export default { box-sizing: border-box; } -/* 媒体查询只需要控制最小宽度即可,不用写死列数 */ -@media (max-width: 768px) { - .material-grid { - grid-template-columns: 1fr; - } -} - -/* =============================== */ - .material-card { border: 1px solid #e9ecf2; border-radius: 8px; @@ -806,3 +849,6 @@ export default { padding-bottom: 40px; } + diff --git a/klp-wms/src/main/java/com/klp/domain/WmsFurnacePlanCoil.java b/klp-wms/src/main/java/com/klp/domain/WmsFurnacePlanCoil.java index 5493ff3a8..c2efabf43 100644 --- a/klp-wms/src/main/java/com/klp/domain/WmsFurnacePlanCoil.java +++ b/klp-wms/src/main/java/com/klp/domain/WmsFurnacePlanCoil.java @@ -47,9 +47,9 @@ public class WmsFurnacePlanCoil extends BaseEntity { private Integer furnaceLevel; /** - * 合同号 + * 合同ID */ - private String contractNo; + private Long contractId; /** * 删除标志(0=正常,1=已删除) diff --git a/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnacePlanCoilBo.java b/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnacePlanCoilBo.java index 902473856..d5b0db937 100644 --- a/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnacePlanCoilBo.java +++ b/klp-wms/src/main/java/com/klp/domain/bo/WmsFurnacePlanCoilBo.java @@ -43,9 +43,9 @@ public class WmsFurnacePlanCoilBo extends BaseEntity { private Integer furnaceLevel; /** - * 合同号 + * 合同ID */ - private String contractNo; + private Long contractId; /** * 钢卷ID列表(逗号分隔) diff --git a/klp-wms/src/main/java/com/klp/domain/vo/WmsFurnacePlanCoilVo.java b/klp-wms/src/main/java/com/klp/domain/vo/WmsFurnacePlanCoilVo.java index 43c223c7f..b708df869 100644 --- a/klp-wms/src/main/java/com/klp/domain/vo/WmsFurnacePlanCoilVo.java +++ b/klp-wms/src/main/java/com/klp/domain/vo/WmsFurnacePlanCoilVo.java @@ -34,8 +34,8 @@ public class WmsFurnacePlanCoilVo { @ExcelProperty(value = "炉火层级") private Integer furnaceLevel; - @ExcelProperty(value = "合同号") - private String contractNo; + @ExcelProperty(value = "合同ID") + private Long contractId; @ExcelProperty(value = "入场钢卷号") private String enterCoilNo; diff --git a/klp-wms/src/main/java/com/klp/service/impl/WmsFurnacePlanCoilServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/WmsFurnacePlanCoilServiceImpl.java index 34f40b873..b2ef79572 100644 --- a/klp-wms/src/main/java/com/klp/service/impl/WmsFurnacePlanCoilServiceImpl.java +++ b/klp-wms/src/main/java/com/klp/service/impl/WmsFurnacePlanCoilServiceImpl.java @@ -64,7 +64,7 @@ public class WmsFurnacePlanCoilServiceImpl implements IWmsFurnacePlanCoilService lqw.eq(bo.getCoilId() != null, WmsFurnacePlanCoil::getCoilId, bo.getCoilId()); lqw.eq(bo.getLogicWarehouseId() != null, WmsFurnacePlanCoil::getLogicWarehouseId, bo.getLogicWarehouseId()); lqw.eq(bo.getFurnaceLevel() != null, WmsFurnacePlanCoil::getFurnaceLevel, bo.getFurnaceLevel()); - lqw.eq(bo.getContractNo() != null, WmsFurnacePlanCoil::getContractNo, bo.getContractNo()); + lqw.eq(bo.getContractId() != null, WmsFurnacePlanCoil::getContractId, bo.getContractId()); return lqw; } diff --git a/klp-wms/src/main/java/com/klp/service/impl/WmsFurnacePlanServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/WmsFurnacePlanServiceImpl.java index a609b4a5e..9904d1e3a 100644 --- a/klp-wms/src/main/java/com/klp/service/impl/WmsFurnacePlanServiceImpl.java +++ b/klp-wms/src/main/java/com/klp/service/impl/WmsFurnacePlanServiceImpl.java @@ -392,6 +392,11 @@ public class WmsFurnacePlanServiceImpl implements IWmsFurnacePlanService { if (targetLocation == null) { throw new ServiceException("钢卷" + coil.getEnterCoilNo() + "未分配库位"); } + // 校验合同ID:必须所有钢卷都已绑定合同 + Long contractId = contractIdMap.get(coil.getCoilId()); + if (contractId == null) { + throw new ServiceException("钢卷" + coil.getEnterCoilNo() + "未绑定合同,请先在明细中设置合同"); + } WmsMaterialCoil oldCoil = materialCoilMapper.selectById(coil.getCoilId()); if (oldCoil == null) { @@ -414,7 +419,7 @@ public class WmsFurnacePlanServiceImpl implements IWmsFurnacePlanService { updateBo.setStatus(0); updateBo.setExportBy(null); updateBo.setExportTime(null); - updateBo.setContractId(contractIdMap.get(coil.getCoilId())); + updateBo.setContractId(contractId); materialCoilService.updateByBo(updateBo, "annealing"); diff --git a/klp-wms/src/main/resources/mapper/klp/WmsFurnacePlanCoilMapper.xml b/klp-wms/src/main/resources/mapper/klp/WmsFurnacePlanCoilMapper.xml index 3a746c15c..dea43a776 100644 --- a/klp-wms/src/main/resources/mapper/klp/WmsFurnacePlanCoilMapper.xml +++ b/klp-wms/src/main/resources/mapper/klp/WmsFurnacePlanCoilMapper.xml @@ -10,7 +10,7 @@ - + diff --git a/script/sql/mysql/klp-oa.sql b/script/sql/mysql/klp-oa.sql index 6e0d5e635..26cb70cdb 100644 --- a/script/sql/mysql/klp-oa.sql +++ b/script/sql/mysql/klp-oa.sql @@ -3976,6 +3976,7 @@ CREATE TABLE `wms_furnace_plan_coil` ( `coil_id` bigint NOT NULL COMMENT '钢卷ID', `logic_warehouse_id` bigint NULL DEFAULT NULL COMMENT '逻辑库区去向(钢卷退火后目标逻辑库区)', `furnace_level` tinyint(1) NULL DEFAULT NULL COMMENT '炉火层级(1=一层,2=二层,3=三层)', + `contract_id` bigint NULL DEFAULT NULL COMMENT '合同ID', `del_flag` tinyint NULL DEFAULT 0 COMMENT '删除标记(0正常 1删除)', `create_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, `update_by` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL, From 289555fd44430f4aa665d2e37d52de5c8a0b18f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A0=82=E7=B3=96?= <2178503051@qq.com> Date: Thu, 25 Jun 2026 15:44:26 +0800 Subject: [PATCH 06/24] =?UTF-8?q?feat(aps):=20=E6=96=B0=E5=A2=9EAPS?= =?UTF-8?q?=E6=8E=92=E4=BA=A7=E7=AE=A1=E7=90=86=E6=A8=A1=E5=9D=97=E5=AE=8C?= =?UTF-8?q?=E6=95=B4=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 本次提交完成APS(高级计划与排程)模块的全量开发: 1. 新增CRM订单相关API接口,包含列表、详情、明细查询 2. 新增产需单相关CRUD API与页面,支持排产单管理与订单绑定 3. 新增按日期查询排产单、订单下钻详情页面 4. 为排产单实体类添加日期格式化注解,修复参数绑定问题 5. 统一封装APS模块主题样式,提供通用混入与变量 6. 实现产需单与销售订单的绑定解绑、明细自动生成功能 --- .../klp/flow/domain/bo/SchProdScheduleBo.java | 3 + klp-ui/src/api/aps/order.js | 27 + klp-ui/src/api/aps/requirement.js | 120 ++ klp-ui/src/api/aps/schedule.js | 35 + klp-ui/src/views/wms/post/aps/order.vue | 445 +++++++ klp-ui/src/views/wms/post/aps/requirement.vue | 1022 +++++++++++++++++ klp-ui/src/views/wms/post/aps/schedule.vue | 316 +++++ .../views/wms/post/aps/scss/aps-theme.scss | 143 +++ 8 files changed, 2111 insertions(+) create mode 100644 klp-ui/src/api/aps/order.js create mode 100644 klp-ui/src/api/aps/requirement.js create mode 100644 klp-ui/src/api/aps/schedule.js create mode 100644 klp-ui/src/views/wms/post/aps/order.vue create mode 100644 klp-ui/src/views/wms/post/aps/requirement.vue create mode 100644 klp-ui/src/views/wms/post/aps/schedule.vue create mode 100644 klp-ui/src/views/wms/post/aps/scss/aps-theme.scss diff --git a/klp-flow/src/main/java/com/klp/flow/domain/bo/SchProdScheduleBo.java b/klp-flow/src/main/java/com/klp/flow/domain/bo/SchProdScheduleBo.java index d9bd551d5..1c6cefd97 100644 --- a/klp-flow/src/main/java/com/klp/flow/domain/bo/SchProdScheduleBo.java +++ b/klp-flow/src/main/java/com/klp/flow/domain/bo/SchProdScheduleBo.java @@ -8,6 +8,7 @@ import javax.validation.constraints.*; import java.math.BigDecimal; import java.util.Date; import com.fasterxml.jackson.annotation.JsonFormat; +import org.springframework.format.annotation.DateTimeFormat; /** * 排产单主业务对象 sch_prod_schedule @@ -33,6 +34,8 @@ public class SchProdScheduleBo extends BaseEntity { /** * 生产日期(和合同号组成业务关联键) */ + @DateTimeFormat(pattern = "yyyy-MM-dd") + @JsonFormat(pattern = "yyyy-MM-dd") private Date prodDate; /** diff --git a/klp-ui/src/api/aps/order.js b/klp-ui/src/api/aps/order.js new file mode 100644 index 000000000..f3aaea115 --- /dev/null +++ b/klp-ui/src/api/aps/order.js @@ -0,0 +1,27 @@ +import request from '@/utils/request' + +// 查询 CRM 订单列表(只读) +export function listCrmOrder(query) { + return request({ + url: '/crm/order/list', + method: 'get', + params: query + }) +} + +// 查询 CRM 订单详情 +export function getCrmOrder(orderId) { + return request({ + url: '/crm/order/' + orderId, + method: 'get' + }) +} + +// 查询 CRM 订单明细列表 +export function listCrmOrderItem(query) { + return request({ + url: '/crm/orderItem/list', + method: 'get', + params: query + }) +} diff --git a/klp-ui/src/api/aps/requirement.js b/klp-ui/src/api/aps/requirement.js new file mode 100644 index 000000000..183aeb8e1 --- /dev/null +++ b/klp-ui/src/api/aps/requirement.js @@ -0,0 +1,120 @@ +import request from '@/utils/request' + +// ====== 产需单(SchProdSchedule)CRUD ====== + +// 查询产需单列表 +export function listRequirement(query) { + return request({ + url: '/flow/prodSchedule/list', + method: 'get', + params: query + }) +} + +// 查询产需单详情 +export function getRequirement(scheduleId) { + return request({ + url: '/flow/prodSchedule/' + scheduleId, + method: 'get' + }) +} + +// 新增产需单 +export function addRequirement(data) { + return request({ + url: '/flow/prodSchedule', + method: 'post', + data + }) +} + +// 修改产需单 +export function updateRequirement(data) { + return request({ + url: '/flow/prodSchedule', + method: 'put', + data + }) +} + +// 删除产需单 +export function delRequirement(scheduleIds) { + return request({ + url: '/flow/prodSchedule/' + scheduleIds, + method: 'delete' + }) +} + +// ====== 产需单明细(SchProdScheduleDetail) ====== + +// 查询产需单明细列表 +export function listRequirementDetail(query) { + return request({ + url: '/flow/prodScheduleDetail/list', + method: 'get', + params: query + }) +} + +// 新增产需单明细 +export function addRequirementDetail(data) { + return request({ + url: '/flow/prodScheduleDetail', + method: 'post', + data + }) +} + +// 修改产需单明细 +export function updateRequirementDetail(data) { + return request({ + url: '/flow/prodScheduleDetail', + method: 'put', + data + }) +} + +// 删除产需单明细 +export function delRequirementDetail(detailIds) { + return request({ + url: '/flow/prodScheduleDetail/' + detailIds, + method: 'delete' + }) +} + +// ====== 销售订单-产需单关联(SchSaleScheduleRel) ====== + +// 查询关联列表 +export function listRel(query) { + return request({ + url: '/flow/saleScheduleRel/list', + method: 'get', + params: query + }) +} + +// 新增关联(绑定订单) +export function addRel(data) { + return request({ + url: '/flow/saleScheduleRel', + method: 'post', + data + }) +} + +// 修改关联 +export function updateRel(data) { + return request({ + url: '/flow/saleScheduleRel', + method: 'put', + data + }) +} + +// 删除关联(解绑订单) +export function delRel(relIds) { + return request({ + url: '/flow/saleScheduleRel/' + relIds, + method: 'delete' + }) +} diff --git a/klp-ui/src/api/aps/schedule.js b/klp-ui/src/api/aps/schedule.js new file mode 100644 index 000000000..bbc342279 --- /dev/null +++ b/klp-ui/src/api/aps/schedule.js @@ -0,0 +1,35 @@ +import request from '@/utils/request' + +// 按日期查询产需单列表 +export function listScheduleByDate(prodDate) { + return request({ + url: '/flow/prodSchedule/list', + method: 'get', + params: { prodDate } + }) +} + +// 查询产需单明细(用于排产单聚合) +export function listScheduleDetail(scheduleId) { + return request({ + url: '/flow/prodScheduleDetail/list', + method: 'get', + params: { scheduleId } + }) +} + +// 查询 CRM 订单信息(用于下钻) +export function getCrmOrderInfo(orderId) { + return request({ + url: '/crm/order/' + orderId, + method: 'get' + }) +} + +// 查询 CRM 订单明细(用于下钻展示) +export function getCrmOrderItem(orderDetailId) { + return request({ + url: '/crm/orderItem/' + orderDetailId, + method: 'get' + }) +} diff --git a/klp-ui/src/views/wms/post/aps/order.vue b/klp-ui/src/views/wms/post/aps/order.vue new file mode 100644 index 000000000..5d3c7608d --- /dev/null +++ b/klp-ui/src/views/wms/post/aps/order.vue @@ -0,0 +1,445 @@ + + + + + diff --git a/klp-ui/src/views/wms/post/aps/requirement.vue b/klp-ui/src/views/wms/post/aps/requirement.vue new file mode 100644 index 000000000..cb8b587e6 --- /dev/null +++ b/klp-ui/src/views/wms/post/aps/requirement.vue @@ -0,0 +1,1022 @@ + + + + + diff --git a/klp-ui/src/views/wms/post/aps/schedule.vue b/klp-ui/src/views/wms/post/aps/schedule.vue new file mode 100644 index 000000000..8c493e237 --- /dev/null +++ b/klp-ui/src/views/wms/post/aps/schedule.vue @@ -0,0 +1,316 @@ + + + + + diff --git a/klp-ui/src/views/wms/post/aps/scss/aps-theme.scss b/klp-ui/src/views/wms/post/aps/scss/aps-theme.scss new file mode 100644 index 000000000..71ced9b91 --- /dev/null +++ b/klp-ui/src/views/wms/post/aps/scss/aps-theme.scss @@ -0,0 +1,143 @@ +// ============================================ +// APS 排产管理模块 — 银灰色 + 红色主题 +// 每个页面通过 @import 引入并提供 scoped 命名空间 +// ============================================ + +// ——— 颜色变量 ——— +$aps-silver-1: #f5f5f5; // 最浅银灰(背景) +$aps-silver-2: #e8e8e8; // 浅银灰(卡片/列表行) +$aps-silver-3: #d9d9d9; // 中银灰(边框) +$aps-silver-4: #8c8c8c; // 深银灰(次要文字/图标) +$aps-silver-5: #595959; // 最深银灰(主标题/强调文字) + +$aps-red-1: #fff1f0; // 极浅红(背景高亮) +$aps-red-2: #ff4d4f; // 标准红(主按钮/标签) +$aps-red-3: #cf1322; // 深红(hover/边框强调) +$aps-red-4: #f5222d; // 辅助红 + +// ——— 混入:列表项 ——— +@mixin aps-list-item { + display: flex; + justify-content: space-between; + align-items: center; + padding: 10px 12px; + margin-bottom: 6px; + border: 1px solid $aps-silver-3; + background-color: #fff; + cursor: pointer; + transition: all 0.2s ease; + border-radius: 4px; + + &:hover { + border-color: $aps-red-2; + background-color: $aps-red-1; + } + + &.active { + border-left: 3px solid $aps-red-2; + border-color: $aps-red-2; + background-color: $aps-red-1; + box-shadow: 0 0 0 1px rgba($aps-red-2, 0.08) inset; + } +} + +// ——— 混入:银色卡片 ——— +@mixin aps-card { + background: #fff; + border: 1px solid $aps-silver-3; + border-radius: 6px; + padding: 16px; +} + +// ——— 混入:银色按钮变体 ——— +@mixin aps-btn-silver { + color: $aps-silver-5; + background: $aps-silver-1; + border-color: $aps-silver-3; + + &:hover { + color: $aps-red-2; + border-color: $aps-red-2; + background: $aps-red-1; + } +} + +// ——— 混入:红色按钮变体 ——— +@mixin aps-btn-red { + color: #fff; + background: $aps-red-2; + border-color: $aps-red-2; + + &:hover { + background: $aps-red-3; + border-color: $aps-red-3; + } +} + +// ——— 混入:状态标签 ——— +@mixin aps-status-tag($bg, $color) { + display: inline-block; + padding: 2px 8px; + border-radius: 3px; + font-size: 12px; + background: $bg; + color: $color; +} + +// ——— 详情卡片通用变量(参照 HTML 设计稿) ——— +$aps-bg: #f4f5f7; +$aps-white: #ffffff; +$aps-border: #c8cdd2; +$aps-text: #2c3e50; +$aps-text-muted: #7f8c8d; +$aps-silver-mid: #d5d8dc; +$aps-shadow-sm: 0 1px 4px rgba(0,0,0,0.08); +$aps-radius: 4px; + +// ——— 混入:详情卡片 ——— +@mixin aps-detail-card { + background: $aps-white; + border: 1px solid $aps-border; + border-radius: $aps-radius; + box-shadow: $aps-shadow-sm; + overflow: hidden; +} + +// ——— 混入:卡片头部渐变 ——— +@mixin aps-card-header { + background: linear-gradient(to right, $aps-red-2, $aps-red-3); + color: white; + padding: 8px 14px; + font-size: 13px; + font-weight: 600; + display: flex; + align-items: center; + justify-content: space-between; +} + +// ——— 混入:表单网格(2列) ——— +@mixin aps-form-grid-2 { + display: grid; + grid-template-columns: repeat(2, 1fr); + gap: 10px 16px; +} + +// ——— 混入:表单字段 ——— +@mixin aps-form-field { + display: flex; + flex-direction: column; + gap: 3px; + + label { + font-size: 11px; + color: $aps-text-muted; + font-weight: 500; + } + + .field-value { + font-size: 13px; + color: $aps-text; + padding: 4px 0; + border-bottom: 1px solid $aps-silver-mid; + } +} From d627a72aea615949d964079e924eefc36241fce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A0=82=E7=B3=96?= <2178503051@qq.com> Date: Thu, 25 Jun 2026 16:08:02 +0800 Subject: [PATCH 07/24] =?UTF-8?q?refactor(cost=20views):=20=E7=BB=9F?= =?UTF-8?q?=E4=B8=80=E8=B0=83=E6=95=B4=E6=95=B0=E5=80=BC=E6=A0=BC=E5=BC=8F?= =?UTF-8?q?=E5=8C=96=E7=B2=BE=E5=BA=A6=E4=B8=BA=E4=B8=A4=E4=BD=8D=E5=B0=8F?= =?UTF-8?q?=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改了三个成本相关页面的数值格式化逻辑: 1. energy.vue和assised.vue的formatNum方法,将保留小数位数从4位改为2位 2. comprehensive.vue的多位置数值处理逻辑,统一将计算结果格式化为两位小数 --- klp-ui/src/views/cost/comprehensive.vue | 8 ++++---- klp-ui/src/views/cost/views/assised.vue | 2 +- klp-ui/src/views/cost/views/enegry.vue | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/klp-ui/src/views/cost/comprehensive.vue b/klp-ui/src/views/cost/comprehensive.vue index 738b9696b..1719a2926 100644 --- a/klp-ui/src/views/cost/comprehensive.vue +++ b/klp-ui/src/views/cost/comprehensive.vue @@ -735,7 +735,7 @@ export default { if (!d.detailDate) return if (!map[d.detailDate]) map[d.detailDate] = { detailDate: d.detailDate } const sfx = d.shift && d.shift !== '0' ? '_' + d.shift : '' - map[d.detailDate]['q' + d.itemId + sfx] = d.quantity + map[d.detailDate]['q' + d.itemId + sfx] = d.quantity != null && d.quantity !== '' ? Number(d.quantity).toFixed(2) : d.quantity }) this.gridRows = Object.values(map).sort((a,b) => a.detailDate.localeCompare(b.detailDate)) }, @@ -780,7 +780,7 @@ export default { }) }) }, - evalF(f) { const s = f.replace(/[^0-9+\-*/.()\s]/g,''); if(!s) return null; try { const r = new Function('return ('+s+')')(); return isFinite(r)?Math.round(r*10000)/10000:null } catch(e){ return null } }, + evalF(f) { const s = f.replace(/[^0-9+\-*/.()\s]/g,''); if(!s) return null; try { const r = new Function('return ('+s+')')(); return isFinite(r)?(Math.round(r*100)/100).toFixed(2):null } catch(e){ return null } }, sortGrid() { this.gridRows.sort((a,b)=>{if(!a.detailDate)return 1;if(!b.detailDate)return -1;return a.detailDate.localeCompare(b.detailDate)}) }, async saveGrid() { const rid = this.activeReport.reportId; if (!rid) return; this.saving = true @@ -860,7 +860,7 @@ export default { try { const val = await handler(col.queryCondition, row, col, this.activeReport, shift) if (val != null) { - const round3 = n => Math.round(n * 1000) / 1000 + const round3 = n => (Math.round(n * 100) / 100).toFixed(2) if (Array.isArray(val)) { this.$set(row, 'q' + col.itemId + '_1', round3(val[0])) this.$set(row, 'q' + col.itemId + '_2', round3(val[1])) @@ -946,7 +946,7 @@ export default { if (!col.queryCondition) return const handler = queryHandlers[col.category] || queryHandlers['default'] if (!handler) { this.$modal.msgWarning(`类别 "${col.category}" 未注册查询处理器`); return } - const round3 = n => Math.round(n * 1000) / 1000 + const round3 = n => (Math.round(n * 100) / 100).toFixed(2) const tasks = [] for (const row of this.gridRows) { if (!row.detailDate) continue diff --git a/klp-ui/src/views/cost/views/assised.vue b/klp-ui/src/views/cost/views/assised.vue index 9d13b37e0..ca0804452 100644 --- a/klp-ui/src/views/cost/views/assised.vue +++ b/klp-ui/src/views/cost/views/assised.vue @@ -130,7 +130,7 @@ export default { else return row.lineType || '-' } }, - formatNum(val) { if (val === null || val === undefined || val === '') return ''; const n = Number(val); if (isNaN(n)) return val; return parseFloat(n.toFixed(4)) }, + formatNum(val) { if (val === null || val === undefined || val === '') return ''; const n = Number(val); if (isNaN(n)) return val; return parseFloat(n.toFixed(2)) }, async loadItems() { if (!this.allItems.length) { const r = await listItem({ pageNum:1, pageSize:999 }); this.allItems = r.rows || [] } }, async enter(row) { const r = await getProdReport(row.reportId); if (r.data) this.activeReport = r.data; else this.activeReport = row; this.loadGrid() } } diff --git a/klp-ui/src/views/cost/views/enegry.vue b/klp-ui/src/views/cost/views/enegry.vue index 134237155..cce34ad09 100644 --- a/klp-ui/src/views/cost/views/enegry.vue +++ b/klp-ui/src/views/cost/views/enegry.vue @@ -130,7 +130,7 @@ export default { else return row.lineType || '-' } }, - formatNum(val) { if (val === null || val === undefined || val === '') return ''; const n = Number(val); if (isNaN(n)) return val; return parseFloat(n.toFixed(4)) }, + formatNum(val) { if (val === null || val === undefined || val === '') return ''; const n = Number(val); if (isNaN(n)) return val; return parseFloat(n.toFixed(2)) }, async loadItems() { if (!this.allItems.length) { const r = await listItem({ pageNum:1, pageSize:999 }); this.allItems = r.rows || [] } }, async enter(row) { const r = await getProdReport(row.reportId); if (r.data) this.activeReport = r.data; else this.activeReport = row; this.loadGrid() } } From c20965406f9a3e44a580acb7bc6916703eba0ca4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A0=82=E7=B3=96?= <2178503051@qq.com> Date: Fri, 26 Jun 2026 09:29:59 +0800 Subject: [PATCH 08/24] =?UTF-8?q?feat(wms/coil):=20=E9=85=B8=E8=BD=A7?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E5=A1=AB=E5=86=99=E5=86=B7=E5=8D=B7=E5=8F=B7?= =?UTF-8?q?,=E8=87=AA=E5=8A=A8=E5=A1=AB=E5=86=99=E6=9C=80=E4=BC=98?= =?UTF-8?q?=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- klp-ui/src/views/wms/coil/panels/L2MatchPanel.vue | 8 +++++++- klp-ui/src/views/wms/coil/typing.vue | 11 ++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/klp-ui/src/views/wms/coil/panels/L2MatchPanel.vue b/klp-ui/src/views/wms/coil/panels/L2MatchPanel.vue index c331a6bb3..f63d45df5 100644 --- a/klp-ui/src/views/wms/coil/panels/L2MatchPanel.vue +++ b/klp-ui/src/views/wms/coil/panels/L2MatchPanel.vue @@ -88,7 +88,8 @@ const PLAN_FIELDS = [ export default { name: 'L2MatchPanel', props: { - hotCoilId: { type: String, default: '' } + hotCoilId: { type: String, default: '' }, + autoFill: { type: Boolean, default: false } }, data() { return { @@ -103,6 +104,11 @@ export default { hotCoilId(val) { if (val) this.loadBestMatch(val) else this.bestMatch = null + }, + bestMatch(val) { + if (val && this.autoFill) { + this.$emit('fill', val) + } } }, created() { diff --git a/klp-ui/src/views/wms/coil/typing.vue b/klp-ui/src/views/wms/coil/typing.vue index 22148fb04..c321ae1bb 100644 --- a/klp-ui/src/views/wms/coil/typing.vue +++ b/klp-ui/src/views/wms/coil/typing.vue @@ -25,7 +25,7 @@
- +
@@ -573,6 +573,10 @@ export default { isDrAction() { return this.actionType === 504 || this.actionType === 524 }, + /** 酸轧产线 */ + isAcidRolling() { + return [11, 120, 200, 201, 520].includes(Number(this.actionType)) + }, /** 镀锌/酸轧产线免验净重和厚度范围 */ isExemptFromValidation() { return [11, 120, 200, 201, 520, 202, 501, 521].includes(Number(this.actionType)) @@ -694,6 +698,11 @@ export default { if (data.end_date) { this.$set(this.updateForm, 'productionEndTime', this.formatDateTime(data.end_date)) } + + if (data.encoilid) { + this.$set(this.updateForm, 'chromePlateCoilNo', data.encoilid) + } + if (data.start_date || data.end_date) this.calculateProductionDuration() const query = { From 395700b8d693237f2d01fe67ee6450d642ecd998 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A0=82=E7=B3=96?= <2178503051@qq.com> Date: Fri, 26 Jun 2026 09:45:42 +0800 Subject: [PATCH 09/24] =?UTF-8?q?refactor(wms/report):=20=E8=B0=83?= =?UTF-8?q?=E6=95=B4=E7=89=A9=E7=90=86=E5=B1=9E=E6=80=A7=E5=88=97=E5=B1=95?= =?UTF-8?q?=E7=A4=BA=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 分别在入库报表页面和报表模板页面,补充实际长度、实际宽度字段到物理属性分组中,优化报表展示内容 --- klp-ui/src/views/wms/report/receive.vue | 32 ++++++------------- .../src/views/wms/report/template/action.vue | 2 +- 2 files changed, 11 insertions(+), 23 deletions(-) diff --git a/klp-ui/src/views/wms/report/receive.vue b/klp-ui/src/views/wms/report/receive.vue index 1e9447d4c..35f8539ef 100644 --- a/klp-ui/src/views/wms/report/receive.vue +++ b/klp-ui/src/views/wms/report/receive.vue @@ -3,14 +3,8 @@ - + - + @@ -86,13 +80,8 @@ - +
@@ -162,11 +151,11 @@ export default { '基本信息': ['itemTypeDesc', 'warehouseName', 'actualWarehouseName', 'dataTypeText'], '钢卷号': ['enterCoilNo', 'supplierCoilNo', 'currentCoilNo'], '时间': ['createTime', 'exportTime', 'exportBy'], - '物理属性': ['netWeight', 'length', 'specification', 'actualThickness', 'theoreticalThickness', 'theoreticalLength'], + '物理属性': ['netWeight', 'length', 'specification', 'actualThickness', 'actualLength', 'actualWidth', 'theoreticalThickness', 'theoreticalLength'], '材质属性': ['material', 'manufacturer', 'surfaceTreatmentDesc', 'zincLayer', 'packingStatus', 'temperGrade', 'coatingType', 'chromePlateCoilNo', 'rawMaterialThickness'], '用途': ['purpose', 'businessPurpose'], '状态': ['qualityStatus', 'statusDesc', 'isRelatedToOrderText'], - '其他': ['itemName', 'itemId', 'packagingRequirement', 'trimmingRequirement', 'transferType', 'contractNo' ,'saleName', 'remark', 'team'], + '其他': ['itemName', 'itemId', 'packagingRequirement', 'trimmingRequirement', 'transferType', 'contractNo', 'saleName', 'remark', 'team'], }, list: [], defaultStartTime: startTime, @@ -188,7 +177,7 @@ export default { loading: false, receiveColumns: [], - + // 厂家材质透视表配置 hierarchicalPivotConfig: { groupFields: ['manufacturer', 'material', 'specification'], @@ -204,7 +193,7 @@ export default { return value.toFixed(3) } }, - + // 宽度厚度统计表配置 crossTableConfig: { rowField: 'computedWidth', @@ -359,5 +348,4 @@ export default { } - + diff --git a/klp-ui/src/views/wms/report/template/action.vue b/klp-ui/src/views/wms/report/template/action.vue index fd2cd111b..0c699af29 100644 --- a/klp-ui/src/views/wms/report/template/action.vue +++ b/klp-ui/src/views/wms/report/template/action.vue @@ -562,7 +562,7 @@ export default { '基本信息': ['itemTypeDesc', 'warehouseName', 'actualWarehouseName', 'dataTypeText'], '钢卷号': ['enterCoilNo', 'supplierCoilNo', 'currentCoilNo'], '时间': ['createTime', 'exportTime', 'exportBy'], - '物理属性': ['netWeight', 'length', 'specification', 'actualThickness', 'theoreticalThickness', 'theoreticalLength', 'scheduleThickness'], + '物理属性': ['netWeight', 'length', 'specification', 'actualThickness', 'actualLength', 'actualWidth', 'theoreticalThickness', 'theoreticalLength', 'scheduleThickness'], '材质属性': ['material', 'manufacturer', 'surfaceTreatmentDesc', 'zincLayer', 'packingStatus', 'temperGrade', 'coatingType', 'chromePlateCoilNo', 'rawMaterialThickness'], '用途': ['purpose', 'businessPurpose'], '状态': ['qualityStatus', 'statusDesc', 'isRelatedToOrderText'], From 238e0d2963517e2b8ad4fdaa2e45d1f8842d77bf Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Fri, 26 Jun 2026 09:48:37 +0800 Subject: [PATCH 10/24] =?UTF-8?q?feat(WmsMaterialCoil):=20=E8=87=AA?= =?UTF-8?q?=E5=AE=9A=E4=B9=89=E6=8A=A5=E8=A1=A8=E5=AF=BC=E5=87=BA=E5=AE=8C?= =?UTF-8?q?=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 WmsMaterialCoilAllExportVo 中新增理论厚度、排产厚度、理论长度、镀铬卷号、实测长度和实测宽度字段 - 在 WmsMaterialCoilExportVo 中新增实测长度和实测宽度字段 - 在控制器中为导出功能添加实测长度和实测宽度列配置 - 在数据库映射文件中添加 actual_length 和 actual_width 字段查询映射 --- .../controller/WmsMaterialCoilController.java | 2 ++ .../domain/vo/WmsMaterialCoilAllExportVo.java | 18 ++++++++++++++++++ .../klp/domain/vo/WmsMaterialCoilExportVo.java | 12 ++++++++++++ .../mapper/klp/WmsMaterialCoilMapper.xml | 4 ++++ 4 files changed, 36 insertions(+) diff --git a/klp-wms/src/main/java/com/klp/controller/WmsMaterialCoilController.java b/klp-wms/src/main/java/com/klp/controller/WmsMaterialCoilController.java index 361dc3553..985f9e703 100644 --- a/klp-wms/src/main/java/com/klp/controller/WmsMaterialCoilController.java +++ b/klp-wms/src/main/java/com/klp/controller/WmsMaterialCoilController.java @@ -201,6 +201,8 @@ public class WmsMaterialCoilController extends BaseController { columns.put("isRelatedToOrderText", "是否与订单相关"); columns.put("saleName", "销售人员"); columns.put("contractNo", "合同编号"); + columns.put("actualLength", "实测长度"); + columns.put("actualWidth", "实测宽度"); columns.put("actualThickness", "实测厚度"); columns.put("transferType", "调拨类型"); columns.put("team", "班组"); diff --git a/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilAllExportVo.java b/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilAllExportVo.java index 0c0ef5ca3..228f75a0e 100644 --- a/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilAllExportVo.java +++ b/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilAllExportVo.java @@ -227,4 +227,22 @@ public class WmsMaterialCoilAllExportVo { */ @ExcelProperty(value = "原料厚度") private String rawMaterialThickness; + + @ExcelProperty(value = "理论厚度") + private String theoreticalThickness; + + @ExcelProperty(value = "排产厚度") + private String scheduleThickness; + + @ExcelProperty(value = "理论长度") + private String theoreticalLength; + + @ExcelProperty(value = "镀铬卷号") + private String chromePlateCoilNo; + + @ExcelProperty(value = "实测长度") + private String actualLength; + + @ExcelProperty(value = "实测宽度") + private String actualWidth; } diff --git a/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilExportVo.java b/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilExportVo.java index 41408ad56..a50adcd8c 100644 --- a/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilExportVo.java +++ b/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilExportVo.java @@ -245,4 +245,16 @@ public class WmsMaterialCoilExportVo { */ @ExcelProperty(value = "原料厚度") private String rawMaterialThickness; + + /** + * 实测长度 + */ + @ExcelProperty(value = "实测长度") + private BigDecimal actualLength; + + /** + * 实测宽度 + */ + @ExcelProperty(value = "实测宽度") + private BigDecimal actualWidth; } diff --git a/klp-wms/src/main/resources/mapper/klp/WmsMaterialCoilMapper.xml b/klp-wms/src/main/resources/mapper/klp/WmsMaterialCoilMapper.xml index 3316e77f0..daa1b12f6 100644 --- a/klp-wms/src/main/resources/mapper/klp/WmsMaterialCoilMapper.xml +++ b/klp-wms/src/main/resources/mapper/klp/WmsMaterialCoilMapper.xml @@ -487,6 +487,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" mc.net_weight AS netWeight, -- 长度 mc.length AS length, + -- 实测长度 + mc.actual_length AS actualLength, + -- 实测宽度 + mc.actual_width AS actualWidth, -- 实测厚度 mc.actual_thickness AS actualThickness, -- 镀层种类 From 230b18eee69285b5ccefdd853ed1072d0d3e7e16 Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Fri, 26 Jun 2026 11:00:14 +0800 Subject: [PATCH 11/24] =?UTF-8?q?feat(wms):=20=E6=B7=BB=E5=8A=A0=E6=9D=90?= =?UTF-8?q?=E6=96=99=E5=8D=B7=E5=8E=9A=E5=BA=A6=E5=B7=AE=E8=AE=A1=E7=AE=97?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在WmsMaterialCoilAllExportVo中新增厚度差字段 - 在导出列配置中添加厚度差映射 - 实现厚度差计算逻辑:理论厚度减去实际厚度 - 添加数字格式异常处理避免程序崩溃 - 支持厚度差数据的Excel导出功能 --- .../com/klp/controller/WmsMaterialCoilController.java | 1 + .../com/klp/domain/vo/WmsMaterialCoilAllExportVo.java | 3 +++ .../klp/service/impl/WmsMaterialCoilServiceImpl.java | 11 +++++++++++ 3 files changed, 15 insertions(+) diff --git a/klp-wms/src/main/java/com/klp/controller/WmsMaterialCoilController.java b/klp-wms/src/main/java/com/klp/controller/WmsMaterialCoilController.java index 985f9e703..21f811fe2 100644 --- a/klp-wms/src/main/java/com/klp/controller/WmsMaterialCoilController.java +++ b/klp-wms/src/main/java/com/klp/controller/WmsMaterialCoilController.java @@ -211,6 +211,7 @@ public class WmsMaterialCoilController extends BaseController { columns.put("theoreticalLength", "理论长度"); columns.put("rawMaterialThickness", "原料厚度"); columns.put("chromePlateCoilNo", "镀铬卷号"); + columns.put("thicknessDifference", "厚度差"); return R.ok(columns); } diff --git a/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilAllExportVo.java b/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilAllExportVo.java index 228f75a0e..cc526a6ea 100644 --- a/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilAllExportVo.java +++ b/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilAllExportVo.java @@ -245,4 +245,7 @@ public class WmsMaterialCoilAllExportVo { @ExcelProperty(value = "实测宽度") private String actualWidth; + + @ExcelProperty(value = "厚度差") + private String thicknessDifference; } diff --git a/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java index 962a57abb..889859d97 100644 --- a/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java +++ b/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java @@ -3807,6 +3807,17 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { String isRelatedText = vo.getIsRelatedToOrder() == 0 ? "否" : "是"; vo.setIsRelatedToOrderText(isRelatedText); } + + // 计算厚度差:理论厚度 - 实际厚度 + if (vo.getTheoreticalThickness() != null && vo.getActualThickness() != null) { + try { + BigDecimal theory = new BigDecimal(vo.getTheoreticalThickness()); + BigDecimal actual = new BigDecimal(vo.getActualThickness()); + vo.setThicknessDifference(theory.subtract(actual).toString()); + } catch (NumberFormatException ignored) { + // 解析失败则留空 + } + } } } From 40c2f8358940645f42c8338fedacf2d3c2f64008 Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Fri, 26 Jun 2026 11:05:12 +0800 Subject: [PATCH 12/24] =?UTF-8?q?docs(domain):=20=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E9=95=80=E9=93=AC=E5=8D=B7=E5=8F=B7=E5=AD=97=E6=AE=B5=E4=B8=BA?= =?UTF-8?q?=E5=B7=A5=E5=BA=8F=E5=8D=B7=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修改 WmsMaterialCoil 实体类中的字段注释 - 更新 WmsMaterialCoilAllExportVo 导出视图对象的 Excel 属性标注 - 修改 WmsMaterialCoilBo 业务对象的字段注释 - 更新控制器中列名映射的中文描述 - 修改 WmsMaterialCoilExportVo 导出视图对象的注释和 Excel 属性 - 更新 MyBatis 映射文件中的 SQL 注释 - 修改服务实现类中的查询条件注释 - 更新 WmsMaterialCoilVo 视图对象的字段注释 --- .../java/com/klp/controller/WmsMaterialCoilController.java | 2 +- klp-wms/src/main/java/com/klp/domain/WmsMaterialCoil.java | 2 +- .../src/main/java/com/klp/domain/bo/WmsMaterialCoilBo.java | 2 +- .../java/com/klp/domain/vo/WmsMaterialCoilAllExportVo.java | 2 +- .../main/java/com/klp/domain/vo/WmsMaterialCoilExportVo.java | 4 ++-- .../src/main/java/com/klp/domain/vo/WmsMaterialCoilVo.java | 2 +- .../java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java | 2 +- .../src/main/resources/mapper/klp/WmsMaterialCoilMapper.xml | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/klp-wms/src/main/java/com/klp/controller/WmsMaterialCoilController.java b/klp-wms/src/main/java/com/klp/controller/WmsMaterialCoilController.java index 21f811fe2..1cb96abc3 100644 --- a/klp-wms/src/main/java/com/klp/controller/WmsMaterialCoilController.java +++ b/klp-wms/src/main/java/com/klp/controller/WmsMaterialCoilController.java @@ -210,7 +210,7 @@ public class WmsMaterialCoilController extends BaseController { columns.put("scheduleThickness", "排产厚度"); columns.put("theoreticalLength", "理论长度"); columns.put("rawMaterialThickness", "原料厚度"); - columns.put("chromePlateCoilNo", "镀铬卷号"); + columns.put("chromePlateCoilNo", "工序卷号"); columns.put("thicknessDifference", "厚度差"); return R.ok(columns); } diff --git a/klp-wms/src/main/java/com/klp/domain/WmsMaterialCoil.java b/klp-wms/src/main/java/com/klp/domain/WmsMaterialCoil.java index 6a2c3a902..bf0a72fbc 100644 --- a/klp-wms/src/main/java/com/klp/domain/WmsMaterialCoil.java +++ b/klp-wms/src/main/java/com/klp/domain/WmsMaterialCoil.java @@ -230,7 +230,7 @@ public class WmsMaterialCoil extends BaseEntity { private BigDecimal theoreticalLength; /** - * 镀铬卷号 + * 工序卷号 */ private String chromePlateCoilNo; diff --git a/klp-wms/src/main/java/com/klp/domain/bo/WmsMaterialCoilBo.java b/klp-wms/src/main/java/com/klp/domain/bo/WmsMaterialCoilBo.java index 8f9283aad..c35199ec8 100644 --- a/klp-wms/src/main/java/com/klp/domain/bo/WmsMaterialCoilBo.java +++ b/klp-wms/src/main/java/com/klp/domain/bo/WmsMaterialCoilBo.java @@ -408,7 +408,7 @@ public class WmsMaterialCoilBo extends BaseEntity { private BigDecimal theoreticalLength; /** - * 镀铬卷号 + * 工序卷号 */ private String chromePlateCoilNo; diff --git a/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilAllExportVo.java b/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilAllExportVo.java index cc526a6ea..4edff3767 100644 --- a/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilAllExportVo.java +++ b/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilAllExportVo.java @@ -237,7 +237,7 @@ public class WmsMaterialCoilAllExportVo { @ExcelProperty(value = "理论长度") private String theoreticalLength; - @ExcelProperty(value = "镀铬卷号") + @ExcelProperty(value = "工序卷号") private String chromePlateCoilNo; @ExcelProperty(value = "实测长度") diff --git a/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilExportVo.java b/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilExportVo.java index a50adcd8c..891fde048 100644 --- a/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilExportVo.java +++ b/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilExportVo.java @@ -229,9 +229,9 @@ public class WmsMaterialCoilExportVo { private BigDecimal theoreticalLength; /** - * 镀铬卷号 + * 工序卷号 */ - @ExcelProperty(value = "镀铬卷号") + @ExcelProperty(value = "工序卷号") private String chromePlateCoilNo; /** diff --git a/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilVo.java b/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilVo.java index 790c121f6..87b367cf0 100644 --- a/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilVo.java +++ b/klp-wms/src/main/java/com/klp/domain/vo/WmsMaterialCoilVo.java @@ -356,7 +356,7 @@ public class WmsMaterialCoilVo extends BaseEntity { private BigDecimal theoreticalLength; /** - * 镀铬卷号 + * 工序卷号 */ private String chromePlateCoilNo; diff --git a/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java b/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java index 889859d97..408f70063 100644 --- a/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java +++ b/klp-wms/src/main/java/com/klp/service/impl/WmsMaterialCoilServiceImpl.java @@ -1057,7 +1057,7 @@ public class WmsMaterialCoilServiceImpl implements IWmsMaterialCoilService { qw.eq(bo.getScheduleThickness() != null, "mc.schedule_thickness", bo.getScheduleThickness()); // 理论长度 qw.eq(bo.getTheoreticalLength() != null, "mc.theoretical_length", bo.getTheoreticalLength()); - // 镀铬卷号 + // 工序卷号 qw.like(StringUtils.isNotBlank(bo.getChromePlateCoilNo()), "mc.chrome_plate_coil_no", bo.getChromePlateCoilNo()); // 生产开始时间 qw.eq(bo.getProductionStartTime() != null, "mc.production_start_time", bo.getProductionStartTime()); diff --git a/klp-wms/src/main/resources/mapper/klp/WmsMaterialCoilMapper.xml b/klp-wms/src/main/resources/mapper/klp/WmsMaterialCoilMapper.xml index daa1b12f6..9dc2d5306 100644 --- a/klp-wms/src/main/resources/mapper/klp/WmsMaterialCoilMapper.xml +++ b/klp-wms/src/main/resources/mapper/klp/WmsMaterialCoilMapper.xml @@ -521,7 +521,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" mc.schedule_thickness AS scheduleThickness, -- 理论长度 mc.theoretical_length AS theoreticalLength, - -- 镀铬卷号 + -- 工序卷号 mc.chrome_plate_coil_no AS chromePlateCoilNo, -- 库存状态(中文显示) CASE From 97c9a3741a1c374981d91f9f6891fc27dd9ab3b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A0=82=E7=B3=96?= <2178503051@qq.com> Date: Fri, 26 Jun 2026 11:43:52 +0800 Subject: [PATCH 13/24] =?UTF-8?q?refactor(wms/coil):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E5=8D=B7=E5=8F=B7=E5=8C=B9=E9=85=8D=E4=B8=8E=E8=A1=A8=E6=A0=BC?= =?UTF-8?q?=E5=B8=83=E5=B1=80=EF=BC=8C=E8=B0=83=E6=95=B4=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E6=8C=89=E9=92=AE=E6=9D=83=E9=99=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 修复卷号匹配字段名不统一问题,将encoilid改为coilId适配新逻辑 2. 调整CoilSelector的列名从镀铬卷号改为工序卷号 3. 调整base.vue表格列位置与注释代码,新增correctButton参数控制数据修正按钮 4. 在ship.vue中传入correctButton参数,优化发货页面功能 --- klp-ui/src/components/CoilSelector/data.js | 6 +- .../views/wms/coil/panels/L2MatchPanel.vue | 4 +- klp-ui/src/views/wms/coil/panels/base.vue | 94 ++++++++++--------- klp-ui/src/views/wms/coil/ship.vue | 2 + klp-ui/src/views/wms/coil/typing.vue | 7 +- 5 files changed, 61 insertions(+), 52 deletions(-) diff --git a/klp-ui/src/components/CoilSelector/data.js b/klp-ui/src/components/CoilSelector/data.js index ab7f314f1..c097d4a3c 100644 --- a/klp-ui/src/components/CoilSelector/data.js +++ b/klp-ui/src/components/CoilSelector/data.js @@ -12,7 +12,7 @@ export const defaultColumns = [ showOverflowTooltip: true }, { - label: '镀铬卷号', + label: '工序卷号', align: 'center', prop: 'chromelCoilNo', showOverflowTooltip: true @@ -90,7 +90,7 @@ export const fullPageDefaultColumns = [ showOverflowTooltip: true }, { - label: '镀铬卷号', + label: '工序卷号', align: 'center', prop: 'chromelCoilNo', showOverflowTooltip: true @@ -183,7 +183,7 @@ export const fullPageDefaultColumns = [ export const optionalColumns = [ { label: '入场卷号', value: 'enterCoilNo' }, { label: '当前卷号', value: 'currentCoilNo' }, - { label: '镀铬卷号', value: 'chromelCoilNo' }, + { label: '工序卷号', value: 'chromelCoilNo' }, { label: '厂家钢卷号', value: 'supplierCoilNo' }, { label: '逻辑库区', value: 'warehouseName' }, { label: '实际库区', value: 'actualWarehouseName' }, diff --git a/klp-ui/src/views/wms/coil/panels/L2MatchPanel.vue b/klp-ui/src/views/wms/coil/panels/L2MatchPanel.vue index f63d45df5..80e0c0bb7 100644 --- a/klp-ui/src/views/wms/coil/panels/L2MatchPanel.vue +++ b/klp-ui/src/views/wms/coil/panels/L2MatchPanel.vue @@ -129,7 +129,7 @@ export default { fr.start_time = excoil.start_date ?? excoil.START_DATE ?? null fr.end_time = excoil.end_date ?? excoil.END_DATE ?? null } - this.bestMatch = fr + this.bestMatch = this.normalizeExcoilRow(fr) }).catch(() => {}).finally(() => { this.matchLoading = false }) }, loadRecentList() { @@ -148,12 +148,12 @@ export default { return val }, normalizeExcoilRow(row) { - console.log(row, '标准化') const g = k => row[k] != null ? row[k] : (row[k.toUpperCase()] != null ? row[k.toUpperCase()] : null) return { hot_coilid: g('hot_coilid'), encoilid: g('encoilid'), excoilid: g('excoilid'), + coilId: g('coilid') || g('encoilid') || g('excoilid'), exit_thick: g('exit_thick'), exit_width: g('exit_width'), exit_length: g('exit_length'), diff --git a/klp-ui/src/views/wms/coil/panels/base.vue b/klp-ui/src/views/wms/coil/panels/base.vue index 9c482b31a..d9e6f7f06 100644 --- a/klp-ui/src/views/wms/coil/panels/base.vue +++ b/klp-ui/src/views/wms/coil/panels/base.vue @@ -155,6 +155,44 @@ :floatLayer="true" :floatLayerConfig="floatLayerConfig" @row-click="handleRowClick" :height="showAbnormal ? 'calc(100vh - 400px)' : 'calc(100vh - 300px)'" border> + + + + + + + - - - - - - - - @@ -32,6 +33,7 @@ export default { showStatus: false, hideType: false, showExportTime: true, + correctButton: true, } } } diff --git a/klp-ui/src/views/wms/coil/typing.vue b/klp-ui/src/views/wms/coil/typing.vue index c321ae1bb..fc3c10087 100644 --- a/klp-ui/src/views/wms/coil/typing.vue +++ b/klp-ui/src/views/wms/coil/typing.vue @@ -699,8 +699,11 @@ export default { this.$set(this.updateForm, 'productionEndTime', this.formatDateTime(data.end_date)) } - if (data.encoilid) { - this.$set(this.updateForm, 'chromePlateCoilNo', data.encoilid) + console.log(data, 'fill') + + if (data.coilId) { + console.log(data.coilId) + this.$set(this.updateForm, 'chromePlateCoilNo', data.coilId) } if (data.start_date || data.end_date) this.calculateProductionDuration() From 174cd2928057fd59c623575a7a43162144318158 Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Fri, 26 Jun 2026 14:14:23 +0800 Subject: [PATCH 14/24] =?UTF-8?q?feat(flow):=20=E6=B7=BB=E5=8A=A0=E6=8E=92?= =?UTF-8?q?=E4=BA=A7=E5=8D=95=E4=B8=BB=E5=8A=A0=E6=98=8E=E7=BB=86=E5=8F=AF?= =?UTF-8?q?=E5=90=88=E5=B9=B6=E5=8A=9F=E8=83=BD=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 创建排产单主加明细可合并的实体类 SchProdScheduleItem - 定义业务对象 SchProdScheduleItemBo 和视图对象 SchProdScheduleItemVo - 实现排产单主加明细可合并的服务接口 ISchProdScheduleItemService - 开发控制器 SchProdScheduleItemController 提供 CRUD 操作接口 - 配置 MyBatis 映射器 SchProdScheduleItemMapper 和 XML 映射文件 - 实现服务层业务逻辑 SchProdScheduleItemServiceImpl - 添加分页查询、新增、修改、删除等核心功能 - 集成 Excel 导出功能支持数据导出操作 --- .../SchProdScheduleItemController.java | 99 ++++++++ .../klp/flow/domain/SchProdScheduleItem.java | 168 +++++++++++++ .../flow/domain/bo/SchProdScheduleItemBo.java | 194 +++++++++++++++ .../flow/domain/vo/SchProdScheduleItemVo.java | 233 ++++++++++++++++++ .../mapper/SchProdScheduleItemMapper.java | 15 ++ .../service/ISchProdScheduleItemService.java | 49 ++++ .../impl/SchProdScheduleItemServiceImpl.java | 140 +++++++++++ .../mapper/flow/SchProdScheduleItemMapper.xml | 50 ++++ 8 files changed, 948 insertions(+) create mode 100644 klp-flow/src/main/java/com/klp/flow/controller/SchProdScheduleItemController.java create mode 100644 klp-flow/src/main/java/com/klp/flow/domain/SchProdScheduleItem.java create mode 100644 klp-flow/src/main/java/com/klp/flow/domain/bo/SchProdScheduleItemBo.java create mode 100644 klp-flow/src/main/java/com/klp/flow/domain/vo/SchProdScheduleItemVo.java create mode 100644 klp-flow/src/main/java/com/klp/flow/mapper/SchProdScheduleItemMapper.java create mode 100644 klp-flow/src/main/java/com/klp/flow/service/ISchProdScheduleItemService.java create mode 100644 klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleItemServiceImpl.java create mode 100644 klp-flow/src/main/resources/mapper/flow/SchProdScheduleItemMapper.xml diff --git a/klp-flow/src/main/java/com/klp/flow/controller/SchProdScheduleItemController.java b/klp-flow/src/main/java/com/klp/flow/controller/SchProdScheduleItemController.java new file mode 100644 index 000000000..0527e52bb --- /dev/null +++ b/klp-flow/src/main/java/com/klp/flow/controller/SchProdScheduleItemController.java @@ -0,0 +1,99 @@ +package com.klp.flow.controller; + +import java.util.List; +import java.util.Arrays; + +import lombok.RequiredArgsConstructor; +import javax.servlet.http.HttpServletResponse; +import javax.validation.constraints.*; +import org.springframework.web.bind.annotation.*; +import org.springframework.validation.annotation.Validated; +import com.klp.common.annotation.RepeatSubmit; +import com.klp.common.annotation.Log; +import com.klp.common.core.controller.BaseController; +import com.klp.common.core.domain.PageQuery; +import com.klp.common.core.domain.R; +import com.klp.common.core.validate.AddGroup; +import com.klp.common.core.validate.EditGroup; +import com.klp.common.enums.BusinessType; +import com.klp.common.utils.poi.ExcelUtil; +import com.klp.flow.domain.vo.SchProdScheduleItemVo; +import com.klp.flow.domain.bo.SchProdScheduleItemBo; +import com.klp.flow.service.ISchProdScheduleItemService; +import com.klp.common.core.page.TableDataInfo; + +/** + * 排产单主加明细可合并 + * + * @author klp + * @date 2026-06-26 + */ +@Validated +@RequiredArgsConstructor +@RestController +@RequestMapping("/flow/prodScheduleItem") +public class SchProdScheduleItemController extends BaseController { + + private final ISchProdScheduleItemService iSchProdScheduleItemService; + + /** + * 查询排产单主加明细可合并列表 + */ + @GetMapping("/list") + public TableDataInfo list(SchProdScheduleItemBo bo, PageQuery pageQuery) { + return iSchProdScheduleItemService.queryPageList(bo, pageQuery); + } + + /** + * 导出排产单主加明细可合并列表 + */ + @Log(title = "排产单主加明细可合并", businessType = BusinessType.EXPORT) + @PostMapping("/export") + public void export(SchProdScheduleItemBo bo, HttpServletResponse response) { + List list = iSchProdScheduleItemService.queryList(bo); + ExcelUtil.exportExcel(list, "排产单主加明细可合并", SchProdScheduleItemVo.class, response); + } + + /** + * 获取排产单主加明细可合并详细信息 + * + * @param scheduleId 主键 + */ + @GetMapping("/{scheduleId}") + public R getInfo(@NotNull(message = "主键不能为空") + @PathVariable Long scheduleId) { + return R.ok(iSchProdScheduleItemService.queryById(scheduleId)); + } + + /** + * 新增排产单主加明细可合并 + */ + @Log(title = "排产单主加明细可合并", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping() + public R add(@Validated(AddGroup.class) @RequestBody SchProdScheduleItemBo bo) { + return toAjax(iSchProdScheduleItemService.insertByBo(bo)); + } + + /** + * 修改排产单主加明细可合并 + */ + @Log(title = "排产单主加明细可合并", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PutMapping() + public R edit(@Validated(EditGroup.class) @RequestBody SchProdScheduleItemBo bo) { + return toAjax(iSchProdScheduleItemService.updateByBo(bo)); + } + + /** + * 删除排产单主加明细可合并 + * + * @param scheduleIds 主键串 + */ + @Log(title = "排产单主加明细可合并", businessType = BusinessType.DELETE) + @DeleteMapping("/{scheduleIds}") + public R remove(@NotEmpty(message = "主键不能为空") + @PathVariable Long[] scheduleIds) { + return toAjax(iSchProdScheduleItemService.deleteWithValidByIds(Arrays.asList(scheduleIds), true)); + } +} diff --git a/klp-flow/src/main/java/com/klp/flow/domain/SchProdScheduleItem.java b/klp-flow/src/main/java/com/klp/flow/domain/SchProdScheduleItem.java new file mode 100644 index 000000000..6a58fc1e0 --- /dev/null +++ b/klp-flow/src/main/java/com/klp/flow/domain/SchProdScheduleItem.java @@ -0,0 +1,168 @@ +package com.klp.flow.domain; + +import com.baomidou.mybatisplus.annotation.*; +import com.klp.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.math.BigDecimal; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +/** + * 排产单主加明细可合并对象 sch_prod_schedule_item + * + * @author klp + * @date 2026-06-26 + */ +@Data +@EqualsAndHashCode(callSuper = true) +@TableName("sch_prod_schedule_item") +public class SchProdScheduleItem extends BaseEntity { + + private static final long serialVersionUID=1L; + + /** + * 排产单主键ID + */ + @TableId(value = "schedule_id") + private Long scheduleId; + /** + * 排产单号(唯一标识,钢卷关联依据) + */ + private String scheduleNo; + /** + * 生产日期(和合同号组成业务关联键) + */ + private Date prodDate; + /** + * 排产状态:0草稿 1待审核 2已下达 3已退回 + */ + private Long scheduleStatus; + /** + * 排产总计划吨数 + */ + private BigDecimal totalPlanWeight; + /** + * 关联销售合同号 + */ + private String relContractNo; + /** + * 业务员 + */ + private String businessUser; + /** + * 联系电话 + */ + private String businessPhone; + /** + * 订单日期 + */ + private Date orderDate; + /** + * 订货单位 + */ + private String customerName; + /** + * 交货期(天) + */ + private Long deliveryCycle; + /** + * 产品用途 + */ + private String usePurpose; + /** + * 品名:冷硬钢卷/镀锌钢卷/冷轧钢卷/镀铬钢卷 + */ + private String productType; + /** + * 厚度公差 + */ + private String thicknessTolerance; + /** + * 宽度公差 + */ + private String widthTolerance; + /** + * 表面质量 + */ + private String surfaceQuality; + /** + * 表面处理 + */ + private String surfaceTreatment; + /** + * 内径尺寸 + */ + private String innerDiameter; + /** + * 外径要求 + */ + private String outerDiameter; + /** + * 包装要求 + */ + private String packReq; + /** + * 切边要求 + */ + private String cutEdgeReq; + /** + * 单件重量 + */ + private String singleCoilWeight; + /** + * 交货重量偏差 + */ + private String weightDeviation; + /** + * 其他技术要求 + */ + private String otherTechReq; + /** + * 付款情况说明 + */ + private String paymentDesc; + /** + * 退回原因 + */ + private String returnReason; + /** + * 排产单主表ID + */ + private String scheduleIds; + /** + * 来源销售订单明细ID(溯源原始订单规格) + */ + private String orderDetailIds; + /** + * 规格 例:1.0X1250 + */ + private String spec; + /** + * 材质 DX51D + */ + private String material; + /** + * 本次排产吨数(数量),可审核修改 + */ + private BigDecimal scheduleWeight; + /** + * 品名项 + */ + private String productItem; + /** + * 单行排产备注 + */ + private String rowRemark; + /** + * 备注 + */ + private String remark; + /** + * 删除标识 0正常 2删除 + */ + @TableLogic + private Long delFlag; + +} diff --git a/klp-flow/src/main/java/com/klp/flow/domain/bo/SchProdScheduleItemBo.java b/klp-flow/src/main/java/com/klp/flow/domain/bo/SchProdScheduleItemBo.java new file mode 100644 index 000000000..7637d7727 --- /dev/null +++ b/klp-flow/src/main/java/com/klp/flow/domain/bo/SchProdScheduleItemBo.java @@ -0,0 +1,194 @@ +package com.klp.flow.domain.bo; + +import com.klp.common.core.domain.BaseEntity; +import lombok.Data; +import lombok.EqualsAndHashCode; +import javax.validation.constraints.*; + +import java.math.BigDecimal; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; + +/** + * 排产单主加明细可合并业务对象 sch_prod_schedule_item + * + * @author klp + * @date 2026-06-26 + */ + +@Data +@EqualsAndHashCode(callSuper = true) +public class SchProdScheduleItemBo extends BaseEntity { + + /** + * 排产单主键ID + */ + private Long scheduleId; + + /** + * 排产单号(唯一标识,钢卷关联依据) + */ + private String scheduleNo; + + /** + * 生产日期(和合同号组成业务关联键) + */ + private Date prodDate; + + /** + * 排产状态:0草稿 1待审核 2已下达 3已退回 + */ + private Long scheduleStatus; + + /** + * 排产总计划吨数 + */ + private BigDecimal totalPlanWeight; + + /** + * 关联销售合同号 + */ + private String relContractNo; + + /** + * 业务员 + */ + private String businessUser; + + /** + * 联系电话 + */ + private String businessPhone; + + /** + * 订单日期 + */ + private Date orderDate; + + /** + * 订货单位 + */ + private String customerName; + + /** + * 交货期(天) + */ + private Long deliveryCycle; + + /** + * 产品用途 + */ + private String usePurpose; + + /** + * 品名:冷硬钢卷/镀锌钢卷/冷轧钢卷/镀铬钢卷 + */ + private String productType; + + /** + * 厚度公差 + */ + private String thicknessTolerance; + + /** + * 宽度公差 + */ + private String widthTolerance; + + /** + * 表面质量 + */ + private String surfaceQuality; + + /** + * 表面处理 + */ + private String surfaceTreatment; + + /** + * 内径尺寸 + */ + private String innerDiameter; + + /** + * 外径要求 + */ + private String outerDiameter; + + /** + * 包装要求 + */ + private String packReq; + + /** + * 切边要求 + */ + private String cutEdgeReq; + + /** + * 单件重量 + */ + private String singleCoilWeight; + + /** + * 交货重量偏差 + */ + private String weightDeviation; + + /** + * 其他技术要求 + */ + private String otherTechReq; + + /** + * 付款情况说明 + */ + private String paymentDesc; + + /** + * 退回原因 + */ + private String returnReason; + + /** + * 排产单主表ID + */ + private String scheduleIds; + + /** + * 来源销售订单明细ID(溯源原始订单规格) + */ + private String orderDetailIds; + + /** + * 规格 例:1.0X1250 + */ + private String spec; + + /** + * 材质 DX51D + */ + private String material; + + /** + * 本次排产吨数(数量),可审核修改 + */ + private BigDecimal scheduleWeight; + + /** + * 品名项 + */ + private String productItem; + + /** + * 单行排产备注 + */ + private String rowRemark; + + /** + * 备注 + */ + private String remark; + + +} diff --git a/klp-flow/src/main/java/com/klp/flow/domain/vo/SchProdScheduleItemVo.java b/klp-flow/src/main/java/com/klp/flow/domain/vo/SchProdScheduleItemVo.java new file mode 100644 index 000000000..6fec3214c --- /dev/null +++ b/klp-flow/src/main/java/com/klp/flow/domain/vo/SchProdScheduleItemVo.java @@ -0,0 +1,233 @@ +package com.klp.flow.domain.vo; + +import java.math.BigDecimal; +import java.util.Date; +import com.fasterxml.jackson.annotation.JsonFormat; +import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; +import com.alibaba.excel.annotation.ExcelProperty; +import com.klp.common.annotation.ExcelDictFormat; +import com.klp.common.convert.ExcelDictConvert; +import lombok.Data; + + +/** + * 排产单主加明细可合并视图对象 sch_prod_schedule_item + * + * @author klp + * @date 2026-06-26 + */ +@Data +@ExcelIgnoreUnannotated +public class SchProdScheduleItemVo { + + private static final long serialVersionUID = 1L; + + /** + * 排产单主键ID + */ + @ExcelProperty(value = "排产单主键ID") + private Long scheduleId; + + /** + * 排产单号(唯一标识,钢卷关联依据) + */ + @ExcelProperty(value = "排产单号", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "唯=一标识,钢卷关联依据") + private String scheduleNo; + + /** + * 生产日期(和合同号组成业务关联键) + */ + @ExcelProperty(value = "生产日期", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "和=合同号组成业务关联键") + private Date prodDate; + + /** + * 排产状态:0草稿 1待审核 2已下达 3已退回 + */ + @ExcelProperty(value = "排产状态:0草稿 1待审核 2已下达 3已退回") + private Long scheduleStatus; + + /** + * 排产总计划吨数 + */ + @ExcelProperty(value = "排产总计划吨数") + private BigDecimal totalPlanWeight; + + /** + * 关联销售合同号 + */ + @ExcelProperty(value = "关联销售合同号") + private String relContractNo; + + /** + * 业务员 + */ + @ExcelProperty(value = "业务员") + private String businessUser; + + /** + * 联系电话 + */ + @ExcelProperty(value = "联系电话") + private String businessPhone; + + /** + * 订单日期 + */ + @ExcelProperty(value = "订单日期") + private Date orderDate; + + /** + * 订货单位 + */ + @ExcelProperty(value = "订货单位") + private String customerName; + + /** + * 交货期(天) + */ + @ExcelProperty(value = "交货期(天)") + private Long deliveryCycle; + + /** + * 产品用途 + */ + @ExcelProperty(value = "产品用途") + private String usePurpose; + + /** + * 品名:冷硬钢卷/镀锌钢卷/冷轧钢卷/镀铬钢卷 + */ + @ExcelProperty(value = "品名:冷硬钢卷/镀锌钢卷/冷轧钢卷/镀铬钢卷") + private String productType; + + /** + * 厚度公差 + */ + @ExcelProperty(value = "厚度公差") + private String thicknessTolerance; + + /** + * 宽度公差 + */ + @ExcelProperty(value = "宽度公差") + private String widthTolerance; + + /** + * 表面质量 + */ + @ExcelProperty(value = "表面质量") + private String surfaceQuality; + + /** + * 表面处理 + */ + @ExcelProperty(value = "表面处理") + private String surfaceTreatment; + + /** + * 内径尺寸 + */ + @ExcelProperty(value = "内径尺寸") + private String innerDiameter; + + /** + * 外径要求 + */ + @ExcelProperty(value = "外径要求") + private String outerDiameter; + + /** + * 包装要求 + */ + @ExcelProperty(value = "包装要求") + private String packReq; + + /** + * 切边要求 + */ + @ExcelProperty(value = "切边要求") + private String cutEdgeReq; + + /** + * 单件重量 + */ + @ExcelProperty(value = "单件重量") + private String singleCoilWeight; + + /** + * 交货重量偏差 + */ + @ExcelProperty(value = "交货重量偏差") + private String weightDeviation; + + /** + * 其他技术要求 + */ + @ExcelProperty(value = "其他技术要求") + private String otherTechReq; + + /** + * 付款情况说明 + */ + @ExcelProperty(value = "付款情况说明") + private String paymentDesc; + + /** + * 退回原因 + */ + @ExcelProperty(value = "退回原因") + private String returnReason; + + /** + * 排产单主表ID + */ + @ExcelProperty(value = "排产单主表ID") + private String scheduleIds; + + /** + * 来源销售订单明细ID(溯源原始订单规格) + */ + @ExcelProperty(value = "来源销售订单明细ID", converter = ExcelDictConvert.class) + @ExcelDictFormat(readConverterExp = "溯=源原始订单规格") + private String orderDetailIds; + + /** + * 规格 例:1.0X1250 + */ + @ExcelProperty(value = "规格 例:1.0X1250") + private String spec; + + /** + * 材质 DX51D + */ + @ExcelProperty(value = "材质 DX51D") + private String material; + + /** + * 本次排产吨数(数量),可审核修改 + */ + @ExcelProperty(value = "本次排产吨数(数量),可审核修改") + private BigDecimal scheduleWeight; + + /** + * 品名项 + */ + @ExcelProperty(value = "品名项") + private String productItem; + + /** + * 单行排产备注 + */ + @ExcelProperty(value = "单行排产备注") + private String rowRemark; + + /** + * 备注 + */ + @ExcelProperty(value = "备注") + private String remark; + + +} diff --git a/klp-flow/src/main/java/com/klp/flow/mapper/SchProdScheduleItemMapper.java b/klp-flow/src/main/java/com/klp/flow/mapper/SchProdScheduleItemMapper.java new file mode 100644 index 000000000..15c302a5f --- /dev/null +++ b/klp-flow/src/main/java/com/klp/flow/mapper/SchProdScheduleItemMapper.java @@ -0,0 +1,15 @@ +package com.klp.flow.mapper; + +import com.klp.flow.domain.SchProdScheduleItem; +import com.klp.flow.domain.vo.SchProdScheduleItemVo; +import com.klp.common.core.mapper.BaseMapperPlus; + +/** + * 排产单主加明细可合并Mapper接口 + * + * @author klp + * @date 2026-06-26 + */ +public interface SchProdScheduleItemMapper extends BaseMapperPlus { + +} diff --git a/klp-flow/src/main/java/com/klp/flow/service/ISchProdScheduleItemService.java b/klp-flow/src/main/java/com/klp/flow/service/ISchProdScheduleItemService.java new file mode 100644 index 000000000..7b187e200 --- /dev/null +++ b/klp-flow/src/main/java/com/klp/flow/service/ISchProdScheduleItemService.java @@ -0,0 +1,49 @@ +package com.klp.flow.service; + +import com.klp.flow.domain.SchProdScheduleItem; +import com.klp.flow.domain.vo.SchProdScheduleItemVo; +import com.klp.flow.domain.bo.SchProdScheduleItemBo; +import com.klp.common.core.page.TableDataInfo; +import com.klp.common.core.domain.PageQuery; + +import java.util.Collection; +import java.util.List; + +/** + * 排产单主加明细可合并Service接口 + * + * @author klp + * @date 2026-06-26 + */ +public interface ISchProdScheduleItemService { + + /** + * 查询排产单主加明细可合并 + */ + SchProdScheduleItemVo queryById(Long scheduleId); + + /** + * 查询排产单主加明细可合并列表 + */ + TableDataInfo queryPageList(SchProdScheduleItemBo bo, PageQuery pageQuery); + + /** + * 查询排产单主加明细可合并列表 + */ + List queryList(SchProdScheduleItemBo bo); + + /** + * 新增排产单主加明细可合并 + */ + Boolean insertByBo(SchProdScheduleItemBo bo); + + /** + * 修改排产单主加明细可合并 + */ + Boolean updateByBo(SchProdScheduleItemBo bo); + + /** + * 校验并批量删除排产单主加明细可合并信息 + */ + Boolean deleteWithValidByIds(Collection ids, Boolean isValid); +} diff --git a/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleItemServiceImpl.java b/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleItemServiceImpl.java new file mode 100644 index 000000000..2eb5bc6c3 --- /dev/null +++ b/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleItemServiceImpl.java @@ -0,0 +1,140 @@ +package com.klp.flow.service.impl; + +import cn.hutool.core.bean.BeanUtil; +import com.klp.common.core.page.TableDataInfo; +import com.klp.common.core.domain.PageQuery; +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.klp.common.utils.StringUtils; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import com.klp.flow.domain.bo.SchProdScheduleItemBo; +import com.klp.flow.domain.vo.SchProdScheduleItemVo; +import com.klp.flow.domain.SchProdScheduleItem; +import com.klp.flow.mapper.SchProdScheduleItemMapper; +import com.klp.flow.service.ISchProdScheduleItemService; + +import java.util.List; +import java.util.Map; +import java.util.Collection; + +/** + * 排产单主加明细可合并Service业务层处理 + * + * @author klp + * @date 2026-06-26 + */ +@RequiredArgsConstructor +@Service +public class SchProdScheduleItemServiceImpl implements ISchProdScheduleItemService { + + private final SchProdScheduleItemMapper baseMapper; + + /** + * 查询排产单主加明细可合并 + */ + @Override + public SchProdScheduleItemVo queryById(Long scheduleId){ + return baseMapper.selectVoById(scheduleId); + } + + /** + * 查询排产单主加明细可合并列表 + */ + @Override + public TableDataInfo queryPageList(SchProdScheduleItemBo bo, PageQuery pageQuery) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + Page result = baseMapper.selectVoPage(pageQuery.build(), lqw); + return TableDataInfo.build(result); + } + + /** + * 查询排产单主加明细可合并列表 + */ + @Override + public List queryList(SchProdScheduleItemBo bo) { + LambdaQueryWrapper lqw = buildQueryWrapper(bo); + return baseMapper.selectVoList(lqw); + } + + private LambdaQueryWrapper buildQueryWrapper(SchProdScheduleItemBo bo) { + Map params = bo.getParams(); + LambdaQueryWrapper lqw = Wrappers.lambdaQuery(); + lqw.eq(StringUtils.isNotBlank(bo.getScheduleNo()), SchProdScheduleItem::getScheduleNo, bo.getScheduleNo()); + lqw.eq(bo.getProdDate() != null, SchProdScheduleItem::getProdDate, bo.getProdDate()); + lqw.eq(bo.getScheduleStatus() != null, SchProdScheduleItem::getScheduleStatus, bo.getScheduleStatus()); + lqw.eq(bo.getTotalPlanWeight() != null, SchProdScheduleItem::getTotalPlanWeight, bo.getTotalPlanWeight()); + lqw.eq(StringUtils.isNotBlank(bo.getRelContractNo()), SchProdScheduleItem::getRelContractNo, bo.getRelContractNo()); + lqw.eq(StringUtils.isNotBlank(bo.getBusinessUser()), SchProdScheduleItem::getBusinessUser, bo.getBusinessUser()); + lqw.eq(StringUtils.isNotBlank(bo.getBusinessPhone()), SchProdScheduleItem::getBusinessPhone, bo.getBusinessPhone()); + lqw.eq(bo.getOrderDate() != null, SchProdScheduleItem::getOrderDate, bo.getOrderDate()); + lqw.like(StringUtils.isNotBlank(bo.getCustomerName()), SchProdScheduleItem::getCustomerName, bo.getCustomerName()); + lqw.eq(bo.getDeliveryCycle() != null, SchProdScheduleItem::getDeliveryCycle, bo.getDeliveryCycle()); + lqw.eq(StringUtils.isNotBlank(bo.getUsePurpose()), SchProdScheduleItem::getUsePurpose, bo.getUsePurpose()); + lqw.eq(StringUtils.isNotBlank(bo.getProductType()), SchProdScheduleItem::getProductType, bo.getProductType()); + lqw.eq(StringUtils.isNotBlank(bo.getThicknessTolerance()), SchProdScheduleItem::getThicknessTolerance, bo.getThicknessTolerance()); + lqw.eq(StringUtils.isNotBlank(bo.getWidthTolerance()), SchProdScheduleItem::getWidthTolerance, bo.getWidthTolerance()); + lqw.eq(StringUtils.isNotBlank(bo.getSurfaceQuality()), SchProdScheduleItem::getSurfaceQuality, bo.getSurfaceQuality()); + lqw.eq(StringUtils.isNotBlank(bo.getSurfaceTreatment()), SchProdScheduleItem::getSurfaceTreatment, bo.getSurfaceTreatment()); + lqw.eq(StringUtils.isNotBlank(bo.getInnerDiameter()), SchProdScheduleItem::getInnerDiameter, bo.getInnerDiameter()); + lqw.eq(StringUtils.isNotBlank(bo.getOuterDiameter()), SchProdScheduleItem::getOuterDiameter, bo.getOuterDiameter()); + lqw.eq(StringUtils.isNotBlank(bo.getPackReq()), SchProdScheduleItem::getPackReq, bo.getPackReq()); + lqw.eq(StringUtils.isNotBlank(bo.getCutEdgeReq()), SchProdScheduleItem::getCutEdgeReq, bo.getCutEdgeReq()); + lqw.eq(StringUtils.isNotBlank(bo.getSingleCoilWeight()), SchProdScheduleItem::getSingleCoilWeight, bo.getSingleCoilWeight()); + lqw.eq(StringUtils.isNotBlank(bo.getWeightDeviation()), SchProdScheduleItem::getWeightDeviation, bo.getWeightDeviation()); + lqw.eq(StringUtils.isNotBlank(bo.getOtherTechReq()), SchProdScheduleItem::getOtherTechReq, bo.getOtherTechReq()); + lqw.eq(StringUtils.isNotBlank(bo.getPaymentDesc()), SchProdScheduleItem::getPaymentDesc, bo.getPaymentDesc()); + lqw.eq(StringUtils.isNotBlank(bo.getReturnReason()), SchProdScheduleItem::getReturnReason, bo.getReturnReason()); + lqw.eq(StringUtils.isNotBlank(bo.getScheduleIds()), SchProdScheduleItem::getScheduleIds, bo.getScheduleIds()); + lqw.eq(StringUtils.isNotBlank(bo.getOrderDetailIds()), SchProdScheduleItem::getOrderDetailIds, bo.getOrderDetailIds()); + lqw.eq(StringUtils.isNotBlank(bo.getSpec()), SchProdScheduleItem::getSpec, bo.getSpec()); + lqw.eq(StringUtils.isNotBlank(bo.getMaterial()), SchProdScheduleItem::getMaterial, bo.getMaterial()); + lqw.eq(bo.getScheduleWeight() != null, SchProdScheduleItem::getScheduleWeight, bo.getScheduleWeight()); + lqw.eq(StringUtils.isNotBlank(bo.getProductItem()), SchProdScheduleItem::getProductItem, bo.getProductItem()); + lqw.eq(StringUtils.isNotBlank(bo.getRowRemark()), SchProdScheduleItem::getRowRemark, bo.getRowRemark()); + return lqw; + } + + /** + * 新增排产单主加明细可合并 + */ + @Override + public Boolean insertByBo(SchProdScheduleItemBo bo) { + SchProdScheduleItem add = BeanUtil.toBean(bo, SchProdScheduleItem.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + bo.setScheduleId(add.getScheduleId()); + } + return flag; + } + + /** + * 修改排产单主加明细可合并 + */ + @Override + public Boolean updateByBo(SchProdScheduleItemBo bo) { + SchProdScheduleItem update = BeanUtil.toBean(bo, SchProdScheduleItem.class); + validEntityBeforeSave(update); + return baseMapper.updateById(update) > 0; + } + + /** + * 保存前的数据校验 + */ + private void validEntityBeforeSave(SchProdScheduleItem entity){ + //TODO 做一些数据校验,如唯一约束 + } + + /** + * 批量删除排产单主加明细可合并 + */ + @Override + public Boolean deleteWithValidByIds(Collection ids, Boolean isValid) { + if(isValid){ + //TODO 做一些业务上的校验,判断是否需要校验 + } + return baseMapper.deleteBatchIds(ids) > 0; + } +} diff --git a/klp-flow/src/main/resources/mapper/flow/SchProdScheduleItemMapper.xml b/klp-flow/src/main/resources/mapper/flow/SchProdScheduleItemMapper.xml new file mode 100644 index 000000000..766356f0f --- /dev/null +++ b/klp-flow/src/main/resources/mapper/flow/SchProdScheduleItemMapper.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 39eaab139e97d22689d485a1146bb8380486991a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A0=82=E7=B3=96?= <2178503051@qq.com> Date: Fri, 26 Jun 2026 15:41:21 +0800 Subject: [PATCH 15/24] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E7=9B=98?= =?UTF-8?q?=E5=BA=93=E7=AE=A1=E7=90=86=E5=85=A8=E6=B5=81=E7=A8=8B=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 1. 新增批量新增盘库差异记录API 2. 新增盘库Excel对比工具函数 3. 新增盘库申请页面与库区明细组件 4. 优化流程图页面,新增流程图下载功能 5. 重构盘库主页面流程状态与操作逻辑 6. 新增多组件拆分与页面模块化改造 --- klp-ui/src/api/flow/countDiscrepancy.js | 9 + klp-ui/src/views/wms/coil/do/trace.vue | 1610 +++++++++++++++++ klp-ui/src/views/wms/post/InvCount/apply.vue | 169 ++ .../src/views/wms/post/InvCount/approval.vue | 713 ++------ .../components/WarehouseDetailPanel.vue | 606 +++++++ .../src/views/wms/post/InvCount/execute.vue | 772 +------- klp-ui/src/views/wms/post/InvCount/index.vue | 300 +-- .../views/wms/post/InvCount/utils/compare.js | 215 +++ klp-ui/src/views/wms/post/flow.vue | 213 ++- 9 files changed, 2994 insertions(+), 1613 deletions(-) create mode 100644 klp-ui/src/views/wms/coil/do/trace.vue create mode 100644 klp-ui/src/views/wms/post/InvCount/apply.vue create mode 100644 klp-ui/src/views/wms/post/InvCount/components/WarehouseDetailPanel.vue create mode 100644 klp-ui/src/views/wms/post/InvCount/utils/compare.js diff --git a/klp-ui/src/api/flow/countDiscrepancy.js b/klp-ui/src/api/flow/countDiscrepancy.js index 448c2fb24..2d8efd0aa 100644 --- a/klp-ui/src/api/flow/countDiscrepancy.js +++ b/klp-ui/src/api/flow/countDiscrepancy.js @@ -35,6 +35,15 @@ export function updateCountDiscrepancy(data) { }) } +// 批量新增盘库差异记录 +export function batchAddCountDiscrepancy(data) { + return request({ + url: '/flow/countDiscrepancy/batch', + method: 'post', + data: data + }) +} + // 删除盘库差异记录 export function delCountDiscrepancy(discrepancyId) { return request({ diff --git a/klp-ui/src/views/wms/coil/do/trace.vue b/klp-ui/src/views/wms/coil/do/trace.vue new file mode 100644 index 000000000..3e21d4e65 --- /dev/null +++ b/klp-ui/src/views/wms/coil/do/trace.vue @@ -0,0 +1,1610 @@ + + + + + \ No newline at end of file diff --git a/klp-ui/src/views/wms/post/InvCount/apply.vue b/klp-ui/src/views/wms/post/InvCount/apply.vue new file mode 100644 index 000000000..2d0129beb --- /dev/null +++ b/klp-ui/src/views/wms/post/InvCount/apply.vue @@ -0,0 +1,169 @@ + + + + + diff --git a/klp-ui/src/views/wms/post/InvCount/approval.vue b/klp-ui/src/views/wms/post/InvCount/approval.vue index a12a0edb8..b40865379 100644 --- a/klp-ui/src/views/wms/post/InvCount/approval.vue +++ b/klp-ui/src/views/wms/post/InvCount/approval.vue @@ -1,139 +1,49 @@ diff --git a/klp-ui/src/views/wms/post/InvCount/components/WarehouseDetailPanel.vue b/klp-ui/src/views/wms/post/InvCount/components/WarehouseDetailPanel.vue new file mode 100644 index 000000000..2921fb5ab --- /dev/null +++ b/klp-ui/src/views/wms/post/InvCount/components/WarehouseDetailPanel.vue @@ -0,0 +1,606 @@ + + + + diff --git a/klp-ui/src/views/wms/post/InvCount/execute.vue b/klp-ui/src/views/wms/post/InvCount/execute.vue index ececc1d5a..015990298 100644 --- a/klp-ui/src/views/wms/post/InvCount/execute.vue +++ b/klp-ui/src/views/wms/post/InvCount/execute.vue @@ -6,162 +6,47 @@
- 盘库执行 - + 差异处理 +
- - - -
-
- +
-
-
- {{ item.planCode }} - {{ item.planName }} -
-
- 执行中 - 差异处理中 -
-
- -
-
-
- - 暂无执行中的盘库计划 +
{{ item.planCode }}{{ item.planName }}
+
差异处理中
+
暂无差异处理中的计划
- - +
- - - - - -
将实盘Excel文件拖到此处,或点击上传
-
仅支持 .xlsx / .xls 格式
-
- -
- - - - - 盘盈 - 盘亏 - 状态不符 - 重量偏差 - - - {{ discForm.enterCoilNo }} - - - {{ discForm.discrepancyDetail }} - - - - - - - - - - - - -
diff --git a/klp-ui/src/views/wms/post/InvCount/index.vue b/klp-ui/src/views/wms/post/InvCount/index.vue index 6b5b3c707..92c589554 100644 --- a/klp-ui/src/views/wms/post/InvCount/index.vue +++ b/klp-ui/src/views/wms/post/InvCount/index.vue @@ -12,7 +12,7 @@ - + @@ -36,7 +36,7 @@
草稿 待审批 - 执行中 + 差异处理中 差异处理中 已归档
@@ -81,7 +81,7 @@ Status / 状态: 草稿 待审批 - 执行中 + 差异处理中 差异处理中 已归档 @@ -106,7 +106,6 @@
提交审批 审批通过,开始盘库 - 核对并生成差异报告 归档封存
@@ -115,270 +114,17 @@
库区盘点明细 · Warehouse Count Details 绑定库区 - 全部生成快照
- -
-
-
- {{ wh.warehouseName || wh.actualWarehouseName || '库区' + (idx+1) }} - {{ wh.systemCoilCount || 0 }}卷 -
-
暂无绑定库区
-
-
-
+ - -
-
-
操作台
-
概览
-
快照
-
差异对比
-
差异明细
-
-
- - -
-
- -
-
-
-
-
生成快照
-
{{ (wh.snapshotCoilLogic || wh.snapshotCoilActual) ? '已生成' : '未生成' }}
-
- 生成 -
-
-
-
-
上传实盘
-
{{ wh.snapshotCoilStats ? '已上传' : '未上传' }}
-
- 上传 -
-
-
-
-
执行对比
-
{{ _diffDone[wh.relId] ? '已完成' : '未对比' }}
-
- 对比 -
-
-
-
-
保存结果
-
对比后可保存
-
- 保存 -
-
- -
-
对比结果摘要
-
-
盘亏:{{ diffMissing.length }}卷
-
盘盈:{{ diffExtra.length }}卷
-
不一致:{{ diffMismatch.length }}卷
-
-
-
-
- - -
- - {{ wh.warehouseName || '-' }} - {{ wh.actualWarehouseName || '-' }} - - 一致 - 不一致 - 未盘点 - - {{ parseTime(wh.ioStartTime, '{y}-{m}-{d} {h}:{i}') || '-' }} - {{ parseTime(wh.ioEndTime, '{y}-{m}-{d} {h}:{i}') || '-' }} - - 查看差异 ({{ (discrepancyMap[wh.relId] || []).length }}) - - {{ wh.systemCoilCount || 0 }} - {{ wh.systemTotalWeight || 0 }} - - 生成快照 - 上传Excel - 移除 - - {{ wh.actualCoilCount || 0 }} - {{ wh.actualTotalWeight || 0 }} - - -
- - -
- - - - 已生成 - 预览 - - 未生成 - - - - 已生成 - 预览 - - 未生成 - - - - 已生成 - 预览 - - 未生成 - - -
- - -
-
-
- - - - - - 重新对比 - - - 重量差异在此阈值内视为相同 -
- - -
-
- - 盘亏(快照有·实盘无) - {{ diffMissing.length }} -
- - - - - - - -
无盘亏卷
-
-
- -
-
- - 盘盈(实盘有·快照无) - {{ diffExtra.length }} -
- - - - - - - -
无盘盈卷
-
-
-
-
-
- - 字段不一致 - {{ diffMismatch.length }} -
- - - - - - - -
无不一致卷
-
-
- 请先生成快照并导入实盘Excel后进行对比 -
-
-
- - -
-
- - - - - - - - - - - - - - - - - - 暂无差异记录 -
-
- -
-
- - -
-
-
- } rawSheetRows - XLSX.utils.sheet_to_json 直接解析的结果 + * @returns {Array} 驼峰字段名数组 + */ +export function parseSnapshotExcel(rawSheetRows) { + return rawSheetRows.map(function(row) { + var newRow = {}; + Object.keys(SNAPSHOT_COL_MAP).forEach(function(zhKey) { + var camelKey = SNAPSHOT_COL_MAP[zhKey]; + if (row[zhKey] !== undefined) newRow[camelKey] = row[zhKey]; + }); + return newRow; + }); +} + +/** + * 将实盘Excel的原始行数据(中文表头)转为标准驼峰字段名对象数组 + * @param {Array} rawSheetRows - XLSX.utils.sheet_to_json 直接解析的结果 + * @returns {Array} 驼峰字段名数组 + */ +export function parsePhysicalExcel(rawSheetRows) { + return rawSheetRows.map(function(row) { + var newRow = {}; + Object.keys(PHYSICAL_HEADER_MAP).forEach(function(zhKey) { + var camelKey = PHYSICAL_HEADER_MAP[zhKey]; + if (row[zhKey] !== undefined) newRow[camelKey] = row[zhKey]; + }); + return newRow; + }); +} + +// ===== 下载函数 ===== + +/** + * 根据ossId从MinIO下载Excel并解析为标准驼峰字段名对象数组 + * @param {string} ossId - OSS文件ID + * @param {Object|null} colMap - 中文表头→驼峰映射表,传 null 则不转换 + * @returns {Promise>} + */ +export async function downloadAndParseExcel(ossId, colMap) { + var ossRes = await listByIds(ossId); + var ossList = ossRes.data || ossRes.rows || []; + if (ossList.length === 0) throw new Error('未找到文件'); + var url = ossList[0].url; + var resp = await fetch(url); + var blob = await resp.blob(); + var arrayBuf = await blob.arrayBuffer(); + var workbook = XLSX.read(new Uint8Array(arrayBuf), { type: 'array' }); + var sheet = workbook.Sheets[workbook.SheetNames[0]]; + var rows = XLSX.utils.sheet_to_json(sheet); + if (colMap) { + rows = rows.map(function(row) { + var newRow = {}; + Object.keys(colMap).forEach(function(zhKey) { + var camelKey = colMap[zhKey]; + if (row[zhKey] !== undefined) newRow[camelKey] = row[zhKey]; + }); + return newRow; + }); + } + return rows; +} + +// ===== 对比函数 ===== + +/** 构建复合键 enterCoilNo|currentCoilNo */ +function makeKey(item) { + return (item.enterCoilNo || '') + '|' + (item.currentCoilNo || ''); +} + +/** + * 对比快照数据与实盘数据,返回四种差异结果 + * @param {Array} snapRows - 快照标准化数据 + * @param {Array} physicalRows - 实盘标准化数据 + * @param {number} weightThreshold - 重量差异阈值(kg) + * @returns {{ missing: Array, extra: Array, mismatch: Array, weightSimilar: Array }} + */ +export function compareCoils(snapRows, physicalRows, weightThreshold) { + var snapMap = {}; + snapRows.forEach(function(item) { + var key = makeKey(item); + if (key !== '||') snapMap[key] = item; + }); + var physicalMap = {}; + physicalRows.forEach(function(item) { + var key = makeKey(item); + if (key !== '||') physicalMap[key] = item; + }); + + var result = { missing: [], extra: [], mismatch: [], weightSimilar: [] }; + + // 盘亏:快照有、实盘无 + Object.keys(snapMap).forEach(function(key) { + if (!physicalMap[key]) result.missing.push(snapMap[key]); + }); + // 盘盈:实盘有、快照无 + Object.keys(physicalMap).forEach(function(key) { + if (!snapMap[key]) result.extra.push(physicalMap[key]); + }); + // 字段不一致 & 重量不同 + Object.keys(snapMap).forEach(function(key) { + var snapItem = snapMap[key]; + var physItem = physicalMap[key]; + if (!snapItem || !physItem) return; + var realDiffs = []; + var weightDiffs = []; + COMPARE_FIELDS.forEach(function(f) { + var snapVal = snapItem[f.snapshotField]; + var physVal = physItem[f.physicalField]; + if (f.isNumber) { + var sn = Number(snapVal) || 0; + var pn = Number(physVal) || 0; + var absDiff = Math.abs(sn - pn); + if (absDiff > 0 && absDiff <= weightThreshold && f.label.indexOf('重量') >= 0) { + weightDiffs.push({ label: f.label, snapshotValue: snapVal, physicalValue: physVal }); + } else if (absDiff > weightThreshold) { + realDiffs.push({ label: f.label, snapshotValue: snapVal, physicalValue: physVal }); + } + } else { + if (String(snapVal || '').trim() !== String(physVal || '').trim()) { + realDiffs.push({ label: f.label, snapshotValue: snapVal, physicalValue: physVal }); + } + } + }); + if (weightDiffs.length > 0) { + result.weightSimilar.push({ + enterCoilNo: snapItem.enterCoilNo || physItem.enterCoilNo, + currentCoilNo: snapItem.currentCoilNo || physItem.currentCoilNo, + diffs: weightDiffs + }); + } + if (realDiffs.length > 0) { + result.mismatch.push({ + enterCoilNo: snapItem.enterCoilNo || physItem.enterCoilNo, + currentCoilNo: snapItem.currentCoilNo || physItem.currentCoilNo, + diffs: realDiffs + }); + } + }); + + return result; +} diff --git a/klp-ui/src/views/wms/post/flow.vue b/klp-ui/src/views/wms/post/flow.vue index 38d2125dd..3498884b8 100644 --- a/klp-ui/src/views/wms/post/flow.vue +++ b/klp-ui/src/views/wms/post/flow.vue @@ -13,6 +13,19 @@ +
+ + + 下载流程图 + + + + 下载 SVG + 下载 PNG + + +
+
@@ -110,80 +123,105 @@ graph TD inventoryCheck: ` graph TD - A["创建盘库单
填写盘库单基本信息
添加盘库计划"]:::c1 + A["创建盘库计划
填写基本信息"]:::c1 - A --> B["盘库计划
设定起止时间
选择库区类型"]:::c2 - B --> C{"库区类型?"}:::cdec + A --> B["创建计划明细
可创建多个明细"]:::c2 - C -->|逻辑库| D["获取库存快照
记录当前时间节点
库存情况"]:::c3 - C -->|物理库| E["获取库存快照
记录当前时间节点
库存情况"]:::c3 - E --> F["记录吞吐记录
额外记录物理库
出入库流水明细"]:::c4 + B --> C["选择库区
逻辑库 / 实际库
至少选一个"]:::c3 + C --> D["生成系统库存快照"]:::c4 + D --> E["上传实盘库存Excel"]:::c5 + E --> F["执行对比
快照 vs 实盘
自动计算差异"]:::c6 - D --> G["人工实地盘库
按盘库计划执行
录入实际库存数据"]:::c5 - F --> G + F --> G["查看差异明细
保存差异并填写处理方式"]:::c7 + G --> H["提交送审"]:::c8 - G --> H["系统自动对照
快照库存 vs 实际库存
逐项比对查找差异"]:::c6 + H --> I{"审批"}:::dec + I -->|不通过| J["退回修改"]:::c7 + J --> G + I -->|通过| K["开始处理差异
逐项执行处理方式"]:::c9 - H --> I["盘亏明细
系统有 实际无
库存缺失项"]:::loss - H --> J["盘盈明细
实际有 系统无
库存多出项"]:::gain - H --> K["明细差异
数据不一致
数量/规格偏差"]:::diff - - I --> L["生成盘库差异报告
汇总盘亏/盘盈/差异
存储差异记录"]:::c7 - J --> L - K --> L - - L --> M(["盘库单封存
流程结束"]):::cend + K --> L{"所有差异
处理完成?"}:::dec + L -->|否| K + L -->|是| M(["完结流程
盘库结束"]):::cend classDef c1 fill:#409eff,stroke:#337ecc,color:#fff,stroke-width:2px classDef c2 fill:#e6fffa,stroke:#13c2c2,color:#303133,stroke-width:2px - classDef cdec fill:#f9f0ff,stroke:#722ed1,color:#303133,stroke-width:2px - classDef c3 fill:#f0f5ff,stroke:#597ef7,color:#303133,stroke-width:2px - classDef c4 fill:#fff7e6,stroke:#fa8c16,color:#303133,stroke-width:2px + classDef c3 fill:#fff7e6,stroke:#fa8c16,color:#303133,stroke-width:2px + classDef c4 fill:#f0f5ff,stroke:#597ef7,color:#303133,stroke-width:2px classDef c5 fill:#e6f7ff,stroke:#1890ff,color:#303133,stroke-width:2px - classDef c6 fill:#fffbe6,stroke:#fadb14,color:#303133,stroke-width:2px - classDef loss fill:#fff1f0,stroke:#f5222d,color:#303133,stroke-width:2px - classDef gain fill:#f6ffed,stroke:#52c41a,color:#303133,stroke-width:2px - classDef diff fill:#fff0f6,stroke:#eb2f96,color:#303133,stroke-width:2px + classDef c6 fill:#fffbe6,stroke:#fadb14,color:#606266,stroke-width:2px classDef c7 fill:#f0f5ff,stroke:#597ef7,color:#303133,stroke-width:2px + classDef c8 fill:#fff0f6,stroke:#eb2f96,color:#303133,stroke-width:2px + classDef c9 fill:#f6ffed,stroke:#52c41a,color:#303133,stroke-width:2px + classDef dec fill:#f9f0ff,stroke:#722ed1,color:#303133,stroke-width:2px classDef cend fill:#dcf7e8,stroke:#52c41a,color:#303133,stroke-width:2px,rx:10,ry:10 linkStyle default stroke:#bfbfbf,stroke-width:2px `, productionSchedule: ` -stateDiagram-v2 - [*] --> 创建排产单: 填写基本信息 - 创建排产单 --> 关联合同获取需求: 选择合同 - 关联合同获取需求 --> 选择需求合并明细: 选取需求
合并相同条目 - 选择需求合并明细 --> 提交审批 +graph TD + A["创建需求单
填写基本信息"]:::p1 - 提交审批 --> 审批驳回: 审批不通过 - 提交审批 --> 审批通过: 审批通过 + A --> B["选择合同
可选一个或多个合同"]:::p2 + B --> C["自动获取需求明细
从所选合同提取"]:::p3 + C --> D["调整需求明细
可编辑/修改/补充"]:::p4 - 审批驳回 --> 选择需求合并明细: 退回修改后重新提交 + D --> E["提交审批"]:::p5 + E --> F{"审批"}:::dec + F -->|不通过| G["退回修改"]:::p4 + G --> D + F -->|通过| H["转化为排产单"]:::p6 - 审批通过 --> 车间接收执行单: 转为执行单推送车间 + H --> I["排产单
可再次编辑"]:::p7 + I --> J["再次提交审批"]:::p5 + J --> K{"审批"}:::dec + K -->|不通过| L["退回修改"]:::p7 + L --> I + K -->|通过| M["提交给车间"]:::p8 - 车间接收执行单 --> 执行生产: 车间接收 - 车间接收执行单 --> 审批驳回: 车间打回拒绝 + M --> N["车间绑定钢卷
每个排产计划
绑定一个或多个钢卷"]:::p9 + N --> O["执行生产"]:::p10 + O --> P(["排产完结"]):::pend - 执行生产 --> [*]: 排产完结 + classDef p1 fill:#409eff,stroke:#337ecc,color:#fff,stroke-width:2px + classDef p2 fill:#e6fffa,stroke:#13c2c2,color:#303133,stroke-width:2px + classDef p3 fill:#fff7e6,stroke:#fa8c16,color:#303133,stroke-width:2px + classDef p4 fill:#f0f5ff,stroke:#597ef7,color:#303133,stroke-width:2px + classDef p5 fill:#e6f7ff,stroke:#1890ff,color:#303133,stroke-width:2px + classDef p6 fill:#fffbe6,stroke:#fadb14,color:#606266,stroke-width:2px + classDef p7 fill:#fff0f6,stroke:#eb2f96,color:#303133,stroke-width:2px + classDef p8 fill:#f6ffed,stroke:#52c41a,color:#303133,stroke-width:2px + classDef p9 fill:#f0f5ff,stroke:#597ef7,color:#303133,stroke-width:2px + classDef p10 fill:#fffbe6,stroke:#fadb14,color:#303133,stroke-width:2px + classDef dec fill:#f9f0ff,stroke:#722ed1,color:#303133,stroke-width:2px + classDef pend fill:#dcf7e8,stroke:#52c41a,color:#303133,stroke-width:2px,rx:10,ry:10 + linkStyle default stroke:#bfbfbf,stroke-width:2px `, equipmentRepair: ` -stateDiagram-v2 - [*] --> 创建维修计划: 点选异常巡检记录
绑定记录与异常设备 - 创建维修计划 --> 审批维修计划 +graph TD + A["创建维修计划"]:::e1 + A1["点选异常巡检记录
绑定记录与异常设备"]:::e1sub + A --> A1 - 审批维修计划 --> 审批驳回: 审批不通过 - 审批维修计划 --> 审批通过: 审批通过 + A1 --> B["提交审批"]:::e2 + B --> C{"审批"}:::edec + C -->|不通过| D["退回修改"]:::e1 + D --> A1 + C -->|通过| E["逐设备维修记录
逐一执行设备维修
记录维修过程与结果"]:::e3 - 审批驳回 --> 创建维修计划: 退回修改后重新提交 + E --> F{"全部设备
维修完成?"}:::edec + F -->|否| E + F -->|是| G(["流程结束"]):::eend - 审批通过 --> 逐设备维修记录: 逐一执行设备维修
记录维修过程与结果 - - 逐设备维修记录 --> 逐设备维修记录: 存在未维修设备 - 逐设备维修记录 --> [*]: 全部设备维修完成
流程结束 -` + classDef e1 fill:#e6fffa,stroke:#13c2c2,color:#303133,stroke-width:2px + classDef e1sub fill:#e6fffa,stroke:#13c2c2,color:#606266,stroke-width:1px,stroke-dasharray:3 3 + classDef e2 fill:#409eff,stroke:#337ecc,color:#fff,stroke-width:2px + classDef e3 fill:#f0f5ff,stroke:#597ef7,color:#303133,stroke-width:2px + classDef edec fill:#f9f0ff,stroke:#722ed1,color:#303133,stroke-width:2px + classDef eend fill:#dcf7e8,stroke:#52c41a,color:#303133,stroke-width:2px,rx:10,ry:10 + linkStyle default stroke:#bfbfbf,stroke-width:2px +`, } export default { @@ -201,6 +239,7 @@ export default { ], svgCache: {}, selectedNode: null, + downloadLoading: false, } }, watch: { @@ -226,6 +265,76 @@ export default { }, }, methods: { + handleDownload(format) { + if (format === 'svg') { + this.downloadSvg() + } else if (format === 'png') { + this.downloadPng() + } + }, + downloadSvg() { + const svgEl = this.$refs.diagram?.querySelector('svg') + if (!svgEl) { + this.$message.warning('流程图尚未渲染完成') + return + } + const clone = svgEl.cloneNode(true) + const serializer = new XMLSerializer() + const source = serializer.serializeToString(clone) + const blob = new Blob([source], { type: 'image/svg+xml;charset=utf-8' }) + this.triggerDownload(URL.createObjectURL(blob), `${this.activeTab}.svg`) + this.$message.success('SVG 已下载') + }, + downloadPng() { + const svgEl = this.$refs.diagram?.querySelector('svg') + if (!svgEl) { + this.$message.warning('流程图尚未渲染完成') + return + } + this.downloadLoading = true + + const clone = svgEl.cloneNode(true) + const serializer = new XMLSerializer() + let source = serializer.serializeToString(clone) + source = source.replace(/<\/?foreignObject[^>]*>/gi, '').replace(/<\/?style[^>]*>/gi, '') + + const svgBlob = new Blob([source], { type: 'image/svg+xml;charset=utf-8' }) + const url = URL.createObjectURL(svgBlob) + + const img = new Image() + img.onload = () => { + const canvas = document.createElement('canvas') + const rect = svgEl.getBoundingClientRect() + const scale = 2 + canvas.width = rect.width * scale + canvas.height = rect.height * scale + const ctx = canvas.getContext('2d') + ctx.scale(scale, scale) + ctx.drawImage(img, 0, 0, rect.width, rect.height) + URL.revokeObjectURL(url) + canvas.toBlob(blob => { + this.downloadLoading = false + if (blob) { + this.triggerDownload(URL.createObjectURL(blob), `${this.activeTab}.png`) + this.$message.success('PNG 已下载') + } + }, 'image/png') + } + img.onerror = () => { + this.downloadLoading = false + this.$message.error('PNG 导出失败') + } + img.src = url + }, + triggerDownload(url, filename) { + const a = document.createElement('a') + a.href = url + a.download = filename + document.body.appendChild(a) + a.click() + document.body.removeChild(a) + URL.revokeObjectURL(url) + }, switchTab(key) { this.activeTab = key this.selectedNode = null @@ -331,4 +440,12 @@ export default { .flow-diagram :deep(svg g:hover) { opacity: 0.8; } + +.flow-toolbar { + display: flex; + justify-content: flex-end; + padding: 6px 12px; + background: #fafafa; + border-bottom: 1px solid #e8e8e8; +} From 7e028da213f9c826b9f3f7a96cf8431ac0e080b5 Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Fri, 26 Jun 2026 16:33:29 +0800 Subject: [PATCH 16/24] =?UTF-8?q?feat(schProdScheduleItem):=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E6=89=B9=E9=87=8F=E6=96=B0=E5=A2=9E=E6=8E=92=E4=BA=A7?= =?UTF-8?q?=E5=8D=95=E4=B8=BB=E5=8A=A0=E6=98=8E=E7=BB=86=E5=8F=AF=E5=90=88?= =?UTF-8?q?=E5=B9=B6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在服务接口中新增insertBatchByBo方法定义 - 在控制器中添加批量新增API端点/batch - 实现服务层批量插入逻辑,支持多条记录同时插入 - 集成日志记录和重复提交防护机制 - 实现批量插入后的ID回填功能 --- .../SchProdScheduleItemController.java | 10 +++++++++ .../service/ISchProdScheduleItemService.java | 5 +++++ .../impl/SchProdScheduleItemServiceImpl.java | 21 +++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/klp-flow/src/main/java/com/klp/flow/controller/SchProdScheduleItemController.java b/klp-flow/src/main/java/com/klp/flow/controller/SchProdScheduleItemController.java index 0527e52bb..9ddc6a593 100644 --- a/klp-flow/src/main/java/com/klp/flow/controller/SchProdScheduleItemController.java +++ b/klp-flow/src/main/java/com/klp/flow/controller/SchProdScheduleItemController.java @@ -75,6 +75,16 @@ public class SchProdScheduleItemController extends BaseController { return toAjax(iSchProdScheduleItemService.insertByBo(bo)); } + /** + * 批量新增排产单主加明细可合并 + */ + @Log(title = "排产单主加明细可合并", businessType = BusinessType.INSERT) + @RepeatSubmit() + @PostMapping("/batch") + public R addBatch(@Validated(AddGroup.class) @RequestBody List boList) { + return toAjax(iSchProdScheduleItemService.insertBatchByBo(boList)); + } + /** * 修改排产单主加明细可合并 */ diff --git a/klp-flow/src/main/java/com/klp/flow/service/ISchProdScheduleItemService.java b/klp-flow/src/main/java/com/klp/flow/service/ISchProdScheduleItemService.java index 7b187e200..8c43ff478 100644 --- a/klp-flow/src/main/java/com/klp/flow/service/ISchProdScheduleItemService.java +++ b/klp-flow/src/main/java/com/klp/flow/service/ISchProdScheduleItemService.java @@ -42,6 +42,11 @@ public interface ISchProdScheduleItemService { */ Boolean updateByBo(SchProdScheduleItemBo bo); + /** + * 批量新增排产单主加明细可合并 + */ + Boolean insertBatchByBo(List boList); + /** * 校验并批量删除排产单主加明细可合并信息 */ diff --git a/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleItemServiceImpl.java b/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleItemServiceImpl.java index 2eb5bc6c3..457835729 100644 --- a/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleItemServiceImpl.java +++ b/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleItemServiceImpl.java @@ -15,6 +15,7 @@ import com.klp.flow.domain.SchProdScheduleItem; import com.klp.flow.mapper.SchProdScheduleItemMapper; import com.klp.flow.service.ISchProdScheduleItemService; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Collection; @@ -110,6 +111,26 @@ public class SchProdScheduleItemServiceImpl implements ISchProdScheduleItemServi return flag; } + /** + * 批量新增排产单主加明细可合并 + */ + @Override + public Boolean insertBatchByBo(List boList) { + List addList = new ArrayList<>(boList.size()); + for (SchProdScheduleItemBo bo : boList) { + SchProdScheduleItem add = BeanUtil.toBean(bo, SchProdScheduleItem.class); + validEntityBeforeSave(add); + addList.add(add); + } + boolean flag = baseMapper.insertBatch(addList); + if (flag) { + for (int i = 0; i < boList.size(); i++) { + boList.get(i).setScheduleId(addList.get(i).getScheduleId()); + } + } + return flag; + } + /** * 修改排产单主加明细可合并 */ From 5f523158c1d39c1daa55b6816ff383dde6d0f47b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A0=82=E7=B3=96?= <2178503051@qq.com> Date: Fri, 26 Jun 2026 17:46:54 +0800 Subject: [PATCH 17/24] =?UTF-8?q?feat(wms/coil/label):=20=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E6=8B=89=E7=9F=AB=E5=92=8C=E5=8F=8C=E6=9C=BA=E6=9E=B6?= =?UTF-8?q?=E5=8E=9F=E6=96=99=E6=A0=87=E7=AD=BE=E6=89=93=E5=8D=B0=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增LajiaoRawTag和ShuangRawTag两个原料标签组件,分别适配拉矫卷和双机架原料卷的打印需求,同时根据仓库ID自动匹配对应的标签类型,完善原料标签的适配场景。 --- .../coil/panels/LabelRender/LajiaoRawTag.vue | 325 ++++++++++++++++++ .../coil/panels/LabelRender/ShuangRawTag.vue | 325 ++++++++++++++++++ .../wms/coil/panels/LabelRender/index.vue | 33 ++ 3 files changed, 683 insertions(+) create mode 100644 klp-ui/src/views/wms/coil/panels/LabelRender/LajiaoRawTag.vue create mode 100644 klp-ui/src/views/wms/coil/panels/LabelRender/ShuangRawTag.vue diff --git a/klp-ui/src/views/wms/coil/panels/LabelRender/LajiaoRawTag.vue b/klp-ui/src/views/wms/coil/panels/LabelRender/LajiaoRawTag.vue new file mode 100644 index 000000000..dc49669ba --- /dev/null +++ b/klp-ui/src/views/wms/coil/panels/LabelRender/LajiaoRawTag.vue @@ -0,0 +1,325 @@ + + + + + \ No newline at end of file diff --git a/klp-ui/src/views/wms/coil/panels/LabelRender/ShuangRawTag.vue b/klp-ui/src/views/wms/coil/panels/LabelRender/ShuangRawTag.vue new file mode 100644 index 000000000..7497d6985 --- /dev/null +++ b/klp-ui/src/views/wms/coil/panels/LabelRender/ShuangRawTag.vue @@ -0,0 +1,325 @@ + + + + + \ No newline at end of file diff --git a/klp-ui/src/views/wms/coil/panels/LabelRender/index.vue b/klp-ui/src/views/wms/coil/panels/LabelRender/index.vue index ee2917c12..2fd4c6177 100644 --- a/klp-ui/src/views/wms/coil/panels/LabelRender/index.vue +++ b/klp-ui/src/views/wms/coil/panels/LabelRender/index.vue @@ -56,6 +56,18 @@ :paperWidthMm="180" :paperHeightMm="100" /> + +
下载标签图片 @@ -80,6 +92,9 @@ import DuGeTag from './DuGeTag.vue'; import TuoZhiTag from './TuoZhiTag.vue'; import SplitTag from './SplitTag.vue'; import TuiHuoRawTag from './TuiHuoRawTag.vue'; +import LajiaoRawTag from './LajiaoRawTag.vue'; +import ShuangRawTag from './ShuangRawTag.vue'; + export default { name: 'LabelRender', @@ -93,6 +108,8 @@ export default { TuoZhiTag, SplitTag, TuiHuoRawTag, + LajiaoRawTag, + ShuangRawTag, }, data() { return { @@ -134,6 +151,14 @@ export default { 'tuihuo-raw': { width: 180, height: 100, + }, + 'lajiao-raw': { + width: 100, + height: 80, + }, + 'shuang-raw': { + width: 100, + height: 80, } }, loading: false, @@ -193,6 +218,14 @@ export default { else if (itemType == 'raw_material' && (warehouseId == '1988150648993148929' || warehouseId == '1988150750390448129')) { this.labelType = 'tuihuo-raw'; } + // 拉矫卷使用拉矫原料标签 + else if (itemType == 'raw_material' && warehouseId == '1988150854442741762') { + this.labelType = 'lajiao-raw'; + } + // 双机架原料卷使用双机架原料标签 + else if (itemType == 'raw_material' && warehouseId == '1992873386047643650') { + this.labelType = 'shuang-raw'; + } // 否则使用普通的原料标签 else if (itemType == 'raw_material') { this.labelType = '2'; From aefee3debbf91862e72fcfc3467d58c44d053e8a Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Fri, 26 Jun 2026 17:49:26 +0800 Subject: [PATCH 18/24] =?UTF-8?q?feat(schProdScheduleItem):=20=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0=E6=8E=92=E4=BA=A7=E5=8D=95=E4=B8=BB=E5=8A=A0=E6=98=8E?= =?UTF-8?q?=E7=BB=86=E5=90=88=E5=B9=B6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 SchProdScheduleItemMergeBo 合并请求对象 - 在 ISchProdScheduleItemService 中添加 mergeByBo 方法定义 - 在 SchProdScheduleItemController 中添加 merge 接口 - 在 SchProdScheduleItemServiceImpl 中实现合并逻辑 - 支持先删除被合并记录再插入合并后新记录的功能 - 使用事务确保合并操作的数据一致性 --- .../SchProdScheduleItemController.java | 11 +++++++ .../domain/bo/SchProdScheduleItemMergeBo.java | 29 +++++++++++++++++++ .../service/ISchProdScheduleItemService.java | 6 ++++ .../impl/SchProdScheduleItemServiceImpl.java | 21 ++++++++++++++ 4 files changed, 67 insertions(+) create mode 100644 klp-flow/src/main/java/com/klp/flow/domain/bo/SchProdScheduleItemMergeBo.java diff --git a/klp-flow/src/main/java/com/klp/flow/controller/SchProdScheduleItemController.java b/klp-flow/src/main/java/com/klp/flow/controller/SchProdScheduleItemController.java index 9ddc6a593..4ea667bf7 100644 --- a/klp-flow/src/main/java/com/klp/flow/controller/SchProdScheduleItemController.java +++ b/klp-flow/src/main/java/com/klp/flow/controller/SchProdScheduleItemController.java @@ -19,6 +19,7 @@ import com.klp.common.enums.BusinessType; import com.klp.common.utils.poi.ExcelUtil; import com.klp.flow.domain.vo.SchProdScheduleItemVo; import com.klp.flow.domain.bo.SchProdScheduleItemBo; +import com.klp.flow.domain.bo.SchProdScheduleItemMergeBo; import com.klp.flow.service.ISchProdScheduleItemService; import com.klp.common.core.page.TableDataInfo; @@ -106,4 +107,14 @@ public class SchProdScheduleItemController extends BaseController { @PathVariable Long[] scheduleIds) { return toAjax(iSchProdScheduleItemService.deleteWithValidByIds(Arrays.asList(scheduleIds), true)); } + + /** + * 合并排产单主加明细可合并:先删除被合并的记录,再插入合并后的新记录 + */ + @Log(title = "排产单主加明细可合并", businessType = BusinessType.UPDATE) + @RepeatSubmit() + @PostMapping("/merge") + public R merge(@Validated @RequestBody SchProdScheduleItemMergeBo mergeBo) { + return toAjax(iSchProdScheduleItemService.mergeByBo(mergeBo)); + } } diff --git a/klp-flow/src/main/java/com/klp/flow/domain/bo/SchProdScheduleItemMergeBo.java b/klp-flow/src/main/java/com/klp/flow/domain/bo/SchProdScheduleItemMergeBo.java new file mode 100644 index 000000000..13979c275 --- /dev/null +++ b/klp-flow/src/main/java/com/klp/flow/domain/bo/SchProdScheduleItemMergeBo.java @@ -0,0 +1,29 @@ +package com.klp.flow.domain.bo; + +import lombok.Data; +import javax.validation.Valid; +import javax.validation.constraints.NotEmpty; +import java.util.List; + +/** + * 排产单主加明细可合并 - 合并请求对象 + * + * @author klp + * @date 2026-06-26 + */ +@Data +public class SchProdScheduleItemMergeBo { + + /** + * 需要被合并删除的记录ID列表 + */ + @NotEmpty(message = "被合并记录ID不能为空") + private List ids; + + /** + * 合并后的新记录 + */ + @Valid + private SchProdScheduleItemBo mergedBo; + +} diff --git a/klp-flow/src/main/java/com/klp/flow/service/ISchProdScheduleItemService.java b/klp-flow/src/main/java/com/klp/flow/service/ISchProdScheduleItemService.java index 8c43ff478..cef5243bf 100644 --- a/klp-flow/src/main/java/com/klp/flow/service/ISchProdScheduleItemService.java +++ b/klp-flow/src/main/java/com/klp/flow/service/ISchProdScheduleItemService.java @@ -3,6 +3,7 @@ package com.klp.flow.service; import com.klp.flow.domain.SchProdScheduleItem; import com.klp.flow.domain.vo.SchProdScheduleItemVo; import com.klp.flow.domain.bo.SchProdScheduleItemBo; +import com.klp.flow.domain.bo.SchProdScheduleItemMergeBo; import com.klp.common.core.page.TableDataInfo; import com.klp.common.core.domain.PageQuery; @@ -51,4 +52,9 @@ public interface ISchProdScheduleItemService { * 校验并批量删除排产单主加明细可合并信息 */ Boolean deleteWithValidByIds(Collection ids, Boolean isValid); + + /** + * 合并多条排产单主加明细可合并记录:先删除被合并的记录,再插入合并后的新记录 + */ + Boolean mergeByBo(SchProdScheduleItemMergeBo mergeBo); } diff --git a/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleItemServiceImpl.java b/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleItemServiceImpl.java index 457835729..1359cf513 100644 --- a/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleItemServiceImpl.java +++ b/klp-flow/src/main/java/com/klp/flow/service/impl/SchProdScheduleItemServiceImpl.java @@ -10,10 +10,12 @@ import com.klp.common.utils.StringUtils; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import com.klp.flow.domain.bo.SchProdScheduleItemBo; +import com.klp.flow.domain.bo.SchProdScheduleItemMergeBo; import com.klp.flow.domain.vo.SchProdScheduleItemVo; import com.klp.flow.domain.SchProdScheduleItem; import com.klp.flow.mapper.SchProdScheduleItemMapper; import com.klp.flow.service.ISchProdScheduleItemService; +import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.List; @@ -158,4 +160,23 @@ public class SchProdScheduleItemServiceImpl implements ISchProdScheduleItemServi } return baseMapper.deleteBatchIds(ids) > 0; } + + /** + * 合并多条排产单主加明细可合并记录:先删除被合并的记录,再插入合并后的新记录 + */ + @Override + @Transactional(rollbackFor = Exception.class) + public Boolean mergeByBo(SchProdScheduleItemMergeBo mergeBo) { + // 先删除被合并的记录 + baseMapper.deleteBatchIds(mergeBo.getIds()); + // 再插入合并后的新记录 + SchProdScheduleItemBo mergedBo = mergeBo.getMergedBo(); + SchProdScheduleItem add = BeanUtil.toBean(mergedBo, SchProdScheduleItem.class); + validEntityBeforeSave(add); + boolean flag = baseMapper.insert(add) > 0; + if (flag) { + mergedBo.setScheduleId(add.getScheduleId()); + } + return flag; + } } From c29f074eaed6ca55239b959f3084c69b5b3f74fc Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Sat, 27 Jun 2026 10:33:28 +0800 Subject: [PATCH 19/24] =?UTF-8?q?feat(menu):=20=E6=B7=BB=E5=8A=A0=E8=8F=9C?= =?UTF-8?q?=E5=8D=95=E6=A0=B7=E5=BC=8F=E5=B1=9E=E6=80=A7=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 SysMenu 实体类中新增 style 字段用于存储菜单样式 - 在 MetaVo 类中添加 style 属性以传递样式信息 - 更新 SysMenuMapper.xml 映射文件中的字段映射和查询语句 - 修改 SysMenuServiceImpl 中的路由构建逻辑以设置菜单样式 - 为不同类型的菜单路由节点添加样式属性的赋值处理 --- .../klp/common/core/domain/entity/SysMenu.java | 5 +++++ .../java/com/klp/system/domain/vo/MetaVo.java | 5 +++++ .../system/service/impl/SysMenuServiceImpl.java | 16 ++++++++++++---- .../resources/mapper/system/SysMenuMapper.xml | 4 +++- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/klp-common/src/main/java/com/klp/common/core/domain/entity/SysMenu.java b/klp-common/src/main/java/com/klp/common/core/domain/entity/SysMenu.java index c72ad5b4a..c214dc446 100644 --- a/klp-common/src/main/java/com/klp/common/core/domain/entity/SysMenu.java +++ b/klp-common/src/main/java/com/klp/common/core/domain/entity/SysMenu.java @@ -96,6 +96,11 @@ public class SysMenu extends TreeEntity { */ private String icon; + /** + * 样式 + */ + private String style; + /** * 备注 */ diff --git a/klp-system/src/main/java/com/klp/system/domain/vo/MetaVo.java b/klp-system/src/main/java/com/klp/system/domain/vo/MetaVo.java index 6309c3517..4b9056d9b 100644 --- a/klp-system/src/main/java/com/klp/system/domain/vo/MetaVo.java +++ b/klp-system/src/main/java/com/klp/system/domain/vo/MetaVo.java @@ -32,6 +32,11 @@ public class MetaVo { */ private String link; + /** + * 菜单样式 + */ + private String style; + public MetaVo(String title, String icon) { this.title = title; this.icon = icon; diff --git a/klp-system/src/main/java/com/klp/system/service/impl/SysMenuServiceImpl.java b/klp-system/src/main/java/com/klp/system/service/impl/SysMenuServiceImpl.java index 889849b2b..acc1e8480 100644 --- a/klp-system/src/main/java/com/klp/system/service/impl/SysMenuServiceImpl.java +++ b/klp-system/src/main/java/com/klp/system/service/impl/SysMenuServiceImpl.java @@ -161,7 +161,9 @@ public class SysMenuServiceImpl implements ISysMenuService { router.setPath(getRouterPath(menu)); router.setComponent(getComponent(menu)); router.setQuery(menu.getQueryParam()); - router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath())); + MetaVo metaVo = new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath()); + metaVo.setStyle(menu.getStyle()); + router.setMeta(metaVo); List cMenus = menu.getChildren(); if (CollUtil.isNotEmpty(cMenus) && UserConstants.TYPE_DIR.equals(menu.getMenuType())) { router.setAlwaysShow(true); @@ -174,12 +176,16 @@ public class SysMenuServiceImpl implements ISysMenuService { children.setPath(menu.getPath()); children.setComponent(menu.getComponent()); children.setName(StringUtils.capitalize(menu.getPath())); - children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath())); + MetaVo childrenMetaVo = new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath()); + childrenMetaVo.setStyle(menu.getStyle()); + children.setMeta(childrenMetaVo); children.setQuery(menu.getQueryParam()); childrenList.add(children); router.setChildren(childrenList); } else if (menu.getParentId().intValue() == 0 && isInnerLink(menu)) { - router.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon())); + MetaVo innerMetaVo = new MetaVo(menu.getMenuName(), menu.getIcon()); + innerMetaVo.setStyle(menu.getStyle()); + router.setMeta(innerMetaVo); router.setPath("/"); List childrenList = new ArrayList<>(); RouterVo children = new RouterVo(); @@ -187,7 +193,9 @@ public class SysMenuServiceImpl implements ISysMenuService { children.setPath(routerPath); children.setComponent(UserConstants.INNER_LINK); children.setName(StringUtils.capitalize(routerPath)); - children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), menu.getPath())); + MetaVo innerChildrenMetaVo = new MetaVo(menu.getMenuName(), menu.getIcon(), menu.getPath()); + innerChildrenMetaVo.setStyle(menu.getStyle()); + children.setMeta(innerChildrenMetaVo); childrenList.add(children); router.setChildren(childrenList); } diff --git a/klp-system/src/main/resources/mapper/system/SysMenuMapper.xml b/klp-system/src/main/resources/mapper/system/SysMenuMapper.xml index 33ec17b8a..9bebaee34 100644 --- a/klp-system/src/main/resources/mapper/system/SysMenuMapper.xml +++ b/klp-system/src/main/resources/mapper/system/SysMenuMapper.xml @@ -20,6 +20,7 @@ + @@ -29,7 +30,7 @@