云
2026-10-28 8010823b016b6441b31a2e8dfd19034e951ede3c
feat(mes): 添加盘号字段并优化权限控制

- 在MES生产任务、质检、批次管理等相关模块中添加盘号(reelNo)字段显示
- 优化业务卡片权限控制逻辑,移除冗余的查询权限验证
- 更新销售明细、退货、调拨等业务流程中的盘号相关数据结构
- 修复退货销售表单中物料选择重复数据处理逻辑
- 移除多个页面中冗余的权限验证配置项
- 优化销售通知单、产品销售等界面的盘号显示功能
已修改61个文件
229 ■■■■■ 文件已修改
src/api/mes/qc/rqc/index.ts 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/mes/wm/batch/index.ts 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/mes/wm/productsales/detail/index.ts 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/mes/wm/productsales/line/index.ts 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/mes/wm/returnsales/detail/index.ts 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/mes/wm/returnsales/line/index.ts 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/mes/wm/salesnotice/line/index.ts 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/mes/wm/transfer/line/index.ts 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/bpm/form/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/bpm/oa/notice/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/bpm/task/copy/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/bpm/task/todo/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/dashboard/analytics/modules/biz-cards.vue 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/erp/finance/payment/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/erp/finance/receipt/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/erp/finance/voucher/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/erp/purchase/invoice/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/erp/purchase/order/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/erp/purchase/request/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/erp/sale/order/index.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/im/manager/group/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/im/manager/message/group/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/im/manager/message/private/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/im/manager/rtc/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/infra/apiAccessLog/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/infra/apiErrorLog/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/infra/job/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/infra/job/logger/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/dv/checkrecord/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/dv/machinery/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/dv/maintenrecord/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/dv/metering/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/dv/meteringcheck/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/dv/repair/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/pro/andon/record/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/pro/task/data.ts 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/pro/task/modules/schedule-form.vue 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/qc/ipqc/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/qc/iqc/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/qc/oqc/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/qc/rqc/data.ts 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/qc/rqc/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/mes/workbench/index.vue 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/srm/supplierApply/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/loginlog/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/mail/log/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/notify/message/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/operatelog/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/sms/log/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/system/social/user/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/wls/barcode/index.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/wls/batch/components/select.vue 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/wls/batch/data.ts 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/wls/materialstock/components/stock-adjust-modal.vue 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/wls/productsales/data.ts 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/wls/returnsales/data.ts 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/wls/returnsales/modules/form.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/wls/returnsales/modules/line-form.vue 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/wls/salesnotice/data.ts 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/wls/salesnotice/modules/line-form.vue 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/wls/transfer/data.ts 1 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/mes/qc/rqc/index.ts
@@ -22,6 +22,7 @@
    itemSpecification?: string; // 规格型号(关联查询)
    unitName?: string; // 单位名称(关联查询)
    batchCode?: string; // 批次号
    reelNo?: string; // 退货批次盘号
    checkQuantity?: number; // 检测数量
    qualifiedQuantity?: number; // 合格品数量
    unqualifiedQuantity?: number; // 不合格数量
src/api/mes/wm/batch/index.ts
@@ -7,6 +7,7 @@
  export interface Batch {
    id?: number; // 批次 ID
    code?: string; // 批次编码
    reelNo?: string; // 生产追溯盘号
    itemId?: number; // 物料 ID
    itemCode?: string; // 物料编码
    itemName?: string; // 物料名称
src/api/mes/wm/productsales/detail/index.ts
@@ -13,6 +13,7 @@
    materialStockId?: number; // 库存记录编号
    batchId?: number; // 批次编号
    batchCode?: string; // 批次号
    reelNo?: string; // 实际拣货库存盘号
    warehouseId?: number; // 仓库编号
    warehouseName?: string; // 仓库名称
    locationId?: number; // 库区编号
src/api/mes/wm/productsales/line/index.ts
@@ -18,6 +18,7 @@
    pickedQuantity?: number; // 已拣货数量
    batchId?: number; // 批次编号
    batchCode?: string; // 批次号
    reelNo?: string; // 销售明细盘号
    oqcCheckFlag?: boolean; // 是否检验
    remark?: string; // 备注
  }
