From 3d0917f1a9d36f4acd6e1bcf8b192edc512bd982 Mon Sep 17 00:00:00 2001 From: YunaiV Date: Mon, 18 May 2026 23:15:34 +0800 Subject: [PATCH] =?UTF-8?q?feat=EF=BC=88wms=EF=BC=89=EF=BC=9A=E5=AE=8C?= =?UTF-8?q?=E6=88=90=20inventory=20index=20=E7=9A=84=E8=BF=81=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/views/wms/inventory/index/data.ts | 249 ++++++++++++++++++ .../src/views/wms/inventory/index/index.vue | 193 ++++++++++++++ .../src/views/wms/inventory/index/data.ts | 247 +++++++++++++++++ .../src/views/wms/inventory/index/index.vue | 193 ++++++++++++++ 4 files changed, 882 insertions(+) create mode 100644 apps/web-antd/src/views/wms/inventory/index/data.ts create mode 100644 apps/web-antd/src/views/wms/inventory/index/index.vue create mode 100644 apps/web-ele/src/views/wms/inventory/index/data.ts create mode 100644 apps/web-ele/src/views/wms/inventory/index/index.vue diff --git a/apps/web-antd/src/views/wms/inventory/index/data.ts b/apps/web-antd/src/views/wms/inventory/index/data.ts new file mode 100644 index 000000000..90479ca7a --- /dev/null +++ b/apps/web-antd/src/views/wms/inventory/index/data.ts @@ -0,0 +1,249 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; + +import { getWarehouseSimpleList } from '#/api/wms/md/warehouse'; + +export const INVENTORY_DIMENSION = { + ITEM: 'item', + WAREHOUSE: 'warehouse', +} as const; + +export type InventoryDimension = + (typeof INVENTORY_DIMENSION)[keyof typeof INVENTORY_DIMENSION]; + +const dimensionOptions = [ + { label: '仓库', value: INVENTORY_DIMENSION.WAREHOUSE }, + { label: '商品', value: INVENTORY_DIMENSION.ITEM }, +]; + +interface DimensionChangeEvent { + target?: { + value?: InventoryDimension; + }; +} + +type DimensionChangeHandler = ( + dimension: InventoryDimension, +) => Promise | void; + +/** 统一解析 antd 事件对象和原始维度值 */ +function getDimensionChangeValue( + value?: DimensionChangeEvent | InventoryDimension, +): InventoryDimension { + if ( + value === INVENTORY_DIMENSION.ITEM || + value === INVENTORY_DIMENSION.WAREHOUSE + ) { + return value; + } + return value?.target?.value ?? INVENTORY_DIMENSION.WAREHOUSE; +} + +/** 搜索表单 */ +export function useGridFormSchema( + onDimensionChange: DimensionChangeHandler, +): VbenFormSchema[] { + return [ + { + fieldName: 'type', + label: '统计维度', + component: 'RadioGroup', + defaultValue: INVENTORY_DIMENSION.WAREHOUSE, + componentProps: { + buttonStyle: 'solid', + optionType: 'button', + options: dimensionOptions, + onChange: (value: DimensionChangeEvent | InventoryDimension) => { + void onDimensionChange(getDimensionChangeValue(value)); + }, + }, + }, + { + fieldName: 'warehouseId', + label: '仓库', + component: 'ApiSelect', + componentProps: { + allowClear: true, + api: getWarehouseSimpleList, + labelField: 'name', + placeholder: '请选择仓库', + showSearch: true, + valueField: 'id', + }, + }, + { + fieldName: 'itemName', + label: '商品名称', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入商品名称', + }, + }, + { + fieldName: 'itemCode', + label: '商品编号', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入商品编号', + }, + }, + { + fieldName: 'skuName', + label: '规格名称', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入规格名称', + }, + }, + { + fieldName: 'skuCode', + label: '规格编号', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入规格编号', + }, + }, + ]; +} + +const warehouseDimensionColumns: VxeTableGridOptions['columns'] = [ + { + field: 'warehouseId', + title: '仓库', + minWidth: 160, + slots: { default: 'warehouseName' }, + }, + { + field: 'warehouseItemId', + title: '商品信息', + minWidth: 240, + slots: { default: 'itemInfo' }, + }, + { + field: 'skuId', + title: '规格信息', + minWidth: 220, + slots: { default: 'skuInfo' }, + }, + { + field: 'quantity', + title: '库存', + align: 'right', + minWidth: 130, + slots: { default: 'quantity' }, + }, +]; + +const itemDimensionColumns: VxeTableGridOptions['columns'] = [ + { + field: 'warehouseItemId', + title: '商品信息', + minWidth: 240, + slots: { default: 'itemInfo' }, + }, + { + field: 'skuId', + title: '规格信息', + minWidth: 220, + slots: { default: 'skuInfo' }, + }, + { + field: 'warehouseId', + title: '仓库', + minWidth: 160, + slots: { default: 'warehouseName' }, + }, + { + field: 'quantity', + title: '库存', + align: 'right', + minWidth: 130, + slots: { default: 'quantity' }, + }, +]; + +/** 库存统计列表字段 */ +export function useGridColumns( + dimension: InventoryDimension = INVENTORY_DIMENSION.WAREHOUSE, +): VxeTableGridOptions['columns'] { + return dimension === INVENTORY_DIMENSION.ITEM + ? itemDimensionColumns + : warehouseDimensionColumns; +} + +/** 库存选择弹窗搜索表单 */ +export function useInventorySelectGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'itemName', + label: '商品名称', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入商品名称', + }, + }, + { + fieldName: 'itemCode', + label: '商品编号', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入商品编号', + }, + }, + { + fieldName: 'skuName', + label: '规格名称', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入规格名称', + }, + }, + { + fieldName: 'skuCode', + label: '规格编号', + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入规格编号', + }, + }, + ]; +} + +/** 库存选择弹窗列表字段 */ +export function useInventorySelectGridColumns(): VxeTableGridOptions['columns'] { + return [ + { type: 'checkbox', width: 50 }, + { + field: 'itemInfo', + title: '商品信息', + minWidth: 220, + slots: { default: 'itemInfo' }, + }, + { + field: 'skuInfo', + title: '规格信息', + minWidth: 220, + slots: { default: 'skuInfo' }, + }, + { + field: 'warehouseName', + title: '仓库', + minWidth: 180, + }, + { + field: 'availableQuantity', + title: '可用库存', + align: 'right', + width: 130, + slots: { default: 'availableQuantity' }, + }, + ]; +} diff --git a/apps/web-antd/src/views/wms/inventory/index/index.vue b/apps/web-antd/src/views/wms/inventory/index/index.vue new file mode 100644 index 000000000..2e227c81a --- /dev/null +++ b/apps/web-antd/src/views/wms/inventory/index/index.vue @@ -0,0 +1,193 @@ + + + diff --git a/apps/web-ele/src/views/wms/inventory/index/data.ts b/apps/web-ele/src/views/wms/inventory/index/data.ts new file mode 100644 index 000000000..27c8cc359 --- /dev/null +++ b/apps/web-ele/src/views/wms/inventory/index/data.ts @@ -0,0 +1,247 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; + +import { getWarehouseSimpleList } from '#/api/wms/md/warehouse'; + +export const INVENTORY_DIMENSION = { + ITEM: 'item', + WAREHOUSE: 'warehouse', +} as const; + +export type InventoryDimension = + (typeof INVENTORY_DIMENSION)[keyof typeof INVENTORY_DIMENSION]; + +const dimensionOptions = [ + { label: '仓库', value: INVENTORY_DIMENSION.WAREHOUSE }, + { label: '商品', value: INVENTORY_DIMENSION.ITEM }, +]; + +interface DimensionChangeEvent { + target?: { + value?: InventoryDimension; + }; +} + +type DimensionChangeHandler = ( + dimension: InventoryDimension, +) => Promise | void; + +/** 统一解析 ele 原始值和兼容事件对象 */ +function getDimensionChangeValue( + value?: DimensionChangeEvent | InventoryDimension, +): InventoryDimension { + if ( + value === INVENTORY_DIMENSION.ITEM || + value === INVENTORY_DIMENSION.WAREHOUSE + ) { + return value; + } + return value?.target?.value ?? INVENTORY_DIMENSION.WAREHOUSE; +} + +/** 搜索表单 */ +export function useGridFormSchema( + onDimensionChange: DimensionChangeHandler, +): VbenFormSchema[] { + return [ + { + fieldName: 'type', + label: '统计维度', + component: 'RadioGroup', + defaultValue: INVENTORY_DIMENSION.WAREHOUSE, + componentProps: { + options: dimensionOptions, + onChange: (value: DimensionChangeEvent | InventoryDimension) => { + void onDimensionChange(getDimensionChangeValue(value)); + }, + }, + }, + { + fieldName: 'warehouseId', + label: '仓库', + component: 'ApiSelect', + componentProps: { + api: getWarehouseSimpleList, + clearable: true, + filterable: true, + labelField: 'name', + placeholder: '请选择仓库', + valueField: 'id', + }, + }, + { + fieldName: 'itemName', + label: '商品名称', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入商品名称', + }, + }, + { + fieldName: 'itemCode', + label: '商品编号', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入商品编号', + }, + }, + { + fieldName: 'skuName', + label: '规格名称', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入规格名称', + }, + }, + { + fieldName: 'skuCode', + label: '规格编号', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入规格编号', + }, + }, + ]; +} + +const warehouseDimensionColumns: VxeTableGridOptions['columns'] = [ + { + field: 'warehouseId', + title: '仓库', + minWidth: 160, + slots: { default: 'warehouseName' }, + }, + { + field: 'warehouseItemId', + title: '商品信息', + minWidth: 240, + slots: { default: 'itemInfo' }, + }, + { + field: 'skuId', + title: '规格信息', + minWidth: 220, + slots: { default: 'skuInfo' }, + }, + { + field: 'quantity', + title: '库存', + align: 'right', + minWidth: 130, + slots: { default: 'quantity' }, + }, +]; + +const itemDimensionColumns: VxeTableGridOptions['columns'] = [ + { + field: 'warehouseItemId', + title: '商品信息', + minWidth: 240, + slots: { default: 'itemInfo' }, + }, + { + field: 'skuId', + title: '规格信息', + minWidth: 220, + slots: { default: 'skuInfo' }, + }, + { + field: 'warehouseId', + title: '仓库', + minWidth: 160, + slots: { default: 'warehouseName' }, + }, + { + field: 'quantity', + title: '库存', + align: 'right', + minWidth: 130, + slots: { default: 'quantity' }, + }, +]; + +/** 库存统计列表字段 */ +export function useGridColumns( + dimension: InventoryDimension = INVENTORY_DIMENSION.WAREHOUSE, +): VxeTableGridOptions['columns'] { + return dimension === INVENTORY_DIMENSION.ITEM + ? itemDimensionColumns + : warehouseDimensionColumns; +} + +/** 库存选择弹窗搜索表单 */ +export function useInventorySelectGridFormSchema(): VbenFormSchema[] { + return [ + { + fieldName: 'itemName', + label: '商品名称', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入商品名称', + }, + }, + { + fieldName: 'itemCode', + label: '商品编号', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入商品编号', + }, + }, + { + fieldName: 'skuName', + label: '规格名称', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入规格名称', + }, + }, + { + fieldName: 'skuCode', + label: '规格编号', + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入规格编号', + }, + }, + ]; +} + +/** 库存选择弹窗列表字段 */ +export function useInventorySelectGridColumns(): VxeTableGridOptions['columns'] { + return [ + { type: 'checkbox', width: 50 }, + { + field: 'itemInfo', + title: '商品信息', + minWidth: 220, + slots: { default: 'itemInfo' }, + }, + { + field: 'skuInfo', + title: '规格信息', + minWidth: 220, + slots: { default: 'skuInfo' }, + }, + { + field: 'warehouseName', + title: '仓库', + minWidth: 180, + }, + { + field: 'availableQuantity', + title: '可用库存', + align: 'right', + width: 130, + slots: { default: 'availableQuantity' }, + }, + ]; +} diff --git a/apps/web-ele/src/views/wms/inventory/index/index.vue b/apps/web-ele/src/views/wms/inventory/index/index.vue new file mode 100644 index 000000000..0613ec284 --- /dev/null +++ b/apps/web-ele/src/views/wms/inventory/index/index.vue @@ -0,0 +1,193 @@ + + +