| | |
| | | <?xml version="1.0" encoding="UTF-8"?> |
| | | <module type="WEB_MODULE" version="4"> |
| | | <component name="NewModuleRootManager"> |
| | | <content url="file://$MODULE_DIR$" /> |
| | | <content url="file://$MODULE_DIR$"> |
| | | <excludeFolder url="file://$MODULE_DIR$/node_modules" /> |
| | | <excludeFolder url="file://$MODULE_DIR$/.pnpm" /> |
| | | <excludeFolder url="file://$MODULE_DIR$/.vite" /> |
| | | <excludeFolder url="file://$MODULE_DIR$/.cache" /> |
| | | <excludeFolder url="file://$MODULE_DIR$/dist" /> |
| | | <excludeFolder url="file://$MODULE_DIR$/build" /> |
| | | </content> |
| | | <orderEntry type="inheritedJdk" /> |
| | | <orderEntry type="sourceFolder" forTests="false" /> |
| | | </component> |
| | |
| | | params, |
| | | }); |
| | | } |
| | | |
| | | /** æ ¹æ®éè´è®¢åçæå°è´§éç¥å */ |
| | | export function generateArrivalNoticeFromPurchaseOrder(purchaseOrderId: number) { |
| | | return requestClient.post<number>( |
| | | `/mes/wm/arrival-notice/generate-from-purchase-order?purchaseOrderId=${purchaseOrderId}`, |
| | | ); |
| | | } |
| | |
| | | params, |
| | | }); |
| | | } |
| | | |
| | | /** æ ¹æ®å°è´§éç¥åçæéè´å
¥åºå */ |
| | | export function generateItemReceiptFromArrivalNotice(arrivalNoticeId: number) { |
| | | return requestClient.post<number>( |
| | | `/mes/wm/item-receipt/generate-from-arrival-notice?arrivalNoticeId=${arrivalNoticeId}`, |
| | | ); |
| | | } |
| | | |
| | | /** æäº¤éè´å
¥åºåå®¡æ¹ */ |
| | | export function submitItemReceiptApproval( |
| | | id: number, |
| | | processDefinitionKey: string, |
| | | ) { |
| | | return requestClient.put( |
| | | `/mes/wm/item-receipt/submit-approval?id=${id}&processDefinitionKey=${processDefinitionKey}`, |
| | | ); |
| | | } |
| | |
| | | id?: number; // éè´§åç¼å· |
| | | code?: string; // éè´§åç¼å· |
| | | name?: string; // éè´§ååç§° |
| | | purchaseOrderId?: number; // éè´è®¢åç¼å· |
| | | purchaseOrderCode?: string; // éè´è®¢åå· |
| | | vendorId?: number; // ä¾åºåç¼å· |
| | | vendorCode?: string; // ä¾åºåç¼ç |
| | |
| | | }, |
| | | children: [ |
| | | { |
| | | path: 'wm/warehouse/location', |
| | | name: 'MesWmLocation', |
| | | meta: { |
| | | title: 'åºåºè®¾ç½®', |
| | | activePath: '/mes/wm/warehouse', |
| | | }, |
| | | component: () => import('#/views/mes/wm/warehouse/location/index.vue'), |
| | | }, |
| | | { |
| | | path: 'wm/warehouse/area', |
| | | name: 'MesWmArea', |
| | | meta: { |
| | | title: 'åºä½è®¾ç½®', |
| | | activePath: '/mes/wm/warehouse', |
| | | }, |
| | | component: () => import('#/views/mes/wm/warehouse/area/index.vue'), |
| | | }, |
| | | { |
| | | path: 'wm/barcode/config', |
| | | name: 'MesWmBarcodeConfig', |
| | | meta: { |
| | | title: 'æ¡ç é
ç½®', |
| | | activePath: '/mes/wm/barcode', |
| | | }, |
| | | component: () => import('#/views/mes/wm/barcode/config/index.vue'), |
| | | }, |
| | | { |
| | | path: 'pro/task/gantt-edit', |
| | | name: 'MesProTaskGanttEdit', |
| | | meta: { |
| | |
| | | <script lang="ts" setup> |
| | | import type { MesMdVendorApi } from '#/api/mes/md/vendor'; |
| | | |
| | | import { computed, ref, useAttrs, watch } from 'vue'; |
| | | import { computed, ref, useAttrs } from 'vue'; |
| | | |
| | | import { IconifyIcon } from '../../../../../packages/icons/src'; |
| | | |
| | | import { Input, Tooltip } from 'ant-design-vue'; |
| | | |
| | | import { getVendor } from '#/api/mes/md/vendor'; |
| | | |
| | | import MdVendorSelectDialog from './select-dialog.vue'; |
| | | |
| | |
| | | disabled?: boolean; |
| | | modelValue?: number; |
| | | placeholder?: string; |
| | | vendorName?: string; |
| | | }>(), |
| | | { |
| | | allowClear: true, |
| | | disabled: false, |
| | | modelValue: undefined, |
| | | placeholder: 'è¯·éæ©ä¾åºå', |
| | | vendorName: undefined, |
| | | }, |
| | | ); |
| | | const emit = defineEmits<{ |
| | | change: [item: MesMdVendorApi.Vendor | undefined]; |
| | | 'update:modelValue': [value: number | undefined]; |
| | | }>(); |
| | | const attrs = useAttrs(); // éä¼ å±æ§ |
| | | const dialogRef = ref<InstanceType<typeof MdVendorSelectDialog>>(); // ä¾åºåéæ©å¼¹çª |
| | | const hovering = ref(false); // æ¯å¦æ¬å |
| | | const selectedItem = ref<MesMdVendorApi.Vendor>(); // å½åéä¸ä¾åºå |
| | | const attrs = useAttrs(); |
| | | const dialogRef = ref<InstanceType<typeof MdVendorSelectDialog>>(); |
| | | const hovering = ref(false); |
| | | const selectedItem = ref<MesMdVendorApi.Vendor>(); |
| | | |
| | | const displayLabel = computed(() => selectedItem.value?.name ?? ''); // éæ©å¨å±ç¤ºåç§° |
| | | const displayLabel = computed(() => props.vendorName || selectedItem.value?.name || ''); |
| | | const showClear = computed( |
| | | () => |
| | | props.allowClear && |
| | |
| | | props.modelValue !== null, |
| | | ); |
| | | |
| | | /** æ ¹æ®ä¾åºåç¼å·åæ¾éæ©å¨ */ |
| | | async function resolveItemById(id: number | undefined) { |
| | | if (!id) { |
| | | selectedItem.value = undefined; |
| | | return; |
| | | } |
| | | if (selectedItem.value?.id === id) { |
| | | return; |
| | | } |
| | | selectedItem.value = await getVendor(id); |
| | | } |
| | | |
| | | watch( |
| | | () => props.modelValue, |
| | | (value) => { |
| | | resolveItemById(value); |
| | | }, |
| | | { immediate: true }, |
| | | ); |
| | | |
| | | /** æ¸
空已éä¾åºå */ |
| | | function clearSelected() { |
| | | selectedItem.value = undefined; |
| | | emit('update:modelValue', undefined); |
| | | emit('change', undefined); |
| | | } |
| | | |
| | | /** æå¼ä¾åºåéæ©å¼¹çª */ |
| | | function handleClick(event: MouseEvent) { |
| | | if (props.disabled) { |
| | | return; |
| | |
| | | dialogRef.value?.open(selectedIds, { multiple: false }); |
| | | } |
| | | |
| | | /** åå¡«éä¸çä¾åºå */ |
| | | function handleSelected(rows: MesMdVendorApi.Vendor[]) { |
| | | const item = rows[0]; |
| | | if (!item) { |
| | |
| | | rules: 'required', |
| | | }, |
| | | { |
| | | fieldName: 'vendorName', |
| | | label: '', |
| | | component: 'Input', |
| | | dependencies: { |
| | | triggerFields: [''], |
| | | show: () => false, |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'purchaseOrderId', |
| | | label: 'éè´è®¢å', |
| | | component: markRaw(ErpPurchaseOrderSelect), |
| | | componentProps: { |
| | | placeholder: 'è¯·éæ©éè´è®¢å', |
| | | onChange: (item: any) => { |
| | | if (item?.supplierId && formApi) { |
| | | formApi.setFieldValue('vendorId', item.supplierId); |
| | | formApi.setFieldValue('vendorName', item.supplierName); |
| | | } |
| | | }, |
| | | }, |
| | | }, |
| | | { |
| | |
| | | component: markRaw(MdVendorSelect), |
| | | componentProps: { |
| | | placeholder: 'è¯·éæ©ä¾åºå', |
| | | disabled: true, |
| | | }, |
| | | dependencies: { |
| | | triggerFields: ['vendorName'], |
| | | componentProps: (values) => ({ |
| | | placeholder: 'è¯·éæ©ä¾åºå', |
| | | disabled: true, |
| | | vendorName: values.vendorName as string, |
| | | }), |
| | | }, |
| | | rules: 'selectRequired', |
| | | }, |
| | |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesWmArrivalNoticeApi } from '#/api/mes/wm/arrivalnotice'; |
| | | |
| | | import { Page, useVbenModal } from '../../../packages/effects/common-ui/src'; |
| | | import { MesWmArrivalNoticeStatusEnum } from '../../../packages/constants/src'; |
| | | import { downloadFileFromBlobPart } from '../../../packages/utils/src'; |
| | | import { Page, useVbenModal } from '@vben/common-ui'; |
| | | import { MesWmArrivalNoticeStatusEnum } from '@vben/constants'; |
| | | import { downloadFileFromBlobPart } from '@vben/utils'; |
| | | |
| | | import { Button, message } from 'ant-design-vue'; |
| | | |
| | |
| | | import { |
| | | deleteArrivalNotice, |
| | | exportArrivalNotice, |
| | | generateArrivalNoticeFromPurchaseOrder, |
| | | getArrivalNoticePage, |
| | | } from '#/api/mes/wm/arrivalnotice'; |
| | | import { $t } from '#/locales'; |
| | | |
| | | import { useGridColumns, useGridFormSchema } from './data'; |
| | | import Form from './modules/form.vue'; |
| | | import PoSelectDialog from './modules/po-select-dialog.vue'; |
| | | |
| | | const [FormModal, formModalApi] = useVbenModal({ |
| | | connectedComponent: Form, |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | const [PoSelectModal, poSelectModalApi] = useVbenModal({ |
| | | connectedComponent: PoSelectDialog, |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | |
| | | message.info('请åå¾ãä»åºç®¡ç - éè´å
¥åºãä¸è¿è¡å
¥åºæä½'); |
| | | } |
| | | |
| | | /** ä»éè´è®¢åçæå°è´§éç¥å */ |
| | | async function handleGenerateFromPO() { |
| | | poSelectModalApi.open(); |
| | | } |
| | | |
| | | /** éè´è®¢åéæ©åè° */ |
| | | async function handlePurchaseOrderSelected(purchaseOrderId: number) { |
| | | const hideLoading = message.loading({ |
| | | content: 'æ£å¨çæå°è´§éç¥å...', |
| | | duration: 0, |
| | | }); |
| | | try { |
| | | const id = await generateArrivalNoticeFromPurchaseOrder(purchaseOrderId); |
| | | message.success('å°è´§éç¥åçææå'); |
| | | // 跳转å°ç¼è¾é¡µ |
| | | formModalApi.setData({ formType: 'update', id }).open(); |
| | | handleRefresh(); |
| | | } finally { |
| | | hideLoading(); |
| | | } |
| | | } |
| | | |
| | | /** 导åºè¡¨æ ¼ */ |
| | | async function handleExport() { |
| | | const data = await exportArrivalNotice(await gridApi.formApi.getValues()); |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <Page auto-content-height><FormModal @success="handleRefresh" /> |
| | | <Page auto-content-height> |
| | | <FormModal @success="handleRefresh" /> |
| | | <PoSelectModal @selected="handlePurchaseOrderSelected" /> |
| | | |
| | | <Grid table-title="å°è´§éç¥åå表"> |
| | | <template #toolbar-tools> |
| | |
| | | onClick: handleCreate, |
| | | }, |
| | | { |
| | | label: 'ä»éè´è®¢åçæ', |
| | | type: 'primary', |
| | | icon: ACTION_ICON.ADD, |
| | | auth: ['mes:wm-arrival-notice:create'], |
| | | onClick: handleGenerateFromPO, |
| | | }, |
| | | { |
| | | label: $t('ui.actionTitle.export'), |
| | | type: 'primary', |
| | | icon: ACTION_ICON.DOWNLOAD, |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { ErpPurchaseOrderApi } from '#/api/erp/purchase/order'; |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | |
| | | import { Page, useVbenModal } from '@vben/common-ui'; |
| | | |
| | | import { message } from 'ant-design-vue'; |
| | | |
| | | import { useVbenVxeGrid } from '#/adapter/vxe-table'; |
| | | import { getPurchaseOrderPage } from '#/api/erp/purchase/order'; |
| | | |
| | | const emit = defineEmits<{ |
| | | selected: [purchaseOrderId: number]; |
| | | }>(); |
| | | |
| | | const [Grid, gridApi] = useVbenVxeGrid({ |
| | | formOptions: { |
| | | schema: [ |
| | | { |
| | | fieldName: 'no', |
| | | label: '订åå·', |
| | | component: 'Input', |
| | | componentProps: { |
| | | allowClear: true, |
| | | placeholder: '请è¾å
¥è®¢åå·', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'supplierName', |
| | | label: 'ä¾åºå', |
| | | component: 'Input', |
| | | componentProps: { |
| | | allowClear: true, |
| | | placeholder: '请è¾å
¥ä¾åºååç§°', |
| | | }, |
| | | }, |
| | | ], |
| | | }, |
| | | gridOptions: { |
| | | columns: [ |
| | | { |
| | | type: 'radio', |
| | | width: 60, |
| | | }, |
| | | { |
| | | field: 'no', |
| | | title: '订åå·', |
| | | minWidth: 160, |
| | | }, |
| | | { |
| | | field: 'supplierName', |
| | | title: 'ä¾åºååç§°', |
| | | minWidth: 120, |
| | | }, |
| | | { |
| | | field: 'orderTime', |
| | | title: 'è®¢åæ¥æ', |
| | | width: 180, |
| | | formatter: 'formatDate', |
| | | }, |
| | | { |
| | | field: 'totalPrice', |
| | | title: 'æ»éé¢', |
| | | width: 120, |
| | | formatter: 'formatMoney', |
| | | }, |
| | | { |
| | | field: 'status', |
| | | title: 'ç¶æ', |
| | | width: 100, |
| | | cellRender: { |
| | | name: 'CellDict', |
| | | props: { type: 'erp_purchase_order_status' }, |
| | | }, |
| | | }, |
| | | ], |
| | | height: 'auto', |
| | | keepSource: true, |
| | | proxyConfig: { |
| | | ajax: { |
| | | query: async ({ page }, formValues) => { |
| | | return await getPurchaseOrderPage({ |
| | | pageNo: page.currentPage, |
| | | pageSize: page.pageSize, |
| | | ...formValues, |
| | | }); |
| | | }, |
| | | }, |
| | | }, |
| | | rowConfig: { |
| | | keyField: 'id', |
| | | isHover: true, |
| | | }, |
| | | toolbarConfig: { |
| | | refresh: true, |
| | | search: true, |
| | | }, |
| | | } as VxeTableGridOptions<ErpPurchaseOrderApi.PurchaseOrder>, |
| | | }); |
| | | |
| | | const [Modal, modalApi] = useVbenModal({ |
| | | async onConfirm() { |
| | | const selectedRows = gridApi.grid.getRadioRecord(); |
| | | if (!selectedRows) { |
| | | message.warning('è¯·éæ©éè´è®¢å'); |
| | | return; |
| | | } |
| | | emit('selected', selectedRows.id); |
| | | await modalApi.close(); |
| | | }, |
| | | async onOpenChange(isOpen: boolean) { |
| | | if (isOpen) { |
| | | await gridApi.query(); |
| | | } |
| | | }, |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <Modal title="éæ©éè´è®¢å" class="w-2/3"> |
| | | <Grid table-title="éè´è®¢åå表" /> |
| | | </Modal> |
| | | </template> |
| | |
| | | column: 1, |
| | | schema: useBarcodeDetailSchema(), |
| | | useCard: false, |
| | | labelStyle: { width: '80px', whiteSpace: 'nowrap' }, |
| | | }); |
| | | |
| | | function openModal(row: Partial<MesWmBarcodeApi.Barcode>) { |
| | |
| | | message.warning('æ¡ç çæå¤±è´¥ï¼æ æ³ä¸è½½'); |
| | | return; |
| | | } |
| | | const link = document.createElement('a'); |
| | | link.href = base64; |
| | | link.download = `barcode_${barcodeData.value.bizCode || 'unknown'}_${Date.now()}.png`; |
| | | link.click(); |
| | | message.success('ä¸è½½æå'); |
| | | |
| | | const canvas = document.createElement('canvas'); |
| | | const ctx = canvas.getContext('2d'); |
| | | if (!ctx) { |
| | | message.error('Canvas åå§å失败'); |
| | | return; |
| | | } |
| | | |
| | | const img = new Image(); |
| | | img.onload = () => { |
| | | const padding = 20; |
| | | const infoX = img.width + padding * 2; |
| | | const infoWidth = 320; |
| | | canvas.width = infoX + infoWidth + padding; |
| | | canvas.height = Math.max(img.height + padding * 2, 360); |
| | | |
| | | ctx.fillStyle = '#ffffff'; |
| | | ctx.fillRect(0, 0, canvas.width, canvas.height); |
| | | |
| | | ctx.drawImage(img, padding, padding); |
| | | |
| | | ctx.fillStyle = '#000000'; |
| | | let y = padding + 10; |
| | | const lineHeight = 26; |
| | | |
| | | // è·ååå
¸ææ¬çè¾
å©å½æ° |
| | | const getFormatText = (val?: number) => { |
| | | const map: Record<number, string> = { 1: 'QR_CODE', 2: 'CODE_128', 3: 'CODE_39', 4: 'EAN_13', 5: 'UPC_A' }; |
| | | return map[val || 1] || 'QR_CODE'; |
| | | }; |
| | | const getBizTypeText = (val?: number) => { |
| | | const map: Record<number, string> = { 1: 'ä»åº', 2: 'åºåº', 3: 'åºä½', 4: 'ç©æ', 5: '客æ·', 6: 'ä¾åºå', 7: 'å·¥å', 8: '设å¤', 9: 'å·¥å
·', 10: '人å', 11: 'å·¥ä½ç«', 12: '车é´', 13: 'åºå', 14: 'æµè½¬å¡', 15: 'è£
ç®±å', 16: 'æ¹æ¬¡' }; |
| | | return map[val || 1] || '-'; |
| | | }; |
| | | const getStatusText = (val?: number) => val === 0 ? 'ç¦ç¨' : 'å¯ç¨'; |
| | | |
| | | const items = [ |
| | | { label: 'æ¡ç æ ¼å¼', value: getFormatText(barcodeData.value.format) }, |
| | | { label: 'ä¸å¡ç±»å', value: getBizTypeText(barcodeData.value.bizType) }, |
| | | { label: 'ä¸å¡ç¼ç ', value: barcodeData.value.bizCode }, |
| | | { label: 'ä¸å¡åç§°', value: barcodeData.value.bizName }, |
| | | { label: 'æ¡ç å
容', value: barcodeData.value.content }, |
| | | { label: 'ç¶æ', value: getStatusText(barcodeData.value.status) }, |
| | | ]; |
| | | |
| | | items.forEach((item) => { |
| | | ctx.font = 'bold 13px Arial, sans-serif'; |
| | | ctx.fillText(`${item.label}:`, infoX, y); |
| | | y += 18; |
| | | ctx.font = '13px Arial, sans-serif'; |
| | | const text = item.value || '-'; |
| | | // å¤çé¿ææ¬æ¢è¡ |
| | | const maxWidth = infoWidth - 10; |
| | | if (ctx.measureText(text).width > maxWidth) { |
| | | let currentText = text; |
| | | while (currentText.length > 0) { |
| | | let line = ''; |
| | | for (let i = 0; i < currentText.length; i++) { |
| | | const testLine = line + currentText[i]; |
| | | if (ctx.measureText(testLine).width > maxWidth) break; |
| | | line = testLine; |
| | | } |
| | | ctx.fillText(line, infoX + 5, y); |
| | | y += 16; |
| | | currentText = currentText.slice(line.length); |
| | | } |
| | | y += 6; |
| | | } else { |
| | | ctx.fillText(text, infoX + 5, y); |
| | | y += lineHeight; |
| | | } |
| | | }); |
| | | |
| | | const link = document.createElement('a'); |
| | | link.href = canvas.toDataURL('image/png'); |
| | | link.download = `barcode_${barcodeData.value.bizCode || 'unknown'}_${Date.now()}.png`; |
| | | link.click(); |
| | | message.success('ä¸è½½æå'); |
| | | }; |
| | | img.src = base64; |
| | | } |
| | | |
| | | async function handleGenerate() { |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <Modal v-model:open="open" title="æ¥çæ¡ç " width="500px"> |
| | | <Modal v-model:open="open" title="æ¥çæ¡ç " width="750px"> |
| | | <div> |
| | | <div |
| | | class="mb-5 flex min-h-50 items-center justify-center rounded bg-gray-100 p-5" |
| | | > |
| | | <div |
| | | v-if="barcodeData.content" |
| | | class="flex items-center justify-center" |
| | | > |
| | | <WlsBarcode |
| | | ref="barcodeRef" |
| | | :content="barcodeData.content" |
| | | :format="barcodeData.format" |
| | | :height="150" |
| | | :width="400" |
| | | /> |
| | | <div class="mb-5 flex min-h-50 items-center rounded bg-gray-100 p-5"> |
| | | <div v-if="barcodeData.content" class="flex w-full items-center gap-6"> |
| | | <div class="flex-shrink-0"> |
| | | <WlsBarcode |
| | | ref="barcodeRef" |
| | | :content="barcodeData.content" |
| | | :format="barcodeData.format" |
| | | :height="150" |
| | | :width="280" |
| | | /> |
| | | </div> |
| | | <div class="flex-1"> |
| | | <Descriptions :data="barcodeData"> |
| | | <template #content> |
| | | <Tooltip :title="barcodeData.content"> |
| | | <span |
| | | class="inline-block max-w-60 overflow-hidden text-ellipsis whitespace-nowrap" |
| | | > |
| | | {{ barcodeData.content }} |
| | | </span> |
| | | </Tooltip> |
| | | </template> |
| | | </Descriptions> |
| | | </div> |
| | | </div> |
| | | <Empty v-else description="ææ æ¡ç æ°æ®" /> |
| | | <Empty v-else description="ææ æ¡ç æ°æ®" class="flex-1" /> |
| | | </div> |
| | | <Descriptions :data="barcodeData"> |
| | | <template #content> |
| | | <Tooltip :title="barcodeData.content"> |
| | | <span |
| | | class="inline-block max-w-75 overflow-hidden text-ellipsis whitespace-nowrap" |
| | | > |
| | | {{ barcodeData.content }} |
| | | </span> |
| | | </Tooltip> |
| | | </template> |
| | | </Descriptions> |
| | | </div> |
| | | <template #footer> |
| | | <Button v-if="!barcodeData.content" @click="handleGenerate"> |
| | |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | import type { MesWmItemReceiptApi } from '#/api/mes/wm/itemreceipt'; |
| | | |
| | | import { Page, useVbenModal } from '../../../packages/effects/common-ui/src'; |
| | | import { MesWmItemReceiptStatusEnum } from '../../../packages/constants/src'; |
| | | import { downloadFileFromBlobPart } from '../../../packages/utils/src'; |
| | | import { Page, useVbenModal } from '@vben/common-ui'; |
| | | import { MesWmItemReceiptStatusEnum } from '@vben/constants'; |
| | | import { downloadFileFromBlobPart } from '@vben/utils'; |
| | | |
| | | import { Button, message } from 'ant-design-vue'; |
| | | |
| | |
| | | cancelItemReceipt, |
| | | deleteItemReceipt, |
| | | exportItemReceipt, |
| | | generateItemReceiptFromArrivalNotice, |
| | | getItemReceiptPage, |
| | | } from '#/api/mes/wm/itemreceipt'; |
| | | import { $t } from '#/locales'; |
| | | |
| | | import { useGridColumns, useGridFormSchema } from './data'; |
| | | import Form from './modules/form.vue'; |
| | | import AnSelectDialog from './modules/an-select-dialog.vue'; |
| | | |
| | | const [FormModal, formModalApi] = useVbenModal({ |
| | | connectedComponent: Form, |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | | const [AnSelectModal, anSelectModalApi] = useVbenModal({ |
| | | connectedComponent: AnSelectDialog, |
| | | destroyOnClose: true, |
| | | }); |
| | | |
| | |
| | | handleRefresh(); |
| | | } |
| | | |
| | | /** ä»å°è´§éç¥çæéè´å
¥åºå */ |
| | | async function handleGenerateFromAN() { |
| | | anSelectModalApi.open(); |
| | | } |
| | | |
| | | /** å°è´§éç¥éæ©åè° */ |
| | | async function handleArrivalNoticeSelected(arrivalNoticeId: number) { |
| | | const hideLoading = message.loading({ |
| | | content: 'æ£å¨çæéè´å
¥åºå...', |
| | | duration: 0, |
| | | }); |
| | | try { |
| | | const id = await generateItemReceiptFromArrivalNotice(arrivalNoticeId); |
| | | message.success('éè´å
¥åºåçææå'); |
| | | // 跳转å°ç¼è¾é¡µ |
| | | formModalApi.setData({ formType: 'update', id }).open(); |
| | | handleRefresh(); |
| | | } finally { |
| | | hideLoading(); |
| | | } |
| | | } |
| | | |
| | | /** 导åºè¡¨æ ¼ */ |
| | | async function handleExport() { |
| | | const data = await exportItemReceipt(await gridApi.formApi.getValues()); |
| | |
| | | </script> |
| | | |
| | | <template> |
| | | <Page auto-content-height><FormModal @success="handleRefresh" /> |
| | | <Page auto-content-height> |
| | | <FormModal @success="handleRefresh" /> |
| | | <AnSelectModal @selected="handleArrivalNoticeSelected" /> |
| | | |
| | | <Grid table-title="éè´å
¥åºåå表"> |
| | | <template #toolbar-tools> |
| | |
| | | onClick: handleCreate, |
| | | }, |
| | | { |
| | | label: 'ä»å°è´§éç¥çæ', |
| | | type: 'primary', |
| | | icon: ACTION_ICON.ADD, |
| | | auth: ['mes:wm-item-receipt:create'], |
| | | onClick: handleGenerateFromAN, |
| | | }, |
| | | { |
| | | label: $t('ui.actionTitle.export'), |
| | | type: 'primary', |
| | | icon: ACTION_ICON.DOWNLOAD, |
| ¶Ô±ÈÐÂÎļþ |
| | |
| | | <script lang="ts" setup> |
| | | import type { MesWmArrivalNoticeApi } from '#/api/mes/wm/arrivalnotice'; |
| | | import type { VxeTableGridOptions } from '#/adapter/vxe-table'; |
| | | |
| | | import { Page, useVbenModal } from '@vben/common-ui'; |
| | | import { MesWmArrivalNoticeStatusEnum } from '@vben/constants'; |
| | | |
| | | import { message } from 'ant-design-vue'; |
| | | |
| | | import { useVbenVxeGrid } from '#/adapter/vxe-table'; |
| | | import { getArrivalNoticePage } from '#/api/mes/wm/arrivalnotice'; |
| | | |
| | | const emit = defineEmits<{ |
| | | selected: [arrivalNoticeId: number]; |
| | | }>(); |
| | | |
| | | const [Grid, gridApi] = useVbenVxeGrid({ |
| | | formOptions: { |
| | | schema: [ |
| | | { |
| | | fieldName: 'code', |
| | | label: 'éç¥åå·', |
| | | component: 'Input', |
| | | componentProps: { |
| | | allowClear: true, |
| | | placeholder: '请è¾å
¥éç¥åå·', |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'vendorName', |
| | | label: 'ä¾åºå', |
| | | component: 'Input', |
| | | componentProps: { |
| | | allowClear: true, |
| | | placeholder: '请è¾å
¥ä¾åºååç§°', |
| | | }, |
| | | }, |
| | | ], |
| | | }, |
| | | gridOptions: { |
| | | columns: [ |
| | | { |
| | | type: 'radio', |
| | | width: 60, |
| | | }, |
| | | { |
| | | field: 'code', |
| | | title: 'éç¥åå·', |
| | | minWidth: 160, |
| | | }, |
| | | { |
| | | field: 'name', |
| | | title: 'éç¥ååç§°', |
| | | minWidth: 150, |
| | | }, |
| | | { |
| | | field: 'vendorName', |
| | | title: 'ä¾åºååç§°', |
| | | minWidth: 120, |
| | | }, |
| | | { |
| | | field: 'purchaseOrderNo', |
| | | title: 'éè´è®¢åå·', |
| | | minWidth: 140, |
| | | }, |
| | | { |
| | | field: 'arrivalDate', |
| | | title: 'å°è´§æ¥æ', |
| | | width: 180, |
| | | formatter: 'formatDate', |
| | | }, |
| | | { |
| | | field: 'status', |
| | | title: 'ç¶æ', |
| | | width: 100, |
| | | cellRender: { |
| | | name: 'CellDict', |
| | | props: { type: 'mes_wm_arrival_notice_status' }, |
| | | }, |
| | | }, |
| | | ], |
| | | height: 'auto', |
| | | keepSource: true, |
| | | proxyConfig: { |
| | | ajax: { |
| | | query: async ({ page }, formValues) => { |
| | | return await getArrivalNoticePage({ |
| | | pageNo: page.currentPage, |
| | | pageSize: page.pageSize, |
| | | status: MesWmArrivalNoticeStatusEnum.PENDING_RECEIPT, |
| | | ...formValues, |
| | | }); |
| | | }, |
| | | }, |
| | | }, |
| | | rowConfig: { |
| | | keyField: 'id', |
| | | isHover: true, |
| | | }, |
| | | toolbarConfig: { |
| | | refresh: true, |
| | | search: true, |
| | | }, |
| | | } as VxeTableGridOptions<MesWmArrivalNoticeApi.ArrivalNotice>, |
| | | }); |
| | | |
| | | const [Modal, modalApi] = useVbenModal({ |
| | | async onConfirm() { |
| | | const selectedRows = gridApi.grid.getRadioRecord(); |
| | | if (!selectedRows) { |
| | | message.warning('è¯·éæ©å°è´§éç¥å'); |
| | | return; |
| | | } |
| | | emit('selected', selectedRows.id); |
| | | await modalApi.close(); |
| | | }, |
| | | async onOpenChange(isOpen: boolean) { |
| | | if (isOpen) { |
| | | await gridApi.query(); |
| | | } |
| | | }, |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <Modal title="éæ©å°è´§éç¥å" class="w-2/3"> |
| | | <Grid table-title="å°è´§éç¥åå表" /> |
| | | </Modal> |
| | | </template> |
| | |
| | | |
| | | import { computed, ref } from 'vue'; |
| | | |
| | | import { confirm, useVbenModal } from '../../../../packages/effects/common-ui/src'; |
| | | import { MesWmItemReceiptStatusEnum } from '../../../../packages/constants/src'; |
| | | import { confirm, useVbenModal } from '@vben/common-ui'; |
| | | import { MesWmItemReceiptStatusEnum } from '@vben/constants'; |
| | | |
| | | import { Button, Divider, message, Popconfirm } from 'ant-design-vue'; |
| | | |
| | |
| | | getItemReceipt, |
| | | stockItemReceipt, |
| | | submitItemReceipt, |
| | | submitItemReceiptApproval, |
| | | updateItemReceipt, |
| | | } from '#/api/mes/wm/itemreceipt'; |
| | | import { $t } from '#/locales'; |
| | |
| | | const canSubmit = computed( |
| | | () => |
| | | // æ¯å¦å¯æäº¤ |
| | | formType.value === 'update' && |
| | | formData.value?.status === MesWmItemReceiptStatusEnum.PREPARE, |
| | | ); |
| | | const canSubmitApproval = computed( |
| | | () => |
| | | // æ¯å¦å¯æäº¤å®¡æ¹ |
| | | formType.value === 'update' && |
| | | formData.value?.status === MesWmItemReceiptStatusEnum.PREPARE, |
| | | ); |
| | |
| | | try { |
| | | await finishItemReceipt(formData.value.id); |
| | | message.success('å
¥åºæå'); |
| | | await modalApi.close(); |
| | | emit('success'); |
| | | } finally { |
| | | modalApi.unlock(); |
| | | } |
| | | } |
| | | |
| | | /** æäº¤å®¡æ¹ */ |
| | | async function handleSubmitApproval() { |
| | | if (!formData.value?.id) { |
| | | return; |
| | | } |
| | | modalApi.lock(); |
| | | try { |
| | | // 使ç¨é»è®¤æµç¨keyï¼å®é
项ç®ä¸å¯è½éè¦å¼¹çªéæ© |
| | | const processDefinitionKey = 'item_receipt_approval'; |
| | | await submitItemReceiptApproval(formData.value.id, processDefinitionKey); |
| | | message.success('æäº¤å®¡æ¹æå'); |
| | | await modalApi.close(); |
| | | emit('success'); |
| | | } finally { |
| | |
| | | > |
| | | <Button type="primary">æäº¤</Button> |
| | | </Popconfirm> |
| | | <Button v-if="canSubmitApproval" type="primary" @click="handleSubmitApproval"> |
| | | æäº¤å®¡æ¹ |
| | | </Button> |
| | | <Button v-if="isStock" type="primary" @click="confirmStock"> |
| | | æ§è¡ä¸æ¶ |
| | | </Button> |
| | |
| | | import { generateAutoCode } from '#/api/mes/md/autocode/record'; |
| | | import { MdItemSelect } from '#/views/mes/md/item/components'; |
| | | import { MdVendorSelect } from '#/views/mes/md/vendor/components'; |
| | | import { ErpPurchaseOrderSelect } from '#/views/erp/purchase/order/components'; |
| | | import { WmBatchSelect } from '#/views/wls/batch/components'; |
| | | import { WmMaterialStockSelect } from '#/views/wls/materialstock/components'; |
| | | import { |
| | |
| | | rules: 'required', |
| | | }, |
| | | { |
| | | fieldName: 'purchaseOrderCode', |
| | | label: 'éè´è®¢åå·', |
| | | fieldName: 'vendorName', |
| | | label: '', |
| | | component: 'Input', |
| | | dependencies: { |
| | | triggerFields: [''], |
| | | show: () => false, |
| | | }, |
| | | }, |
| | | { |
| | | fieldName: 'purchaseOrderId', |
| | | label: 'éè´è®¢å', |
| | | component: markRaw(ErpPurchaseOrderSelect), |
| | | componentProps: { |
| | | placeholder: '请è¾å
¥éè´è®¢åå·', |
| | | placeholder: 'è¯·éæ©éè´è®¢å', |
| | | onChange: (item: any) => { |
| | | if (item?.supplierId && formApi) { |
| | | formApi.setFieldValue('vendorId', item.supplierId); |
| | | formApi.setFieldValue('vendorName', item.supplierName); |
| | | } |
| | | }, |
| | | }, |
| | | }, |
| | | { |
| | |
| | | component: markRaw(MdVendorSelect), |
| | | componentProps: { |
| | | placeholder: 'è¯·éæ©ä¾åºå', |
| | | disabled: true, |
| | | }, |
| | | dependencies: { |
| | | triggerFields: ['vendorName'], |
| | | componentProps: (values) => ({ |
| | | placeholder: 'è¯·éæ©ä¾åºå', |
| | | disabled: true, |
| | | vendorName: values.vendorName as string, |
| | | }), |
| | | }, |
| | | rules: 'selectRequired', |
| | | }, |
| | |
| | | import { useGridColumns, useGridFormSchema } from './data'; |
| | | import Form from './modules/form.vue'; |
| | | |
| | | defineOptions({ name: 'WlsArea' }); |
| | | |
| | | const route = useRoute(); |
| | | |
| | | const [FormModal, formModalApi] = useVbenModal({ |
| | |
| | | import { useGridColumns, useGridFormSchema } from './data'; |
| | | import Form from './modules/form.vue'; |
| | | |
| | | defineOptions({ name: 'WlsWarehouse' }); |
| | | |
| | | const router = useRouter(); |
| | | |
| | | const [FormModal, formModalApi] = useVbenModal({ |
| | |
| | | /** 跳转åºåºå表 */ |
| | | function handleOpenLocation(row: MesWmWarehouseApi.Warehouse) { |
| | | router.push({ |
| | | name: 'WlsLocation', |
| | | path: '/wls/location', |
| | | query: { warehouseId: String(row.id) }, |
| | | }); |
| | | } |
| | |
| | | import { useGridColumns, useGridFormSchema } from './data'; |
| | | import Form from './modules/form.vue'; |
| | | |
| | | defineOptions({ name: 'WlsLocation' }); |
| | | |
| | | const route = useRoute(); |
| | | const router = useRouter(); |
| | | |
| | |
| | | /** 跳转åºä½å表 */ |
| | | function handleOpenArea(row: MesWmWarehouseLocationApi.WarehouseLocation) { |
| | | router.push({ |
| | | name: 'WlsArea', |
| | | path: '/wls/area', |
| | | query: { locationId: String(row.id) }, |
| | | }); |
| | | } |
| | |
| | | oxc: { |
| | | enable: false, |
| | | }, |
| | | optimizeDeps: { |
| | | include: [ |
| | | "vue", |
| | | "vue-router", |
| | | "pinia", |
| | | "ant-design-vue", |
| | | "dayjs", |
| | | "@vueuse/core", |
| | | "axios", |
| | | ], |
| | | exclude: [ |
| | | "dhtmlx-gantt", |
| | | "tinymce", |
| | | "bpmn-js", |
| | | "bpmn-js-properties-panel", |
| | | "video.js", |
| | | ], |
| | | }, |
| | | build: { |
| | | rollupOptions: { |
| | | output: { |
| | | manualChunks: { |
| | | "vendor-vue": ["vue", "vue-router", "pinia"], |
| | | "vendor-ui": ["ant-design-vue", "@vueuse/core"], |
| | | "vendor-utils": ["dayjs", "axios", "@vee-validate/zod", "zod"], |
| | | "vendor-editor": [ |
| | | "tinymce", |
| | | "@tinymce/tinymce-vue", |
| | | "@form-create/ant-design-vue", |
| | | ], |
| | | }, |
| | | }, |
| | | }, |
| | | }, |
| | | server: { |
| | | allowedHosts: true, |
| | | watch: { |