diff --git a/apps/web-antd/src/views/wms/order/shipment/data.ts b/apps/web-antd/src/views/wms/order/shipment/data.ts new file mode 100644 index 000000000..eac4d1b10 --- /dev/null +++ b/apps/web-antd/src/views/wms/order/shipment/data.ts @@ -0,0 +1,437 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { WmsWarehouseApi } from '#/api/wms/md/warehouse'; +import type { DescriptionItemSchema } from '#/components/description'; + +import { h, markRaw } from 'vue'; + +import { DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; +import { formatDate, formatDateTime } from '@vben/utils'; + +import { z } from '#/adapter/form'; +import { getSimpleUserList } from '#/api/system/user'; +import { DictTag } from '#/components/dict-tag'; +import { buildNumberRangeSchema } from '#/components/number-range-input'; +import { getRangePickerDefaultProps } from '#/utils'; +import { WmsMerchantSelect } from '#/views/wms/md/merchant/components'; +import { WmsWarehouseSelect } from '#/views/wms/md/warehouse/components'; +import { + formatPrice, + formatQuantity, + formatSumPrice, + formatSumQuantity, + PRICE_PRECISION, + QUANTITY_PRECISION, +} from '#/views/wms/utils/format'; + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入出库单号', + }, + fieldName: 'no', + label: '出库单号', + }, + { + component: 'Input', + componentProps: { + allowClear: true, + placeholder: '请输入业务单号', + }, + fieldName: 'bizOrderNo', + label: '业务单号', + }, + { + component: 'Select', + componentProps: { + allowClear: true, + options: getDictOptions(DICT_TYPE.WMS_ORDER_STATUS, 'number'), + placeholder: '请选择单据状态', + }, + fieldName: 'status', + label: '单据状态', + }, + { + component: markRaw(WmsWarehouseSelect), + fieldName: 'warehouseId', + label: '仓库', + }, + { + component: markRaw(WmsMerchantSelect), + componentProps: { + customer: true, + placeholder: '请选择客户', + }, + fieldName: 'merchantId', + label: '客户', + }, + { + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + fieldName: 'orderTime', + label: '单据日期', + }, + buildNumberRangeSchema( + '数量', + 'totalQuantityRange', + 'totalQuantityMin', + 'totalQuantityMax', + QUANTITY_PRECISION, + ), + buildNumberRangeSchema( + '总金额', + 'totalPriceRange', + 'totalPriceMin', + 'totalPriceMax', + PRICE_PRECISION, + ), + { + component: 'Select', + componentProps: { + allowClear: true, + options: getDictOptions(DICT_TYPE.WMS_SHIPMENT_ORDER_TYPE, 'number'), + placeholder: '请选择出库类型', + }, + fieldName: 'type', + label: '出库类型', + }, + { + component: 'ApiSelect', + componentProps: { + allowClear: true, + api: getSimpleUserList, + labelField: 'nickname', + placeholder: '请选择创建用户', + showSearch: true, + valueField: 'id', + }, + fieldName: 'creator', + label: '创建用户', + }, + { + component: 'ApiSelect', + componentProps: { + allowClear: true, + api: getSimpleUserList, + labelField: 'nickname', + placeholder: '请选择更新用户', + showSearch: true, + valueField: 'id', + }, + fieldName: 'updater', + label: '更新用户', + }, + { + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + fieldName: 'createTime', + label: '创建时间', + }, + { + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + allowClear: true, + }, + fieldName: 'updateTime', + label: '更新时间', + }, + ]; +} + +/** 列表表格列 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + fixed: 'left', + slots: { content: 'expand_content' }, + type: 'expand', + width: 48, + }, + { + field: 'no', + fixed: 'left', + slots: { default: 'no' }, + title: '单号/业务单号', + width: 260, + }, + { + align: 'center', + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.WMS_ORDER_STATUS }, + }, + field: 'status', + fixed: 'left', + title: '出库状态', + width: 110, + }, + { + align: 'center', + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.WMS_SHIPMENT_ORDER_TYPE }, + }, + field: 'type', + title: '出库类型', + width: 120, + }, + { + field: 'warehouseName', + minWidth: 180, + title: '仓库', + }, + { + field: 'quantityAmount', + minWidth: 180, + slots: { default: 'quantityAmount' }, + title: '总数量/总金额(元)', + }, + { + field: 'merchantName', + minWidth: 160, + title: '客户', + }, + { + field: 'operateInfo', + minWidth: 260, + slots: { default: 'operateInfo' }, + title: '操作信息', + }, + { + field: 'remark', + minWidth: 160, + title: '备注', + }, + { + field: 'actions', + fixed: 'right', + slots: { default: 'actions' }, + title: '操作', + width: 220, + }, + ]; +} + +/** 详情的字段 */ +export function useDetailSchema(): DescriptionItemSchema[] { + return [ + { + field: 'no', + label: '出库单号', + render: (val) => val || '-', + }, + { + field: 'type', + label: '出库类型', + render: (val) => + val === undefined || val === null + ? '-' + : h(DictTag, { + type: DICT_TYPE.WMS_SHIPMENT_ORDER_TYPE, + value: val, + }), + }, + { + field: 'warehouseName', + label: '仓库', + render: (val) => val || '-', + }, + { + field: 'status', + label: '单据状态', + render: (val) => + val === undefined || val === null + ? '-' + : h(DictTag, { + type: DICT_TYPE.WMS_ORDER_STATUS, + value: val, + }), + }, + { + field: 'orderTime', + label: '单据日期', + render: (val) => formatDate(val, 'YYYY-MM-DD') || '-', + }, + { + field: 'merchantName', + label: '客户', + render: (val) => val || '-', + }, + { + field: 'bizOrderNo', + label: '业务单号', + render: (val) => val || '-', + }, + { + field: 'totalQuantity', + label: '总数量', + render: (val) => formatQuantity(val) || '-', + }, + { + field: 'totalPrice', + label: '总金额', + render: (val) => formatPrice(val) || '-', + }, + { + field: 'createTime', + label: '创建时间', + render: (val) => formatDateTime(val) || '-', + }, + { + field: 'creatorName', + label: '创建人', + render: (val, data) => val || data?.creator || '-', + }, + { + field: 'updateTime', + label: '更新时间', + render: (val) => formatDateTime(val) || '-', + }, + { + field: 'updaterName', + label: '更新人', + render: (val, data) => val || data?.updater || '-', + }, + { + field: 'remark', + label: '备注', + render: (val) => val || '-', + span: 2, + }, + ]; +} + +interface ShipmentFormSchemaOptions { + onWarehouseChange: (warehouse?: WmsWarehouseApi.Warehouse) => void; +} + +/** 表单的配置项 */ +export function useFormSchema({ + onWarehouseChange, +}: ShipmentFormSchemaOptions): VbenFormSchema[] { + return [ + { + component: 'Input', + dependencies: { + show: () => false, + triggerFields: [''], + }, + fieldName: 'id', + }, + { + component: 'Input', + componentProps: { + maxLength: 64, + placeholder: '请输入出库单号', + }, + fieldName: 'no', + label: '出库单号', + rules: z.string().min(1, '出库单号不能为空').max(64), + }, + { + component: 'Select', + componentProps: { + allowClear: true, + options: getDictOptions(DICT_TYPE.WMS_SHIPMENT_ORDER_TYPE, 'number'), + placeholder: '请选择出库类型', + }, + fieldName: 'type', + label: '出库类型', + rules: 'required', + }, + { + component: markRaw(WmsWarehouseSelect), + componentProps: { + onChange: onWarehouseChange, + }, + fieldName: 'warehouseId', + label: '仓库', + rules: 'required', + }, + { + component: 'DatePicker', + componentProps: { + class: 'w-full', + format: 'YYYY-MM-DD', + placeholder: '请选择单据日期', + valueFormat: 'x', + }, + fieldName: 'orderTime', + label: '单据日期', + rules: 'required', + }, + { + component: markRaw(WmsMerchantSelect), + componentProps: { + customer: true, + placeholder: '请选择客户', + }, + fieldName: 'merchantId', + label: '客户', + }, + { + component: 'Input', + componentProps: { + maxLength: 64, + placeholder: '请输入业务单号', + }, + fieldName: 'bizOrderNo', + label: '业务单号', + }, + { + component: 'Textarea', + componentProps: { + maxLength: 255, + placeholder: '请输入备注', + }, + fieldName: 'remark', + formItemClass: 'col-span-2', + label: '备注', + }, + ]; +} + +interface ShipmentOrderDetailFooterRow { + quantity?: number; + totalPrice?: number; +} +type ShipmentOrderDetailFooterColumn = Pick< + NonNullable[number]>, + 'field' +>; + +/** 明细表格的合计行 */ +export function getDetailFooter({ + columns, + data, +}: { + columns: ShipmentOrderDetailFooterColumn[]; + data: ShipmentOrderDetailFooterRow[]; +}) { + return [ + columns.map((column, index) => { + if (index === 0) { + return '合计'; + } + if (column.field === 'quantity') { + return formatSumQuantity(data, (detail) => detail.quantity); + } + if (column.field === 'totalPrice') { + return formatSumPrice(data, (detail) => detail.totalPrice); + } + return ''; + }), + ]; +} diff --git a/apps/web-antd/src/views/wms/order/shipment/index.vue b/apps/web-antd/src/views/wms/order/shipment/index.vue new file mode 100644 index 000000000..5598b7cef --- /dev/null +++ b/apps/web-antd/src/views/wms/order/shipment/index.vue @@ -0,0 +1,345 @@ + + + diff --git a/apps/web-antd/src/views/wms/order/shipment/modules/detail.vue b/apps/web-antd/src/views/wms/order/shipment/modules/detail.vue new file mode 100644 index 000000000..891af12cf --- /dev/null +++ b/apps/web-antd/src/views/wms/order/shipment/modules/detail.vue @@ -0,0 +1,121 @@ + + + diff --git a/apps/web-antd/src/views/wms/order/shipment/modules/form.vue b/apps/web-antd/src/views/wms/order/shipment/modules/form.vue new file mode 100644 index 000000000..e2198392d --- /dev/null +++ b/apps/web-antd/src/views/wms/order/shipment/modules/form.vue @@ -0,0 +1,535 @@ + + + diff --git a/apps/web-antd/src/views/wms/order/shipment/modules/print.vue b/apps/web-antd/src/views/wms/order/shipment/modules/print.vue new file mode 100644 index 000000000..89670420c --- /dev/null +++ b/apps/web-antd/src/views/wms/order/shipment/modules/print.vue @@ -0,0 +1,231 @@ + + + + + diff --git a/apps/web-ele/src/views/wms/order/shipment/data.ts b/apps/web-ele/src/views/wms/order/shipment/data.ts new file mode 100644 index 000000000..3346afcca --- /dev/null +++ b/apps/web-ele/src/views/wms/order/shipment/data.ts @@ -0,0 +1,437 @@ +import type { VbenFormSchema } from '#/adapter/form'; +import type { VxeTableGridOptions } from '#/adapter/vxe-table'; +import type { WmsWarehouseApi } from '#/api/wms/md/warehouse'; +import type { DescriptionItemSchema } from '#/components/description'; + +import { h, markRaw } from 'vue'; + +import { DICT_TYPE } from '@vben/constants'; +import { getDictOptions } from '@vben/hooks'; +import { formatDate, formatDateTime } from '@vben/utils'; + +import { z } from '#/adapter/form'; +import { getSimpleUserList } from '#/api/system/user'; +import { DictTag } from '#/components/dict-tag'; +import { buildNumberRangeSchema } from '#/components/number-range-input'; +import { getRangePickerDefaultProps } from '#/utils'; +import { WmsMerchantSelect } from '#/views/wms/md/merchant/components'; +import { WmsWarehouseSelect } from '#/views/wms/md/warehouse/components'; +import { + formatPrice, + formatQuantity, + formatSumPrice, + formatSumQuantity, + PRICE_PRECISION, + QUANTITY_PRECISION, +} from '#/views/wms/utils/format'; + +/** 列表的搜索表单 */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入出库单号', + }, + fieldName: 'no', + label: '出库单号', + }, + { + component: 'Input', + componentProps: { + clearable: true, + placeholder: '请输入业务单号', + }, + fieldName: 'bizOrderNo', + label: '业务单号', + }, + { + component: 'Select', + componentProps: { + clearable: true, + options: getDictOptions(DICT_TYPE.WMS_ORDER_STATUS, 'number'), + placeholder: '请选择单据状态', + }, + fieldName: 'status', + label: '单据状态', + }, + { + component: markRaw(WmsWarehouseSelect), + fieldName: 'warehouseId', + label: '仓库', + }, + { + component: markRaw(WmsMerchantSelect), + componentProps: { + customer: true, + placeholder: '请选择客户', + }, + fieldName: 'merchantId', + label: '客户', + }, + { + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + clearable: true, + }, + fieldName: 'orderTime', + label: '单据日期', + }, + buildNumberRangeSchema( + '数量', + 'totalQuantityRange', + 'totalQuantityMin', + 'totalQuantityMax', + QUANTITY_PRECISION, + ), + buildNumberRangeSchema( + '总金额', + 'totalPriceRange', + 'totalPriceMin', + 'totalPriceMax', + PRICE_PRECISION, + ), + { + component: 'Select', + componentProps: { + clearable: true, + options: getDictOptions(DICT_TYPE.WMS_SHIPMENT_ORDER_TYPE, 'number'), + placeholder: '请选择出库类型', + }, + fieldName: 'type', + label: '出库类型', + }, + { + component: 'ApiSelect', + componentProps: { + api: getSimpleUserList, + clearable: true, + filterable: true, + labelField: 'nickname', + placeholder: '请选择创建用户', + valueField: 'id', + }, + fieldName: 'creator', + label: '创建用户', + }, + { + component: 'ApiSelect', + componentProps: { + api: getSimpleUserList, + clearable: true, + filterable: true, + labelField: 'nickname', + placeholder: '请选择更新用户', + valueField: 'id', + }, + fieldName: 'updater', + label: '更新用户', + }, + { + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + clearable: true, + }, + fieldName: 'createTime', + label: '创建时间', + }, + { + component: 'RangePicker', + componentProps: { + ...getRangePickerDefaultProps(), + clearable: true, + }, + fieldName: 'updateTime', + label: '更新时间', + }, + ]; +} + +/** 列表表格列 */ +export function useGridColumns(): VxeTableGridOptions['columns'] { + return [ + { + fixed: 'left', + slots: { content: 'expand_content' }, + type: 'expand', + width: 48, + }, + { + field: 'no', + fixed: 'left', + slots: { default: 'no' }, + title: '单号/业务单号', + width: 260, + }, + { + align: 'center', + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.WMS_ORDER_STATUS }, + }, + field: 'status', + fixed: 'left', + title: '出库状态', + width: 110, + }, + { + align: 'center', + cellRender: { + name: 'CellDict', + props: { type: DICT_TYPE.WMS_SHIPMENT_ORDER_TYPE }, + }, + field: 'type', + title: '出库类型', + width: 120, + }, + { + field: 'warehouseName', + minWidth: 180, + title: '仓库', + }, + { + field: 'quantityAmount', + minWidth: 180, + slots: { default: 'quantityAmount' }, + title: '总数量/总金额(元)', + }, + { + field: 'merchantName', + minWidth: 160, + title: '客户', + }, + { + field: 'operateInfo', + minWidth: 260, + slots: { default: 'operateInfo' }, + title: '操作信息', + }, + { + field: 'remark', + minWidth: 160, + title: '备注', + }, + { + field: 'actions', + fixed: 'right', + slots: { default: 'actions' }, + title: '操作', + width: 220, + }, + ]; +} + +/** 详情的字段 */ +export function useDetailSchema(): DescriptionItemSchema[] { + return [ + { + field: 'no', + label: '出库单号', + render: (val) => val || '-', + }, + { + field: 'type', + label: '出库类型', + render: (val) => + val === undefined || val === null + ? '-' + : h(DictTag, { + type: DICT_TYPE.WMS_SHIPMENT_ORDER_TYPE, + value: val, + }), + }, + { + field: 'warehouseName', + label: '仓库', + render: (val) => val || '-', + }, + { + field: 'status', + label: '单据状态', + render: (val) => + val === undefined || val === null + ? '-' + : h(DictTag, { + type: DICT_TYPE.WMS_ORDER_STATUS, + value: val, + }), + }, + { + field: 'orderTime', + label: '单据日期', + render: (val) => formatDate(val, 'YYYY-MM-DD') || '-', + }, + { + field: 'merchantName', + label: '客户', + render: (val) => val || '-', + }, + { + field: 'bizOrderNo', + label: '业务单号', + render: (val) => val || '-', + }, + { + field: 'totalQuantity', + label: '总数量', + render: (val) => formatQuantity(val) || '-', + }, + { + field: 'totalPrice', + label: '总金额', + render: (val) => formatPrice(val) || '-', + }, + { + field: 'createTime', + label: '创建时间', + render: (val) => formatDateTime(val) || '-', + }, + { + field: 'creatorName', + label: '创建人', + render: (val, data) => val || data?.creator || '-', + }, + { + field: 'updateTime', + label: '更新时间', + render: (val) => formatDateTime(val) || '-', + }, + { + field: 'updaterName', + label: '更新人', + render: (val, data) => val || data?.updater || '-', + }, + { + field: 'remark', + label: '备注', + render: (val) => val || '-', + span: 2, + }, + ]; +} + +interface ShipmentFormSchemaOptions { + onWarehouseChange: (warehouse?: WmsWarehouseApi.Warehouse) => void; +} + +/** 表单的配置项 */ +export function useFormSchema({ + onWarehouseChange, +}: ShipmentFormSchemaOptions): VbenFormSchema[] { + return [ + { + component: 'Input', + dependencies: { + show: () => false, + triggerFields: [''], + }, + fieldName: 'id', + }, + { + component: 'Input', + componentProps: { + maxLength: 64, + placeholder: '请输入出库单号', + }, + fieldName: 'no', + label: '出库单号', + rules: z.string().min(1, '出库单号不能为空').max(64), + }, + { + component: 'Select', + componentProps: { + clearable: true, + options: getDictOptions(DICT_TYPE.WMS_SHIPMENT_ORDER_TYPE, 'number'), + placeholder: '请选择出库类型', + }, + fieldName: 'type', + label: '出库类型', + rules: 'required', + }, + { + component: markRaw(WmsWarehouseSelect), + componentProps: { + onChange: onWarehouseChange, + }, + fieldName: 'warehouseId', + label: '仓库', + rules: 'required', + }, + { + component: 'DatePicker', + componentProps: { + class: 'w-full', + format: 'YYYY-MM-DD', + placeholder: '请选择单据日期', + valueFormat: 'x', + }, + fieldName: 'orderTime', + label: '单据日期', + rules: 'required', + }, + { + component: markRaw(WmsMerchantSelect), + componentProps: { + customer: true, + placeholder: '请选择客户', + }, + fieldName: 'merchantId', + label: '客户', + }, + { + component: 'Input', + componentProps: { + maxLength: 64, + placeholder: '请输入业务单号', + }, + fieldName: 'bizOrderNo', + label: '业务单号', + }, + { + component: 'Textarea', + componentProps: { + maxLength: 255, + placeholder: '请输入备注', + }, + fieldName: 'remark', + formItemClass: 'col-span-2', + label: '备注', + }, + ]; +} + +interface ShipmentOrderDetailFooterRow { + quantity?: number; + totalPrice?: number; +} +type ShipmentOrderDetailFooterColumn = Pick< + NonNullable[number]>, + 'field' +>; + +/** 明细表格的合计行 */ +export function getDetailFooter({ + columns, + data, +}: { + columns: ShipmentOrderDetailFooterColumn[]; + data: ShipmentOrderDetailFooterRow[]; +}) { + return [ + columns.map((column, index) => { + if (index === 0) { + return '合计'; + } + if (column.field === 'quantity') { + return formatSumQuantity(data, (detail) => detail.quantity); + } + if (column.field === 'totalPrice') { + return formatSumPrice(data, (detail) => detail.totalPrice); + } + return ''; + }), + ]; +} diff --git a/apps/web-ele/src/views/wms/order/shipment/index.vue b/apps/web-ele/src/views/wms/order/shipment/index.vue new file mode 100644 index 000000000..445249ea7 --- /dev/null +++ b/apps/web-ele/src/views/wms/order/shipment/index.vue @@ -0,0 +1,346 @@ + + + diff --git a/apps/web-ele/src/views/wms/order/shipment/modules/detail.vue b/apps/web-ele/src/views/wms/order/shipment/modules/detail.vue new file mode 100644 index 000000000..e51c5c365 --- /dev/null +++ b/apps/web-ele/src/views/wms/order/shipment/modules/detail.vue @@ -0,0 +1,120 @@ + + + diff --git a/apps/web-ele/src/views/wms/order/shipment/modules/form.vue b/apps/web-ele/src/views/wms/order/shipment/modules/form.vue new file mode 100644 index 000000000..a28892cab --- /dev/null +++ b/apps/web-ele/src/views/wms/order/shipment/modules/form.vue @@ -0,0 +1,535 @@ + + + diff --git a/apps/web-ele/src/views/wms/order/shipment/modules/print.vue b/apps/web-ele/src/views/wms/order/shipment/modules/print.vue new file mode 100644 index 000000000..89670420c --- /dev/null +++ b/apps/web-ele/src/views/wms/order/shipment/modules/print.vue @@ -0,0 +1,231 @@ + + + + +