src/api/mes/wm/returnsales/detail/index.ts
@@ -10,6 +10,7 @@
    quantity?: number; // 数量
    batchId?: number; // 批次编号
    batchCode?: string; // 批次号
    reelNo?: string; // 上架批次盘号
    warehouseId?: number; // 仓库编号
    warehouseName?: string; // 仓库名称
    locationId?: number; // 库区编号
src/api/mes/wm/returnsales/line/index.ts
@@ -15,6 +15,7 @@
    quantity?: number; // 退货数量
    batchId?: number; // 批次编号
    batchCode?: string; // 批次号
    reelNo?: string; // 退货批次盘号
    rqcCheckFlag?: boolean; // 是否需要质检
    rqcId?: number; // 退货检验单编号
    qualityStatus?: number; // 质量状态
src/api/mes/wm/salesnotice/line/index.ts
@@ -15,6 +15,7 @@
    unitMeasureName?: string; // 单位
    batchId?: number; // 批次编号
    batchCode?: string; // 批次号
    reelNo?: string; // 销售明细盘号
    quantity?: number; // 发货数量
    outCount?: number; // 已出库数量
    oqcCheckFlag?: boolean; // 是否检验
src/api/mes/wm/transfer/line/index.ts
@@ -14,6 +14,7 @@
    quantity?: number; // 转移数量
    batchId?: number; // 批次编号
    batchCode?: string; // 批次号
    reelNo?: string; // 调拨批次盘号
    fromWarehouseId?: number; // 移出仓库编号
    fromWarehouseName?: string; // 移出仓库名称
    fromLocationId?: number; // 移出库区编号
src/views/bpm/form/index.vue
@@ -153,7 +153,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['bpm:form:query'],
              onClick: handleDetail.bind(null, row),
            },
            {
src/views/bpm/oa/notice/index.vue
@@ -139,7 +139,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['bpm:oa-notice:query'],
              onClick: handleDetail.bind(null, row),
            },
            {
src/views/bpm/task/copy/index.vue
@@ -65,7 +65,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['bpm:task:query'],
              onClick: handleDetail.bind(null, row),
            },
          ]"
src/views/bpm/task/todo/index.vue
@@ -63,7 +63,6 @@
              label: '办理',
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['bpm:task:query'],
              onClick: handleAudit.bind(null, row),
            },
          ]"
