银川
1.库存现有量添加自定义出库入库功能
2.整理重复文件
已添加2个文件
已重命名1个文件
已修改10个文件
已删除160个文件
| | |
| | | warehouseName?: string; |
| | | remark?: string; |
| | | createTime?: string; |
| | | // 忥ç¸å
³å段 |
| | | syncMes?: boolean; |
| | | // æ¹æ¬¡å±æ§é
ç½®åæ®µ |
| | | produceDateFlag?: boolean; |
| | | expireDateFlag?: boolean; |
| | | receiptDateFlag?: boolean; |
| | | vendorFlag?: boolean; |
| | | purchaseOrderCodeFlag?: boolean; |
| | | lotNumberFlag?: boolean; |
| | | qualityStatusFlag?: boolean; |
| | | } |
| | | |
| | | /** ç©æå页æ¥è¯¢åæ° */ |
| | |
| | | batchCode?: string; // æ¹æ¬¡å·ï¼æ°å»ºæ¹æ¬¡æ¶ä¼ å
¥ï¼ |
| | | produceDate?: string; // çäº§æ¥æï¼æ°å»ºæ¹æ¬¡æ¶ä¼ å
¥ï¼ |
| | | expireDate?: string; // æææï¼æ°å»ºæ¹æ¬¡æ¶ä¼ å
¥ï¼ |
| | | receiptDate?: string; // å
¥åºæ¥æ |
| | | vendorId?: number; // ä¾åºåID |
| | | purchaseOrderCode?: string; // éè´è®¢åå· |
| | | lotNumber?: string; // ç产æ¹å· |
| | | qualityStatus?: string; // è´¨éç¶æ |
| | | quantity: number; // å
¥åºæ°éï¼å¿
须大äº0ï¼ |
| | | reason?: string; // å
¥åºåå |
| | | } |
| | |
| | | import { getDictOptions } from "#/packages/effects/hooks/src"; |
| | | |
| | | import { z } from '#/adapter/form'; |
| | | import { getItemTypeSimpleList } from '#/api/mes/md/item/type'; |
| | | import { getUnitPage } from '#/api/mdm/unit'; |
| | | |
| | | /** ç©æç±»åé项 */ |
| | | export const ITEM_TYPE_OPTIONS = [ |
| | | { label: "åæ", value: 1 }, |
| | | { label: "åæå", value: 2 }, |
| | | { label: "æå", value: 3 }, |
| | | { label: "è¾
æ", value: 4 }, |
| | | ]; |
| | | // ç¼ååä½å表 |
| | | let unitListCache: any[] | null = null; |
| | | let unitListPromise: Promise<any[]> | null = null; |
| | | |
| | | /** ç©æç±»åæ å° */ |
| | | export const ITEM_TYPE_MAP: Record<number, string> = { |
| | | 1: "åæ", |
| | | 2: "åæå", |
| | | 3: "æå", |
| | | 4: "è¾
æ", |
| | | }; |
| | | |
| | | /** ç©æç±»åé¢è²æ å° */ |
| | | export const ITEM_TYPE_COLOR_MAP: Record<number, string> = { |
| | | 1: "green", |
| | | 2: "orange", |
| | | 3: "blue", |
| | | 4: "purple", |
| | | }; |
| | | /** è·ååä½å表ï¼å¸¦ç¼åï¼ */ |
| | | async function getUnitListCached() { |
| | | if (unitListCache) { |
| | | return unitListCache; |
| | | } |
| | | if (unitListPromise) { |
| | | return unitListPromise; |
| | | } |
| | | unitListPromise = getUnitPage({ pageNo: 1, pageSize: 100, status: 0 }).then((res) => { |
| | | unitListCache = res.list || []; |
| | | return unitListCache; |
| | | }).finally(() => { |
| | | unitListPromise = null; |
| | | }); |
| | | return unitListPromise; |
| | | } |
| | | |
| | | /** æ°å¢/ä¿®æ¹ç表å */ |
| | | export function useFormSchema(): VbenFormSchema[] { |
| | |
| | | rules: "required", |
| | | }, |
| | | { |
| | | component: "RadioGroup", |
| | | fieldName: "itemType", |
| | | label: "ç©æç±»å", |
| | | component: "ApiSelect", |
| | | fieldName: "categoryId", |
| | | label: "ç©æåç±»", |
| | | rules: "selectRequired", |
| | | componentProps: { |
| | | options: ITEM_TYPE_OPTIONS, |
| | | buttonStyle: "solid", |
| | | optionType: "button", |
| | | placeholder: "è¯·éæ©ç©æåç±»", |
| | | allowClear: true, |
| | | api: async () => { |
| | | const res = await getItemTypeSimpleList(); |
| | | return res || []; |
| | | }, |
| | | labelField: "name", |
| | | valueField: "id", |
| | | }, |
| | | rules: "required", |
| | | }, |
| | | { |
| | | component: "Input", |
| | |
| | | componentProps: { |
| | | placeholder: "è¯·éæ©è®¡éåä½", |
| | | allowClear: true, |
| | | api: async () => { |
| | | const res = await getUnitPage({ pageNo: 1, pageSize: 100, status: 0 }); |
| | | return res.list || []; |
| | | }, |
| | | api: getUnitListCached, |
| | | labelField: "name", |
| | | valueField: "id", |
| | | }, |
| | |
| | | componentProps: { |
| | | placeholder: "è¯·éæ©è¾
åä½1", |
| | | allowClear: true, |
| | | api: async () => { |
| | | const res = await getUnitPage({ pageNo: 1, pageSize: 100, status: 0 }); |
| | | return res.list || []; |
| | | }, |
| | | api: getUnitListCached, |
| | | labelField: "name", |
| | | valueField: "id", |
| | | }, |
| | |
| | | componentProps: { |
| | | placeholder: "è¯·éæ©è¾
åä½2", |
| | | allowClear: true, |
| | | api: async () => { |
| | | const res = await getUnitPage({ pageNo: 1, pageSize: 100, status: 0 }); |
| | | return res.list || []; |
| | | }, |
| | | api: getUnitListCached, |
| | | labelField: "name", |
| | | valueField: "id", |
| | | }, |
| | |
| | | component: 'Switch', |
| | | fieldName: 'isBatchManaged', |
| | | label: 'æ¹æ¬¡ç®¡ç', |
| | | defaultValue: true, |
| | | defaultValue: false, |
| | | componentProps: { |
| | | class: "w-auto", |
| | | checkedChildren: "æ¯", |
| | | unCheckedChildren: "å¦", |
| | | }, |
| | | rules: z.boolean().default(true), |
| | | rules: z.boolean().default(false), |
| | | }, |
| | | { |
| | | component: "Switch", |
| | |
| | | rows: 3, |
| | | }, |
| | | }, |
| | | // ===== æ¹æ¬¡å±æ§é
ç½®ï¼isBatchManaged = true æ¶æ¾ç¤ºï¼ ===== |
| | | { |
| | | component: "Divider", |
| | | fieldName: "batchConfigDivider", |
| | | label: "æ¹æ¬¡å±æ§é
ç½®", |
| | | formItemClass: "col-span-2", |
| | | componentProps: { |
| | | orientation: "left", |
| | | plain: true, |
| | | }, |
| | | dependencies: { |
| | | triggerFields: ["isBatchManaged"], |
| | | show: (values) => values.isBatchManaged === true, |
| | | }, |
| | | }, |
| | | { |
| | | component: "Switch", |
| | | fieldName: "produceDateFlag", |
| | | label: "çäº§æ¥æå¿
å¡«", |
| | | defaultValue: false, |
| | | componentProps: { |
| | | class: "w-auto", |
| | | checkedChildren: "æ¯", |
| | | unCheckedChildren: "å¦", |
| | | }, |
| | | dependencies: { |
| | | triggerFields: ["isBatchManaged"], |
| | | show: (values) => values.isBatchManaged === true, |
| | | }, |
| | | }, |
| | | { |
| | | component: "Switch", |
| | | fieldName: "expireDateFlag", |
| | | label: "æææå¿
å¡«", |
| | | defaultValue: false, |
| | | componentProps: { |
| | | class: "w-auto", |
| | | checkedChildren: "æ¯", |
| | | unCheckedChildren: "å¦", |
| | | }, |
| | | dependencies: { |
| | | triggerFields: ["isBatchManaged"], |
| | | show: (values) => values.isBatchManaged === true, |
| | | }, |
| | | }, |
| | | { |
| | | component: "Switch", |
| | | fieldName: "receiptDateFlag", |
| | | label: "å
¥åºæ¥æå¿
å¡«", |
| | | defaultValue: false, |
| | | componentProps: { |
| | | class: "w-auto", |
| | | checkedChildren: "æ¯", |
| | | unCheckedChildren: "å¦", |
| | | }, |
| | | dependencies: { |
| | | triggerFields: ["isBatchManaged"], |
| | | show: (values) => values.isBatchManaged === true, |
| | | }, |
| | | }, |
| | | { |
| | | component: "Switch", |
| | | fieldName: "vendorFlag", |
| | | label: "ä¾åºåå¿
å¡«", |
| | | defaultValue: false, |
| | | componentProps: { |
| | | class: "w-auto", |
| | | checkedChildren: "æ¯", |
| | | unCheckedChildren: "å¦", |
| | | }, |
| | | dependencies: { |
| | | triggerFields: ["isBatchManaged"], |
| | | show: (values) => values.isBatchManaged === true, |
| | | }, |
| | | }, |
| | | { |
| | | component: "Switch", |
| | | fieldName: "purchaseOrderCodeFlag", |
| | | label: "éè´è®¢åå·å¿
å¡«", |
| | | defaultValue: false, |
| | | componentProps: { |
| | | class: "w-auto", |
| | | checkedChildren: "æ¯", |
| | | unCheckedChildren: "å¦", |
| | | }, |
| | | dependencies: { |
| | | triggerFields: ["isBatchManaged"], |
| | | show: (values) => values.isBatchManaged === true, |
| | | }, |
| | | }, |
| | | { |
| | | component: "Switch", |
| | | fieldName: "lotNumberFlag", |
| | | label: "ç产æ¹å·å¿
å¡«", |
| | | defaultValue: false, |
| | | componentProps: { |
| | | class: "w-auto", |
| | | checkedChildren: "æ¯", |
| | | unCheckedChildren: "å¦", |
| | | }, |
| | | dependencies: { |
| | | triggerFields: ["isBatchManaged"], |
| | | show: (values) => values.isBatchManaged === true, |
| | | }, |
| | | }, |
| | | { |
| | | component: "Switch", |
| | | fieldName: "qualityStatusFlag", |
| | | label: "è´¨éç¶æå¿
å¡«", |
| | | defaultValue: false, |
| | | componentProps: { |
| | | class: "w-auto", |
| | | checkedChildren: "æ¯", |
| | | unCheckedChildren: "å¦", |
| | | }, |
| | | dependencies: { |
| | | triggerFields: ["isBatchManaged"], |
| | | show: (values) => values.isBatchManaged === true, |
| | | }, |
| | | }, |
| | | ]; |
| | | } |
| | | |
| | |
| | | componentProps: { |
| | | placeholder: "请è¾å
¥ç©æåç§°", |
| | | allowClear: true, |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: "itemType", |
| | | label: "ç©æç±»å", |
| | | component: "Select", |
| | | componentProps: { |
| | | placeholder: "è¯·éæ©ç©æç±»å", |
| | | allowClear: true, |
| | | options: ITEM_TYPE_OPTIONS, |
| | | }, |
| | | }, |
| | | { |
| | |
| | | minWidth: 150, |
| | | }, |
| | | { |
| | | field: "categoryName", |
| | | title: "ç©æåç±»", |
| | | minWidth: 120, |
| | | slots: { default: "categoryName" }, |
| | | }, |
| | | { |
| | | field: "unitMeasureName", |
| | | title: "åä½", |
| | | minWidth: 80, |
| | |
| | | field: "warehouseName", |
| | | title: "é»è®¤ä»åº", |
| | | minWidth: 100, |
| | | }, |
| | | { |
| | | field: "itemType", |
| | | title: "ç©æç±»å", |
| | | minWidth: 100, |
| | | slots: { default: "itemType" }, |
| | | }, |
| | | { |
| | | field: "purchasePrice", |
| | |
| | | <script lang="ts" setup> |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MdmItemApi } from '#/api/mdm/item'; |
| | | import type { MesMdItemTypeApi } from '#/api/mes/md/item/type'; |
| | | |
| | | import { ref } from 'vue'; |
| | | |
| | |
| | | getItemPage, |
| | | updateItemStatus, |
| | | } from '#/api/mdm/item'; |
| | | import { getItemTypeSimpleList } from '#/api/mes/md/item/type'; |
| | | import { $t } from '#/locales'; |
| | | |
| | | import { useGridColumns, useGridFormSchema, ITEM_TYPE_MAP, ITEM_TYPE_COLOR_MAP } from './data'; |
| | | import { useGridColumns, useGridFormSchema } from './data'; |
| | | import Form from './modules/form.vue'; |
| | | |
| | | defineOptions({ name: 'MdmItem' }); |
| | |
| | | connectedComponent: Form, |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | // åç±»å表ç¼å |
| | | const categoryList = ref<MesMdItemTypeApi.ItemType[]>([]); |
| | | |
| | | /** è·ååç±»åç§° */ |
| | | function getCategoryName(categoryId?: number) { |
| | | if (!categoryId || !categoryList.value.length) return ''; |
| | | const category = categoryList.value.find((item) => item.id === categoryId); |
| | | return category?.name || ''; |
| | | } |
| | | |
| | | /** å·æ°è¡¨æ ¼ */ |
| | | function handleRefresh() { |
| | |
| | | proxyConfig: { |
| | | ajax: { |
| | | query: async ({ page }, formValues) => { |
| | | // å è½½åç±»å表ï¼ç¨äºæ¾ç¤ºåç±»åç§°ï¼ |
| | | if (!categoryList.value.length) { |
| | | try { |
| | | categoryList.value = await getItemTypeSimpleList(); |
| | | } catch { |
| | | categoryList.value = []; |
| | | } |
| | | } |
| | | return await getItemPage({ |
| | | pageNo: page.currentPage, |
| | | pageSize: page.pageSize, |
| | |
| | | ]" |
| | | /> |
| | | </template> |
| | | <template #itemType="{ row }"> |
| | | <Tag v-if="row.itemType === 1" color="green">åæ</Tag> |
| | | <Tag v-else-if="row.itemType === 2" color="orange">åæå</Tag> |
| | | <Tag v-else-if="row.itemType === 3" color="blue">æå</Tag> |
| | | <Tag v-else-if="row.itemType === 4" color="purple">è¾
æ</Tag> |
| | | <template #categoryName="{ row }"> |
| | | <Tag v-if="row.categoryId === 1" color="green">{{ getCategoryName(row.categoryId) }}</Tag> |
| | | <Tag v-else-if="row.categoryId === 2" color="orange">{{ getCategoryName(row.categoryId) }}</Tag> |
| | | <Tag v-else-if="row.categoryId === 3" color="blue">{{ getCategoryName(row.categoryId) }}</Tag> |
| | | <Tag v-else-if="row.categoryId === 4" color="purple">{{ getCategoryName(row.categoryId) }}</Tag> |
| | | <Tag v-else-if="row.categoryId === 5" color="cyan">{{ getCategoryName(row.categoryId) }}</Tag> |
| | | <span v-else>{{ getCategoryName(row.categoryId) }}</span> |
| | | </template> |
| | | <template #isBatchManaged="{ row }"> |
| | | <Tag v-if="row.isBatchManaged" color="success">æ¯</Tag> |
| | |
| | | <script lang="ts" setup> |
| | | import type { MdmItemApi } from '#/api/mdm/item'; |
| | | import type { MdmItemBatchConfigApi } from '#/api/mes/md/item-batch-config'; |
| | | import type { VbenFormApi } from '#/adapter/form'; |
| | | |
| | | import { computed, ref, watch } from 'vue'; |
| | | import { ref } from 'vue'; |
| | | |
| | | import { useVbenModal } from "#/packages/effects/common-ui/src"; |
| | | import { useVbenModal } from "#/packages/effects/common-ui/src"; |
| | | |
| | | import { message } from "ant-design-vue"; |
| | | import { message } from "ant-design-vue"; |
| | | |
| | | import { useVbenForm } from '#/adapter/form'; |
| | | import { createItem, getItem, updateItem } from '#/api/mdm/item'; |
| | | import { saveItemBatchConfig } from '#/api/mes/md/item-batch-config'; |
| | | import { $t } from '#/locales'; |
| | | |
| | | import { useFormSchema } from '../data'; |
| | | import ItemBatchConfig from '../components/batch-config.vue'; |
| | | |
| | | defineOptions({ name: "ItemForm" }); |
| | | defineOptions({ name: "ItemForm" }); |
| | | |
| | | const emit = defineEmits(['success']); |
| | | const formData = ref<MdmItemApi.Item>(); |
| | | const batchConfigRef = ref<InstanceType<typeof ItemBatchConfig>>(); |
| | | const batchConfig = ref<Partial<MdmItemBatchConfigApi.ItemBatchConfig>>({}); |
| | | |
| | | // å½å表åä¸çæ¹æ¬¡ç®¡çå¼å
³å¼ï¼ç¨äºæ§å¶æ¹æ¬¡é
ç½®æ¾ç¤ºï¼ |
| | | const currentIsBatchManaged = ref<boolean>(false); |
| | | |
| | | const getTitle = computed(() => { |
| | | return formData.value?.id |
| | | ? $t('ui.actionTitle.edit', ['ç©æ']) |
| | | : $t('ui.actionTitle.create', ['ç©æ']); |
| | | }); |
| | | |
| | | const [Form, formApi] = useVbenForm({ |
| | | commonConfig: { |
| | |
| | | schema: useFormSchema(), |
| | | showDefaultActions: false, |
| | | wrapperClass: 'grid-cols-2', |
| | | // çå¬è¡¨åå¼åå |
| | | handleValuesChange: (values: any) => { |
| | | currentIsBatchManaged.value = values?.isBatchManaged === true; |
| | | }, |
| | | }); |
| | | |
| | | const [Modal, modalApi] = useVbenModal({ |
| | |
| | | modalApi.lock(); |
| | | const data = (await formApi.getValues()) as MdmItemApi.Item; |
| | | try { |
| | | // ä¿åç©æåºæ¬ä¿¡æ¯ |
| | | const itemId = await (formData.value?.id ? updateItem(data) : createItem(data)); |
| | | const savedItemId = typeof itemId === 'number' ? itemId : data.id; |
| | | |
| | | // 妿å¯ç¨æ¹æ¬¡ç®¡çï¼ä¿åæ¹æ¬¡é
ç½® |
| | | if (data.isBatchManaged && savedItemId) { |
| | | await saveItemBatchConfig({ |
| | | ...batchConfig.value, |
| | | itemId: savedItemId, |
| | | }); |
| | | } |
| | | |
| | | await (formData.value?.id ? updateItem(data) : createItem(data)); |
| | | await modalApi.close(); |
| | | emit('success'); |
| | | message.success($t('ui.actionMessage.operationSuccess')); |
| | |
| | | async onOpenChange(isOpen: boolean) { |
| | | if (!isOpen) { |
| | | formData.value = undefined; |
| | | batchConfig.value = {}; |
| | | currentIsBatchManaged.value = false; |
| | | return; |
| | | } |
| | | const data = modalApi.getData<MdmItemApi.Item>(); |
| | |
| | | try { |
| | | formData.value = await getItem(data.id); |
| | | await formApi.setValues(formData.value); |
| | | currentIsBatchManaged.value = formData.value?.isBatchManaged === true; |
| | | // å è½½æ¹æ¬¡é
ç½® |
| | | if (batchConfigRef.value && currentIsBatchManaged.value) { |
| | | await batchConfigRef.value.loadConfig(); |
| | | } |
| | | } finally { |
| | | modalApi.unlock(); |
| | | } |
| | |
| | | // æ°å¢æ¨¡å¼ |
| | | formData.value = undefined; |
| | | await formApi.resetForm(); |
| | | // è·å表åé»è®¤å¼ï¼isBatchManaged é»è®¤ trueï¼ |
| | | const defaultValues = await formApi.getValues(); |
| | | currentIsBatchManaged.value = defaultValues?.isBatchManaged === true; |
| | | } |
| | | }, |
| | | }); |
| | | |
| | | /** å¤çæ¹æ¬¡é
ç½®åå */ |
| | | function handleBatchConfigChange(config: Partial<MdmItemBatchConfigApi.ItemBatchConfig>) { |
| | | batchConfig.value = config; |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | | <Modal class="w-[1000px]" :title="getTitle"> |
| | | <Modal class="w-[1000px]" :title="formData?.id ? $t('ui.actionTitle.edit', ['ç©æ']) : $t('ui.actionTitle.create', ['ç©æ'])"> |
| | | <Form class="mx-4" /> |
| | | <ItemBatchConfig |
| | | ref="batchConfigRef" |
| | | :item-id="formData?.id" |
| | | :is-batch-managed="currentIsBatchManaged" |
| | | @change="handleBatchConfigChange" |
| | | /> |
| | | </Modal> |
| | | </template> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | export { default as ErpSupplierSelectDialog } from './select-dialog.vue'; |
| | | export { default as ErpSupplierSelect } from './select.vue'; |
| ÎļþÃû´Ó src/views/stocktaking/plan/components/select-dialog.vue ÐÞ¸Ä |
| | |
| | | <script lang="ts" setup> |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesWmStockTakingPlanApi } from '#/api/mes/wm/stocktaking/plan'; |
| | | import type { ErpSupplierApi } from '#/api/erp/purchase/supplier'; |
| | | |
| | | import { nextTick, ref } from 'vue'; |
| | | |
| | |
| | | import { message, Modal } from 'ant-design-vue'; |
| | | |
| | | import { useVbenVxeGrid } from '#/adapter/vxe-table'; |
| | | import { getStockTakingPlanPage } from '#/api/mes/wm/stocktaking/plan'; |
| | | import { getSupplierPage } from '#/api/erp/purchase/supplier'; |
| | | |
| | | import { useSelectGridColumns, useSelectGridFormSchema } from '../data'; |
| | | defineOptions({ name: 'ErpSupplierSelectDialog' }); |
| | | |
| | | const emit = defineEmits<{ |
| | | selected: [rows: MesWmStockTakingPlanApi.StockTakingPlan[]]; |
| | | selected: [rows: ErpSupplierApi.Supplier[]]; |
| | | }>(); |
| | | |
| | | const open = ref(false); // å¼¹çªæ¯å¦æå¼ |
| | | const multiple = ref(true); // æ¯å¦å¤é |
| | | const selectedRows = ref<MesWmStockTakingPlanApi.StockTakingPlan[]>([]); // å·²éçç¹æ¹æ¡ |
| | | const preSelectedIds = ref<number[]>([]); // é¢éçç¹æ¹æ¡ç¼å· |
| | | const open = ref(false); |
| | | const multiple = ref(true); |
| | | const selectedRows = ref<ErpSupplierApi.Supplier[]>([]); |
| | | const preSelectedIds = ref<number[]>([]); |
| | | |
| | | /** è·åå¤éè®°å½ï¼å
å« VXE reserve è·¨é¡µè®°å½ */ |
| | | function getTableRows() { |
| | | return gridApi.grid.getTableData().fullData as ErpSupplierApi.Supplier[]; |
| | | } |
| | | |
| | | function getMultipleSelectedRows() { |
| | | const selectedMap = new Map< |
| | | number, |
| | | MesWmStockTakingPlanApi.StockTakingPlan |
| | | >(); |
| | | const selectedMap = new Map<number, ErpSupplierApi.Supplier>(); |
| | | const records = [ |
| | | ...(gridApi.grid.getCheckboxReserveRecords?.() ?? []), |
| | | ...(gridApi.grid.getCheckboxRecords?.() ?? []), |
| | | ] as MesWmStockTakingPlanApi.StockTakingPlan[]; |
| | | ] as ErpSupplierApi.Supplier[]; |
| | | records.forEach((row) => { |
| | | if (row.id !== undefined && row.id !== null) { |
| | | selectedMap.set(row.id, row); |
| | | const rowId = row.id; |
| | | if (rowId) { |
| | | selectedMap.set(rowId, row); |
| | | } |
| | | }); |
| | | return [...selectedMap.values()]; |
| | | } |
| | | |
| | | /** å¤çå¾éåå */ |
| | | function handleCheckboxSelectChange() { |
| | | selectedRows.value = getMultipleSelectedRows(); |
| | | } |
| | | |
| | | /** å¤çåéåå */ |
| | | function handleRadioChange(row: MesWmStockTakingPlanApi.StockTakingPlan) { |
| | | function handleRadioChange(row: ErpSupplierApi.Supplier) { |
| | | selectedRows.value = [row]; |
| | | } |
| | | |
| | | /** å¤é模å¼ä¸åæ¢è¡å¾é */ |
| | | async function toggleMultipleRow(row: MesWmStockTakingPlanApi.StockTakingPlan) { |
| | | async function toggleMultipleRow(row: ErpSupplierApi.Supplier) { |
| | | const selected = gridApi.grid.isCheckedByCheckboxRow(row); |
| | | await gridApi.grid.setCheckboxRow(row, !selected); |
| | | selectedRows.value = getMultipleSelectedRows(); |
| | | } |
| | | |
| | | /** å¤çè¡åå»ï¼åéç´æ¥ç¡®è®¤ï¼å¤é忢å¾é */ |
| | | async function handleCellDblclick({ |
| | | row, |
| | | }: { |
| | | row: MesWmStockTakingPlanApi.StockTakingPlan; |
| | | }) { |
| | | async function handleCellDblclick({ row }: { row: ErpSupplierApi.Supplier }) { |
| | | if (multiple.value) { |
| | | await toggleMultipleRow(row); |
| | | return; |
| | |
| | | handleConfirm(); |
| | | } |
| | | |
| | | /** åæ¾é¢éçç¹æ¹æ¡ */ |
| | | async function applyPreSelection() { |
| | | if (preSelectedIds.value.length === 0) { |
| | | return; |
| | | } |
| | | const rows = |
| | | gridApi.grid.getData() as MesWmStockTakingPlanApi.StockTakingPlan[]; |
| | | const rows = getTableRows(); |
| | | for (const row of rows) { |
| | | if ( |
| | | row.id === undefined || |
| | |
| | | } |
| | | } |
| | | |
| | | function useSelectGridFormSchema() { |
| | | return [ |
| | | { |
| | | fieldName: 'name', |
| | | label: 'ä¾åºååç§°', |
| | | component: 'Input', |
| | | componentProps: { |
| | | placeholder: '请è¾å
¥ä¾åºååç§°', |
| | | allowClear: true, |
| | | }, |
| | | }, |
| | | ]; |
| | | } |
| | | |
| | | function useSelectGridColumns(multiple = false): VxeTableGridOptions<ErpSupplierApi.Supplier>['columns'] { |
| | | return [ |
| | | { |
| | | type: multiple ? 'checkbox' : 'radio', |
| | | width: 50, |
| | | }, |
| | | { |
| | | field: 'name', |
| | | title: 'ä¾åºååç§°', |
| | | minWidth: 150, |
| | | }, |
| | | { |
| | | field: 'contact', |
| | | title: 'è系人', |
| | | minWidth: 120, |
| | | }, |
| | | { |
| | | field: 'mobile', |
| | | title: 'ææºå·ç ', |
| | | minWidth: 130, |
| | | }, |
| | | { |
| | | field: 'telephone', |
| | | title: 'èç³»çµè¯', |
| | | minWidth: 130, |
| | | }, |
| | | ]; |
| | | } |
| | | |
| | | const [Grid, gridApi] = useVbenVxeGrid({ |
| | | formOptions: { |
| | | schema: useSelectGridFormSchema(), |
| | | }, |
| | | gridOptions: { |
| | | columns: useSelectGridColumns(true), |
| | | height: 480, |
| | | height: 520, |
| | | keepSource: true, |
| | | checkboxConfig: { |
| | | highlight: true, |
| | |
| | | proxyConfig: { |
| | | ajax: { |
| | | query: async ({ page }, formValues) => { |
| | | return await getStockTakingPlanPage({ |
| | | return await getSupplierPage({ |
| | | pageNo: page.currentPage, |
| | | pageSize: page.pageSize, |
| | | ...formValues, |
| | | // éæ©å¨åªå±ç¤ºå¯ç¨ç¶æçæ¹æ¡ |
| | | status: CommonStatusEnum.ENABLE, |
| | | }); |
| | | }, |
| | |
| | | refresh: true, |
| | | search: true, |
| | | }, |
| | | } as VxeTableGridOptions<MesWmStockTakingPlanApi.StockTakingPlan>, |
| | | } as VxeTableGridOptions<ErpSupplierApi.Supplier>, |
| | | gridEvents: { |
| | | cellDblclick: handleCellDblclick, |
| | | checkboxAll: handleCheckboxSelectChange, |
| | | checkboxChange: handleCheckboxSelectChange, |
| | | radioChange: ({ |
| | | row, |
| | | }: { |
| | | row: MesWmStockTakingPlanApi.StockTakingPlan; |
| | | }) => { |
| | | radioChange: ({ row }: { row: ErpSupplierApi.Supplier }) => { |
| | | handleRadioChange(row); |
| | | }, |
| | | }, |
| | | }); |
| | | |
| | | /** éç½®æ¥è¯¢åéæ©ç¶æ */ |
| | | async function resetQueryState() { |
| | | selectedRows.value = []; |
| | | await gridApi.grid.clearCheckboxRow(); |
| | |
| | | await gridApi.formApi.resetForm(); |
| | | } |
| | | |
| | | /** æå¼çç¹æ¹æ¡éæ©å¼¹çª */ |
| | | async function openModal( |
| | | selectedIds?: number[], |
| | | options?: { multiple?: boolean }, |
| | |
| | | await applyPreSelection(); |
| | | } |
| | | |
| | | /** å
³éå¼¹çª */ |
| | | function closeModal() { |
| | | async function closeModal() { |
| | | open.value = false; |
| | | await resetQueryState(); |
| | | } |
| | | |
| | | /** ç¡®è®¤éæ© */ |
| | | function handleConfirm() { |
| | | const rows = multiple.value ? getMultipleSelectedRows() : selectedRows.value; |
| | | if (rows.length === 0) { |
| | |
| | | <template> |
| | | <Modal |
| | | v-model:open="open" |
| | | :destroy-on-close="true" |
| | | title="çç¹æ¹æ¡éæ©" |
| | | title="ä¾åºåéæ©" |
| | | width="70%" |
| | | @cancel="closeModal" |
| | | :destroy-on-close="true" |
| | | @ok="handleConfirm" |
| | | @cancel="closeModal" |
| | | > |
| | | <Grid table-title="çç¹æ¹æ¡å表" /> |
| | | <Grid table-title="ä¾åºåå表" /> |
| | | </Modal> |
| | | </template> |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { ErpSupplierApi } from '#/api/erp/purchase/supplier'; |
| | | |
| | | import { computed, ref, useAttrs } from 'vue'; |
| | | |
| | | import { IconifyIcon } from '@vben/icons'; |
| | | |
| | | import { Input, Tooltip } from 'ant-design-vue'; |
| | | |
| | | import ErpSupplierSelectDialog from './select-dialog.vue'; |
| | | |
| | | defineOptions({ name: 'ErpSupplierSelect', inheritAttrs: false }); |
| | | |
| | | const props = withDefaults( |
| | | defineProps<{ |
| | | allowClear?: boolean; |
| | | disabled?: boolean; |
| | | modelValue?: number; |
| | | placeholder?: string; |
| | | supplierName?: string; |
| | | }>(), |
| | | { |
| | | allowClear: true, |
| | | disabled: false, |
| | | modelValue: undefined, |
| | | placeholder: 'è¯·éæ©ä¾åºå', |
| | | supplierName: undefined, |
| | | }, |
| | | ); |
| | | const emit = defineEmits<{ |
| | | change: [item: ErpSupplierApi.Supplier | undefined]; |
| | | 'update:modelValue': [value: number | undefined]; |
| | | }>(); |
| | | const attrs = useAttrs(); |
| | | const dialogRef = ref<InstanceType<typeof ErpSupplierSelectDialog>>(); |
| | | const hovering = ref(false); |
| | | const selectedItem = ref<ErpSupplierApi.Supplier>(); |
| | | |
| | | const displayLabel = computed(() => props.supplierName || selectedItem.value?.name || ''); |
| | | const showClear = computed( |
| | | () => |
| | | props.allowClear && |
| | | !props.disabled && |
| | | hovering.value && |
| | | props.modelValue !== null, |
| | | ); |
| | | |
| | | function clearSelected() { |
| | | selectedItem.value = undefined; |
| | | emit('update:modelValue', undefined); |
| | | emit('change', undefined); |
| | | } |
| | | |
| | | function handleClick(event: MouseEvent) { |
| | | if (props.disabled) { |
| | | return; |
| | | } |
| | | const target = event.target as HTMLElement; |
| | | if (showClear.value && target.closest('.ant-input-suffix')) { |
| | | event.stopPropagation(); |
| | | clearSelected(); |
| | | return; |
| | | } |
| | | const selectedIds = ( |
| | | props.modelValue === null ? [] : [props.modelValue] |
| | | ) as number[]; |
| | | dialogRef.value?.open(selectedIds, { multiple: false }); |
| | | } |
| | | |
| | | function handleSelected(rows: ErpSupplierApi.Supplier[]) { |
| | | const item = rows[0]; |
| | | if (!item) { |
| | | return; |
| | | } |
| | | selectedItem.value = item; |
| | | emit('update:modelValue', item.id); |
| | | emit('change', item); |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | | <div |
| | | v-bind="attrs" |
| | | class="w-full" |
| | | :class="disabled ? 'cursor-not-allowed' : 'cursor-pointer'" |
| | | @click="handleClick" |
| | | @mouseenter="hovering = true" |
| | | @mouseleave="hovering = false" |
| | | > |
| | | <Tooltip :mouse-enter-delay="0.5" :open="selectedItem ? undefined : false"> |
| | | <template #title> |
| | | <div v-if="selectedItem" class="leading-6"> |
| | | <div>åç§°ï¼{{ selectedItem.name || '-' }}</div> |
| | | <div>è系人ï¼{{ selectedItem.contact || '-' }}</div> |
| | | <div>çµè¯ï¼{{ selectedItem.mobile || selectedItem.telephone || '-' }}</div> |
| | | </div> |
| | | </template> |
| | | <Input |
| | | :disabled="disabled" |
| | | :placeholder="placeholder" |
| | | :value="displayLabel" |
| | | readonly |
| | | > |
| | | <template #suffix> |
| | | <IconifyIcon |
| | | class="size-4" |
| | | :icon="showClear ? 'lucide:circle-x' : 'lucide:search'" |
| | | /> |
| | | </template> |
| | | </Input> |
| | | </Tooltip> |
| | | </div> |
| | | <ErpSupplierSelectDialog ref="dialogRef" @selected="handleSelected" /> |
| | | </template> |
| | |
| | | <script lang="ts" setup> |
| | | import type { MdmItemApi } from '#/api/mdm/item'; |
| | | import type { MesWmBatchApi } from '#/api/mes/wm/batch'; |
| | | import type { DescriptionItemSchema } from '#/components/description'; |
| | | |
| | | import { ref } from 'vue'; |
| | | |
| | | import { useVbenModal } from '@vben/common-ui'; |
| | | |
| | | import { getItem } from '#/api/mdm/item'; |
| | | import { getBatch } from '#/api/mes/wm/batch'; |
| | | import { useDescription } from '#/components/description'; |
| | | |
| | | import { useDetailSchema } from '../data'; |
| | | |
| | | const detailData = ref<MesWmBatchApi.Batch>(); // å½åæ¹æ¬¡è¯¦æ
|
| | | const detailData = ref<MesWmBatchApi.Batch>(); |
| | | const itemData = ref<MdmItemApi.Item>(); |
| | | |
| | | const [Descriptions] = useDescription({ |
| | | /** æ ¹æ®ç©ææ¹æ¬¡å±æ§é
ç½®è¿æ»¤è¯¦æ
åæ®µ */ |
| | | function filterSchemaByItemFlags( |
| | | schema: DescriptionItemSchema[], |
| | | item: MdmItemApi.Item | undefined, |
| | | ): DescriptionItemSchema[] { |
| | | // åºç¡æ°æ®å段å§ç»æ¾ç¤º |
| | | const basicFields = new Set([ |
| | | 'code', |
| | | 'itemCode', |
| | | 'itemName', |
| | | 'itemSpecification', |
| | | 'unitName', |
| | | ]); |
| | | |
| | | // æ¹æ¬¡å±æ§åæ®µä¸ flag çæ å° |
| | | const flagFieldMap: Record<string, keyof MdmItemApi.Item> = { |
| | | produceDate: 'produceDateFlag', |
| | | expireDate: 'expireDateFlag', |
| | | receiptDate: 'receiptDateFlag', |
| | | vendorName: 'vendorFlag', |
| | | purchaseOrderCode: 'purchaseOrderCodeFlag', |
| | | lotNumber: 'lotNumberFlag', |
| | | qualityStatus: 'qualityStatusFlag', |
| | | }; |
| | | |
| | | return schema.filter((s) => { |
| | | if (basicFields.has(s.field!)) return true; |
| | | const flagField = flagFieldMap[s.field!]; |
| | | if (flagField) { |
| | | return item?.[flagField] === true; |
| | | } |
| | | // éåºç¡ãéæ¹æ¬¡å±æ§å段ä¸å±ç¤º |
| | | return false; |
| | | }); |
| | | } |
| | | |
| | | const [Descriptions, descApi] = useDescription({ |
| | | bordered: true, |
| | | column: 3, |
| | | schema: useDetailSchema(), |
| | |
| | | async onOpenChange(isOpen) { |
| | | if (!isOpen) { |
| | | detailData.value = undefined; |
| | | itemData.value = undefined; |
| | | return; |
| | | } |
| | | const data = modalApi.getData<{ id?: number }>(); |
| | |
| | | modalApi.lock(); |
| | | try { |
| | | detailData.value = await getBatch(data.id); |
| | | // è·åç©æè¯¦æ
ä»¥è¯»åæ¹æ¬¡å±æ§é
ç½® |
| | | if (detailData.value?.itemId) { |
| | | itemData.value = await getItem(detailData.value.itemId); |
| | | const filtered = filterSchemaByItemFlags( |
| | | useDetailSchema(), |
| | | itemData.value, |
| | | ); |
| | | descApi.setDescProps({ schema: filtered }); |
| | | } |
| | | } finally { |
| | | modalApi.unlock(); |
| | | } |
| | |
| | | import { generateAutoCode } from '#/api/mes/md/autocode/record'; |
| | | import { getRangePickerDefaultProps } from '#/utils'; |
| | | import { MdItemSelect } from '#/views/mes/md/item/components'; |
| | | import { MdVendorSelect } from '#/views/mes/md/vendor/components'; |
| | | import { ErpSupplierSelect } from '#/views/erp/purchase/supplier/components'; |
| | | import { |
| | | WmArrivalNoticeLineSelect, |
| | | WmArrivalNoticeSelect, |
| | |
| | | { |
| | | fieldName: 'vendorId', |
| | | label: 'ä¾åºå', |
| | | component: markRaw(MdVendorSelect), |
| | | component: markRaw(ErpSupplierSelect), |
| | | componentProps: { |
| | | placeholder: 'è¯·éæ©ä¾åºå', |
| | | }, |
| | |
| | | { |
| | | fieldName: 'vendorId', |
| | | label: 'ä¾åºå', |
| | | component: markRaw(MdVendorSelect), |
| | | component: markRaw(ErpSupplierSelect), |
| | | componentProps: { |
| | | placeholder: 'è¯·éæ©ä¾åºå', |
| | | }, |
| | |
| | | <script lang="ts" setup> |
| | | import type { MdmItemBatchConfigApi } from '#/api/mes/md/item-batch-config'; |
| | | import type { MdmItemApi } from '#/api/mdm/item'; |
| | | |
| | | import { computed, ref, watch } from 'vue'; |
| | | import { computed } from 'vue'; |
| | | |
| | | import { Divider, Tag } from 'ant-design-vue'; |
| | | |
| | | import { getItemBatchConfigByItemId } from '#/api/mes/md/item-batch-config'; |
| | | |
| | | const props = defineProps<{ |
| | | itemId?: number; |
| | | isBatchManaged?: boolean; |
| | | item?: MdmItemApi.Item | null; |
| | | }>(); |
| | | |
| | | // æ¹æ¬¡é
ç½®æ°æ® |
| | | const config = ref<MdmItemBatchConfigApi.ItemBatchConfig | null>(null); |
| | | |
| | | // æ¯å¦å è½½ä¸ |
| | | const loading = ref(false); |
| | | |
| | | // æ¯å¦æ¾ç¤ºï¼å¯ç¨æ¹æ¬¡ç®¡çæ¶æ¾ç¤ºï¼ |
| | | const visible = computed(() => props.isBatchManaged === true); |
| | | const visible = computed(() => props.item?.isBatchManaged === true); |
| | | |
| | | // å·²å¯ç¨çæ¹æ¬¡å±æ§å表ï¼ä»
ä¿ç7ä¸ªåæ®µï¼ |
| | | // å·²å¯ç¨çæ¹æ¬¡å±æ§å表 |
| | | const enabledProps = computed(() => { |
| | | if (!config.value) return []; |
| | | const props: { label: string; value: boolean }[] = []; |
| | | if (config.value.produceDateFlag) props.push({ label: 'çäº§æ¥æ', value: true }); |
| | | if (config.value.expireDateFlag) props.push({ label: 'æææ', value: true }); |
| | | if (config.value.receiptDateFlag) props.push({ label: 'å
¥åºæ¥æ', value: true }); |
| | | if (config.value.vendorFlag) props.push({ label: 'ä¾åºå', value: true }); |
| | | if (config.value.purchaseOrderCodeFlag) props.push({ label: 'éè´è®¢åå·', value: true }); |
| | | if (config.value.lotNumberFlag) props.push({ label: 'ç产æ¹å·', value: true }); |
| | | if (config.value.qualityStatusFlag) props.push({ label: 'è´¨éç¶æ', value: true }); |
| | | return props; |
| | | }); |
| | | |
| | | /** å è½½æ¹æ¬¡é
ç½® */ |
| | | async function loadConfig() { |
| | | if (!props.itemId || !props.isBatchManaged) { |
| | | config.value = null; |
| | | return; |
| | | } |
| | | loading.value = true; |
| | | try { |
| | | const data = await getItemBatchConfigByItemId(props.itemId); |
| | | config.value = data; |
| | | } catch { |
| | | config.value = null; |
| | | } finally { |
| | | loading.value = false; |
| | | } |
| | | } |
| | | |
| | | /** éç½® */ |
| | | function reset() { |
| | | config.value = null; |
| | | loading.value = false; |
| | | } |
| | | |
| | | // çå¬ itemId ååï¼å è½½é
ç½® |
| | | watch( |
| | | () => [props.itemId, props.isBatchManaged], |
| | | () => { |
| | | if (props.itemId && props.isBatchManaged) { |
| | | loadConfig(); |
| | | } else { |
| | | reset(); |
| | | } |
| | | }, |
| | | { immediate: true }, |
| | | ); |
| | | |
| | | defineExpose({ |
| | | loadConfig, |
| | | reset, |
| | | if (!props.item) return []; |
| | | const list: string[] = []; |
| | | if (props.item.produceDateFlag) list.push('çäº§æ¥æ'); |
| | | if (props.item.expireDateFlag) list.push('æææ'); |
| | | if (props.item.receiptDateFlag) list.push('å
¥åºæ¥æ'); |
| | | if (props.item.vendorFlag) list.push('ä¾åºå'); |
| | | if (props.item.purchaseOrderCodeFlag) list.push('éè´è®¢åå·'); |
| | | if (props.item.lotNumberFlag) list.push('ç产æ¹å·'); |
| | | if (props.item.qualityStatusFlag) list.push('è´¨éç¶æ'); |
| | | return list; |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <div v-if="visible" class="mt-4 rounded border border-gray-200 bg-gray-50 p-4"> |
| | | <div v-if="visible" class="mx-4 mt-4 rounded border border-gray-200 bg-gray-50 p-4"> |
| | | <Divider orientation="left">æ¹æ¬¡å±æ§</Divider> |
| | | <div v-if="loading" class="text-center text-gray-500">å è½½ä¸...</div> |
| | | <div v-else-if="enabledProps.length === 0" class="text-center text-gray-500"> |
| | | <div v-if="enabledProps.length === 0" class="text-center text-gray-500"> |
| | | è¯¥ç©ææªé
ç½®æ¹æ¬¡å±æ§ |
| | | </div> |
| | | <div v-else class="flex flex-wrap gap-2"> |
| | | <Tag v-for="prop in enabledProps" :key="prop.label" color="blue"> |
| | | {{ prop.label }} |
| | | <Tag v-for="prop in enabledProps" :key="prop" color="blue"> |
| | | {{ prop }} |
| | | </Tag> |
| | | </div> |
| | | <p class="mt-2 text-xs text-gray-500"> |
| | |
| | | MaterialStockAdjustOutParams, |
| | | } from '#/api/mes/wm/materialstock'; |
| | | import type { MdmItemApi } from '#/api/mdm/item'; |
| | | import type { MdmItemBatchConfigApi } from '#/api/mes/md/item-batch-config'; |
| | | import type { VbenFormSchema } from '#/adapter/form'; |
| | | |
| | | import { ref } from 'vue'; |
| | |
| | | adjustMaterialStockOut, |
| | | } from '#/api/mes/wm/materialstock'; |
| | | import { getItem } from '#/api/mdm/item'; |
| | | import { getItemBatchConfigByItemId } from '#/api/mes/md/item-batch-config'; |
| | | import { MdmItemSelect } from '#/views/basicData/mdm/components'; |
| | | import { MdVendorSelect } from '#/views/mes/md/vendor/components'; |
| | | import { ErpSupplierSelect } from '#/views/erp/purchase/supplier/components'; |
| | | import BatchConfigDisplay from './batch-config-display.vue'; |
| | | import { |
| | | WmWarehouseAreaSelect, |
| | |
| | | const batchEnabled = ref(false); |
| | | // æ¯å¦æå¨å¡«åæ¹æ¬¡å· |
| | | const manualBatchEntry = ref(false); |
| | | // ç©ææ¹æ¬¡é
ç½® |
| | | const batchConfig = ref<MdmItemBatchConfigApi.ItemBatchConfig | null>(null); |
| | | // æ¹æ¬¡é
ç½®å±ç¤ºç»ä»¶å¼ç¨ |
| | | const batchConfigDisplayRef = ref<InstanceType<typeof BatchConfigDisplay>>(); |
| | | |
| | | // æ é¢ |
| | | const modalTitle = ref('åºåè°æ´'); |
| | | |
| | | /** å è½½ç©ææ¹æ¬¡é
ç½®å¹¶æ´æ°å段æ¾ç¤º */ |
| | | async function loadBatchConfigAndUpdateFields(itemId: number) { |
| | | try { |
| | | const config = await getItemBatchConfigByItemId(itemId); |
| | | batchConfig.value = config; |
| | | } catch { |
| | | batchConfig.value = null; |
| | | } |
| | | await updateBatchFields(); |
| | | } |
| | | |
| | | /** æ´æ°æ¹æ¬¡å段æ¾ç¤ºï¼æ ¹æ®é
ç½®å±ç¤ºå·²å¯ç¨ç屿§ï¼ */ |
| | | /** æ´æ°æ¹æ¬¡å段æ¾ç¤ºï¼æ ¹æ®ç©ææ°æ®ä¸çæ¹æ¬¡é
ç½®å±ç¤ºå·²å¯ç¨ç屿§ï¼ */ |
| | | async function updateBatchFields() { |
| | | const enabled = selectedItem.value?.isBatchManaged === true; |
| | | batchEnabled.value = enabled; |
| | | |
| | | if (!enabled) { |
| | | // éèæææ¹æ¬¡ç¸å
³å段 |
| | | formApi.updateSchema([ |
| | | { fieldName: 'batchCode', dependencies: { show: () => false } }, |
| | | { fieldName: 'manualBatchEntry', dependencies: { show: () => false } }, |
| | | { fieldName: 'produceDate', dependencies: { show: () => false } }, |
| | | { fieldName: 'expireDate', dependencies: { show: () => false } }, |
| | | { fieldName: 'manualBatchEntry', dependencies: { show: () => false } }, |
| | | { fieldName: 'receiptDate', dependencies: { show: () => false } }, |
| | | { fieldName: 'vendorId', dependencies: { show: () => true } }, |
| | | { fieldName: 'purchaseOrderCode', dependencies: { show: () => false } }, |
| | | { fieldName: 'lotNumber', dependencies: { show: () => false } }, |
| | | { fieldName: 'qualityStatus', dependencies: { show: () => false } }, |
| | | ]); |
| | | return; |
| | | } |
| | | |
| | | // å¯ç¨æ¹æ¬¡ç®¡çï¼æ ¹æ®é
ç½®æ¾ç¤ºå段 |
| | | const config = batchConfig.value; |
| | | const item = selectedItem.value; |
| | | const isIn = operateType.value === 1; |
| | | |
| | | // æ¯å¦æå¨å¡«åæ¹æ¬¡å·æ§å¶æ¹æ¬¡å·åæ®µçæ¾ç¤º |
| | | const showBatchCode = manualBatchEntry.value; |
| | | const showProduceDate = isIn && !!config?.produceDateFlag; |
| | | const showExpireDate = isIn && !!config?.expireDateFlag; |
| | | |
| | | formApi.updateSchema([ |
| | | { fieldName: 'batchCode', dependencies: { show: () => showBatchCode } }, |
| | | { fieldName: 'produceDate', dependencies: { show: () => showProduceDate } }, |
| | | { fieldName: 'expireDate', dependencies: { show: () => showExpireDate } }, |
| | | { fieldName: 'batchCode', dependencies: { show: () => manualBatchEntry.value } }, |
| | | { fieldName: 'manualBatchEntry', dependencies: { show: () => true } }, |
| | | { fieldName: 'produceDate', dependencies: { show: () => isIn && !!item?.produceDateFlag } }, |
| | | { fieldName: 'expireDate', dependencies: { show: () => isIn && !!item?.expireDateFlag } }, |
| | | { fieldName: 'receiptDate', dependencies: { show: () => isIn && !!item?.receiptDateFlag } }, |
| | | { fieldName: 'vendorId', dependencies: { show: () => !isIn || !!item?.vendorFlag } }, |
| | | { fieldName: 'purchaseOrderCode', dependencies: { show: () => isIn && !!item?.purchaseOrderCodeFlag } }, |
| | | { fieldName: 'lotNumber', dependencies: { show: () => isIn && !!item?.lotNumberFlag } }, |
| | | { fieldName: 'qualityStatus', dependencies: { show: () => isIn && !!item?.qualityStatusFlag } }, |
| | | ]); |
| | | } |
| | | |
| | |
| | | if (item?.id) { |
| | | const itemDetail = await getItem(item.id); |
| | | selectedItem.value = itemDetail; |
| | | // å è½½ç©ææ¹æ¬¡é
ç½®å¹¶æ´æ°å段 |
| | | await loadBatchConfigAndUpdateFields(item.id); |
| | | // æ ¹æ®ç©ææ°æ®æ´æ°æ¹æ¬¡å段 |
| | | await updateBatchFields(); |
| | | } else { |
| | | batchConfig.value = null; |
| | | batchEnabled.value = false; |
| | | } |
| | | // æ¸
ç©ºæ¹æ¬¡ç¸å
³å¼ |
| | |
| | | }, |
| | | dependencies: { |
| | | triggerFields: ['itemId'], |
| | | show: () => false, // é»è®¤éè |
| | | show: () => false, |
| | | }, |
| | | }, |
| | | // å
¥åºæ¥æï¼æ ¹æ®æ¹æ¬¡é
ç½®æ¾ç¤ºï¼ä»
å
¥åºï¼ |
| | | { |
| | | fieldName: 'receiptDate', |
| | | label: 'å
¥åºæ¥æ', |
| | | component: 'DatePicker', |
| | | componentProps: { |
| | | placeholder: 'è¯·éæ©å
¥åºæ¥æ', |
| | | format: 'YYYY-MM-DD', |
| | | valueFormat: 'YYYY-MM-DD', |
| | | }, |
| | | dependencies: { |
| | | triggerFields: ['itemId'], |
| | | show: () => false, |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'vendorId', |
| | | label: 'ä¾åºå', |
| | | component: markRaw(MdVendorSelect), |
| | | component: markRaw(ErpSupplierSelect), |
| | | componentProps: { |
| | | placeholder: 'è¯·éæ©ä¾åºå', |
| | | }, |
| | | rules: 'selectRequired', |
| | | }, |
| | | // éè´è®¢åå·ï¼æ ¹æ®æ¹æ¬¡é
ç½®æ¾ç¤ºï¼ä»
å
¥åºï¼ |
| | | { |
| | | fieldName: 'purchaseOrderCode', |
| | | label: 'éè´è®¢åå·', |
| | | component: 'Input', |
| | | componentProps: { |
| | | placeholder: '请è¾å
¥éè´è®¢åå·', |
| | | }, |
| | | dependencies: { |
| | | triggerFields: ['itemId'], |
| | | show: () => false, |
| | | }, |
| | | }, |
| | | // ç产æ¹å·ï¼æ ¹æ®æ¹æ¬¡é
ç½®æ¾ç¤ºï¼ä»
å
¥åºï¼ |
| | | { |
| | | fieldName: 'lotNumber', |
| | | label: 'ç产æ¹å·', |
| | | component: 'Input', |
| | | componentProps: { |
| | | placeholder: '请è¾å
¥ç产æ¹å·', |
| | | }, |
| | | dependencies: { |
| | | triggerFields: ['itemId'], |
| | | show: () => false, |
| | | }, |
| | | }, |
| | | // è´¨éç¶æï¼æ ¹æ®æ¹æ¬¡é
ç½®æ¾ç¤ºï¼ä»
å
¥åºï¼ |
| | | { |
| | | fieldName: 'qualityStatus', |
| | | label: 'è´¨éç¶æ', |
| | | component: 'Select', |
| | | componentProps: { |
| | | placeholder: 'è¯·éæ©è´¨éç¶æ', |
| | | allowClear: true, |
| | | options: [ |
| | | { label: 'åæ ¼', value: 'QUALIFIED' }, |
| | | { label: 'ä¸åæ ¼', value: 'UNQUALIFIED' }, |
| | | { label: 'å¾
æ£', value: 'PENDING' }, |
| | | ], |
| | | }, |
| | | dependencies: { |
| | | triggerFields: ['itemId'], |
| | | show: () => false, |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'quantity', |
| | |
| | | selectedWarehouse.value = null; |
| | | selectedLocation.value = null; |
| | | batchEnabled.value = false; |
| | | batchConfig.value = null; |
| | | operateType.value = 1; |
| | | modalTitle.value = 'åºåè°æ´'; |
| | | return; |
| | |
| | | // é»è®¤éèæ¹æ¬¡ç¸å
³å段 |
| | | formApi.updateSchema([ |
| | | { fieldName: 'batchCode', dependencies: { show: () => false } }, |
| | | { fieldName: 'manualBatchEntry', dependencies: { show: () => false } }, |
| | | { fieldName: 'produceDate', dependencies: { show: () => false } }, |
| | | { fieldName: 'expireDate', dependencies: { show: () => false } }, |
| | | { fieldName: 'manualBatchEntry', dependencies: { show: () => false } }, |
| | | { fieldName: 'receiptDate', dependencies: { show: () => false } }, |
| | | { fieldName: 'purchaseOrderCode', dependencies: { show: () => false } }, |
| | | { fieldName: 'lotNumber', dependencies: { show: () => false } }, |
| | | { fieldName: 'qualityStatus', dependencies: { show: () => false } }, |
| | | ]); |
| | | // éç½®æå¨å¡«åæ¹æ¬¡å·ç¶æ |
| | | manualBatchEntry.value = false; |
| | |
| | | if (data.itemId) { |
| | | const itemDetail = await getItem(data.itemId); |
| | | selectedItem.value = itemDetail; |
| | | await loadBatchConfigAndUpdateFields(data.itemId); |
| | | await updateBatchFields(); |
| | | } |
| | | } |
| | | }, |
| | |
| | | |
| | | const values = await formApi.getValues(); |
| | | |
| | | const { |
| | | itemId, |
| | | warehouseId, |
| | | locationId, |
| | | areaId, |
| | | batchCode, |
| | | produceDate, |
| | | expireDate, |
| | | vendorId, |
| | | quantity, |
| | | reason, |
| | | } = values; |
| | | |
| | | // å¯ç¨æ¹æ¬¡ç®¡çæ¶çæ ¡éª |
| | | if (batchEnabled.value) { |
| | | // æå¨å¡«åæ¹æ¬¡å·æ¶ï¼æ¹æ¬¡å·å¿
å¡« |
| | | if (manualBatchEntry.value && !batchCode) { |
| | | if (manualBatchEntry.value && !values.batchCode) { |
| | | message.error('请è¾å
¥æ¹æ¬¡å·'); |
| | | return; |
| | | } |
| | | // æ ¹æ®æ¹æ¬¡é
ç½®æ ¡éªå¿
å¡«åæ®µï¼ä»
å
¥åºï¼ |
| | | if (operateType.value === 1) { |
| | | const config = batchConfig.value; |
| | | if (config?.produceDateFlag && !produceDate) { |
| | | const item = selectedItem.value; |
| | | if (item?.produceDateFlag && !values.produceDate) { |
| | | message.error('è¯·éæ©çäº§æ¥æ'); |
| | | return; |
| | | } |
| | | if (config?.expireDateFlag && !expireDate) { |
| | | if (item?.expireDateFlag && !values.expireDate) { |
| | | message.error('è¯·éæ©æææ'); |
| | | return; |
| | | } |
| | | if (item?.receiptDateFlag && !values.receiptDate) { |
| | | message.error('è¯·éæ©å
¥åºæ¥æ'); |
| | | return; |
| | | } |
| | | if (item?.purchaseOrderCodeFlag && !values.purchaseOrderCode) { |
| | | message.error('请è¾å
¥éè´è®¢åå·'); |
| | | return; |
| | | } |
| | | if (item?.lotNumberFlag && !values.lotNumber) { |
| | | message.error('请è¾å
¥ç产æ¹å·'); |
| | | return; |
| | | } |
| | | if (item?.qualityStatusFlag && !values.qualityStatus) { |
| | | message.error('è¯·éæ©è´¨éç¶æ'); |
| | | return; |
| | | } |
| | | } |
| | |
| | | if (type === 1) { |
| | | // å
¥åº |
| | | const params: MaterialStockAdjustInParams = { |
| | | itemId, |
| | | warehouseId, |
| | | locationId, |
| | | areaId, |
| | | batchCode, |
| | | produceDate, |
| | | expireDate, |
| | | vendorId, |
| | | quantity, |
| | | reason, |
| | | itemId: values.itemId, |
| | | warehouseId: values.warehouseId, |
| | | locationId: values.locationId, |
| | | areaId: values.areaId, |
| | | batchCode: values.batchCode, |
| | | produceDate: values.produceDate, |
| | | expireDate: values.expireDate, |
| | | receiptDate: values.receiptDate, |
| | | vendorId: values.vendorId, |
| | | purchaseOrderCode: values.purchaseOrderCode, |
| | | lotNumber: values.lotNumber, |
| | | qualityStatus: values.qualityStatus, |
| | | quantity: values.quantity, |
| | | reason: values.reason, |
| | | }; |
| | | await adjustMaterialStockIn(params); |
| | | message.success('å
¥åºæå'); |
| | | } else { |
| | | // åºåº |
| | | const params: MaterialStockAdjustOutParams = { |
| | | itemId, |
| | | warehouseId, |
| | | locationId, |
| | | areaId, |
| | | batchCode, |
| | | vendorId, |
| | | quantity, |
| | | reason, |
| | | itemId: values.itemId, |
| | | warehouseId: values.warehouseId, |
| | | locationId: values.locationId, |
| | | areaId: values.areaId, |
| | | batchCode: values.batchCode, |
| | | vendorId: values.vendorId, |
| | | quantity: values.quantity, |
| | | reason: values.reason, |
| | | }; |
| | | await adjustMaterialStockOut(params); |
| | | message.success('åºåºæå'); |
| | |
| | | <Form class="mx-4" /> |
| | | <BatchConfigDisplay |
| | | ref="batchConfigDisplayRef" |
| | | :item-id="selectedItem?.id" |
| | | :is-batch-managed="batchEnabled" |
| | | :item="selectedItem" |
| | | /> |
| | | </Modal> |
| | | </template> |
| | |
| | | "/admin-api": { |
| | | changeOrigin: true, |
| | | rewrite: path => path.replace(/^\/admin-api/, ""), |
| | | target: "http://192.168.0.244:48080/admin-api", |
| | | target: "http://192.168.0.226:48080/admin-api", |
| | | ws: true, |
| | | }, |
| | | }, |