import type { FormSchema } from '@/components/core/schema-form/'; import Api from '@/api'; import { debounce, isEmpty } from 'lodash-es'; import { MaterialsInOutEnum } from '@/enums/materialsInventoryEnum'; import { toRaw } from 'vue'; import { calcNumber } from '@/utils/common'; import { formatToDate } from '@/utils/dateUtil'; export const formSchemas = (isEdit: boolean = false): FormSchema[] => [ { field: 'inOrOut', component: 'Select', label: '出入库', rules: [{ required: true, type: 'number' }], defaultValue: MaterialsInOutEnum.In, colProps: { span: 8, }, componentProps: { allowClear: false, disabled: isEdit, options: [ { label: '出库', value: MaterialsInOutEnum.Out }, { label: '入库', value: MaterialsInOutEnum.In }, ], }, }, { field: 'inventoryId', component: 'Select', label: '产品', //出口用 rules: [{ required: true, type: 'number' }], vIf: ({ formModel }) => formModel.inOrOut === MaterialsInOutEnum.Out && !isEdit, colProps: { span: 24, }, helpMessage: '出库必须选择某个价格的某个产品。因为库中的相同产品的价格,可能会不同(不同批次的产品)。另外在库存管理中会显示不同价格的相同产品。', componentProps: ({ formInstance, schema, formModel }) => ({ showSearch: true, filterOption: false, disabled: isEdit, fieldNames: { label: 'label', value: 'value', }, options: [], getPopupContainer: () => document.body, defaultActiveFirstOption: true, onClear: async () => { const newSchema = { field: schema.field, componentProps: { options: [] as LabelValueOptions, }, }; const options = await getInventories().finally(() => (schema.loading = false)); newSchema.componentProps.options = options; formInstance?.updateSchema([newSchema]); }, request: { watchFields: ['inOrOut'], options: { immediate: true, }, callback: async ({ formModel }) => { if (formModel.inOrOut === MaterialsInOutEnum.Out) { return getInventories(); } else { return Promise.resolve([] as LabelValueOptions); } }, }, onSelect: async (id: number) => { const data = await Api.materialsInventory.materialsInventoryInfo({ id, }); if (!isEmpty(data)) { const { project, unitPrice, quantity, product } = data as API.MaterialsInventoryEntity; const amount = calcNumber(unitPrice, quantity, 'multiply'); formInstance?.setFieldsValue({ projectId: project.id, productId: product.id, unitPrice, quantity, amount, }); console.log(data, formModel); } }, onSearch: debounce(async (keyword) => { schema.loading = true; const newSchema = { field: schema.field, componentProps: { options: [] as LabelValueOptions, }, }; formInstance?.updateSchema([newSchema]); const options = await getInventories(keyword).finally(() => (schema.loading = false)); newSchema.componentProps.options = options; formInstance?.updateSchema([newSchema]); }, 500), }), }, { field: 'productId', component: 'Select', vShow: ({ formModel }) => formModel.inOrOut === MaterialsInOutEnum.In || isEdit, label: '产品', colProps: { span: 16, }, helpMessage: '如未找到对应产品,请先去产品管理添加产品。', rules: [{ required: true, type: 'number' }], componentProps: ({ formInstance, schema, formModel }) => ({ showSearch: true, filterOption: false, disabled: isEdit, fieldNames: { label: 'label', value: 'value', }, options: [], getPopupContainer: () => document.body, defaultActiveFirstOption: true, onClear: async () => { const newSchema = { field: schema.field, componentProps: { options: [] as LabelValueOptions, }, }; const options = await getProductOptions().finally(() => (schema.loading = false)); newSchema.componentProps.options = options; formInstance?.updateSchema([newSchema]); }, request: () => { return getProductOptions(); }, onSearch: debounce(async (keyword) => { schema.loading = true; const newSchema = { field: schema.field, componentProps: { options: [] as LabelValueOptions, }, }; formInstance?.updateSchema([newSchema]); const options = await getProductOptions(keyword).finally(() => (schema.loading = false)); newSchema.componentProps.options = options; formInstance?.updateSchema([newSchema]); }, 500), }), }, { field: 'projectId', component: 'Select', label: '项目', colProps: { span: 12, }, vIf: ({ formModel }) => formModel.inOrOut === MaterialsInOutEnum.In || isEdit || formModel.inventoryId, rules: [{ required: true, type: 'number' }], helpMessage: '如未找到对应项目,请先去项目管理添加项目。出库时选择的项目可以入库时不同', componentProps: ({ formInstance, schema, formModel }) => ({ // disabled: Object.is(formModel.inOrOut, MaterialsInOutEnum.Out) || isEdit, showSearch: true, filterOption: false, fieldNames: { label: 'label', value: 'value', }, getPopupContainer: () => document.body, defaultActiveFirstOption: true, onClear: async () => { const newSchema = { field: schema.field, componentProps: { options: [] as LabelValueOptions, }, }; const options = await getProjectOptions().finally(() => (schema.loading = false)); newSchema.componentProps.options = options; formInstance?.updateSchema([newSchema]); }, request: () => { return getProjectOptions(); }, onSearch: debounce(async (keyword) => { schema.loading = true; const newSchema = { field: schema.field, componentProps: { options: [] as LabelValueOptions, }, }; formInstance?.updateSchema([newSchema]); const options = await getProjectOptions(keyword).finally(() => (schema.loading = false)); newSchema.componentProps.options = options; formInstance?.updateSchema([newSchema]); }, 500), }), }, { label: '时间', field: 'time', component: 'DatePicker', defaultValue: formatToDate(new Date()), colProps: { span: 12, }, componentProps: { valueFormat: 'YYYY-MM-DD', }, }, { label: '数量', helpMessage: ({ formModel }) => { return '出库时,选择产品后显示的数量为实时的库存剩余数量。'; }, field: 'quantity', component: 'InputNumber', colProps: { span: 12, }, rules: [{ required: true, type: 'number', min: 1 }], componentProps: ({ formInstance, formModel }) => ({ disabled: isEdit, onBlur(e) { const { quantity, unitPrice, amount, inOrOut } = toRaw(formModel); // 出库只关心数量,单价已经有了,直接算出出库金额 if (MaterialsInOutEnum.Out === inOrOut) { if (unitPrice) { formInstance?.setFieldsValue({ amount: calcNumber(unitPrice, quantity, 'multiply'), }); } } else { // 入库一般是先输入总价和数量,然后计算单价 if (amount) { formInstance?.setFieldsValue({ unitPrice: calcNumber(amount, quantity, 'divide'), }); } else if (unitPrice) { formInstance?.setFieldsValue({ amount: calcNumber(unitPrice, quantity, 'multiply'), }); } } }, }), }, { label: '单价', field: 'unitPrice', component: 'InputNumber', colProps: { span: 12, }, helpMessage: ({ formModel }) => { return '出库时,单价不可更改,如需修改单价,请找到入库记录进行修改。'; }, dynamicDisabled: ({ formModel }) => { return formModel.inOrOut === MaterialsInOutEnum.Out; }, componentProps: ({ formInstance, formModel }) => ({ onChange(e) { const { quantity, unitPrice } = toRaw(formModel); if (quantity) { formInstance?.setFieldsValue({ amount: calcNumber(unitPrice, quantity, 'multiply'), }); } }, }), }, { label: '金额', field: 'amount', component: 'InputNumber', colProps: { span: 12, }, helpMessage: ({ formModel }) => { return '出库时,金额不可更改,输入数量会自动计算。'; }, dynamicDisabled: ({ formModel }) => { return formModel.inOrOut === MaterialsInOutEnum.Out; }, componentProps: ({ formInstance, formModel }) => ({ disabled: isEdit, onChange(e) { const { quantity, amount } = toRaw(formModel); if (quantity) { formInstance?.setFieldsValue({ unitPrice: calcNumber(amount, quantity, 'divide'), }); } }, }), }, { label: '经办人', field: 'agent', component: 'Input', colProps: { span: 12, }, }, { label: '领料单号', field: 'issuanceNumber', component: 'Input', vIf: ({ formModel }) => formModel.inOrOut === MaterialsInOutEnum.Out, colProps: { span: 12, }, }, { label: '备注', field: 'remark', component: 'InputTextArea', }, ]; export const getProjectOptions = async (keyword?: string): Promise => { const { items: result } = await Api.project.projectList({ pageSize: 100, name: keyword }); return ( result?.map((item) => ({ label: `${item.name}`, value: item.id, })) || [] ); }; const getProductOptions = async (keyword?: string): Promise => { const { items: result } = await Api.product.productList({ pageSize: 100, keyword: keyword }); return ( result?.map((item) => ({ label: ` ${item.name} ${item.productNumber ? `(${item.productNumber})` : ''} ${item.company?.name ? `(${item.company?.name})` : ''} `, value: item.id, })) || [] ); }; const getInventoryNumberOptions = async ( inventoryInOutNumber?: string, ): Promise => { const { items: result } = await Api.materialsInOut.materialsInOutList({ inventoryInOutNumber, isCreateOut: true, pageSize: 100, }); return ( result?.map((item) => ({ label: `${item.inventoryInOutNumber} (${item.project?.name || '-'}) (${item.product?.company?.name || '-'}) (${item.product?.name || '-'})`, value: item.inventoryInOutNumber, })) || [] ); }; const getInventories = async (keyword?: string): Promise => { const { items: result } = await Api.materialsInventory.materialsInventoryList({ keyword, isCreateInout: true, pageSize: 100, }); return ( result?.map((item) => ({ label: `${item.product?.name} (¥${parseFloat(item.unitPrice)}) (${item.product?.company?.name || '-'}) (${item.project?.name || '-'}) `, value: item.id, })) || [] ); };