src/views/dashboard/analytics/modules/biz-cards.vue
@@ -23,11 +23,11 @@
const saleCount = ref(0);
const stockCount = ref(0);
const bpmTodoCount = ref(0);
const { canNavigate, canQuery } = useHomeAccess();
const canViewPurchase = computed(() => canQuery('erp:purchase-order:query') && canNavigate('ErpPurchaseOrder'));
const canViewSale = computed(() => canQuery('erp:sale-order:query') && canNavigate('ErpSaleOrder'));
const canViewStock = computed(() => canQuery('mes:wm-material-stock:query') && canNavigate('MesWmMaterialStock'));
const canViewBpmTodo = computed(() => canQuery('bpm:task:query') && canNavigate('BpmTaskTodo'));
const { canNavigate } = useHomeAccess();
const canViewPurchase = computed(() => canNavigate('ErpPurchaseOrder'));
const canViewSale = computed(() => canNavigate('ErpSaleOrder'));
const canViewStock = computed(() => canNavigate('MesWmMaterialStock'));
const canViewBpmTodo = computed(() => canNavigate('BpmTaskTodo'));
async function loadPurchase() {
  if (!canViewPurchase.value) return;
src/views/erp/finance/payment/index.vue
@@ -215,7 +215,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['erp:finance-payment:query'],
              onClick: handleDetail.bind(null, row),
            },
            {
src/views/erp/finance/receipt/index.vue
@@ -174,7 +174,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['erp:finance-receipt:query'],
              onClick: handleDetail.bind(null, row),
            },
            {
src/views/erp/finance/voucher/index.vue
@@ -243,7 +243,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['finance:voucher:query'],
              onClick: handleDetail.bind(null, row),
            },
            {
src/views/erp/purchase/invoice/index.vue
@@ -171,7 +171,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['erp:purchase-invoice:query'],
              onClick: handleDetail.bind(null, row),
            },
            {
src/views/erp/purchase/order/index.vue
@@ -206,7 +206,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['erp:purchase-order:query'],
              onClick: handleDetail.bind(null, row),
            },
            {
src/views/erp/purchase/request/index.vue
@@ -262,7 +262,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['erp:purchase-request:query'],
              onClick: handleDetail.bind(null, row),
            },
            {
src/views/erp/sale/order/index.vue
@@ -362,14 +362,12 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['erp:sale-order:query'],
              onClick: handleDetail.bind(null, row),
            },
            {
              label: '打印',
              type: 'link',
              icon: 'lucide:printer',
              auth: ['erp:sale-order:query'],
              onClick: handlePrint.bind(null, row),
            },
            {
@@ -395,7 +393,6 @@
              label: '审批进度',
              type: 'link',
              icon: 'lucide:file-clock',
              auth: ['erp:sale-order:query'],
              ifShow: () => row.status === 15 && !!row.processInstanceId,
              onClick: handleViewApproval.bind(null, row),
            },
src/views/im/manager/group/index.vue
@@ -133,7 +133,6 @@
              label: '详情',
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['im:manager:group:query'],
              onClick: handleDetail.bind(null, row),
            },
            {
src/views/im/manager/message/group/index.vue
@@ -99,7 +99,6 @@
              label: '详情',
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['im:manager:message:query'],
              onClick: handleDetail.bind(null, row),
            },
          ]"
src/views/im/manager/message/private/index.vue
@@ -90,7 +90,6 @@
              label: '详情',
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['im:manager:message:query'],
              onClick: handleDetail.bind(null, row),
            },
          ]"
src/views/im/manager/rtc/index.vue
@@ -87,7 +87,6 @@
              label: '详情',
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['im:manager:rtc:query'],
              onClick: handleDetail.bind(null, row),
            },
          ]"
src/views/infra/apiAccessLog/index.vue
@@ -90,7 +90,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['infra:api-access-log:query'],
              onClick: handleDetail.bind(null, row),
            },
          ]"
src/views/infra/apiErrorLog/index.vue
@@ -112,7 +112,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['infra:api-error-log:query'],
              onClick: handleDetail.bind(null, row),
            },
            {
src/views/infra/job/index.vue
@@ -283,7 +283,6 @@
            {
              label: $t('common.detail'),
              type: 'link',
              auth: ['infra:job:query'],
              onClick: handleDetail.bind(null, row),
            },
            {
src/views/infra/job/logger/index.vue
@@ -87,7 +87,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['infra:job:query'],
              onClick: handleDetail.bind(null, row),
            },
          ]"
src/views/mes/dv/checkrecord/index.vue
@@ -151,7 +151,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['mes:dv-check-record:query'],
              onClick: handleDetail.bind(null, row),
            },
          ]"
src/views/mes/dv/machinery/index.vue
@@ -185,7 +185,6 @@
                  label: $t('common.detail'),
                  type: 'link',
                  icon: ACTION_ICON.VIEW,
                  auth: ['mes:dv-machinery:query'],
                  onClick: handleDetail.bind(null, row),
                },
              ]"
src/views/mes/dv/maintenrecord/index.vue
@@ -151,7 +151,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['mes:dv-mainten-record:query'],
              onClick: handleDetail.bind(null, row),
            },
          ]"
