| | |
| | | import type { VbenFormApi, VbenFormSchema } from '#/adapter/form'; |
| | | import type { VbenFormSchema } from '#/adapter/form'; |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { AftersalesTicketApi } from '#/api/aftersales/ticket'; |
| | | import type { ErpSaleOrderApi } from '#/api/erp/sale/order'; |
| | | |
| | | import { h, markRaw } from 'vue'; |
| | | |
| | |
| | | import { Button, Tag } from 'ant-design-vue'; |
| | | |
| | | import { z } from '#/adapter/form'; |
| | | import CrmCustomerSelect from '#/components/crm-customer-select.vue'; |
| | | import { ErpSaleOrderSelect } from '#/views/erp/sale/order/components'; |
| | | import { MdItemSelect } from '#/views/mes/md/item/components'; |
| | | import { WmBatchSelect } from '#/views/wls/batch/components'; |
| | | import { UserSelect } from '#/views/system/user/components'; |
| | | import { getDeptList } from '#/api/system/dept'; |
| | | import { handleTree } from '#/packages/utils/src'; |
| | | |
| | | /** 表单类型 */ |
| | | export type TicketFormType = 'create' | 'detail' | 'update'; |
| | |
| | | } |
| | | |
| | | /** 工单表单 */ |
| | | export function useTicketFormSchema( |
| | | formType: TicketFormType, |
| | | formApi?: VbenFormApi, |
| | | onSaleOrderChange?: (order: Record<string, unknown> | undefined) => void, |
| | | ): VbenFormSchema[] { |
| | | export function useTicketFormSchema(formType: TicketFormType): VbenFormSchema[] { |
| | | const readonly = isHeaderReadonly(formType); |
| | | return [ |
| | | { |
| | |
| | | rules: 'required', |
| | | }, |
| | | { |
| | | fieldName: 'saleOrderId', |
| | | label: '销售订单号', |
| | | component: markRaw(ErpSaleOrderSelect), |
| | | componentProps: { |
| | | placeholder: '请选择销售订单', |
| | | outStatus: 3, |
| | | onChange: (item: Record<string, unknown> | undefined) => { |
| | | if (formApi) { |
| | | formApi.setFieldValue('saleOrderNo', item?.no ?? ''); |
| | | if (item?.customerId) { |
| | | formApi.setFieldValue('customerId', item.customerId); |
| | | } |
| | | } |
| | | onSaleOrderChange?.(item); |
| | | }, |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'saleOrderNo', |
| | | component: 'Input', |
| | | dependencies: { |
| | | triggerFields: [''], |
| | | show: () => false, |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'customerId', |
| | | fieldName: 'customerName', |
| | | label: '客户', |
| | | component: markRaw(CrmCustomerSelect), |
| | | component: 'Input', |
| | | componentProps: { |
| | | placeholder: '请选择客户', |
| | | placeholder: '请输入客户', |
| | | }, |
| | | rules: 'selectRequired', |
| | | rules: 'required', |
| | | }, |
| | | { |
| | | fieldName: 'contactId', |
| | | fieldName: 'contactName', |
| | | label: '联系人', |
| | | component: 'Input', |
| | | componentProps: { |
| | |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'customerId', |
| | | fieldName: 'customerName', |
| | | label: '客户', |
| | | component: markRaw(CrmCustomerSelect), |
| | | component: 'Input', |
| | | componentProps: { |
| | | placeholder: '请选择客户', |
| | | allowClear: true, |
| | | placeholder: '请输入客户', |
| | | }, |
| | | }, |
| | | { |
| | |
| | | { |
| | | field: 'customerName', |
| | | title: '客户', |
| | | minWidth: 150, |
| | | }, |
| | | { |
| | | field: 'saleOrderNo', |
| | | title: '销售订单号', |
| | | minWidth: 150, |
| | | }, |
| | | { |
| | |
| | | ): VxeTableGridOptions<AftersalesTicketApi.TicketItem>['columns'] { |
| | | return [ |
| | | { |
| | | field: 'itemNo', |
| | | title: '明细单号', |
| | | minWidth: 170, |
| | | }, |
| | | { |
| | | field: 'itemCode', |
| | | title: '物料编码', |
| | | minWidth: 120, |
| | |
| | | width: 90, |
| | | slots: { default: 'needReturn' }, |
| | | }, |
| | | { |
| | | field: 'deptName', |
| | | title: '部门', |
| | | minWidth: 120, |
| | | }, |
| | | { |
| | | field: 'reasonType', |
| | | title: '原因类型', |
| | | width: 120, |
| | | slots: { default: 'reasonType' }, |
| | | }, |
| | | { |
| | | field: 'reason', |
| | | title: '具体原因', |
| | | minWidth: 160, |
| | | }, |
| | | ...(editable |
| | | ? [ |
| | | { |
| | |
| | | } |
| | | |
| | | /** 工单明细行表单 */ |
| | | export function useTicketItemFormSchema( |
| | | clientId?: number, |
| | | salesOrderCode?: string, |
| | | orderItems?: ErpSaleOrderApi.SaleOrderItem[], |
| | | formApi?: VbenFormApi, |
| | | ): VbenFormSchema[] { |
| | | const hasOrderItems = orderItems && orderItems.length > 0; |
| | | export function useTicketItemFormSchema(): VbenFormSchema[] { |
| | | return [ |
| | | { |
| | | fieldName: 'itemId', |
| | | label: '物料', |
| | | component: hasOrderItems ? 'Select' : markRaw(MdItemSelect), |
| | | componentProps: hasOrderItems |
| | | ? { |
| | | placeholder: '请选择物料', |
| | | options: orderItems!.map((oi) => ({ |
| | | label: `${oi.productName || ''} (${oi.productBarCode || oi.productId})`, |
| | | value: oi.productId, |
| | | })), |
| | | showSearch: true, |
| | | onChange: (value: number) => { |
| | | const oi = orderItems!.find((o) => o.productId === value); |
| | | if (oi && formApi) { |
| | | formApi.setValues({ |
| | | itemName: oi.productName, |
| | | itemCode: oi.productBarCode || '', |
| | | saleQuantity: oi.count, |
| | | batchCode: oi.batchCode || '', |
| | | }); |
| | | } |
| | | }, |
| | | } |
| | | : { |
| | | placeholder: '请选择物料', |
| | | }, |
| | | rules: 'selectRequired', |
| | | }, |
| | | { |
| | | fieldName: 'itemCode', |
| | | component: 'Input', |
| | | dependencies: { triggerFields: [''], show: () => false }, |
| | | }, |
| | | { |
| | | fieldName: 'itemName', |
| | | label: '物料', |
| | | component: 'Input', |
| | | dependencies: { triggerFields: [''], show: () => false }, |
| | | componentProps: { |
| | | placeholder: '请输入物料', |
| | | }, |
| | | rules: 'required', |
| | | }, |
| | | ...(hasOrderItems |
| | | ? [ |
| | | { |
| | | fieldName: 'batchCode', |
| | | label: '批次', |
| | | component: 'Input', |
| | | componentProps: { |
| | | disabled: true, |
| | | placeholder: '自动从订单带入', |
| | | }, |
| | | }, |
| | | ] |
| | | : [ |
| | | { |
| | | fieldName: 'batchId', |
| | | label: '批次', |
| | | component: markRaw(WmBatchSelect), |
| | | componentProps: { |
| | | clientId, |
| | | placeholder: '请选择批次', |
| | | salesOrderCode, |
| | | }, |
| | | dependencies: { |
| | | triggerFields: ['itemId'], |
| | | componentProps: (values: Record<string, unknown>) => ({ |
| | | clientId, |
| | | itemId: values.itemId, |
| | | placeholder: '请选择批次', |
| | | salesOrderCode, |
| | | }), |
| | | }, |
| | | }, |
| | | ]), |
| | | { |
| | | fieldName: 'batchCode', |
| | | label: '批次', |
| | | component: 'Input', |
| | | componentProps: { |
| | | placeholder: '请输入批次', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'saleQuantity', |
| | | label: '销售数量', |
| | |
| | | rules: z.boolean().default(false), |
| | | }, |
| | | { |
| | | fieldName: 'deptId', |
| | | label: '部门', |
| | | component: 'ApiTreeSelect', |
| | | componentProps: { |
| | | api: async () => handleTree(await getDeptList()), |
| | | labelField: 'name', |
| | | valueField: 'id', |
| | | childrenField: 'children', |
| | | placeholder: '请选择部门', |
| | | treeDefaultExpandAll: true, |
| | | }, |
| | | rules: 'selectRequired', |
| | | }, |
| | | { |
| | | fieldName: 'reasonType', |
| | | label: '原因类型', |
| | | component: 'Select', |
| | | componentProps: { |
| | | options: getDictOptions(DICT_TYPE.AFTERSALE_REASON_TYPE, 'number'), |
| | | placeholder: '请选择原因类型', |
| | | }, |
| | | rules: 'selectRequired', |
| | | }, |
| | | { |
| | | fieldName: 'reason', |
| | | label: '具体原因', |
| | | component: 'Textarea', |
| | | formItemClass: 'col-span-3', |
| | | componentProps: { |
| | | placeholder: '请输入具体原因', |
| | | rows: 2, |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'remark', |
| | | label: '备注', |
| | | component: 'Textarea', |