From d3feb61e62f1abc15f6eb952d0d8f43bc425a6b0 Mon Sep 17 00:00:00 2001 From: liyongde <1419499670@qq.com> Date: Tue, 18 Aug 2026 13:57:14 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=AD=90=E5=8D=B7=E5=8C=85=E8=A3=85?= =?UTF-8?q?=E5=85=B3=E7=B3=BB=E6=96=B0=E5=A2=9E=E5=88=A4=E6=96=ADerp?= =?UTF-8?q?=E5=8D=B7=E5=8F=B7=E6=98=AF=E5=90=A6=E5=AD=98=E5=9C=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...ub-package-relation-card-batch-design.html | 85 ++++++++++ ...8-18-pda-bind-package-relation-design.html | 50 ++++++ .../SlittingproductionplanMapper.java | 7 + .../SubPackageRelationServiceImpl.java | 35 ++++ .../subpackagerelation/modules/batch-form.vue | 156 ++++++++++-------- 5 files changed, 260 insertions(+), 73 deletions(-) create mode 100644 docs/prototype_design/design/2026-08-17-sub-package-relation-card-batch-design.html create mode 100644 docs/prototype_design/design/2026-08-18-pda-bind-package-relation-design.html diff --git a/docs/prototype_design/design/2026-08-17-sub-package-relation-card-batch-design.html b/docs/prototype_design/design/2026-08-17-sub-package-relation-card-batch-design.html new file mode 100644 index 00000000..d65c6a41 --- /dev/null +++ b/docs/prototype_design/design/2026-08-17-sub-package-relation-card-batch-design.html @@ -0,0 +1,85 @@ + + + + + + 批量新增子卷包装关系 · 卡片式方案 + + + +
消息管理员
首页 / 物流管理 / 子卷包装关系
子卷包装关系列表
木箱唯一码木箱类型尺寸(mm)子卷号入库日期状态
BXSN-260817-001BX-A1200 × 1000 × 900JR-260817-012026-08-17已入库
BXSN-260817-002BX-B1100 × 900 × 850JR-260817-022026-08-17已包装
+ +
+ + + + + + diff --git a/docs/prototype_design/design/2026-08-18-pda-bind-package-relation-design.html b/docs/prototype_design/design/2026-08-18-pda-bind-package-relation-design.html new file mode 100644 index 00000000..76f62b3a --- /dev/null +++ b/docs/prototype_design/design/2026-08-18-pda-bind-package-relation-design.html @@ -0,0 +1,50 @@ + + + + + + 绑定包装关系 - PDA 原型 + + + +

绑定包装关系

2
待绑定记录逐条录入后批量提交

木箱信息通过搜索弹窗选择,尺寸自动带出