src/views/mes/dv/metering/index.vue
@@ -184,7 +184,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['mes:dv-metering:query'],
              onClick: handleDetail.bind(null, row),
            },
          ]"
src/views/mes/dv/meteringcheck/index.vue
@@ -147,7 +147,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['mes:dv-metering-check:query'],
              onClick: handleDetail.bind(null, row),
            },
          ]"
src/views/mes/dv/repair/index.vue
@@ -167,7 +167,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['mes:dv-repair:query'],
              onClick: handleDetail.bind(null, row),
            },
          ]"
src/views/mes/pro/andon/record/index.vue
@@ -143,7 +143,6 @@
            {
              label: '详情',
              type: 'link',
              auth: ['mes:pro-andon-record:query'],
              onClick: handleDetail.bind(null, row),
            },
            {
src/views/mes/pro/task/data.ts
@@ -115,6 +115,11 @@
      width: 140,
    },
    {
      field: 'reelNo',
      title: '盘号',
      minWidth: 140,
    },
    {
      field: 'productCode',
      title: '产品编码',
      width: 120,
@@ -225,6 +230,14 @@
      },
    },
    {
      fieldName: 'reelNo',
      label: '盘号',
      component: 'Input',
      componentProps: {
        disabled: true,
      },
    },
    {
      fieldName: 'type',
      label: '订单类型',
      component: 'Select',
@@ -295,12 +308,11 @@
      },
    },
    {
      fieldName: 'status',
      fieldName: 'statusLabel',
      label: '订单状态',
      component: 'Select',
      component: 'Input',
      componentProps: {
        disabled: true,
        options: getDictOptions(DICT_TYPE.MES_PRO_WORK_ORDER_STATUS, 'number'),
      },
    },
    {
src/views/mes/pro/task/modules/schedule-form.vue
@@ -5,6 +5,8 @@
import { computed, ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { DICT_TYPE } from '@vben/constants';
import { getDictLabel } from '@vben/hooks';
import { Button, Card, message, Popconfirm, Steps } from 'ant-design-vue';
@@ -103,7 +105,12 @@
    try {
      workOrder.value = await getWorkOrder(data.id);
      // 设置到 values
      await formApi.setValues(workOrder.value);
      await formApi.setValues({
        ...workOrder.value,
        statusLabel: workOrder.value.status == null
          ? '-'
          : getDictLabel(DICT_TYPE.MES_PRO_WORK_ORDER_STATUS, workOrder.value.status) || '-',
      });
      if (workOrder.value.productId) {
        await loadRouteProcesses(
          workOrder.value.id!,
src/views/mes/qc/ipqc/index.vue
@@ -213,7 +213,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['mes:qc-ipqc:query'],
              onClick: handleDetail.bind(null, row),
            },
          ]"
src/views/mes/qc/iqc/index.vue
@@ -226,7 +226,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['mes:qc-iqc:query'],
              onClick: handleDetail.bind(null, row),
            },
          ]"
src/views/mes/qc/oqc/index.vue
@@ -212,7 +212,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['mes:qc-oqc:query'],
              onClick: handleDetail.bind(null, row),
            },
          ]"
src/views/mes/qc/rqc/data.ts
@@ -423,6 +423,7 @@
      title: '批次号',
      width: 130,
    },
    { field: 'reelNo', title: '盘号', width: 130 },
    {
      field: 'checkResult',
      title: '检测结果',
src/views/mes/qc/rqc/index.vue
@@ -173,7 +173,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['mes:qc-rqc:query'],
              onClick: handleDetail.bind(null, row),
            },
          ]"
