feat(mes):盘号字段支持 添加和报工时间功能
- 在多个数据表单中添加 reelNo 盘号字段显示和编辑功能
- 为批量报工和快速报工功能添加报工时间选择器
- 更新 API 接口定义以支持 reelNo 和 feedbackTime 字段
- 修改 MPS 批量下发逻辑为逐条下发并显示结果反馈
- 移除不再使用的 checkFlag 相关逻辑和依赖
- 在销售订单明细中添加盘号输入和打印显示功能
- 更新生产反馈表单的质检流程逻辑
| | |
| | | seq?: number; // 前端行号 |
| | | orderId?: number; // 采购订单编号 |
| | | productId?: number; // 产品编号 |
| | | reelNo?: string; // 手工录入的盘号 |
| | | productName?: string; // 产品名称 |
| | | productBarCode?: string; // 产品条码 |
| | | productUnitId?: number; // 产品单位编号 |
| | |
| | | checkFlag?: boolean; // 是否需要检验 |
| | | workOrderId?: number; // 生产订单编号 |
| | | workOrderCode?: string; // 订单编码 |
| | | reelNo?: string; // 销售明细盘号 |
| | | workOrderName?: string; // 订单名称 |
| | | taskId?: number; // 生产任务编号 |
| | | taskCode?: string; // 任务编码 |
| | |
| | | taskId: number; |
| | | paramValues?: MesProFeedbackApi.ParamValue[]; |
| | | feedbackQuantity: number; |
| | | feedbackTime?: string; |
| | | remark?: string; |
| | | } |
| | | |
| | |
| | | export interface BatchCreateReq { |
| | | taskIds: number[]; |
| | | feedbackQuantity: number; |
| | | feedbackTime?: string; |
| | | remark?: string; |
| | | } |
| | | |
| | |
| | | saleOrderNo?: string; // 销售订单号 |
| | | saleOrderItemId?: number; // 销售订单明细ID |
| | | productId?: number; // 产品ID |
| | | reelNo?: string; // 销售明细盘号 |
| | | productCode?: string; // 产品编码 |
| | | productName?: string; // 产品名称 |
| | | productSpecification?: string; // 规格型号 |
| | |
| | | mergeBatchNo?: string; // 合并批次号 |
| | | remark?: string; // 备注 |
| | | createTime?: number; // 创建时间 |
| | | } |
| | | |
| | | export interface BatchIssueResult { |
| | | mpsId: number; |
| | | workOrderId?: number; |
| | | error?: string; |
| | | } |
| | | |
| | | /** MPS 分页查询参数 */ |
| | |
| | | return requestClient.post(`/mes/pro-mps/issue?id=${id}`); |
| | | } |
| | | |
| | | /** 合并下发 MPS */ |
| | | export function mergeIssueMps(ids: number[]) { |
| | | return requestClient.post('/mes/pro-mps/merge-issue', ids); |
| | | /** 批量逐条下发,每个计划分别返回结果。 */ |
| | | export function batchIssueMps(ids: number[]) { |
| | | return requestClient.post<MesProMpsApi.BatchIssueResult[]>('/mes/pro-mps/batch-issue', ids); |
| | | } |
| | | |
| | | /** 取消 MPS */ |
| | |
| | | orderSourceType?: number; // 来源类型 |
| | | orderSourceCode?: string; // 来源单据编号 |
| | | productId?: number; // 产品编号 |
| | | reelNo?: string; // 销售明细盘号 |
| | | productName?: string; // 产品名称 |
| | | productCode?: string; // 产品编码 |
| | | itemCode?: string; // 产品编码(物料编码) |
| | |
| | | sourceLineId?: number; // 来源单据行 ID |
| | | sourceDocCode?: string; // 来源单据编号(关联查询) |
| | | workOrderId?: number; // 生产订单 ID |
| | | reelNo?: string; // 销售明细盘号 |
| | | workOrderCode?: string; // 订单编号(关联查询) |
| | | workOrderName?: string; // 订单名称(关联查询) |
| | | taskId?: number; // 生产任务 ID |
| | |
| | | sourceDocId?: number; // 来源单据 ID |
| | | sourceLineId?: number; // 来源单据行 ID |
| | | sourceDocCode?: string; // 来源单据编号(关联查询) |
| | | reelNo?: string; // 销售明细盘号 |
| | | clientId?: number; // 客户 ID |
| | | clientNickname?: string; // 客户简称(关联查询) |
| | | batchCode?: string; // 批次号 |
| | |
| | | vendorName?: string; // 供应商名称 |
| | | // 订单/工作站/任务(IPQC/RQC 场景) |
| | | workOrderId?: number; // 生产订单 ID |
| | | reelNo?: string; // 销售明细盘号 |
| | | workstationId?: number; // 工作站 ID |
| | | workstationName?: string; // 工作站名称 |
| | | taskId?: number; // 生产任务 ID |
| | |
| | | unitMeasureName?: string; // 计量单位名称 |
| | | batchId?: number; // 批次编号 |
| | | batchCode?: string; // 批次号 |
| | | reelNo?: string; // 生产追溯盘号 |
| | | warehouseId?: number; // 仓库编号 |
| | | warehouseCode?: string; // 仓库编码 |
| | | warehouseName?: string; // 仓库名称 |
| | |
| | | unitMeasureName?: string; // 单位 |
| | | quantity?: number; // 产出数量 |
| | | batchCode?: string; // 批次号 |
| | | reelNo?: string; // 销售明细盘号 |
| | | qualityStatus?: number; // 质量状态 |
| | | locationId?: number; // 库位编号 |
| | | locationName?: string; // 库位名称 |
| | |
| | | unitMeasureName?: string; // 计量单位名称 |
| | | batchId?: number; // 批次编号 |
| | | batchCode?: string; // 批次号 |
| | | reelNo?: string; // 生产追溯盘号 |
| | | warehouseId?: number; // 仓库编号 |
| | | warehouseCode?: string; // 仓库编码 |
| | | warehouseName?: string; // 仓库名称 |
| | |
| | | slots: { default: 'productId' }, |
| | | }, |
| | | { |
| | | field: 'reelNo', |
| | | title: '盘号', |
| | | minWidth: 150, |
| | | slots: { default: 'reelNo' }, |
| | | }, |
| | | { |
| | | field: 'productSpecification', |
| | | title: '规格型号', |
| | | minWidth: 120, |
| | |
| | | const newRow = { |
| | | id: undefined, |
| | | productId: undefined, |
| | | reelNo: undefined, |
| | | productUnitName: undefined, |
| | | productPrice: undefined, |
| | | stockCount: undefined, |
| | |
| | | /> |
| | | <span v-else>{{ row.productName || '-' }}</span> |
| | | </template> |
| | | <template #reelNo="{ row }"> |
| | | <Input |
| | | v-if="!disabled" |
| | | v-model:value="row.reelNo" |
| | | :maxlength="128" |
| | | placeholder="手工填写盘号" |
| | | @change="handleRowChange(row)" |
| | | /> |
| | | <span v-else>{{ row.reelNo || '-' }}</span> |
| | | </template> |
| | | <template #needProduction="{ row }"> |
| | | <Select |
| | | v-if="!disabled" |
| | |
| | | <div v-if="item.productSpecification" class="text-xs"> |
| | | {{ item.productSpecification }} |
| | | </div> |
| | | <div v-if="item.reelNo" class="text-xs">盘号:{{ item.reelNo }}</div> |
| | | </td> |
| | | <td class="border border-solid border-[#dcdfe6] p-2 text-center"> |
| | | {{ item.productUnitName || '-' }} |
| | |
| | | import { Button } from 'ant-design-vue'; |
| | | |
| | | import { generateAutoCode } from '#/api/mes/md/autocode/record'; |
| | | import { getRouteProcessByRouteAndProcess } from '#/api/mes/pro/route/process'; |
| | | import { getSimpleUserList } from '#/api/system/user'; |
| | | import { loadParamDetails } from './param-state'; |
| | | |
| | |
| | | { field: 'workstationName', title: '工作站', width: 120 }, |
| | | { field: 'processName', title: '工序', width: 100 }, |
| | | { field: 'workOrderCode', title: '生产订单编码', width: 160 }, |
| | | { field: 'reelNo', title: '盘号', minWidth: 120 }, |
| | | { field: 'itemCode', title: '产品物料编码', width: 120 }, |
| | | { field: 'itemName', title: '产品物料名称', minWidth: 140 }, |
| | | { field: 'itemSpecification', title: '规格型号', width: 120 }, |
| | | { field: 'unitMeasureName', title: '单位', width: 80 }, |
| | | { field: 'feedbackQuantity', title: '报工数量', width: 100 }, |
| | | { field: 'qualifiedQuantity', title: '质检合格数量', width: 120 }, |
| | | { field: 'unqualifiedQuantity', title: '质检不合格数量', width: 130 }, |
| | | { field: 'feedbackUserNickname', title: '报工人', width: 100 }, |
| | | { |
| | | field: 'feedbackTime', |
| | |
| | | * - submit / approve / detail:主体字段只读 |
| | | * |
| | | * 报工只填写"报工数量";合格品/不良品数量由质检确定,报工环节不采集。 |
| | | * 质检工序报工后进入待检验(uncheckQuantity = 报工数量),非质检工序直接完结。 |
| | | * 报工审批后产出均待检验,合格品经检验后入库。 |
| | | */ |
| | | export function useFormSchema( |
| | | formType: FormType, |
| | |
| | | fieldName: 'id', |
| | | component: 'Input', |
| | | dependencies: { triggerFields: [''], show: () => false }, |
| | | }, |
| | | { |
| | | fieldName: 'checkFlag', |
| | | component: 'Input', |
| | | dependencies: { triggerFields: [''], show: () => false }, |
| | | defaultValue: true, |
| | | }, |
| | | { |
| | | fieldName: 'routeId', |
| | |
| | | // 订单变更:清空任务及任务带出的产品信息、数量区域控制位 |
| | | onChange: async () => { |
| | | await formApi?.setValues({ |
| | | checkFlag: true, |
| | | itemCode: undefined, |
| | | itemId: undefined, |
| | | itemName: undefined, |
| | |
| | | workstationId: values.workstationId, |
| | | }), |
| | | }, |
| | | // 任务变更:自动填充关联字段、产品信息、checkFlag,并加载任务绑定的工艺参数 |
| | | // 任务变更:自动填充关联字段、产品信息,并加载任务绑定的工艺参数 |
| | | componentProps: { |
| | | onChange: async (task?: MesProTaskApi.Task) => { |
| | | await loadParamDetails(task?.id); |
| | |
| | | workstationId: task.workstationId, |
| | | reportableQuantity: task.reportableQuantity, |
| | | }); |
| | | // 工艺路线工序的 checkFlag 决定数量区域展示 |
| | | if (task.routeId && task.processId) { |
| | | try { |
| | | const routeProcess = await getRouteProcessByRouteAndProcess( |
| | | task.routeId, |
| | | task.processId, |
| | | ); |
| | | await formApi?.setFieldValue( |
| | | 'checkFlag', |
| | | routeProcess?.checkFlag ?? false, |
| | | ); |
| | | } catch { |
| | | await formApi?.setFieldValue('checkFlag', true); |
| | | } |
| | | } |
| | | }, |
| | | }, |
| | | rules: 'selectRequired', |
| | |
| | | import { useVbenModal } from '@vben/common-ui'; |
| | | |
| | | import { Button, message, Tag } from 'ant-design-vue'; |
| | | import dayjs from 'dayjs'; |
| | | |
| | | import { batchCreateFeedback } from '#/api/mes/pro/feedback'; |
| | | import ProTaskSelectDialog from '#/views/mes/pro/task/components/select-dialog.vue'; |
| | |
| | | selectedTasks.value = []; |
| | | formData.value = { |
| | | feedbackQuantity: undefined, |
| | | feedbackTime: dayjs().format('YYYY-MM-DD HH:mm:ss'), |
| | | remark: '', |
| | | }; |
| | | } |
| | |
| | | const selectedTasks = ref<MesProTaskApi.Task[]>([]); |
| | | const formData = ref({ |
| | | feedbackQuantity: undefined as number | undefined, |
| | | feedbackTime: dayjs().format('YYYY-MM-DD HH:mm:ss'), |
| | | remark: '', |
| | | }); |
| | | const submitting = ref(false); |
| | |
| | | const result = await batchCreateFeedback({ |
| | | taskIds: selectedTasks.value.map((t) => t.id!), |
| | | feedbackQuantity: formData.value.feedbackQuantity, |
| | | feedbackTime: formData.value.feedbackTime || undefined, |
| | | remark: formData.value.remark || undefined, |
| | | }); |
| | | if (result.failCount) { |
| | |
| | | class="!w-full" |
| | | /> |
| | | </a-form-item> |
| | | <a-form-item label="报工时间"> |
| | | <a-date-picker |
| | | v-model:value="formData.feedbackTime" |
| | | show-time |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | class="!w-full" |
| | | /> |
| | | </a-form-item> |
| | | <a-form-item label="备注"> |
| | | <a-textarea |
| | | v-model:value="formData.remark" |
| | |
| | | submitFeedback, |
| | | updateFeedback, |
| | | } from '#/api/mes/pro/feedback'; |
| | | import { getRouteProcessByRouteAndProcess } from '#/api/mes/pro/route/process'; |
| | | import { getWorkOrder } from '#/api/mes/pro/workorder'; |
| | | import { $t } from '#/locales'; |
| | | |
| | |
| | | |
| | | /** 提交前对齐数量:报工只填写报工数量,合格/不良/废品数量由质检确定,报工环节不采集 */ |
| | | function alignQuantity(data: MesProFeedbackApi.Feedback) { |
| | | data.uncheckQuantity = data.checkFlag ? data.feedbackQuantity : 0; |
| | | data.uncheckQuantity = data.feedbackQuantity; |
| | | delete data.qualifiedQuantity; |
| | | delete data.unqualifiedQuantity; |
| | | delete data.laborScrapQuantity; |
| | |
| | | } |
| | | } |
| | | |
| | | /** 加载工序的 checkFlag 用于回显数量区域 */ |
| | | async function resolveCheckFlag(routeId?: number, processId?: number) { |
| | | if (!routeId || !processId) { |
| | | return true; |
| | | } |
| | | try { |
| | | const routeProcess = await getRouteProcessByRouteAndProcess( |
| | | routeId, |
| | | processId, |
| | | ); |
| | | return routeProcess?.checkFlag ?? false; |
| | | } catch { |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | const [Modal, modalApi] = useVbenModal({ |
| | | async onConfirm() { |
| | | if (formType.value === 'detail' || formType.value === 'approve') { |
| | |
| | | try { |
| | | formData.value = await getFeedback(data.id); |
| | | await loadParamDetails(formData.value.taskId); |
| | | const checkFlag = await resolveCheckFlag( |
| | | formData.value.routeId, |
| | | formData.value.processId, |
| | | ); |
| | | // 设置到 values |
| | | await formApi.setValues({ ...formData.value, checkFlag }); |
| | | await formApi.setValues({ ...formData.value }); |
| | | // 记录初始快照(含数量对齐结果),submit 时用于跳过无变更的保存请求 |
| | | originalSnapshot.value = JSON.stringify(await getAlignedData()); |
| | | } finally { |
| | |
| | | { field: 'quantity', title: '产出数量', minWidth: 100 }, |
| | | { field: 'unitMeasureName', title: '单位', minWidth: 80 }, |
| | | { field: 'batchCode', title: '批次号', minWidth: 120 }, |
| | | { field: 'reelNo', title: '盘号', minWidth: 120 }, |
| | | { |
| | | field: 'qualityStatus', |
| | | title: '质量状态', |
| | |
| | | title: '销售订单号', |
| | | width: 180, |
| | | }, |
| | | { field: 'reelNo', title: '盘号', minWidth: 120 }, |
| | | { |
| | | field: 'productCode', |
| | | title: '产品编码', |
| | |
| | | import { Page, useVbenModal } from '@vben/common-ui'; |
| | | import { downloadFileFromBlobPart, isEmpty } from '@vben/utils'; |
| | | |
| | | import { Button, message, Tag } from 'ant-design-vue'; |
| | | import { Button, message, Modal, Tag } from 'ant-design-vue'; |
| | | |
| | | import { ACTION_ICON, TableAction, useVbenVxeGrid } from '#/adapter/vxe-table'; |
| | | import { |
| | |
| | | exportMps, |
| | | getMpsPage, |
| | | issueMps, |
| | | mergeIssueMps, |
| | | batchIssueMps, |
| | | } from '#/api/mes/pro/mps'; |
| | | import { $t } from '#/locales'; |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | /** 合并下发 */ |
| | | async function handleMergeIssue() { |
| | | if (checkedIds.value.length < 2) { |
| | | message.warning('请至少选择2条记录'); |
| | | return; |
| | | } |
| | | // 校验:相同产品、草稿状态 |
| | | const firstRow = checkedRows.value[0]; |
| | | const isSameProduct = checkedRows.value.every( |
| | | (row) => row.productId === firstRow.productId, |
| | | ); |
| | | if (!isSameProduct) { |
| | | message.error('只能选择相同产品的MPS进行合并下发'); |
| | | /** 批量逐条下发,每条计划生成独立工单。 */ |
| | | async function handleBatchIssue() { |
| | | if (checkedIds.value.length === 0) { |
| | | message.warning('请至少选择一条记录'); |
| | | return; |
| | | } |
| | | const isAllDraft = checkedRows.value.every( |
| | | (row) => row.status === MpsStatusEnum.DRAFT, |
| | | ); |
| | | if (!isAllDraft) { |
| | | message.error('只能选择草稿状态的MPS进行合并下发'); |
| | | message.error('请选择草稿状态的生产计划'); |
| | | return; |
| | | } |
| | | const hideLoading = message.loading({ |
| | | content: '合并下发中...', |
| | | content: '批量下发中...', |
| | | duration: 0, |
| | | }); |
| | | try { |
| | | await mergeIssueMps(checkedIds.value); |
| | | message.success('合并下发成功'); |
| | | const results = await batchIssueMps(checkedIds.value); |
| | | const failures = results.filter((item) => item.error); |
| | | if (failures.length) { |
| | | const names = new Map(checkedRows.value.map((row) => [row.id, row.code])); |
| | | Modal.warning({ |
| | | title: `成功 ${results.length - failures.length} 条,失败 ${failures.length} 条`, |
| | | content: failures.map((item) => `${names.get(item.mpsId) || item.mpsId}:${item.error}`).join(';'), |
| | | }); |
| | | } else { |
| | | message.success(`已下发 ${results.length} 条生产计划`); |
| | | } |
| | | handleRefresh(); |
| | | } finally { |
| | | hideLoading(); |
| | |
| | | onClick: handleExport, |
| | | }, |
| | | { |
| | | label: '合并下发', |
| | | label: '批量下发', |
| | | type: 'primary', |
| | | disabled: isEmpty(checkedIds) || checkedIds.length < 2, |
| | | disabled: isEmpty(checkedIds), |
| | | icon: ACTION_ICON.AUDIT, |
| | | auth: ['mes:pro-mps:merge-issue'], |
| | | auth: ['mes:pro-mps:issue'], |
| | | popConfirm: { |
| | | title: '确认合并下发选中的MPS吗?', |
| | | confirm: handleMergeIssue, |
| | | title: '确认逐条下发选中的生产计划吗?每条计划将生成独立工单。', |
| | | confirm: handleBatchIssue, |
| | | }, |
| | | }, |
| | | ]" |
| | |
| | | label: $t('common.detail'), |
| | | type: 'link', |
| | | icon: ACTION_ICON.VIEW, |
| | | auth: ['mes:pro-mps:query'], |
| | | onClick: handleDetail.bind(null, row), |
| | | }, |
| | | { |
| | |
| | | <Descriptions.Item label="销售订单明细ID"> |
| | | {{ formData.saleOrderItemId }} |
| | | </Descriptions.Item> |
| | | <Descriptions.Item label="盘号"> |
| | | {{ formData.reelNo || '-' }} |
| | | </Descriptions.Item> |
| | | <Descriptions.Item label="产品编码"> |
| | | {{ formData.productCode }} |
| | | </Descriptions.Item> |
| | |
| | | import { useVbenModal } from '@vben/common-ui'; |
| | | |
| | | import { message } from 'ant-design-vue'; |
| | | import dayjs from 'dayjs'; |
| | | |
| | | import { quickCreateFeedback } from '#/api/mes/pro/feedback'; |
| | | import { |
| | |
| | | selectedTask.value = undefined; |
| | | formData.value = { |
| | | feedbackQuantity: undefined, |
| | | feedbackTime: dayjs().format('YYYY-MM-DD HH:mm:ss'), |
| | | remark: '', |
| | | }; |
| | | // 预设任务时加载其工艺参数;否则等待选择任务后再加载 |
| | |
| | | const selectedTask = ref<MesProTaskApi.Task>(); |
| | | const formData = ref({ |
| | | feedbackQuantity: undefined as number | undefined, |
| | | feedbackTime: dayjs().format('YYYY-MM-DD HH:mm:ss'), |
| | | remark: '', |
| | | }); |
| | | const submitting = ref(false); |
| | |
| | | await quickCreateFeedback({ |
| | | taskId, |
| | | feedbackQuantity: formData.value.feedbackQuantity, |
| | | feedbackTime: formData.value.feedbackTime || undefined, |
| | | paramValues: paramDetails.value.map((detail) => ({ |
| | | detailId: detail.id, |
| | | value: detail.paramValue, |
| | |
| | | <a-input-number |
| | | v-model:value="formData.feedbackQuantity" |
| | | :min="0.01" |
| | | :max="pendingQuantity || undefined" |
| | | :precision="2" |
| | | placeholder="请输入报工数量" |
| | | class="!w-full" |
| | | /> |
| | | </a-form-item> |
| | | <a-form-item label="报工时间"> |
| | | <a-date-picker |
| | | v-model:value="formData.feedbackTime" |
| | | show-time |
| | | value-format="YYYY-MM-DD HH:mm:ss" |
| | | class="!w-full" |
| | | /> |
| | | </a-form-item> |
| | | <div v-if="paramDetails.length" class="mb-4"> |
| | | <div class="mb-1 font-medium">工艺参数</div> |
| | | <div |
| | |
| | | title: '来源单据编号', |
| | | width: 140, |
| | | }, |
| | | { field: 'reelNo', title: '盘号', minWidth: 120 }, |
| | | { |
| | | field: 'productCode', |
| | | title: '产品编码', |
| | |
| | | title: '订单编号', |
| | | width: 140, |
| | | }, |
| | | { field: 'reelNo', title: '盘号', minWidth: 120 }, |
| | | { |
| | | field: 'productCode', |
| | | title: '产品编号', |
| | |
| | | import { |
| | | DICT_TYPE, |
| | | MesAutoCodeRuleCode, |
| | | MesProTaskStatusEnum, |
| | | } from '@vben/constants'; |
| | | import { getDictOptions } from '@vben/hooks'; |
| | | |
| | |
| | | component: markRaw(ProTaskSelect), |
| | | componentProps: { |
| | | placeholder: '请选择生产任务', |
| | | statuses: [MesProTaskStatusEnum.PREPARE], |
| | | }, |
| | | dependencies: { |
| | | triggerFields: ['sourceDocId', 'workOrderId', 'workstationId'], |
| | | componentProps: (values) => ({ |
| | | disabled: !!values.sourceDocId || !values.workOrderId, |
| | | placeholder: '请选择生产任务', |
| | | statuses: [MesProTaskStatusEnum.PREPARE], |
| | | workOrderId: values.workOrderId, |
| | | workstationId: values.workstationId, |
| | | }), |
| | |
| | | title: '生产订单编号', |
| | | width: 140, |
| | | }, |
| | | { field: 'reelNo', title: '盘号', minWidth: 120 }, |
| | | { |
| | | field: 'itemCode', |
| | | title: '产品物料编码', |
| | |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'reelNo', |
| | | label: '盘号', |
| | | component: 'Input', |
| | | componentProps: { maxlength: 128, placeholder: '请输入盘号' }, |
| | | dependencies: { |
| | | triggerFields: ['sourceDocId'], |
| | | componentProps: (values) => ({ |
| | | disabled: !!values.sourceDocId, |
| | | maxlength: 128, |
| | | placeholder: values.sourceDocId ? '保存后从销售明细带入' : '请输入盘号', |
| | | }), |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'outQuantity', |
| | | label: '发货数量', |
| | | component: 'InputNumber', |
| | |
| | | title: '批次号', |
| | | width: 130, |
| | | }, |
| | | { field: 'reelNo', title: '盘号', minWidth: 120 }, |
| | | { |
| | | field: 'itemCode', |
| | | title: '产品物料编码', |
| | |
| | | title: '来源单据编号', |
| | | width: 160, |
| | | }, |
| | | { field: 'reelNo', title: '盘号', minWidth: 120 }, |
| | | { |
| | | field: 'qcType', |
| | | title: '检验类型', |
| | |
| | | <div v-if="selectedItem" class="leading-6"> |
| | | <div>物料:{{ selectedItem.itemName || '-' }}</div> |
| | | <div>批次:{{ selectedItem.batchCode || '-' }}</div> |
| | | <div>盘号:{{ selectedItem.reelNo || '-' }}</div> |
| | | <div>数量:{{ selectedItem.quantity ?? '-' }}</div> |
| | | <div>仓库:{{ selectedItem.warehouseName || '-' }}</div> |
| | | <div>库区:{{ selectedItem.locationName || '-' }}</div> |
| | |
| | | title: '产品物料名称', |
| | | minWidth: 140, |
| | | }, |
| | | { field: 'reelNo', title: '盘号', minWidth: 120 }, |
| | | { |
| | | field: 'specification', |
| | | title: '规格型号', |
| | |
| | | title: '入库批次号', |
| | | minWidth: 120, |
| | | }, |
| | | { field: 'reelNo', title: '盘号', minWidth: 120 }, |
| | | { |
| | | field: 'warehouseName', |
| | | title: '仓库', |