+ + + +
+
+ + + diff --git a/nl-module-lms/nl-module-lms-server/src/main/java/cn/code/nl/module/lms/dal/mysql/slittingproductionplan/SlittingproductionplanMapper.java b/nl-module-lms/nl-module-lms-server/src/main/java/cn/code/nl/module/lms/dal/mysql/slittingproductionplan/SlittingproductionplanMapper.java index b3c92aa5..8ccd00e8 100644 --- a/nl-module-lms/nl-module-lms-server/src/main/java/cn/code/nl/module/lms/dal/mysql/slittingproductionplan/SlittingproductionplanMapper.java +++ b/nl-module-lms/nl-module-lms-server/src/main/java/cn/code/nl/module/lms/dal/mysql/slittingproductionplan/SlittingproductionplanMapper.java @@ -31,5 +31,12 @@ public interface SlittingproductionplanMapper extends BaseMapperX selectListByExtContainerNames(Collection extContainerNames) { + return selectList(SlittingproductionplanDO::getExtContainerName, extContainerNames); + } + } diff --git a/nl-module-lms/nl-module-lms-server/src/main/java/cn/code/nl/module/lms/service/subpackagerelation/SubPackageRelationServiceImpl.java b/nl-module-lms/nl-module-lms-server/src/main/java/cn/code/nl/module/lms/service/subpackagerelation/SubPackageRelationServiceImpl.java index 5daa928a..a9265299 100644 --- a/nl-module-lms/nl-module-lms-server/src/main/java/cn/code/nl/module/lms/service/subpackagerelation/SubPackageRelationServiceImpl.java +++ b/nl-module-lms/nl-module-lms-server/src/main/java/cn/code/nl/module/lms/service/subpackagerelation/SubPackageRelationServiceImpl.java @@ -3,6 +3,7 @@ package cn.code.nl.module.lms.service.subpackagerelation; import cn.hutool.core.collection.CollUtil; import cn.code.nl.module.lms.dal.dataobject.boxtype.BoxTypeDO; import cn.code.nl.module.lms.dal.mysql.boxtype.BoxTypeMapper; +import cn.code.nl.module.lms.dal.mysql.slittingproductionplan.SlittingproductionplanMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import jakarta.annotation.Resource; @@ -38,6 +39,8 @@ public class SubPackageRelationServiceImpl implements SubPackageRelationService private static final String DUPLICATE_CLIENT_KEY = "DUPLICATE_CLIENT_KEY"; /** 子卷号重复错误码 */ private static final String DUPLICATE_CONTAINER_NAME = "DUPLICATE_CONTAINER_NAME"; + /** ERP 卷号未同步错误码 */ + private static final String ERP_CONTAINER_NOT_SYNCED = "ERP_CONTAINER_NOT_SYNCED"; /** 木箱类型不存在错误码 */ private static final String BOX_TYPE_NOT_FOUND = "BOX_TYPE_NOT_FOUND"; /** 木箱已绑定其他类型错误码 */ @@ -55,6 +58,10 @@ public class SubPackageRelationServiceImpl implements SubPackageRelationService @Resource private BoxTypeMapper boxTypeMapper; + /** 分切生产计划数据访问对象 */ + @Resource + private SlittingproductionplanMapper slittingproductionplanMapper; + /** 子卷包装关系分组独立事务保存服务 */ @Resource private SubPackageRelationBatchSaveService batchSaveService; @@ -161,6 +168,34 @@ public class SubPackageRelationServiceImpl implements SubPackageRelationService .build(); } + containerNames = validItems.stream() + .map(context -> context.item().getContainerName().trim()) + .collect(Collectors.toCollection(LinkedHashSet::new)); + Set syncedContainerNames = slittingproductionplanMapper + .selectListByExtContainerNames(containerNames).stream() + .map(item -> item.getExtContainerName()) + .filter(Objects::nonNull) + .map(String::trim) + .collect(Collectors.toSet()); + List syncedItems = new ArrayList<>(); + for (BatchItemContext context : validItems) { + String containerName = context.item().getContainerName().trim(); + if (!syncedContainerNames.contains(containerName)) { + failures.add(buildFailure(context.item().getClientKey(), context.rowIndex(), + ERP_CONTAINER_NOT_SYNCED, "ERP 卷号未同步:" + containerName)); + continue; + } + syncedItems.add(context); + } + validItems = syncedItems; + if (CollUtil.isEmpty(validItems)) { + return SubPackageRelationBatchCreateRespVO.builder() + .successCount(0) + .failureCount(failures.size()) + .failures(failures) + .build(); + } + Set boxTypes = validItems.stream() .map(context -> context.item().getBoxType()) .collect(Collectors.toCollection(LinkedHashSet::new)); diff --git a/nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/views/lms/subpackagerelation/modules/batch-form.vue b/nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/views/lms/subpackagerelation/modules/batch-form.vue index 6f62b1b1..4d757605 100644 --- a/nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/views/lms/subpackagerelation/modules/batch-form.vue +++ b/nl-ui/nl-ui-admin-vben/yudao-ui-admin-vben/apps/web-antdv-next/src/views/lms/subpackagerelation/modules/batch-form.vue @@ -19,6 +19,7 @@ import { message, Segmented, Select, + Table, } from 'antdv-next'; import { batchCreateSubPackageRelation } from '#/api/lms/subpackagerelation'; @@ -43,6 +44,31 @@ const viewOptions = [ { label: '▤ 卡片', value: 'card' }, { label: '▦ 表格', value: 'table' }, ]; +const batchTableColumns = [ + { title: '序号', key: 'sequence', width: 70, fixed: 'left' as const }, + { title: '木箱唯一码', key: 'packageBoxSn', width: 200 }, + { title: '子卷号', key: 'containerName', width: 200 }, + { title: '木箱类型', key: 'boxType', width: 190 }, + { title: '木箱长', key: 'boxLength', width: 130 }, + { title: '木箱宽', key: 'boxWidth', width: 130 }, + { title: '木箱高', key: 'boxHigh', width: 130 }, + { + title: '保质期(天)', + key: 'qualityGuaranPeriod', + width: 170, + }, + { title: '入库日期', key: 'dateOfFgInbound', width: 180 }, + { title: '状态', key: 'status', width: 140 }, + { title: '操作', key: 'operations', width: 150, fixed: 'right' as const }, +]; +const requiredColumnKeys = new Set([ + 'boxType', + 'containerName', + 'dateOfFgInbound', + 'packageBoxSn', + 'qualityGuaranPeriod', + 'status', +]); const statusOptions = computed(() => getDictOptions(DICT_TYPE.SUB_PACKAGE_STATUS).map((item) => ({ @@ -50,6 +76,11 @@ const statusOptions = computed(() => value: String(item.value), })), ); +const errorRowKeys = computed(() => + rows.value + .filter((row) => rowErrors.value.has(row.clientKey)) + .map((row) => row.clientKey), +); function reset() { rows.value = [createBatchRow()]; @@ -222,34 +253,37 @@ const [Modal, modalApi] = useVbenModal({
- - - - - - - - - - - - -
序号* 木箱唯一码* 子卷号* 木箱类型木箱长木箱宽木箱高* 保质期(天)* 入库日期* 状态操作
+ + + + +
@@ -359,7 +393,7 @@ const [Modal, modalApi] = useVbenModal({ .table-wrap { flex: 1; min-height: 420px; - overflow: auto; + overflow: hidden; background: hsl(var(--background)); border: 1px solid hsl(var(--border)); border-radius: 10px; @@ -367,42 +401,31 @@ const [Modal, modalApi] = useVbenModal({ .batch-table { width: 100%; - min-width: 1780px; - border-collapse: separate; - border-spacing: 0; } -.batch-table th, -.batch-table td { - padding: 10px; - vertical-align: top; - background: hsl(var(--background)); - border-right: 1px solid hsl(var(--border)); - border-bottom: 1px solid hsl(var(--border)); +.batch-table :deep(.ant-table) { + border-radius: 10px; } -.batch-table th { - position: sticky; - top: 0; - z-index: 3; +.batch-table :deep(.ant-table-thead > tr > th) { height: 48px; color: #4b5870; font-weight: 600; - text-align: left; white-space: nowrap; background: #f3f6fb; - vertical-align: middle; } -.batch-table th i { +.batch-table :deep(.ant-table-tbody > tr > td) { + padding: 10px; + vertical-align: top; + background: hsl(var(--background)); +} + +.batch-table i { color: #ff4d4f; font-style: normal; } -.batch-table td { - min-width: 145px; -} - .batch-table :deep(.ant-input), .batch-table :deep(.ant-input-affix-wrapper), .batch-table :deep(.ant-picker), @@ -429,34 +452,16 @@ const [Modal, modalApi] = useVbenModal({ } .batch-table .sequence { - position: sticky; - left: 0; - z-index: 2; - min-width: 64px; + display: block; color: #788196; text-align: center; } -.batch-table th:first-child { - left: 0; - z-index: 5; - min-width: 64px; - text-align: center; -} - -.batch-table th:last-child, .batch-table .operations { - position: sticky; - right: 0; - z-index: 2; - min-width: 128px; - text-align: center; + display: flex; + align-items: center; + justify-content: center; white-space: nowrap; - box-shadow: -5px 0 12px rgb(21 35 62 / 6%); -} - -.batch-table th:last-child { - z-index: 5; } .batch-table small { @@ -474,7 +479,12 @@ const [Modal, modalApi] = useVbenModal({ border-color: #ff4d4f; } -.row-error td { +.batch-table :deep(.ant-table-expanded-row > td) { + padding: 0 !important; +} + +.row-error { + padding: 9px 16px; color: #ff4d4f; background: #fff2f0; }