src/views/mes/workbench/index.vue
@@ -35,7 +35,7 @@
const tabItems: WorkbenchTabItem[] = [
  { key: 'detail', label: '工单详情', icon: 'lucide:file-text' },
  { key: 'feedback', label: '报工', icon: 'lucide:edit-3', auth: ['mes:pro-feedback:create'] },
  { key: 'history', label: '报工记录', icon: 'lucide:history' ,auth: ['mes:pro-feedback:query']},
  { key: 'history', label: '报工记录', icon: 'lucide:history' },
  { key: 'record-param', label: '生产记录参数', icon: 'lucide:file-cog' },
  { key: 'product-issue', label: '领料', icon: 'lucide:clipboard-list' },
  { key: 'return-issue', label: '退料', icon: 'lucide:rotate-ccw' },
src/views/srm/supplierApply/index.vue
@@ -160,7 +160,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['srm:supplier-apply:query'],
              onClick: handleDetail.bind(null, row),
            },
            {
src/views/system/loginlog/index.vue
@@ -87,7 +87,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['system:login-log:query'],
              onClick: handleDetail.bind(null, row),
            },
          ]"
src/views/system/mail/log/index.vue
@@ -75,7 +75,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['system:mail-log:query'],
              onClick: handleDetail.bind(null, row),
            },
          ]"
src/views/system/notify/message/index.vue
@@ -67,7 +67,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['system:notify-message:query'],
              onClick: handleDetail.bind(null, row),
            },
          ]"
src/views/system/operatelog/index.vue
@@ -87,7 +87,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['system:operate-log:query'],
              onClick: handleDetail.bind(null, row),
            },
          ]"
src/views/system/sms/log/index.vue
@@ -87,7 +87,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['system:sms-log:query'],
              onClick: handleDetail.bind(null, row),
            },
          ]"
src/views/system/social/user/index.vue
@@ -62,7 +62,6 @@
              label: $t('common.detail'),
              type: 'link',
              icon: ACTION_ICON.VIEW,
              auth: ['system:social-user:query'],
              onClick: handleDetail.bind(null, row),
            },
          ]"
src/views/wls/barcode/index.vue
@@ -203,7 +203,6 @@
            {
              label: $t('common.detail'),
              type: 'link',
              auth: ['mes:wm-barcode:query'],
              onClick: handleView.bind(null, row),
            },
            {
src/views/wls/batch/components/select.vue
@@ -128,6 +128,7 @@
          <div>物料编码:{{ selectedItem.itemCode || '-' }}</div>
          <div>物料名称:{{ selectedItem.itemName || '-' }}</div>
          <div>生产批号:{{ selectedItem.lotNumber || '-' }}</div>
          <div>盘号:{{ selectedItem.reelNo || '-' }}</div>
        </div>
      </template>
      <Input
src/views/wls/batch/data.ts
@@ -178,6 +178,11 @@
      width: 150,
    },
    {
      field: 'reelNo',
      title: '盘号',
      width: 120,
    },
    {
      field: 'itemCode',
      title: '物料编码',
      width: 150,
@@ -285,6 +290,10 @@
      label: '批次编号',
    },
    {
      field: 'reelNo',
      label: '盘号',
    },
    {
      field: 'itemCode',
      label: '物料编码',
    },
