From f27942c8f916cd3354b3ed59ed75669544ae4df0 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Fri, 29 May 2026 19:24:52 +0800 Subject: [PATCH] =?UTF-8?q?feat(mes):=20=E8=BF=81=E7=A7=BB=20barcode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/mes/wm/barcode/config/data.ts | 98 +++ .../src/views/mes/wm/barcode/config/index.vue | 156 +++++ .../mes/wm/barcode/config/modules/form.vue | 89 +++ .../web-antd/src/views/mes/wm/barcode/data.ts | 599 ++++++++++++++++++ .../src/views/mes/wm/barcode/index.vue | 245 +++++++ .../src/views/mes/wm/barcode/modules/form.vue | 123 ++++ .../src/views/mes/wm/barcode/config/data.ts | 101 +++ .../src/views/mes/wm/barcode/config/index.vue | 160 +++++ .../mes/wm/barcode/config/modules/form.vue | 89 +++ apps/web-ele/src/views/mes/wm/barcode/data.ts | 599 ++++++++++++++++++ .../src/views/mes/wm/barcode/index.vue | 242 +++++++ .../src/views/mes/wm/barcode/modules/form.vue | 123 ++++ 12 files changed, 2624 insertions(+) create mode 100644 apps/web-antd/src/views/mes/wm/barcode/config/data.ts create mode 100644 apps/web-antd/src/views/mes/wm/barcode/config/index.vue create mode 100644 apps/web-antd/src/views/mes/wm/barcode/config/modules/form.vue create mode 100644 apps/web-antd/src/views/mes/wm/barcode/data.ts create mode 100644 apps/web-antd/src/views/mes/wm/barcode/index.vue create mode 100644 apps/web-antd/src/views/mes/wm/barcode/modules/form.vue create mode 100644 apps/web-ele/src/views/mes/wm/barcode/config/data.ts create mode 100644 apps/web-ele/src/views/mes/wm/barcode/config/index.vue create mode 100644 apps/web-ele/src/views/mes/wm/barcode/config/modules/form.vue create mode 100644 apps/web-ele/src/views/mes/wm/barcode/data.ts create mode 100644 apps/web-ele/src/views/mes/wm/barcode/index.vue create mode 100644 apps/web-ele/src/views/mes/wm/barcode/modules/form.vue diff --git a/apps/web-antd/src/views/mes/wm/barcode/config/data.ts b/apps/web-antd/src/views/mes/wm/barcode/config/data.ts new file mode 100644 index 000000000..dc715da79 --- /dev/null +++ b/apps/web-antd/src/views/mes/wm/barcode/config/data.ts @@ -0,0 +1,98 @@ +import type { VbenFormSchema } from '#/adapter/form'; + +import { CommonStatusEnum, DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { z } from '#/adapter/form'; + +// TODO @AI:这里的代码风格不对; +/** 表单 */ +export function useFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { triggerFields: [''], show: () => false }, + }, + { + fieldName: 'format', + label: '条码格式', + component: 'Select', + componentProps: { + options: getDictOptions(DICT_TYPE.MES_WM_BARCODE_FORMAT, 'number'), + placeholder: '请选择条码格式', + }, + rules: 'required', + }, + { + fieldName: 'bizType', + label: '业务类型', + component: 'Select', + componentProps: { + options: getDictOptions(DICT_TYPE.MES_WM_BARCODE_BIZ_TYPE, 'number'), + placeholder: '请选择业务类型', + }, + dependencies: { + triggerFields: ['id'], + componentProps: (values) => ({ + // 编辑时业务类型不允许变更 TODO @AI:这种简单的注释,可以考虑放到 disabled 后面;写到 style 里; + disabled: !!values.id, + }), + }, + rules: 'required', + }, + { + fieldName: 'contentFormat', + label: '内容格式模板', + component: 'Input', + componentProps: { + placeholder: '支持{BUSINESSCODE}占位符,如:WH-{BUSINESSCODE}', + }, + rules: 'required', + }, + { + fieldName: 'contentExample', + label: '内容样例', + component: 'Input', + componentProps: { + placeholder: '如:WH-WH001', + }, + }, + { + fieldName: 'autoGenerateFlag', + label: '自动生成', + component: 'Switch', + componentProps: { + checkedChildren: '是', + unCheckedChildren: '否', + }, + rules: z.boolean().default(true), + }, + { + fieldName: 'defaultTemplate', + label: '默认打印模板', + component: 'Input', + componentProps: { + placeholder: '请输入打印模板', + }, + }, + { + fieldName: 'status', + label: '状态', + component: 'RadioGroup', + componentProps: { + options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), + }, + rules: z.number().default(CommonStatusEnum.ENABLE), + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + componentProps: { + placeholder: '请输入备注', + rows: 2, + }, + }, + ]; +} diff --git a/apps/web-antd/src/views/mes/wm/barcode/config/index.vue b/apps/web-antd/src/views/mes/wm/barcode/config/index.vue new file mode 100644 index 000000000..bf71f29c9 --- /dev/null +++ b/apps/web-antd/src/views/mes/wm/barcode/config/index.vue @@ -0,0 +1,156 @@ + + + diff --git a/apps/web-antd/src/views/mes/wm/barcode/config/modules/form.vue b/apps/web-antd/src/views/mes/wm/barcode/config/modules/form.vue new file mode 100644 index 000000000..fc1ff9725 --- /dev/null +++ b/apps/web-antd/src/views/mes/wm/barcode/config/modules/form.vue @@ -0,0 +1,89 @@ + + + diff --git a/apps/web-antd/src/views/mes/wm/barcode/data.ts b/apps/web-antd/src/views/mes/wm/barcode/data.ts new file mode 100644 index 000000000..6e20264cc --- /dev/null +++ b/apps/web-antd/src/views/mes/wm/barcode/data.ts @@ -0,0 +1,599 @@ +import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { MesWmBarcodeApi } from '#/api/mes/wm/barcode'; +import type { MesWmBarcodeConfigApi } from '#/api/mes/wm/barcode/config'; + +import { markRaw } from 'vue'; + +import { CommonStatusEnum, DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { z } from '#/adapter/form'; +import { generateBarcodeContent } from '#/api/mes/wm/barcode'; +import DvMachinerySelect from '#/views/mes/dv/machinery/components/dv-machinery-select.vue'; +import MdClientSelect from '#/views/mes/md/client/components/md-client-select.vue'; +import MdItemSelect from '#/views/mes/md/item/components/md-item-select.vue'; +import MdVendorSelect from '#/views/mes/md/vendor/components/md-vendor-select.vue'; +import MdWorkshopSelect from '#/views/mes/md/workstation/components/md-workshop-select.vue'; +import MdWorkstationSelect from '#/views/mes/md/workstation/components/md-workstation-select.vue'; +import ProWorkOrderSelect from '#/views/mes/pro/workorder/components/pro-work-order-select.vue'; +import TmToolSelect from '#/views/mes/tm/tool/components/tm-tool-select.vue'; +import { BarcodeBizTypeEnum } from '#/views/mes/utils/constants'; + +import WmMaterialStockSelect from './../materialstock/components/wm-material-stock-select.vue'; +import { + WmWarehouseAreaSelect, + WmWarehouseLocationSelect, + WmWarehouseSelect, +} from './../warehouse/components'; + +/** 业务对象选中后回填业务编码、业务名称、条码内容 */ +async function applyBizSelected(formApi: VbenFormApi, item: any) { + const values = await formApi.getValues(); + const bizType = values.bizType as number | undefined; + if (!item) { + await formApi.setValues({ + bizCode: undefined, + bizName: undefined, + content: undefined, + }); + return; + } + let bizCode: string | undefined; + let bizName: string | undefined; + if (bizType === BarcodeBizTypeEnum.STOCK) { + bizCode = item.itemCode; + bizName = item.itemName; + } else { + bizCode = item.code || item.username; + bizName = item.name || item.nickname; + } + let content: string | undefined; + if (bizType && bizCode) { + try { + content = await generateBarcodeContent(bizType, bizCode); + } catch (error) { + console.error('生成条码内容失败:', error); + } + } + await formApi.setValues({ bizCode, bizName, content }); +} + +/** 新增/修改条码的表单 */ +export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { + // TODO @AI:是不是可以去掉 onBizChange,直接搞个 handleBizTypeChange 函数? + const onBizChange = (item: any) => { + if (formApi) { + void applyBizSelected(formApi, item); + } + }; + + return [ + { + fieldName: 'bizType', + label: '业务类型', + component: 'Select', + componentProps: { + options: getDictOptions(DICT_TYPE.MES_WM_BARCODE_BIZ_TYPE, 'number'), + placeholder: '请选择业务类型', + // 业务类型变更时清空业务字段 + onChange: () => + formApi?.setValues({ + bizId: undefined, + bizCode: undefined, + bizName: undefined, + content: undefined, + locationWarehouseId: undefined, + areaWarehouseId: undefined, + areaLocationId: undefined, + }), + }, + rules: 'required', + }, + // ==================== 业务对象选择器(按 bizType 切换) ==================== + { + fieldName: 'bizId', + label: '仓库', + component: markRaw(WmWarehouseSelect), + componentProps: { + onChange: onBizChange, + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => values.bizType === BarcodeBizTypeEnum.WAREHOUSE, + }, + rules: 'required', + }, + { + fieldName: 'locationWarehouseId', + label: '库区·仓库', + component: markRaw(WmWarehouseSelect), + componentProps: { + placeholder: '请选择仓库', + onChange: () => + formApi?.setValues({ + bizId: undefined, + bizCode: undefined, + bizName: undefined, + content: undefined, + }), + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => values.bizType === BarcodeBizTypeEnum.LOCATION, + }, + }, + { + fieldName: 'bizId', + label: '库区', + component: markRaw(WmWarehouseLocationSelect), + dependencies: { + triggerFields: ['bizType', 'locationWarehouseId'], + show: (values) => values.bizType === BarcodeBizTypeEnum.LOCATION, + componentProps: (values) => ({ + placeholder: '请选择库区', + warehouseId: values.locationWarehouseId, + onChange: onBizChange, + }), + }, + rules: 'required', + }, + { + fieldName: 'areaWarehouseId', + label: '库位·仓库', + component: markRaw(WmWarehouseSelect), + componentProps: { + placeholder: '请选择仓库', + onChange: () => + formApi?.setValues({ + areaLocationId: undefined, + bizId: undefined, + bizCode: undefined, + bizName: undefined, + content: undefined, + }), + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => values.bizType === BarcodeBizTypeEnum.AREA, + }, + }, + { + fieldName: 'areaLocationId', + label: '库位·库区', + component: markRaw(WmWarehouseLocationSelect), + dependencies: { + triggerFields: ['bizType', 'areaWarehouseId'], + show: (values) => values.bizType === BarcodeBizTypeEnum.AREA, + componentProps: (values) => ({ + placeholder: '请选择库区', + warehouseId: values.areaWarehouseId, + onChange: () => + formApi?.setValues({ + bizId: undefined, + bizCode: undefined, + bizName: undefined, + content: undefined, + }), + }), + }, + }, + { + fieldName: 'bizId', + label: '库位', + component: markRaw(WmWarehouseAreaSelect), + dependencies: { + triggerFields: ['bizType', 'areaLocationId'], + show: (values) => values.bizType === BarcodeBizTypeEnum.AREA, + componentProps: (values) => ({ + placeholder: '请选择库位', + locationId: values.areaLocationId, + onChange: onBizChange, + }), + }, + rules: 'required', + }, + { + fieldName: 'bizId', + label: '工单', + component: markRaw(ProWorkOrderSelect), + componentProps: { + onChange: onBizChange, + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => values.bizType === BarcodeBizTypeEnum.WORKORDER, + }, + rules: 'required', + }, + { + fieldName: 'bizId', + label: '设备', + component: markRaw(DvMachinerySelect), + componentProps: { + onChange: onBizChange, + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => values.bizType === BarcodeBizTypeEnum.MACHINERY, + }, + rules: 'required', + }, + { + fieldName: 'bizId', + label: '产品物料', + component: markRaw(MdItemSelect), + componentProps: { + onChange: onBizChange, + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => values.bizType === BarcodeBizTypeEnum.ITEM, + }, + rules: 'required', + }, + { + fieldName: 'bizId', + label: '供应商', + component: markRaw(MdVendorSelect), + componentProps: { + onChange: onBizChange, + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => values.bizType === BarcodeBizTypeEnum.VENDOR, + }, + rules: 'required', + }, + { + fieldName: 'bizId', + label: '工作站', + component: markRaw(MdWorkstationSelect), + componentProps: { + onChange: onBizChange, + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => values.bizType === BarcodeBizTypeEnum.WORKSTATION, + }, + rules: 'required', + }, + { + fieldName: 'bizId', + label: '车间', + component: markRaw(MdWorkshopSelect), + componentProps: { + onChange: onBizChange, + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => values.bizType === BarcodeBizTypeEnum.WORKSHOP, + }, + rules: 'required', + }, + { + fieldName: 'bizId', + label: '客户', + component: markRaw(MdClientSelect), + componentProps: { + onChange: onBizChange, + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => values.bizType === BarcodeBizTypeEnum.CLIENT, + }, + rules: 'required', + }, + { + fieldName: 'bizId', + label: '工具', + component: markRaw(TmToolSelect), + componentProps: { + onChange: onBizChange, + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => values.bizType === BarcodeBizTypeEnum.TOOL, + }, + rules: 'required', + }, + { + fieldName: 'bizId', + label: '库存', + component: markRaw(WmMaterialStockSelect), + componentProps: { + onChange: onBizChange, + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => values.bizType === BarcodeBizTypeEnum.STOCK, + }, + rules: 'required', + }, + { + fieldName: 'bizId', + label: '业务编号', + component: 'InputNumber', + componentProps: { + class: '!w-full', + min: 1, + placeholder: '请输入业务编号', + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => + values.bizType !== undefined && + ![ + BarcodeBizTypeEnum.AREA, + BarcodeBizTypeEnum.CLIENT, + BarcodeBizTypeEnum.ITEM, + BarcodeBizTypeEnum.LOCATION, + BarcodeBizTypeEnum.MACHINERY, + BarcodeBizTypeEnum.STOCK, + BarcodeBizTypeEnum.TOOL, + BarcodeBizTypeEnum.VENDOR, + BarcodeBizTypeEnum.WAREHOUSE, + BarcodeBizTypeEnum.WORKORDER, + BarcodeBizTypeEnum.WORKSHOP, + BarcodeBizTypeEnum.WORKSTATION, + ].includes(values.bizType), + }, + }, + { + fieldName: 'bizCode', + label: '业务编码', + component: 'Input', + componentProps: { + disabled: true, + placeholder: '自动填充', + }, + }, + { + fieldName: 'bizName', + label: '业务名称', + component: 'Input', + componentProps: { + disabled: true, + placeholder: '自动填充', + }, + }, + { + fieldName: 'content', + label: '条码内容', + component: 'Input', + componentProps: { + placeholder: '请输入条码内容或自动生成', + }, + rules: 'required', + }, + { + fieldName: 'status', + label: '状态', + component: 'RadioGroup', + componentProps: { + options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), + }, + rules: z.number().default(CommonStatusEnum.ENABLE), + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + componentProps: { + placeholder: '请输入备注', + rows: 2, + }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'bizType', + label: '业务类型', + component: 'Select', + componentProps: { + allowClear: true, + options: getDictOptions(DICT_TYPE.MES_WM_BARCODE_BIZ_TYPE, 'number'), + placeholder: '请选择业务类型', + }, + }, + { + fieldName: 'bizCode', + label: '业务编码', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入业务编码', + }, + }, + { + fieldName: 'bizName', + label: '业务名称', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入业务名称', + }, + }, + { + fieldName: 'content', + label: '条码内容', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入条码内容', + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + type: 'checkbox', + width: 50, + }, + { + field: 'content', + title: '条码', + width: 180, + slots: { default: 'barcode' }, + }, + { + field: 'format', + title: '条码格式', + width: 110, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_WM_BARCODE_FORMAT }, + }, + }, + { + field: 'bizType', + title: '业务类型', + width: 110, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_WM_BARCODE_BIZ_TYPE }, + }, + }, + { + field: 'content', + title: '条码内容', + minWidth: 160, + }, + { + field: 'bizCode', + title: '业务编码', + width: 130, + }, + { + field: 'bizName', + title: '业务名称', + minWidth: 140, + }, + { + field: 'status', + title: '状态', + width: 90, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.COMMON_STATUS }, + }, + }, + { + title: '操作', + width: 200, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 配置列表的搜索表单 */ +export function useConfigGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'format', + label: '条码格式', + component: 'Select', + componentProps: { + allowClear: true, + options: getDictOptions(DICT_TYPE.MES_WM_BARCODE_FORMAT, 'number'), + placeholder: '请选择条码格式', + }, + }, + { + fieldName: 'bizType', + label: '业务类型', + component: 'Select', + componentProps: { + allowClear: true, + options: getDictOptions(DICT_TYPE.MES_WM_BARCODE_BIZ_TYPE, 'number'), + placeholder: '请选择业务类型', + }, + }, + ]; +} + +/** 配置列表的字段 */ +export function useConfigGridColumns( + onAutoGenerateChange: ( + row: MesWmBarcodeConfigApi.BarcodeConfig, + ) => Promise, +): VxeTableGridOptions['columns'] { + return [ + { + field: 'id', + title: '编号', + width: 100, + }, + { + field: 'format', + title: '条码格式', + width: 110, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_WM_BARCODE_FORMAT }, + }, + }, + { + field: 'bizType', + title: '业务类型', + width: 110, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_WM_BARCODE_BIZ_TYPE }, + }, + }, + { + field: 'contentFormat', + title: '内容格式', + minWidth: 160, + }, + { + field: 'contentExample', + title: '内容样例', + minWidth: 160, + }, + { + field: 'defaultTemplate', + title: '默认打印模板', + minWidth: 140, + }, + { + field: 'autoGenerateFlag', + title: '自动生成', + width: 100, + cellRender: { + name: 'CellSwitch', + attrs: { beforeChange: onAutoGenerateChange }, + }, + }, + { + field: 'status', + title: '状态', + width: 90, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.COMMON_STATUS }, + }, + }, + { + field: 'createTime', + title: '创建时间', + width: 180, + formatter: 'formatDateTime', + }, + { + title: '操作', + width: 160, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-antd/src/views/mes/wm/barcode/index.vue b/apps/web-antd/src/views/mes/wm/barcode/index.vue new file mode 100644 index 000000000..0e64bb09f --- /dev/null +++ b/apps/web-antd/src/views/mes/wm/barcode/index.vue @@ -0,0 +1,245 @@ + + + diff --git a/apps/web-antd/src/views/mes/wm/barcode/modules/form.vue b/apps/web-antd/src/views/mes/wm/barcode/modules/form.vue new file mode 100644 index 000000000..fdb634d92 --- /dev/null +++ b/apps/web-antd/src/views/mes/wm/barcode/modules/form.vue @@ -0,0 +1,123 @@ + + + diff --git a/apps/web-ele/src/views/mes/wm/barcode/config/data.ts b/apps/web-ele/src/views/mes/wm/barcode/config/data.ts new file mode 100644 index 000000000..a4db5ed2b --- /dev/null +++ b/apps/web-ele/src/views/mes/wm/barcode/config/data.ts @@ -0,0 +1,101 @@ +import type { VbenFormSchema } from '#/adapter/form'; + +import { CommonStatusEnum, DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { z } from '#/adapter/form'; + +/** 表单 */ +export function useFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'id', + component: 'Input', + dependencies: { + triggerFields: [''], + show: () => false, + }, + }, + { + fieldName: 'format', + label: '条码格式', + component: 'Select', + componentProps: { + options: getDictOptions(DICT_TYPE.MES_WM_BARCODE_FORMAT, 'number'), + placeholder: '请选择条码格式', + }, + rules: 'required', + }, + { + fieldName: 'bizType', + label: '业务类型', + component: 'Select', + componentProps: { + options: getDictOptions(DICT_TYPE.MES_WM_BARCODE_BIZ_TYPE, 'number'), + placeholder: '请选择业务类型', + }, + dependencies: { + triggerFields: ['id'], + componentProps: (values) => ({ + // 编辑时业务类型不允许变更 + disabled: !!values.id, + }), + }, + rules: 'required', + }, + { + fieldName: 'contentFormat', + label: '内容格式模板', + component: 'Input', + componentProps: { + placeholder: '支持{BUSINESSCODE}占位符,如:WH-{BUSINESSCODE}', + }, + rules: 'required', + }, + { + fieldName: 'contentExample', + label: '内容样例', + component: 'Input', + componentProps: { + placeholder: '如:WH-WH001', + }, + }, + { + fieldName: 'autoGenerateFlag', + label: '自动生成', + component: 'Switch', + componentProps: { + activeText: '是', + inactiveText: '否', + inlinePrompt: true, + }, + rules: z.boolean().default(true), + }, + { + fieldName: 'defaultTemplate', + label: '默认打印模板', + component: 'Input', + componentProps: { + placeholder: '请输入打印模板', + }, + }, + { + fieldName: 'status', + label: '状态', + component: 'RadioGroup', + componentProps: { + options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), + }, + rules: z.number().default(CommonStatusEnum.ENABLE), + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + componentProps: { + placeholder: '请输入备注', + rows: 2, + }, + }, + ]; +} diff --git a/apps/web-ele/src/views/mes/wm/barcode/config/index.vue b/apps/web-ele/src/views/mes/wm/barcode/config/index.vue new file mode 100644 index 000000000..57b87a676 --- /dev/null +++ b/apps/web-ele/src/views/mes/wm/barcode/config/index.vue @@ -0,0 +1,160 @@ + + + diff --git a/apps/web-ele/src/views/mes/wm/barcode/config/modules/form.vue b/apps/web-ele/src/views/mes/wm/barcode/config/modules/form.vue new file mode 100644 index 000000000..092080a7e --- /dev/null +++ b/apps/web-ele/src/views/mes/wm/barcode/config/modules/form.vue @@ -0,0 +1,89 @@ + + + diff --git a/apps/web-ele/src/views/mes/wm/barcode/data.ts b/apps/web-ele/src/views/mes/wm/barcode/data.ts new file mode 100644 index 000000000..6a97762f7 --- /dev/null +++ b/apps/web-ele/src/views/mes/wm/barcode/data.ts @@ -0,0 +1,599 @@ +import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { MesWmBarcodeApi } from '#/api/mes/wm/barcode'; +import type { MesWmBarcodeConfigApi } from '#/api/mes/wm/barcode/config'; + +import { markRaw } from 'vue'; + +import { CommonStatusEnum, DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; + +import { z } from '#/adapter/form'; +import { generateBarcodeContent } from '#/api/mes/wm/barcode'; +import DvMachinerySelect from '#/views/mes/dv/machinery/components/dv-machinery-select.vue'; +import MdClientSelect from '#/views/mes/md/client/components/md-client-select.vue'; +import MdItemSelect from '#/views/mes/md/item/components/md-item-select.vue'; +import MdVendorSelect from '#/views/mes/md/vendor/components/md-vendor-select.vue'; +import MdWorkshopSelect from '#/views/mes/md/workstation/components/md-workshop-select.vue'; +import MdWorkstationSelect from '#/views/mes/md/workstation/components/md-workstation-select.vue'; +import ProWorkOrderSelect from '#/views/mes/pro/workorder/components/pro-work-order-select.vue'; +import TmToolSelect from '#/views/mes/tm/tool/components/tm-tool-select.vue'; +import { BarcodeBizTypeEnum } from '#/views/mes/utils/constants'; + +import WmMaterialStockSelect from './../materialstock/components/wm-material-stock-select.vue'; +import { + WmWarehouseAreaSelect, + WmWarehouseLocationSelect, + WmWarehouseSelect, +} from './../warehouse/components'; + +/** 业务对象选中后回填业务编码、业务名称、条码内容 */ +async function applyBizSelected(formApi: VbenFormApi, item: any) { + const values = await formApi.getValues(); + const bizType = values.bizType as number | undefined; + if (!item) { + await formApi.setValues({ + bizCode: undefined, + bizName: undefined, + content: undefined, + }); + return; + } + let bizCode: string | undefined; + let bizName: string | undefined; + if (bizType === BarcodeBizTypeEnum.STOCK) { + bizCode = item.itemCode; + bizName = item.itemName; + } else { + bizCode = item.code || item.username; + bizName = item.name || item.nickname; + } + let content: string | undefined; + if (bizType && bizCode) { + try { + content = await generateBarcodeContent(bizType, bizCode); + } catch (error) { + console.error('生成条码内容失败:', error); + } + } + await formApi.setValues({ bizCode, bizName, content }); +} + +/** 新增/修改条码的表单 */ +export function useFormSchema(formApi?: VbenFormApi): VbenFormSchema[] { + const onBizChange = (item: any) => { + if (formApi) { + void applyBizSelected(formApi, item); + } + }; + + return [ + { + fieldName: 'bizType', + label: '业务类型', + component: 'Select', + componentProps: { + // 业务类型变更时清空业务字段 + onChange: () => + formApi?.setValues({ + bizId: undefined, + bizCode: undefined, + bizName: undefined, + content: undefined, + locationWarehouseId: undefined, + areaWarehouseId: undefined, + areaLocationId: undefined, + }), + options: getDictOptions(DICT_TYPE.MES_WM_BARCODE_BIZ_TYPE, 'number'), + placeholder: '请选择业务类型', + }, + rules: 'required', + }, + // ==================== 业务对象选择器(按 bizType 切换) ==================== + { + fieldName: 'bizId', + label: '仓库', + component: markRaw(WmWarehouseSelect), + componentProps: { + onChange: onBizChange, + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => values.bizType === BarcodeBizTypeEnum.WAREHOUSE, + }, + rules: 'required', + }, + { + fieldName: 'locationWarehouseId', + label: '库区·仓库', + component: markRaw(WmWarehouseSelect), + componentProps: { + onChange: () => + formApi?.setValues({ + bizId: undefined, + bizCode: undefined, + bizName: undefined, + content: undefined, + }), + placeholder: '请选择仓库', + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => values.bizType === BarcodeBizTypeEnum.LOCATION, + }, + }, + { + fieldName: 'bizId', + label: '库区', + component: markRaw(WmWarehouseLocationSelect), + dependencies: { + triggerFields: ['bizType', 'locationWarehouseId'], + show: (values) => values.bizType === BarcodeBizTypeEnum.LOCATION, + componentProps: (values) => ({ + onChange: onBizChange, + placeholder: '请选择库区', + warehouseId: values.locationWarehouseId, + }), + }, + rules: 'required', + }, + { + fieldName: 'areaWarehouseId', + label: '库位·仓库', + component: markRaw(WmWarehouseSelect), + componentProps: { + onChange: () => + formApi?.setValues({ + areaLocationId: undefined, + bizId: undefined, + bizCode: undefined, + bizName: undefined, + content: undefined, + }), + placeholder: '请选择仓库', + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => values.bizType === BarcodeBizTypeEnum.AREA, + }, + }, + { + fieldName: 'areaLocationId', + label: '库位·库区', + component: markRaw(WmWarehouseLocationSelect), + dependencies: { + triggerFields: ['bizType', 'areaWarehouseId'], + show: (values) => values.bizType === BarcodeBizTypeEnum.AREA, + componentProps: (values) => ({ + onChange: () => + formApi?.setValues({ + bizId: undefined, + bizCode: undefined, + bizName: undefined, + content: undefined, + }), + placeholder: '请选择库区', + warehouseId: values.areaWarehouseId, + }), + }, + }, + { + fieldName: 'bizId', + label: '库位', + component: markRaw(WmWarehouseAreaSelect), + dependencies: { + triggerFields: ['bizType', 'areaLocationId'], + show: (values) => values.bizType === BarcodeBizTypeEnum.AREA, + componentProps: (values) => ({ + locationId: values.areaLocationId, + onChange: onBizChange, + placeholder: '请选择库位', + }), + }, + rules: 'required', + }, + { + fieldName: 'bizId', + label: '工单', + component: markRaw(ProWorkOrderSelect), + componentProps: { + onChange: onBizChange, + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => values.bizType === BarcodeBizTypeEnum.WORKORDER, + }, + rules: 'required', + }, + { + fieldName: 'bizId', + label: '设备', + component: markRaw(DvMachinerySelect), + componentProps: { + onChange: onBizChange, + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => values.bizType === BarcodeBizTypeEnum.MACHINERY, + }, + rules: 'required', + }, + { + fieldName: 'bizId', + label: '产品物料', + component: markRaw(MdItemSelect), + componentProps: { + onChange: onBizChange, + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => values.bizType === BarcodeBizTypeEnum.ITEM, + }, + rules: 'required', + }, + { + fieldName: 'bizId', + label: '供应商', + component: markRaw(MdVendorSelect), + componentProps: { + onChange: onBizChange, + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => values.bizType === BarcodeBizTypeEnum.VENDOR, + }, + rules: 'required', + }, + { + fieldName: 'bizId', + label: '工作站', + component: markRaw(MdWorkstationSelect), + componentProps: { + onChange: onBizChange, + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => values.bizType === BarcodeBizTypeEnum.WORKSTATION, + }, + rules: 'required', + }, + { + fieldName: 'bizId', + label: '车间', + component: markRaw(MdWorkshopSelect), + componentProps: { + onChange: onBizChange, + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => values.bizType === BarcodeBizTypeEnum.WORKSHOP, + }, + rules: 'required', + }, + { + fieldName: 'bizId', + label: '客户', + component: markRaw(MdClientSelect), + componentProps: { + onChange: onBizChange, + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => values.bizType === BarcodeBizTypeEnum.CLIENT, + }, + rules: 'required', + }, + { + fieldName: 'bizId', + label: '工具', + component: markRaw(TmToolSelect), + componentProps: { + onChange: onBizChange, + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => values.bizType === BarcodeBizTypeEnum.TOOL, + }, + rules: 'required', + }, + { + fieldName: 'bizId', + label: '库存', + component: markRaw(WmMaterialStockSelect), + componentProps: { + onChange: onBizChange, + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => values.bizType === BarcodeBizTypeEnum.STOCK, + }, + rules: 'required', + }, + { + fieldName: 'bizId', + label: '业务编号', + component: 'InputNumber', + componentProps: { + class: '!w-full', + controlsPosition: 'right', + min: 1, + placeholder: '请输入业务编号', + }, + dependencies: { + triggerFields: ['bizType'], + show: (values) => + values.bizType !== undefined && + ![ + BarcodeBizTypeEnum.AREA, + BarcodeBizTypeEnum.CLIENT, + BarcodeBizTypeEnum.ITEM, + BarcodeBizTypeEnum.LOCATION, + BarcodeBizTypeEnum.MACHINERY, + BarcodeBizTypeEnum.STOCK, + BarcodeBizTypeEnum.TOOL, + BarcodeBizTypeEnum.VENDOR, + BarcodeBizTypeEnum.WAREHOUSE, + BarcodeBizTypeEnum.WORKORDER, + BarcodeBizTypeEnum.WORKSHOP, + BarcodeBizTypeEnum.WORKSTATION, + ].includes(values.bizType), + }, + }, + { + fieldName: 'bizCode', + label: '业务编码', + component: 'Input', + componentProps: { + disabled: true, + placeholder: '自动填充', + }, + }, + { + fieldName: 'bizName', + label: '业务名称', + component: 'Input', + componentProps: { + disabled: true, + placeholder: '自动填充', + }, + }, + { + fieldName: 'content', + label: '条码内容', + component: 'Input', + componentProps: { + placeholder: '请输入条码内容或自动生成', + }, + rules: 'required', + }, + { + fieldName: 'status', + label: '状态', + component: 'RadioGroup', + componentProps: { + options: getDictOptions(DICT_TYPE.COMMON_STATUS, 'number'), + }, + rules: z.number().default(CommonStatusEnum.ENABLE), + }, + { + fieldName: 'remark', + label: '备注', + component: 'Textarea', + componentProps: { + placeholder: '请输入备注', + rows: 2, + }, + }, + ]; +} + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'bizType', + label: '业务类型', + component: 'Select', + componentProps: { + clearable: true, + options: getDictOptions(DICT_TYPE.MES_WM_BARCODE_BIZ_TYPE, 'number'), + placeholder: '请选择业务类型', + }, + }, + { + fieldName: 'bizCode', + label: '业务编码', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入业务编码', + }, + }, + { + fieldName: 'bizName', + label: '业务名称', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入业务名称', + }, + }, + { + fieldName: 'content', + label: '条码内容', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入条码内容', + }, + }, + ]; +} + +/** 列表的字段 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + type: 'checkbox', + width: 50, + }, + { + field: 'content', + title: '条码', + width: 180, + slots: { default: 'barcode' }, + }, + { + field: 'format', + title: '条码格式', + width: 110, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_WM_BARCODE_FORMAT }, + }, + }, + { + field: 'bizType', + title: '业务类型', + width: 110, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_WM_BARCODE_BIZ_TYPE }, + }, + }, + { + field: 'content', + title: '条码内容', + minWidth: 160, + }, + { + field: 'bizCode', + title: '业务编码', + width: 130, + }, + { + field: 'bizName', + title: '业务名称', + minWidth: 140, + }, + { + field: 'status', + title: '状态', + width: 90, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.COMMON_STATUS }, + }, + }, + { + title: '操作', + width: 200, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} + +/** 配置列表的搜索表单 */ +export function useConfigGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'format', + label: '条码格式', + component: 'Select', + componentProps: { + clearable: true, + options: getDictOptions(DICT_TYPE.MES_WM_BARCODE_FORMAT, 'number'), + placeholder: '请选择条码格式', + }, + }, + { + fieldName: 'bizType', + label: '业务类型', + component: 'Select', + componentProps: { + clearable: true, + options: getDictOptions(DICT_TYPE.MES_WM_BARCODE_BIZ_TYPE, 'number'), + placeholder: '请选择业务类型', + }, + }, + ]; +} + +/** 配置列表的字段 */ +export function useConfigGridColumns( + onAutoGenerateChange: ( + row: MesWmBarcodeConfigApi.BarcodeConfig, + ) => Promise, +): VxeTableGridOptions['columns'] { + return [ + { + field: 'id', + title: '编号', + width: 100, + }, + { + field: 'format', + title: '条码格式', + width: 110, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_WM_BARCODE_FORMAT }, + }, + }, + { + field: 'bizType', + title: '业务类型', + width: 110, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.MES_WM_BARCODE_BIZ_TYPE }, + }, + }, + { + field: 'contentFormat', + title: '内容格式', + minWidth: 160, + }, + { + field: 'contentExample', + title: '内容样例', + minWidth: 160, + }, + { + field: 'defaultTemplate', + title: '默认打印模板', + minWidth: 140, + }, + { + field: 'autoGenerateFlag', + title: '自动生成', + width: 100, + cellRender: { + name: 'CellSwitch', + attrs: { beforeChange: onAutoGenerateChange }, + }, + }, + { + field: 'status', + title: '状态', + width: 90, + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.COMMON_STATUS }, + }, + }, + { + field: 'createTime', + title: '创建时间', + width: 180, + formatter: 'formatDateTime', + }, + { + title: '操作', + width: 160, + fixed: 'right', + slots: { default: 'actions' }, + }, + ]; +} diff --git a/apps/web-ele/src/views/mes/wm/barcode/index.vue b/apps/web-ele/src/views/mes/wm/barcode/index.vue new file mode 100644 index 000000000..95e42d800 --- /dev/null +++ b/apps/web-ele/src/views/mes/wm/barcode/index.vue @@ -0,0 +1,242 @@ + + + diff --git a/apps/web-ele/src/views/mes/wm/barcode/modules/form.vue b/apps/web-ele/src/views/mes/wm/barcode/modules/form.vue new file mode 100644 index 000000000..417398449 --- /dev/null +++ b/apps/web-ele/src/views/mes/wm/barcode/modules/form.vue @@ -0,0 +1,123 @@ + + +