From 8b1b73b297451d87e2ebf8c1bcb05c64f108127c Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期四, 30 七月 2026 13:36:35 +0800
Subject: [PATCH] 银川 1.销售退货选择销售订单逻辑修改
---
src/views/erp/sale/order/components/select.vue | 8
src/api/erp/sale/order/index.ts | 1
src/views/mes/md/item/components/select-dialog.vue | 15 +
src/views/mes/pro/workorder/modules/form.vue | 48 +++--
src/views/wls/returnsales/modules/line-list.vue | 4
src/views/erp/sale/return/modules/item-form.vue | 75 +++++++++
src/views/erp/sale/return/modules/form.vue | 138 +++++++++++++----
src/views/wls/returnsales/modules/form.vue | 32 +++
src/views/wls/returnsales/modules/line-form.vue | 37 ++++
src/views/erp/sale/order/components/select-dialog.vue | 5
src/views/mes/md/item/components/select.vue | 7
src/views/wls/returnsales/data.ts | 54 ++++++
12 files changed, 358 insertions(+), 66 deletions(-)
diff --git a/src/api/erp/sale/order/index.ts b/src/api/erp/sale/order/index.ts
index 7e42f11..5468cab 100644
--- a/src/api/erp/sale/order/index.ts
+++ b/src/api/erp/sale/order/index.ts
@@ -55,6 +55,7 @@
stockCount?: number; // 搴撳瓨鏁伴噺锛堟樉绀哄瓧娈碉級
needProduction?: number; // 鏄惁闇�瑕佺敓浜э細0-涓嶉渶瑕侊紝1-闇�瑕�
mpsId?: number; // MPS缂栧彿
+ batchCode?: string; // 鎵规鍙�
}
}
diff --git a/src/views/erp/sale/order/components/select-dialog.vue b/src/views/erp/sale/order/components/select-dialog.vue
index 9a1dfe1..8c8980e 100644
--- a/src/views/erp/sale/order/components/select-dialog.vue
+++ b/src/views/erp/sale/order/components/select-dialog.vue
@@ -17,6 +17,7 @@
const open = ref(false);
const multiple = ref(true);
+const outStatus = ref<number | undefined>(undefined);
const status = ref<number | undefined>(undefined);
const selectedRows = ref<ErpSaleOrderApi.SaleOrder[]>([]);
const preSelectedIds = ref<number[]>([]);
@@ -117,6 +118,7 @@
return await getSaleOrderPage({
pageNo: page.currentPage,
pageSize: page.pageSize,
+ outStatus: outStatus.value,
status: status.value,
...formValues,
});
@@ -149,10 +151,11 @@
/** 鎵撳紑閿�鍞鍗曢�夋嫨寮圭獥 */
async function openModal(
selectedIds?: number[],
- options?: { multiple?: boolean; status?: number },
+ options?: { multiple?: boolean; outStatus?: number; status?: number },
) {
open.value = true;
multiple.value = options?.multiple ?? true;
+ outStatus.value = options?.outStatus;
status.value = options?.status;
preSelectedIds.value = selectedIds || [];
await nextTick();
diff --git a/src/views/erp/sale/order/components/select.vue b/src/views/erp/sale/order/components/select.vue
index 12652d0..a81843d 100644
--- a/src/views/erp/sale/order/components/select.vue
+++ b/src/views/erp/sale/order/components/select.vue
@@ -18,6 +18,7 @@
allowClear?: boolean;
disabled?: boolean;
modelValue?: number;
+ outStatus?: number;
placeholder?: string;
status?: number;
}>(),
@@ -25,6 +26,7 @@
allowClear: true,
disabled: false,
modelValue: undefined,
+ outStatus: undefined,
placeholder: '璇烽�夋嫨閿�鍞鍗�',
status: undefined,
},
@@ -84,7 +86,11 @@
const selectedIds = (
props.modelValue === null ? [] : [props.modelValue]
) as number[];
- dialogRef.value?.open(selectedIds, { multiple: false, status: props.status });
+ dialogRef.value?.open(selectedIds, {
+ multiple: false,
+ outStatus: props.outStatus,
+ status: props.status,
+ });
}
function handleSelected(rows: ErpSaleOrderApi.SaleOrder[]) {
diff --git a/src/views/erp/sale/return/modules/form.vue b/src/views/erp/sale/return/modules/form.vue
index 7611a0c..64d7dd5 100644
--- a/src/views/erp/sale/return/modules/form.vue
+++ b/src/views/erp/sale/return/modules/form.vue
@@ -13,6 +13,7 @@
import { useVbenForm } from '#/adapter/form';
import { getAccountSimpleList } from '#/api/erp/finance/account';
+import { getSaleOrderItemListByOrderId, getSaleOrderPage } from '#/api/erp/sale/order';
import {
createSaleReturn,
getSaleReturn,
@@ -48,6 +49,7 @@
});
const formType = ref<FormType>('create'); // 琛ㄥ崟绫诲瀷锛�'create' | 'edit' | 'detail'
const itemFormRef = ref<InstanceType<typeof ItemForm>>();
+const orderItems = ref<ErpSaleOrderApi.SaleOrderItem[]>([]);
const getTitle = computed(() => {
if (formType.value === 'create') {
@@ -113,7 +115,7 @@
}
/** 閫夋嫨閿�鍞鍗� */
-function handleUpdateOrder(order: ErpSaleOrderApi.SaleOrder) {
+async function handleUpdateOrder(order: ErpSaleOrderApi.SaleOrder) {
formData.value = {
...formData.value,
orderId: order.id,
@@ -123,16 +125,34 @@
remark: order.remark!,
discountPercent: order.discountPercent!,
};
- // 灏嗚鍗曢」璁剧疆鍒伴��璐у崟椤�
- order.items!.forEach((item: any) => {
- item.totalCount = item.count;
- item.count = item.totalCount - item.returnCount;
- item.orderItemId = item.id;
- item.id = undefined;
- });
- formData.value.items = order.items!.filter(
- (item) => item.count && item.count > 0,
- ) as ErpSaleReturnApi.SaleReturnItem[];
+ // 鍔犺浇鍏宠仈閿�鍞鍗曠殑鐗╂枡鍒楄〃
+ const items = await getSaleOrderItemListByOrderId(order.id!);
+ orderItems.value = items;
+ // 灏嗚鍗曢」杞崲涓洪��璐у崟椤癸紙浠呬繚鐣欏彲閫�璐ф暟閲� > 0 鐨勯」锛�
+ const returnItems: ErpSaleReturnApi.SaleReturnItem[] = [];
+ for (const item of items) {
+ const returnCount = (item as { returnCount?: number }).returnCount ?? 0;
+ const remainingCount = (item.count ?? 0) - returnCount;
+ if (remainingCount <= 0) continue;
+
+ returnItems.push({
+ orderItemId: item.id,
+ productId: item.productId,
+ productName: item.productName || '',
+ productPrice: item.productPrice || 0,
+ productUnitId: item.productUnitId,
+ productUnitName: item.productUnitName,
+ productBarCode: item.productBarCode,
+ totalCount: item.count,
+ count: remainingCount,
+ taxPercent: item.taxPercent || 0,
+ remark: item.remark || '',
+ totalProductPrice: 0,
+ taxPrice: 0,
+ totalPrice: 0,
+ });
+ }
+ formData.value.items = returnItems;
formApi.setValues(formData.value, false);
}
@@ -171,14 +191,72 @@
async onOpenChange(isOpen: boolean) {
if (!isOpen) {
formData.value = {} as ErpSaleReturnApi.SaleReturn;
+ orderItems.value = [];
return;
}
- // 鍔犺浇鏁版嵁
- const data = modalApi.getData<{ formType: FormType; id?: number }>();
- formType.value = data.formType;
+ const modalData = modalApi.getData<{ formType: FormType; id?: number }>();
+ formType.value = modalData.formType;
+
+ // 缂栬緫/璇︽儏妯″紡锛氬厛鍔犺浇鏁版嵁锛屽啀鏇存柊 schema锛岀‘淇濇覆鏌撴椂 orderNo 宸插氨缁�
+ if (modalData?.id) {
+ modalApi.lock();
+ try {
+ const apiData = await getSaleReturn(modalData.id);
+ const raw = apiData as Record<string, unknown>;
+
+ // 鎻愬彇璁㈠崟鍙凤紙灏濊瘯澶氱鍙兘鐨勫瓧娈靛悕 / 宓屽缁撴瀯锛�
+ const getOrderNo = (): string => {
+ if (raw.orderNo) return raw.orderNo as string;
+ if (raw.salesOrderCode) return raw.salesOrderCode as string;
+ if (raw.salesOrderNo) return raw.salesOrderNo as string;
+ const so = raw.salesOrder as Record<string, unknown> | undefined;
+ if (so?.no) return so.no as string;
+ const o = raw.order as Record<string, unknown> | undefined;
+ if (o?.no) return o.no as string;
+ return '';
+ };
+
+ // 鎻愬彇璁㈠崟ID锛堝皾璇曞绉嶅彲鑳界殑瀛楁鍚� / 宓屽缁撴瀯锛�
+ const getOrderId = (): number | undefined => {
+ if (raw.orderId) return raw.orderId as number;
+ if (raw.salesOrderId) return raw.salesOrderId as number;
+ const so = raw.salesOrder as Record<string, unknown> | undefined;
+ if (so?.id) return so.id as number;
+ const o = raw.order as Record<string, unknown> | undefined;
+ if (o?.id) return o.id as number;
+ return undefined;
+ };
+
+ let orderNo = getOrderNo();
+ let orderId = getOrderId();
+
+ // 濡傛灉鏈夎鍗曞彿浣嗘病鏈夎鍗旾D锛岄�氳繃璁㈠崟鍙峰弽鏌ヨ鍗旾D
+ if (orderNo && !orderId) {
+ const orderPage = await getSaleOrderPage({
+ pageNo: 1,
+ pageSize: 1,
+ no: orderNo,
+ } as Record<string, unknown> as never);
+ const list = (orderPage as Record<string, unknown>)?.list as Array<Record<string, unknown>> | undefined;
+ if (list?.length) {
+ orderId = list[0].id as number;
+ }
+ }
+
+ formData.value = { ...apiData, orderNo, orderId };
+ if (orderId) {
+ orderItems.value = await getSaleOrderItemListByOrderId(orderId);
+ }
+ } finally {
+ modalApi.unlock();
+ }
+ }
+
+ // 鏁版嵁灏辩华鍚庡啀鏇存柊 schema 鍜岃缃〃鍗曞��
formApi.setDisabled(formType.value === 'detail');
formApi.updateSchema(useFormSchema(formType.value));
- if (!data || !data.id) {
+
+ if (!modalData?.id) {
// 鏂板鏃讹紝榛樿閫変腑璐︽埛
const accountList = await getAccountSimpleList();
const defaultAccount = accountList.find((item) => item.defaultStatus);
@@ -187,23 +265,17 @@
}
return;
}
- modalApi.lock();
- try {
- formData.value = await getSaleReturn(data.id);
- // 璁剧疆鍒� values
- await formApi.setValues(formData.value, false);
- if (formData.value?.attachmentList?.length) {
- const blobIds = formData.value.attachmentList.map((item) => ({
- uid: String(item.id),
- name: item.name || '',
- url: item.url || '',
- status: 'done',
- id: item.id,
- }));
- await formApi.setFieldValue('blobIds', blobIds);
- }
- } finally {
- modalApi.unlock();
+
+ await formApi.setValues(formData.value, false);
+ if (formData.value?.attachmentList?.length) {
+ const blobIds = formData.value.attachmentList.map((item) => ({
+ uid: String(item.id),
+ name: item.name || '',
+ url: item.url || '',
+ status: 'done',
+ id: item.id,
+ }));
+ await formApi.setFieldValue('blobIds', blobIds);
}
},
});
@@ -224,6 +296,7 @@
:disabled="formType === 'detail'"
:discount-percent="formData?.discountPercent ?? 0"
:other-price="formData?.otherPrice ?? 0"
+ :order-items="orderItems"
@update:items="handleUpdateItems"
@update:discount-price="handleUpdateDiscountPrice"
@update:other-price="handleUpdateOtherPrice"
@@ -232,6 +305,7 @@
</template>
<template #orderNo>
<SaleOrderSelect
+ :key="formData?.orderNo ?? 'empty'"
:order-no="formData?.orderNo"
@update:order="handleUpdateOrder"
/>
diff --git a/src/views/erp/sale/return/modules/item-form.vue b/src/views/erp/sale/return/modules/item-form.vue
index af30c83..04cb817 100644
--- a/src/views/erp/sale/return/modules/item-form.vue
+++ b/src/views/erp/sale/return/modules/item-form.vue
@@ -1,5 +1,6 @@
<script lang="ts" setup>
import type { MdmItemApi } from '#/api/mdm/item';
+import type { ErpSaleOrderApi } from '#/api/erp/sale/order';
import type { ErpSaleReturnApi } from '#/api/erp/sale/return';
import { computed, nextTick, onMounted, ref, watch } from 'vue';
@@ -24,6 +25,7 @@
disabled?: boolean;
discountPercent?: number;
otherPrice?: number;
+ orderItems?: ErpSaleOrderApi.SaleOrderItem[];
}
const props = withDefaults(defineProps<Props>(), {
@@ -31,6 +33,7 @@
disabled: false,
discountPercent: 0,
otherPrice: 0,
+ orderItems: () => [],
});
const emit = defineEmits([
@@ -141,6 +144,57 @@
emit('update:items', [...tableData.value]);
}
+/** 澶勭悊鏂板鐗╂枡琛� */
+function handleAdd() {
+ const newRow: ErpSaleReturnApi.SaleReturnItem = {
+ seq: Date.now(),
+ productId: undefined,
+ productName: '',
+ productPrice: 0,
+ productUnitId: undefined,
+ productUnitName: '',
+ count: 0,
+ totalProductPrice: 0,
+ taxPercent: 0,
+ taxPrice: 0,
+ totalPrice: 0,
+ remark: '',
+ };
+ tableData.value.push(newRow);
+ emit('update:items', [...tableData.value]);
+}
+
+/** 澶勭悊浜у搧鍙樻洿锛氫紭鍏堜粠鍏宠仈璁㈠崟鐗╂枡涓~鍏咃紝鍏滃簳浠庡叏閮ㄧ墿鏂欎腑鏌ユ壘 */
+function handleProductChange(row: ErpSaleReturnApi.SaleReturnItem) {
+ // 浼樺厛浠庡叧鑱旇鍗曠殑鐗╂枡涓煡鎵�
+ const orderItem = props.orderItems.find(
+ (item) => item.productId === row.productId,
+ );
+ if (orderItem) {
+ row.productName = orderItem.productName;
+ row.productPrice = orderItem.productPrice ?? 0;
+ row.productUnitId = orderItem.productUnitId;
+ row.productUnitName = orderItem.productUnitName;
+ row.productBarCode = orderItem.productBarCode;
+ row.taxPercent = orderItem.taxPercent ?? 0;
+ row.count = row.count || 1;
+ handleRowChange(row);
+ return;
+ }
+ // 鍏滃簳锛氫粠鍏ㄩ儴鐗╂枡涓煡鎵�
+ const product = productOptions.value.find((item) => item.id === row.productId);
+ if (product) {
+ row.productName = product.name || '';
+ row.productPrice = product.salesPrice ?? 0;
+ row.productUnitId = product.unitMeasureId;
+ row.productUnitName = product.unitMeasureName;
+ row.productBarCode = product.barCode;
+ row.taxPercent = 0;
+ row.count = row.count || 1;
+ handleRowChange(row);
+ }
+}
+
/** 澶勭悊浠撳簱鍙樻洿 */
async function handleWarehouseChange(row: ErpSaleReturnApi.SaleReturnItem) {
const stockCount = await getWarehouseStockCount({
@@ -177,6 +231,9 @@
for (let i = 0; i < tableData.value.length; i++) {
const item = tableData.value[i];
if (item) {
+ if (!item.productId) {
+ throw new Error(`绗� ${i + 1} 琛岋細浜у搧涓嶈兘涓虹┖`);
+ }
if (!item.warehouseId) {
throw new Error(`绗� ${i + 1} 琛岋細浠撳簱涓嶈兘涓虹┖`);
}
@@ -215,13 +272,14 @@
</template>
<template #productId="{ row }">
<Select
- disabled
+ :disabled="disabled"
v-model:value="row.productId"
- :options="productOptions"
- :field-names="{ label: 'name', value: 'id' }"
+ :options="orderItems?.length ? orderItems : productOptions"
+ :field-names="orderItems?.length ? { label: 'productName', value: 'productId' } : { label: 'name', value: 'id' }"
class="w-full"
placeholder="璇烽�夋嫨浜у搧"
show-search
+ @change="handleProductChange(row)"
/>
</template>
<template #count="{ row }">
@@ -291,6 +349,17 @@
</div>
</div>
</div>
+ <TableAction
+ v-if="!disabled"
+ class="mt-2 flex justify-center"
+ :actions="[
+ {
+ label: '娣诲姞閫�璐т骇鍝�',
+ type: 'default',
+ onClick: handleAdd,
+ },
+ ]"
+ />
</template>
</Grid>
</template>
diff --git a/src/views/mes/md/item/components/select-dialog.vue b/src/views/mes/md/item/components/select-dialog.vue
index a7ed8b8..d377f66 100644
--- a/src/views/mes/md/item/components/select-dialog.vue
+++ b/src/views/mes/md/item/components/select-dialog.vue
@@ -26,6 +26,7 @@
const selectedRows = ref<MesMdItemApi.Item[]>([]); // 宸查�夌墿鏂欏垪琛�
const selectedItemTypeId = ref<number>(); // 褰撳墠绛涢�夊垎绫荤紪鍙�
const preSelectedIds = ref<number[]>([]); // 棰勯�夌墿鏂欑紪鍙峰垪琛�
+ const productIds = ref<number[]>([]); // 闄愬畾鍙�夌殑鐗╂枡缂栧彿鍒楄〃锛堜负绌哄垯涓嶉檺鍒讹級
const typeTreeRef = ref<InstanceType<typeof MdItemTypeTree>>(); // 鐗╂枡鍒嗙被鏍�
/** 鑾峰彇褰撳墠琛ㄦ牸鏁版嵁 */
@@ -130,13 +131,20 @@
proxyConfig: {
ajax: {
query: async ({ page }, formValues) => {
- return await getItemPage({
+ const params: Record<string, unknown> = {
pageNo: page.currentPage,
pageSize: page.pageSize,
...formValues,
itemTypeId: selectedItemTypeId.value,
status: CommonStatusEnum.ENABLE,
- });
+ };
+ // 闄愬畾鍙�夌墿鏂欒寖鍥�
+ if (productIds.value.length > 0) {
+ params.pageSize = 1000;
+ params.ids = productIds.value.join(',');
+ }
+ const result = await getItemPage(params as never);
+ return result;
},
},
},
@@ -173,11 +181,12 @@
/** 鎵撳紑鐗╂枡閫夋嫨寮圭獥 */
async function openModal(
selectedIds?: number[],
- options?: { multiple?: boolean }
+ options?: { multiple?: boolean; productIds?: number[] }
) {
open.value = true;
multiple.value = options?.multiple ?? true;
preSelectedIds.value = selectedIds || [];
+ productIds.value = options?.productIds || [];
await nextTick();
gridApi.setGridOptions({
columns: useItemSelectGridColumns(multiple.value),
diff --git a/src/views/mes/md/item/components/select.vue b/src/views/mes/md/item/components/select.vue
index e5ffb2b..d157aff 100644
--- a/src/views/mes/md/item/components/select.vue
+++ b/src/views/mes/md/item/components/select.vue
@@ -19,12 +19,14 @@
disabled?: boolean;
modelValue?: number;
placeholder?: string;
+ productIds?: number[];
}>(),
{
allowClear: true,
disabled: false,
modelValue: undefined,
placeholder: '璇烽�夋嫨浜у搧鐗╂枡',
+ productIds: () => [],
},
);
const emit = defineEmits<{
@@ -86,7 +88,10 @@
const selectedIds = (
props.modelValue === null ? [] : [props.modelValue]
) as number[];
- dialogRef.value?.open(selectedIds, { multiple: false });
+ dialogRef.value?.open(selectedIds, {
+ multiple: false,
+ productIds: props.productIds,
+ });
}
/** 鍥炲~閫変腑鐨勭墿鏂� */
diff --git a/src/views/mes/pro/workorder/modules/form.vue b/src/views/mes/pro/workorder/modules/form.vue
index c998ef8..1181216 100644
--- a/src/views/mes/pro/workorder/modules/form.vue
+++ b/src/views/mes/pro/workorder/modules/form.vue
@@ -99,19 +99,17 @@
});
/** 閲嶆柊鎸傝浇 schema 骞舵寜琛ㄥ崟鎬佹帶鍒跺簳閮ㄦ寜閽� */
+ const mainActionText = computed(() => {
+ if (isConfirm.value) return '纭';
+ if (isFinish.value) return '瀹屾垚';
+ return '鎻愪氦';
+ });
+
+ const showMainBtn = computed(() => isEditable.value || isConfirm.value || isFinish.value);
+
function applySchema() {
formApi.setState({ schema: useFormSchema(formType.value, formApi) });
- const showBtn = isEditable.value || isConfirm.value || isFinish.value;
- modalApi.setState({
- showConfirmButton: showBtn,
- confirmText: isConfirm.value || canConfirm.value
- ? '纭'
- : isFinish.value
- ? '瀹屾垚'
- : isCreateMode.value
- ? '鏂板'
- : '淇濆瓨',
- });
+ modalApi.setState({ showCancelButton: false, showConfirmButton: false });
}
/** 浠呬繚瀛橈紙涓嶆敼鍙樼姸鎬侊級 */
@@ -353,14 +351,26 @@
</Tabs>
</template>
<template #prepend-footer>
- <Button v-if="canConfirm"
- @click="handleSave">
- 淇濆瓨
- </Button>
- <Button v-if="formType === 'detail' && formData?.id"
- @click="handleBarcode">
- 鏌ョ湅鏉$爜
- </Button>
+ <div class="flex flex-auto items-center">
+ <Button v-if="showMainBtn"
+ type="primary"
+ @click="modalApi.onConfirm()">
+ {{ mainActionText }}
+ </Button>
+ </div>
+ </template>
+ <template #append-footer>
+ <div class="flex gap-2">
+ <Button v-if="canConfirm"
+ @click="handleSave">
+ 淇濆瓨淇敼
+ </Button>
+ <Button v-if="formType === 'detail' && formData?.id"
+ @click="handleBarcode">
+ 鏌ョ湅鏉$爜
+ </Button>
+ <Button @click="modalApi.close()">鍙栨秷</Button>
+ </div>
</template>
</Modal>
<BarcodeDetail ref="barcodeDetailRef" />
diff --git a/src/views/wls/returnsales/data.ts b/src/views/wls/returnsales/data.ts
index fadbd4a..9b61d3c 100644
--- a/src/views/wls/returnsales/data.ts
+++ b/src/views/wls/returnsales/data.ts
@@ -1,3 +1,4 @@
+import type { ErpSaleOrderApi } from '#/api/erp/sale/order';
import type { VbenFormApi, VbenFormSchema } from '#/adapter/form';
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { MesWmReturnSalesApi } from '#/api/mes/wm/returnsales';
@@ -35,6 +36,7 @@
export function useFormSchema(
formType: FormType,
formApi?: VbenFormApi,
+ onOrderChange?: (item: Record<string, unknown> | undefined) => void,
): VbenFormSchema[] {
return [
{
@@ -100,6 +102,7 @@
label: '閿�鍞鍗曞彿',
component: markRaw(ErpSaleOrderSelect),
componentProps: {
+ outStatus: 3,
placeholder: '璇烽�夋嫨閿�鍞鍗�',
onChange: (item: any) => {
if (formApi) {
@@ -108,6 +111,7 @@
formApi.setFieldValue('clientId', item.customerId);
}
}
+ onOrderChange?.(item);
},
},
rules: 'selectRequired',
@@ -342,15 +346,31 @@
export function useLineFormSchema(
clientId?: number,
salesOrderCode?: string,
+ items?: ErpSaleOrderApi.SaleOrderItem[],
+ onItemChange?: (item: ErpSaleOrderApi.SaleOrderItem | undefined) => void,
): VbenFormSchema[] {
+ const hasItems = items && items.length > 0;
return [
{
fieldName: 'itemId',
label: '鐗╂枡',
- component: markRaw(MdItemSelect),
- componentProps: {
- placeholder: '璇烽�夋嫨鐗╂枡',
- },
+ component: hasItems ? 'Select' : markRaw(MdItemSelect),
+ componentProps: hasItems
+ ? {
+ placeholder: '璇烽�夋嫨鐗╂枡',
+ options: items.map((item) => ({
+ label: `${item.productName || ''}锛�${item.productBarCode || ''}锛塦,
+ value: item.productId,
+ })),
+ onChange: (value: number | undefined) => {
+ const selected = items.find((i) => i.productId === value);
+ onItemChange?.(selected);
+ },
+ }
+ : {
+ placeholder: '璇烽�夋嫨鐗╂枡',
+ productIds: [],
+ },
rules: 'selectRequired',
},
{
@@ -363,6 +383,30 @@
placeholder: '璇疯緭鍏ラ��璐ф暟閲�',
precision: 2,
},
+ dependencies: {
+ triggerFields: ['itemId'],
+ componentProps: (values) => {
+ const selected = items?.find((i) => i.productId === values.itemId);
+ return {
+ class: '!w-full',
+ max: selected?.count ?? undefined,
+ min: 0,
+ placeholder: '璇疯緭鍏ラ��璐ф暟閲�',
+ precision: 2,
+ };
+ },
+ rules: (values) => {
+ const selected = items?.find((i) => i.productId === values.itemId);
+ const max = selected?.count;
+ if (max !== undefined && max !== null) {
+ return z
+ .number({ message: '璇疯緭鍏ラ��璐ф暟閲�' })
+ .min(0)
+ .max(max, `鍙��璐ф暟閲忎笉鑳借秴杩� ${max}`);
+ }
+ return z.number({ message: '璇疯緭鍏ラ��璐ф暟閲�' }).min(0);
+ },
+ },
rules: 'required',
},
{
@@ -371,6 +415,7 @@
component: markRaw(WmBatchSelect),
componentProps: {
clientId,
+ disabled: true,
placeholder: '璇烽�夋嫨鎵规',
salesOrderCode,
},
@@ -378,6 +423,7 @@
triggerFields: ['itemId'],
componentProps: (values) => ({
clientId,
+ disabled: true,
itemId: values.itemId,
placeholder: '璇烽�夋嫨鎵规',
salesOrderCode,
diff --git a/src/views/wls/returnsales/modules/form.vue b/src/views/wls/returnsales/modules/form.vue
index 3cae020..2f57364 100644
--- a/src/views/wls/returnsales/modules/form.vue
+++ b/src/views/wls/returnsales/modules/form.vue
@@ -19,6 +19,9 @@
submitReturnSales,
updateReturnSales,
} from '#/api/mes/wm/returnsales';
+import type { ErpSaleOrderApi } from '#/api/erp/sale/order';
+
+import { getSaleOrder, getSaleOrderPage } from '#/api/erp/sale/order';
import { $t } from '#/locales';
import { useFormSchema } from '../data';
@@ -28,6 +31,7 @@
const formType = ref<FormType>('create');
const formData = ref<MesWmReturnSalesApi.ReturnSales>();
const originalSnapshot = ref(''); // 琛ㄥ崟鍘熷鏁版嵁蹇収锛岀敤浜庢彁浜ゆ椂璺宠繃鏈彉鏇寸殑淇濆瓨璇锋眰
+const saleOrderItems = ref<ErpSaleOrderApi.SaleOrderItem[]>([]); // 褰撳墠閿�鍞鍗曠殑鐗╂枡琛�
const isEditable = computed(() =>
// 鏄惁涓虹紪杈戞ā寮忥紙鍙繚瀛橈級
['create', 'update'].includes(formType.value),
@@ -169,13 +173,38 @@
// 鍔犺浇鏁版嵁
const data = modalApi.getData<{ formType: FormType; id?: number }>();
formType.value = data.formType;
- formApi.setState({ schema: useFormSchema(formType.value, formApi) });
+ formApi.setState({
+ schema: useFormSchema(formType.value, formApi, (item) => {
+ if (item?.id) {
+ getSaleOrder(item.id as number).then((order) => {
+ saleOrderItems.value = (order as ErpSaleOrderApi.SaleOrder)?.items || [];
+ });
+ } else {
+ saleOrderItems.value = [];
+ }
+ }),
+ });
formApi.setDisabled(!isEditable.value);
modalApi.setState({ showConfirmButton: isEditable.value });
if (data?.id) {
modalApi.lock();
try {
formData.value = await getReturnSales(data.id);
+ // 閫氳繃閿�鍞鍗曞彿鍙嶆煡璁㈠崟ID锛岀‘淇� ErpSaleOrderSelect 鑳芥纭洖鏄�
+ if (formData.value?.salesOrderCode && !formData.value.saleOrderId) {
+ const orderPage = await getSaleOrderPage({
+ pageNo: 1,
+ pageSize: 1,
+ no: formData.value.salesOrderCode,
+ } as Record<string, unknown> as never);
+ const list = (orderPage as Record<string, unknown>)?.list as Array<Record<string, unknown>> | undefined;
+ if (list?.length) {
+ const orderId = list[0].id as number;
+ (formData.value as Record<string, unknown>).saleOrderId = orderId;
+ const order = await getSaleOrder(orderId);
+ saleOrderItems.value = order?.items || [];
+ }
+ }
// 璁剧疆鍒� values
await formApi.setValues(formData.value);
} finally {
@@ -198,6 +227,7 @@
:client-id="formData.clientId"
:form-type="formType"
:return-id="formData.id"
+ :sale-order-items="saleOrderItems"
:sales-order-code="formData.salesOrderCode"
/>
</div>
diff --git a/src/views/wls/returnsales/modules/line-form.vue b/src/views/wls/returnsales/modules/line-form.vue
index 0736b8b..06adfaf 100644
--- a/src/views/wls/returnsales/modules/line-form.vue
+++ b/src/views/wls/returnsales/modules/line-form.vue
@@ -1,4 +1,5 @@
<script lang="ts" setup>
+import type { ErpSaleOrderApi } from '#/api/erp/sale/order';
import type { MesWmReturnSalesLineApi } from '#/api/mes/wm/returnsales/line';
import { computed, ref } from 'vue';
@@ -8,6 +9,7 @@
import { message } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form';
+import { getBatchPage } from '#/api/mes/wm/batch';
import {
createReturnSalesLine,
getReturnSalesLine,
@@ -20,6 +22,7 @@
const emit = defineEmits(['success']);
const formData = ref<MesWmReturnSalesLineApi.ReturnSalesLine>();
const returnId = ref<number>(); // 鎵�灞為��璐у崟缂栧彿
+const maxQuantity = ref<number>(); // 褰撳墠閫変腑鐗╂枡鍙��璐х殑鏈�澶ф暟閲�
const getTitle = computed(() => {
return formData.value?.id
@@ -73,12 +76,38 @@
const data = modalApi.getData<{
clientId?: number;
id?: number;
+ items?: ErpSaleOrderApi.SaleOrderItem[];
returnId: number;
salesOrderCode?: string;
}>();
returnId.value = data.returnId;
+ maxQuantity.value = undefined;
formApi.setState({
- schema: useLineFormSchema(data.clientId, data.salesOrderCode),
+ schema: useLineFormSchema(
+ data.clientId,
+ data.salesOrderCode,
+ data.items || [],
+ async (item) => {
+ maxQuantity.value = item?.count;
+ // 閲嶇疆鎵规
+ await formApi.setFieldValue('batchId', undefined);
+ if (item?.batchCode) {
+ try {
+ const batchPage = await getBatchPage({
+ code: item.batchCode,
+ pageNo: 1,
+ pageSize: 1,
+ });
+ const batchList = batchPage?.list;
+ if (batchList?.length) {
+ await formApi.setFieldValue('batchId', batchList[0].id);
+ }
+ } catch {
+ // 鏌ヨ澶辫触鏃跺拷鐣�
+ }
+ }
+ },
+ ),
});
if (!data.id) {
return;
@@ -98,5 +127,11 @@
<template>
<Modal :title="getTitle" class="w-3/5">
<Form class="mx-4" />
+ <div
+ v-if="maxQuantity !== undefined"
+ class="mx-4 mt-2 text-sm text-blue-600"
+ >
+ 褰撳墠鐗╂枡鍙��璐ф暟閲忥細<span class="font-bold">{{ maxQuantity }}</span>
+ </div>
</Modal>
</template>
diff --git a/src/views/wls/returnsales/modules/line-list.vue b/src/views/wls/returnsales/modules/line-list.vue
index d1ab690..9c635e2 100644
--- a/src/views/wls/returnsales/modules/line-list.vue
+++ b/src/views/wls/returnsales/modules/line-list.vue
@@ -1,6 +1,7 @@
<script lang="ts" setup>
import type { FormType } from '../data';
+import type { ErpSaleOrderApi } from '#/api/erp/sale/order';
import type { VxeTableGridOptions } from '#/adapter/vxe-table';
import type { MesWmReturnSalesDetailApi } from '#/api/mes/wm/returnsales/detail';
import type { MesWmReturnSalesLineApi } from '#/api/mes/wm/returnsales/line';
@@ -29,6 +30,7 @@
clientId?: number;
formType: FormType;
returnId: number;
+ saleOrderItems?: ErpSaleOrderApi.SaleOrderItem[];
salesOrderCode?: string;
}>();
@@ -64,6 +66,7 @@
lineFormModalApi
.setData({
clientId: props.clientId,
+ items: props.saleOrderItems,
returnId: props.returnId,
salesOrderCode: props.salesOrderCode,
})
@@ -76,6 +79,7 @@
.setData({
clientId: props.clientId,
id: row.id,
+ items: props.saleOrderItems,
returnId: props.returnId,
salesOrderCode: props.salesOrderCode,
})
--
Gitblit v1.9.3