src/views/wls/materialstock/components/stock-adjust-modal.vue
@@ -21,6 +21,7 @@
import { getItem } from '#/api/mdm/item';
import { MdmItemSelect } from '#/views/basicData/mdm/components';
import { SrmSupplierSelect } from '#/views/srm/supplier/components';
import { WmBatchSelect } from '#/views/wls/batch/components';
import BatchConfigDisplay from './batch-config-display.vue';
import {
  WmWarehouseAreaSelect,
@@ -42,6 +43,7 @@
const batchEnabled = ref(false);
// 是否手动填写批次号
const manualBatchEntry = ref(false);
const hasExistingBatch = ref(false);
// 批次配置展示组件引用
const batchConfigDisplayRef = ref<InstanceType<typeof BatchConfigDisplay>>();
@@ -69,7 +71,7 @@
  }
  const item = selectedItem.value;
  const isIn = operateType.value === 1;
  const isIn = operateType.value === 1 && !hasExistingBatch.value;
  formApi.updateSchema([
    { fieldName: 'batchCode', dependencies: { show: () => manualBatchEntry.value } },
@@ -86,6 +88,7 @@
/** 物料选择变化 */
async function handleItemChange(item: MdmItemApi.Item | undefined) {
  hasExistingBatch.value = false;
  selectedItem.value = item || null;
  if (item?.id) {
    const itemDetail = await getItem(item.id);
@@ -97,6 +100,7 @@
  }
  // 清空批次相关值
  await formApi.setFieldValue('batchCode', undefined);
  await formApi.setFieldValue('batchId', undefined);
  await formApi.setFieldValue('produceDate', undefined);
  await formApi.setFieldValue('expireDate', undefined);
  await formApi.setFieldValue('manualBatchEntry', false);
@@ -158,6 +162,24 @@
        onChange: handleItemChange,
      },
      rules: 'selectRequired',
    },
    {
      fieldName: 'batchId',
      label: '已有批次/盘号',
      component: markRaw(WmBatchSelect),
      componentProps: { placeholder: '可选择已有追溯批次', disabled: true },
      dependencies: {
        triggerFields: ['itemId'],
        componentProps: (values: any) => ({
          itemId: values.itemId,
          disabled: !values.itemId,
          placeholder: '可选择已有追溯批次',
          onChange: async (batch: any) => {
            hasExistingBatch.value = !!batch?.id;
            await updateBatchFields();
          },
        }),
      },
    },
    {
      fieldName: 'warehouseId',
@@ -402,6 +424,7 @@
      selectedWarehouse.value = null;
      selectedLocation.value = null;
      batchEnabled.value = false;
      hasExistingBatch.value = false;
      operateType.value = 1;
      modalTitle.value = '库存调整';
      return;
@@ -450,7 +473,7 @@
  const values = await formApi.getValues();
  // 启用批次管理时的校验
  if (batchEnabled.value) {
  if (batchEnabled.value && !values.batchId) {
    if (manualBatchEntry.value && !values.batchCode) {
      message.error('请输入批次号');
      return;
@@ -494,6 +517,7 @@
        warehouseId: values.warehouseId,
        locationId: values.locationId,
        areaId: values.areaId,
        batchId: values.batchId,
        batchCode: values.batchCode,
        produceDate: values.produceDate,
        expireDate: values.expireDate,
@@ -514,6 +538,7 @@
        warehouseId: values.warehouseId,
        locationId: values.locationId,
        areaId: values.areaId,
        batchId: values.batchId,
        batchCode: values.batchCode,
        vendorId: values.vendorId,
        quantity: values.quantity,
src/views/wls/productsales/data.ts
@@ -433,6 +433,11 @@
      width: 100,
    },
    {
      field: 'reelNo',
      title: '销售盘号',
      minWidth: 120,
    },
    {
      field: 'batchCode',
      title: '批次号',
      minWidth: 120,
@@ -567,6 +572,11 @@
): VxeTableGridOptions<MesWmProductSalesDetailApi.ProductSalesDetail>['columns'] {
  return [
    {
      field: 'reelNo',
      title: '拣货盘号',
      minWidth: 120,
    },
    {
      field: 'warehouseName',
      title: '仓库名称',
      minWidth: 100,
src/views/wls/returnsales/data.ts
@@ -308,6 +308,7 @@
      title: '批次号',
      minWidth: 120,
    },
    { field: 'reelNo', title: '盘号', minWidth: 120 },
    {
      field: 'rqcCheckFlag',
      title: '是否需要质检',
@@ -355,13 +356,14 @@
      componentProps: hasItems
        ? {
            placeholder: '请选择物料',
            options: items.map((item) => ({
            options: items.filter((item, index) => items.findIndex((other) => other.productId === item.productId) === index).map((item) => ({
              label: `${item.productName || ''}(${item.productBarCode || ''})`,
              value: item.productId,
            })),
            showSearch: true,
            onChange: (value: number | undefined) => {
              const selected = items.find((i) => i.productId === value);
              const matches = items.filter((i) => i.productId === value);
              const selected = matches.length === 1 ? matches[0] : undefined;
              onItemChange?.(selected);
            },
          }
@@ -384,7 +386,8 @@
      dependencies: {
        triggerFields: ['itemId'],
        componentProps: (values) => {
          const selected = items?.find((i) => i.productId === values.itemId);
          const matches = items?.filter((i) => i.productId === values.itemId) ?? [];
          const selected = matches.length === 1 ? matches[0] : undefined;
          return {
            class: '!w-full',
            max: selected?.count ?? undefined,
@@ -394,7 +397,8 @@
          };
        },
        rules: (values) => {
          const selected = items?.find((i) => i.productId === values.itemId);
          const matches = items?.filter((i) => i.productId === values.itemId) ?? [];
          const selected = matches.length === 1 ? matches[0] : undefined;
          const max = selected?.count;
          if (max !== undefined && max !== null) {
            return z
@@ -413,7 +417,7 @@
      component: markRaw(WmBatchSelect),
      componentProps: {
        clientId,
        disabled: true,
        disabled: false,
        placeholder: '请选择批次',
        salesOrderCode,
      },
@@ -421,7 +425,7 @@
        triggerFields: ['itemId'],
        componentProps: (values) => ({
          clientId,
          disabled: true,
          disabled: !values.itemId,
          itemId: values.itemId,
          placeholder: '请选择批次',
          salesOrderCode,
@@ -452,6 +456,7 @@
  stockable: boolean,
): VxeTableGridOptions<MesWmReturnSalesDetailApi.ReturnSalesDetail>['columns'] {
  return [
    { field: 'reelNo', title: '盘号', minWidth: 120 },
    {
      field: 'batchCode',
      title: '批次号',
src/views/wls/returnsales/modules/form.vue
@@ -167,6 +167,7 @@
  async onOpenChange(isOpen: boolean) {
    if (!isOpen) {
      formData.value = undefined;
      saleOrderItems.value = [];
      originalSnapshot.value = '';
      return;
    }
@@ -201,10 +202,12 @@
          if (list?.length) {
            const orderId = list[0].id as number;
            (formData.value as Record<string, unknown>).saleOrderId = orderId;
            const order = await getSaleOrder(orderId);
            saleOrderItems.value = order?.items || [];
          }
        }
        if (formData.value?.saleOrderId) {
          const order = await getSaleOrder(formData.value.saleOrderId);
          saleOrderItems.value = order?.items || [];
        }
        // 设置到 values
        await formApi.setValues(formData.value);
      } finally {
src/views/wls/returnsales/modules/line-form.vue
@@ -9,7 +9,6 @@
import { message } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form';
import { getBatchPage } from '#/api/mes/wm/batch';
import {
  createReturnSalesLine,
  getReturnSalesLine,
@@ -91,21 +90,6 @@
          maxQuantity.value = item?.count;
          // 重置批次
          await formApi.setFieldValue('batchId', undefined);
          if (item?.batchCode) {
            try {
              const batchPage = await getBatchPage({
                code: item.batchCode,
                pageNo: 1,
                pageSize: 1,
              });
              const batchList = batchPage?.list;
              if (batchList?.length) {
                await formApi.setFieldValue('batchId', batchList[0].id);
              }
            } catch {
              // 查询失败时忽略
            }
          }
        },
      ),
    });
src/views/wls/salesnotice/data.ts
@@ -318,6 +318,11 @@
      },
    },
    {
      field: 'reelNo',
      title: '盘号',
      minWidth: 120,
    },
    {
      field: 'batchCode',
      title: '批次号',
      minWidth: 120,
src/views/wls/salesnotice/modules/line-form.vue
@@ -1,13 +1,16 @@
<script lang="ts" setup>
import type { MesWmSalesNoticeLineApi } from '#/api/mes/wm/salesnotice/line';
import type { ErpSaleOrderApi } from '#/api/erp/sale/order';
import { computed, ref } from 'vue';
import { useVbenModal } from '@vben/common-ui';
import { message } from 'ant-design-vue';
import { message, Select } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form';
import { getSaleOrderItemListByOrderId } from '#/api/erp/sale/order';
import { getSalesNotice } from '#/api/mes/wm/salesnotice';
import {
  createSalesNoticeLine,
  getSalesNoticeLine,
@@ -20,6 +23,18 @@
const emit = defineEmits(['success']);
const formData = ref<MesWmSalesNoticeLineApi.SalesNoticeLine>();
const noticeId = ref<number>(); // 所属通知单编号
const saleOrderId = ref<number>();
const saleOrderItemId = ref<number>();
const saleItems = ref<ErpSaleOrderApi.SaleOrderItem[]>([]);
const saleItemOptions = computed(() => saleItems.value.map((item) => ({
  value: item.id,
  label: `${item.productName || item.productId || '-'} / 盘号:${item.reelNo || '未填写'} / 明细:${item.id}`,
})));
async function handleSaleItemChange(id: number) {
  const item = saleItems.value.find((entry) => entry.id === id);
  if (item?.productId) await formApi.setFieldValue('itemId', item.productId);
}
const getTitle = computed(() => {
  return formData.value?.id
@@ -43,6 +58,10 @@
const [Modal, modalApi] = useVbenModal({
  async onConfirm() {
    if (saleOrderId.value && !saleOrderItemId.value) {
      message.warning('请选择销售订单明细');
      return;
    }
    const { valid } = await formApi.validate();
    if (!valid) {
      return;
@@ -52,6 +71,7 @@
    const data =
      (await formApi.getValues()) as MesWmSalesNoticeLineApi.SalesNoticeLine;
    data.noticeId = noticeId.value;
    data.saleOrderItemId = saleOrderItemId.value;
    try {
      await (formData.value?.id
        ? updateSalesNoticeLine({ ...data, id: formData.value.id })
@@ -67,19 +87,26 @@
  async onOpenChange(isOpen: boolean) {
    if (!isOpen) {
      formData.value = undefined;
      saleOrderId.value = undefined;
      saleOrderItemId.value = undefined;
      saleItems.value = [];
      return;
    }
    // 加载数据
    const data = modalApi.getData<{ id?: number; noticeId: number }>();
    noticeId.value = data.noticeId;
    if (!data.id) {
      return;
    }
    modalApi.lock();
    try {
      formData.value = await getSalesNoticeLine(data.id);
      // 设置到 values
      await formApi.setValues(formData.value);
      const notice = await getSalesNotice(data.noticeId);
      saleOrderId.value = notice.saleOrderId;
      if (notice.saleOrderId) {
        saleItems.value = await getSaleOrderItemListByOrderId(notice.saleOrderId);
      }
      if (data.id) {
        formData.value = await getSalesNoticeLine(data.id);
        saleOrderItemId.value = formData.value.saleOrderItemId;
        await formApi.setValues(formData.value);
      }
    } finally {
      modalApi.unlock();
    }
@@ -89,6 +116,11 @@
<template>
  <Modal :title="getTitle" class="w-3/5">
    <div v-if="saleOrderId" class="mx-4 mb-4 flex items-center gap-3">
      <span>销售明细</span>
      <Select v-model:value="saleOrderItemId" class="flex-1" :options="saleItemOptions"
        placeholder="请选择销售订单明细和盘号" @change="handleSaleItemChange" />
    </div>
    <Form class="mx-4" />
  </Modal>
</template>
src/views/wls/transfer/data.ts
@@ -375,6 +375,7 @@
      title: '批次号',
      minWidth: 120,
    },
    { field: 'reelNo', title: '盘号', minWidth: 120 },
    {
      field: 'fromWarehouseName',
      title: '移出仓库',