From 57295febd254991c01eff2345ba293b89287689d Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期五, 10 七月 2026 16:07:07 +0800
Subject: [PATCH] 银川 1.仓储物流页面开发、联调 2.项目配置修改
---
src/api/mes/wm/arrivalnotice/index.ts | 7
src/api/mes/wm/returnvendor/index.ts | 1
src/router/routes/modules/mes.ts | 27 --
src/views/wls/warehouse/area/index.vue | 2
src/api/mes/wm/itemreceipt/index.ts | 17 +
.idea/mom-pro2-before.iml | 9
src/views/wls/arrivalnotice/data.ts | 24 ++
vite.config.ts | 34 ++
src/views/wls/itemreceipt/index.vue | 46 +++
src/views/wls/itemreceipt/modules/form.vue | 32 ++
src/views/wls/arrivalnotice/index.vue | 46 +++
src/views/wls/barcode/components/detail.vue | 139 ++++++++--
src/views/wls/itemreceipt/modules/an-select-dialog.vue | 129 ++++++++++
src/views/wls/returnvendor/data.ts | 31 ++
src/views/mes/md/vendor/components/select.vue | 39 --
src/views/wls/warehouse/index.vue | 4
src/views/wls/arrivalnotice/modules/po-select-dialog.vue | 123 ++++++++++
src/views/wls/warehouse/location/index.vue | 4
18 files changed, 608 insertions(+), 106 deletions(-)
diff --git a/.idea/mom-pro2-before.iml b/.idea/mom-pro2-before.iml
index c956989..f856ba1 100644
--- a/.idea/mom-pro2-before.iml
+++ b/.idea/mom-pro2-before.iml
@@ -1,7 +1,14 @@
<?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>
diff --git a/src/api/mes/wm/arrivalnotice/index.ts b/src/api/mes/wm/arrivalnotice/index.ts
index d664093..687c1a6 100644
--- a/src/api/mes/wm/arrivalnotice/index.ts
+++ b/src/api/mes/wm/arrivalnotice/index.ts
@@ -62,3 +62,10 @@
params,
});
}
+
+/** 鏍规嵁閲囪喘璁㈠崟鐢熸垚鍒拌揣閫氱煡鍗� */
+export function generateArrivalNoticeFromPurchaseOrder(purchaseOrderId: number) {
+ return requestClient.post<number>(
+ `/mes/wm/arrival-notice/generate-from-purchase-order?purchaseOrderId=${purchaseOrderId}`,
+ );
+}
diff --git a/src/api/mes/wm/itemreceipt/index.ts b/src/api/mes/wm/itemreceipt/index.ts
index 24a4a61..e03b8cd 100644
--- a/src/api/mes/wm/itemreceipt/index.ts
+++ b/src/api/mes/wm/itemreceipt/index.ts
@@ -84,3 +84,20 @@
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}`,
+ );
+}
diff --git a/src/api/mes/wm/returnvendor/index.ts b/src/api/mes/wm/returnvendor/index.ts
index c721c52..3d35cb0 100644
--- a/src/api/mes/wm/returnvendor/index.ts
+++ b/src/api/mes/wm/returnvendor/index.ts
@@ -8,6 +8,7 @@
id?: number; // 閫�璐у崟缂栧彿
code?: string; // 閫�璐у崟缂栧彿
name?: string; // 閫�璐у崟鍚嶇О
+ purchaseOrderId?: number; // 閲囪喘璁㈠崟缂栧彿
purchaseOrderCode?: string; // 閲囪喘璁㈠崟鍙�
vendorId?: number; // 渚涘簲鍟嗙紪鍙�
vendorCode?: string; // 渚涘簲鍟嗙紪鐮�
diff --git a/src/router/routes/modules/mes.ts b/src/router/routes/modules/mes.ts
index 91aec0a..de6c512 100644
--- a/src/router/routes/modules/mes.ts
+++ b/src/router/routes/modules/mes.ts
@@ -12,33 +12,6 @@
},
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: {
diff --git a/src/views/mes/md/vendor/components/select.vue b/src/views/mes/md/vendor/components/select.vue
index 408972a..b824102 100644
--- a/src/views/mes/md/vendor/components/select.vue
+++ b/src/views/mes/md/vendor/components/select.vue
@@ -1,13 +1,11 @@
<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';
@@ -19,24 +17,26 @@
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 &&
@@ -45,34 +45,12 @@
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;
@@ -89,7 +67,6 @@
dialogRef.value?.open(selectedIds, { multiple: false });
}
-/** 鍥炲~閫変腑鐨勪緵搴斿晢 */
function handleSelected(rows: MesMdVendorApi.Vendor[]) {
const item = rows[0];
if (!item) {
diff --git a/src/views/wls/arrivalnotice/data.ts b/src/views/wls/arrivalnotice/data.ts
index bbed3bb..95b24b4 100644
--- a/src/views/wls/arrivalnotice/data.ts
+++ b/src/views/wls/arrivalnotice/data.ts
@@ -77,11 +77,26 @@
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);
+ }
+ },
},
},
{
@@ -90,6 +105,15 @@
component: markRaw(MdVendorSelect),
componentProps: {
placeholder: '璇烽�夋嫨渚涘簲鍟�',
+ disabled: true,
+ },
+ dependencies: {
+ triggerFields: ['vendorName'],
+ componentProps: (values) => ({
+ placeholder: '璇烽�夋嫨渚涘簲鍟�',
+ disabled: true,
+ vendorName: values.vendorName as string,
+ }),
},
rules: 'selectRequired',
},
diff --git a/src/views/wls/arrivalnotice/index.vue b/src/views/wls/arrivalnotice/index.vue
index df90182..15f292e 100644
--- a/src/views/wls/arrivalnotice/index.vue
+++ b/src/views/wls/arrivalnotice/index.vue
@@ -2,9 +2,9 @@
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';
@@ -12,15 +12,22 @@
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,
});
@@ -69,6 +76,28 @@
message.info('璇峰墠寰�銆愪粨搴撶鐞� - 閲囪喘鍏ュ簱銆戜腑杩涜鍏ュ簱鎿嶄綔');
}
+/** 浠庨噰璐鍗曠敓鎴愬埌璐ч�氱煡鍗� */
+async function handleGenerateFromPO() {
+ poSelectModalApi.open();
+}
+
+/** 閲囪喘璁㈠崟閫夋嫨鍥炶皟 */
+async function handlePurchaseOrderSelected(purchaseOrderId: number) {
+ const hideLoading = message.loading({
+ content: '姝e湪鐢熸垚鍒拌揣閫氱煡鍗�...',
+ 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());
@@ -107,7 +136,9 @@
</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>
@@ -121,6 +152,13 @@
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,
diff --git a/src/views/wls/arrivalnotice/modules/po-select-dialog.vue b/src/views/wls/arrivalnotice/modules/po-select-dialog.vue
new file mode 100644
index 0000000..6d6d492
--- /dev/null
+++ b/src/views/wls/arrivalnotice/modules/po-select-dialog.vue
@@ -0,0 +1,123 @@
+<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>
diff --git a/src/views/wls/barcode/components/detail.vue b/src/views/wls/barcode/components/detail.vue
index 17a9f37..c9abe98 100644
--- a/src/views/wls/barcode/components/detail.vue
+++ b/src/views/wls/barcode/components/detail.vue
@@ -24,6 +24,7 @@
column: 1,
schema: useBarcodeDetailSchema(),
useCard: false,
+ labelStyle: { width: '80px', whiteSpace: 'nowrap' },
});
function openModal(row: Partial<MesWmBarcodeApi.Barcode>) {
@@ -98,11 +99,86 @@
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() {
@@ -126,36 +202,35 @@
</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">
diff --git a/src/views/wls/itemreceipt/index.vue b/src/views/wls/itemreceipt/index.vue
index 9e3f25c..552e77a 100644
--- a/src/views/wls/itemreceipt/index.vue
+++ b/src/views/wls/itemreceipt/index.vue
@@ -2,9 +2,9 @@
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';
@@ -13,15 +13,22 @@
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,
});
@@ -77,6 +84,28 @@
handleRefresh();
}
+/** 浠庡埌璐ч�氱煡鐢熸垚閲囪喘鍏ュ簱鍗� */
+async function handleGenerateFromAN() {
+ anSelectModalApi.open();
+}
+
+/** 鍒拌揣閫氱煡閫夋嫨鍥炶皟 */
+async function handleArrivalNoticeSelected(arrivalNoticeId: number) {
+ const hideLoading = message.loading({
+ content: '姝e湪鐢熸垚閲囪喘鍏ュ簱鍗�...',
+ 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());
@@ -115,7 +144,9 @@
</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>
@@ -129,6 +160,13 @@
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,
diff --git a/src/views/wls/itemreceipt/modules/an-select-dialog.vue b/src/views/wls/itemreceipt/modules/an-select-dialog.vue
new file mode 100644
index 0000000..eef4eef
--- /dev/null
+++ b/src/views/wls/itemreceipt/modules/an-select-dialog.vue
@@ -0,0 +1,129 @@
+<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>
diff --git a/src/views/wls/itemreceipt/modules/form.vue b/src/views/wls/itemreceipt/modules/form.vue
index a0fae09..6794cc1 100644
--- a/src/views/wls/itemreceipt/modules/form.vue
+++ b/src/views/wls/itemreceipt/modules/form.vue
@@ -5,8 +5,8 @@
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';
@@ -17,6 +17,7 @@
getItemReceipt,
stockItemReceipt,
submitItemReceipt,
+ submitItemReceiptApproval,
updateItemReceipt,
} from '#/api/mes/wm/itemreceipt';
import { $t } from '#/locales';
@@ -37,6 +38,12 @@
const canSubmit = computed(
() =>
// 鏄惁鍙彁浜�
+ formType.value === 'update' &&
+ formData.value?.status === MesWmItemReceiptStatusEnum.PREPARE,
+);
+const canSubmitApproval = computed(
+ () =>
+ // 鏄惁鍙彁浜ゅ鎵�
formType.value === 'update' &&
formData.value?.status === MesWmItemReceiptStatusEnum.PREPARE,
);
@@ -118,6 +125,24 @@
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 {
@@ -230,6 +255,9 @@
>
<Button type="primary">鎻愪氦</Button>
</Popconfirm>
+ <Button v-if="canSubmitApproval" type="primary" @click="handleSubmitApproval">
+ 鎻愪氦瀹℃壒
+ </Button>
<Button v-if="isStock" type="primary" @click="confirmStock">
鎵ц涓婃灦
</Button>
diff --git a/src/views/wls/returnvendor/data.ts b/src/views/wls/returnvendor/data.ts
index 6844970..a0494ea 100644
--- a/src/views/wls/returnvendor/data.ts
+++ b/src/views/wls/returnvendor/data.ts
@@ -14,6 +14,7 @@
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 {
@@ -87,11 +88,26 @@
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);
+ }
+ },
},
},
{
@@ -100,6 +116,15 @@
component: markRaw(MdVendorSelect),
componentProps: {
placeholder: '璇烽�夋嫨渚涘簲鍟�',
+ disabled: true,
+ },
+ dependencies: {
+ triggerFields: ['vendorName'],
+ componentProps: (values) => ({
+ placeholder: '璇烽�夋嫨渚涘簲鍟�',
+ disabled: true,
+ vendorName: values.vendorName as string,
+ }),
},
rules: 'selectRequired',
},
diff --git a/src/views/wls/warehouse/area/index.vue b/src/views/wls/warehouse/area/index.vue
index 64b6950..53ed2b7 100644
--- a/src/views/wls/warehouse/area/index.vue
+++ b/src/views/wls/warehouse/area/index.vue
@@ -22,6 +22,8 @@
import { useGridColumns, useGridFormSchema } from './data';
import Form from './modules/form.vue';
+defineOptions({ name: 'WlsArea' });
+
const route = useRoute();
const [FormModal, formModalApi] = useVbenModal({
diff --git a/src/views/wls/warehouse/index.vue b/src/views/wls/warehouse/index.vue
index 9edfabd..e02033c 100644
--- a/src/views/wls/warehouse/index.vue
+++ b/src/views/wls/warehouse/index.vue
@@ -18,6 +18,8 @@
import { useGridColumns, useGridFormSchema } from './data';
import Form from './modules/form.vue';
+defineOptions({ name: 'WlsWarehouse' });
+
const router = useRouter();
const [FormModal, formModalApi] = useVbenModal({
@@ -65,7 +67,7 @@
/** 璺宠浆搴撳尯鍒楄〃 */
function handleOpenLocation(row: MesWmWarehouseApi.Warehouse) {
router.push({
- name: 'WlsLocation',
+ path: '/wls/location',
query: { warehouseId: String(row.id) },
});
}
diff --git a/src/views/wls/warehouse/location/index.vue b/src/views/wls/warehouse/location/index.vue
index 9de6261..e956665 100644
--- a/src/views/wls/warehouse/location/index.vue
+++ b/src/views/wls/warehouse/location/index.vue
@@ -22,6 +22,8 @@
import { useGridColumns, useGridFormSchema } from './data';
import Form from './modules/form.vue';
+defineOptions({ name: 'WlsLocation' });
+
const route = useRoute();
const router = useRouter();
@@ -99,7 +101,7 @@
/** 璺宠浆搴撲綅鍒楄〃 */
function handleOpenArea(row: MesWmWarehouseLocationApi.WarehouseLocation) {
router.push({
- name: 'WlsArea',
+ path: '/wls/area',
query: { locationId: String(row.id) },
});
}
diff --git a/vite.config.ts b/vite.config.ts
index 22580b3..a38ba42 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -7,6 +7,40 @@
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: {
--
Gitblit v1.9.3