From 08bb5d242135e2c1f0fc17d2b5f7ae548275a3a2 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期五, 28 八月 2026 17:15:33 +0800
Subject: [PATCH] feat(mes): 实现临时码预生成和补录功能
---
src/views/mes/pro/pallet/data.ts | 5
src/views/mes/pro/bagCode/index.vue | 29 ++
src/views/mes/pro/batch/index.vue | 67 ++++
src/views/mes/pro/batch/modules/pre-generate.vue | 80 ++++++
src/views/mes/pro/pallet/modules/bind-batch.vue | 88 ++++++
src/views/mes/pro/batch/modules/form.vue | 16 +
src/api/mes/pro/pallet/index.ts | 38 ++
src/api/mes/pro/batch/index.ts | 29 ++
src/views/mes/pro/pallet/index.vue | 102 +++++++
src/views/mes/pro/bagCode/modules/bind-batch.vue | 62 ++++
src/api/mes/pro/bagCode/index.ts | 20 +
src/views/mes/pro/bagCode/data.ts | 2
src/views/mes/pro/pallet/modules/generate-form.vue | 125 +++------
src/views/mes/pro/bagCode/modules/generate-form.vue | 29 --
src/views/mes/pro/batch/data.ts | 21 +
src/views/mes/pro/components/qr-trace-modal.vue | 44 ++
16 files changed, 613 insertions(+), 144 deletions(-)
diff --git a/src/api/mes/pro/bagCode/index.ts b/src/api/mes/pro/bagCode/index.ts
index 5c381e9..22d4b6e 100644
--- a/src/api/mes/pro/bagCode/index.ts
+++ b/src/api/mes/pro/bagCode/index.ts
@@ -36,9 +36,17 @@
/** 鐢熸垚鏁版嵁鍖呰姹� */
export interface GenerateParams {
- batchId: number; // 鐢熶骇鎵规缂栧彿
count: number; // 鐢熸垚琚嬫暟
remark?: string; // 澶囨敞
+ }
+
+ export interface GenerateResult {
+ uuid?: string;
+ }
+
+ export interface BindBatchParams {
+ batchId: number;
+ ids: number[];
}
/** 缁戝畾/瑙g粦鎵樼洏璇锋眰 */
@@ -111,7 +119,15 @@
/** 鐢熸垚琚嬬爜鏁版嵁鍖咃紙杩斿洖鐢熸垚缁� UUID锛� */
export function generateBagCodes(data: MesProBagCodeApi.GenerateParams) {
- return requestClient.post<string>('/mes/pro/bag-code/generate', data);
+ return requestClient.post<MesProBagCodeApi.GenerateResult>(
+ '/mes/pro/bag-code/generate',
+ data,
+ );
+}
+
+/** 褰曞叆鐢熶骇鎵规 */
+export function bindBagCodeBatch(data: MesProBagCodeApi.BindBatchParams) {
+ return requestClient.put('/mes/pro/bag-code/bind-batch', data);
}
/** 鍒犻櫎琚嬬爜鐢熸垚缁� */
diff --git a/src/api/mes/pro/batch/index.ts b/src/api/mes/pro/batch/index.ts
index 01e4424..86544c8 100644
--- a/src/api/mes/pro/batch/index.ts
+++ b/src/api/mes/pro/batch/index.ts
@@ -18,7 +18,8 @@
/** 鐢熶骇鎵规 */
export interface Batch {
id?: number; // 缂栧彿
- code?: string; // 鎵规鍙凤紙鑷姩鐢熸垚锛�
+ code?: string; // 鎵规鍙凤紙琛ュ綍姝e紡淇℃伅鍚庤嚜鍔ㄧ敓鎴愶級
+ tempCode?: string; // 涓存椂鎵规鐮侊紙棰勭敓鎴愪簩缁寸爜闃舵浣跨敤锛屾壂鐮佽拷婧吋瀹癸級
itemId?: number; // 鍝佺锛堜骇鍝佺墿鏂欙級缂栧彿
itemCode?: string; // 鍝佺缂栫爜锛堝悗绔嫾鎺ワ級
itemName?: string; // 鍝佺鍚嶇О锛堝悗绔嫾鎺ワ級
@@ -41,7 +42,8 @@
/** 鐢熶骇鎵规鎵爜杩芥函 */
export interface BatchTrace {
id?: number; // 鐢熶骇鎵规缂栧彿
- code?: string; // 鎵规鍙凤紙浜岀淮鐮佸唴瀹癸級
+ code?: string; // 鎵规鍙凤紙琛ュ綍鍚庣殑姝e紡鎵规鍙凤級
+ tempCode?: string; // 涓存椂鎵规鐮侊紙浜岀淮鐮佸唴瀹癸紱鏈ˉ褰曚俊鎭椂灞曠ず锛�
status?: number; // 鎵规鐘舵�侊紙瀛楀吀 mes_pro_batch_status锛�
produceDate?: string; // 鐢熶骇鏃ユ湡
lineCode?: string; // 浜х嚎缂栫爜
@@ -65,6 +67,7 @@
/** 鐢熶骇鎵规鍒嗛〉鏌ヨ鍙傛暟 */
export interface PageParams extends PageParam {
code?: string;
+ tempCode?: string;
itemId?: number;
lineId?: number;
lineCode?: string;
@@ -73,6 +76,12 @@
status?: number;
produceDate?: string[];
createTime?: string[];
+ }
+
+ /** 棰勭敓鎴愭壒娆′簩缁寸爜杩斿洖椤� */
+ export interface PreGenerateResult {
+ id: number; // 鐢熶骇鎵规缂栧彿
+ tempCode: string; // 涓存椂鎵规鐮侊紙浜岀淮鐮佸唴瀹癸級
}
}
@@ -91,6 +100,22 @@
);
}
+/** 棰勭敓鎴愭壒娆′复鏃朵簩缁寸爜锛堜粎鐢熸垚涓存椂鎵规鐮侊紝涓嶅綍鍏ヤ笟鍔′俊鎭級 */
+export function preGenerateBatch(data: {
+ count: number;
+ remark?: string;
+}) {
+ return requestClient.post<MesProBatchApi.PreGenerateResult[]>(
+ '/mes/pro/batch/pre-generate',
+ data,
+ );
+}
+
+/** 琛ュ綍鎵规姝e紡淇℃伅锛堢敓鎴愭寮忔壒娆″彿锛� */
+export function fillBatchInfo(data: MesProBatchApi.Batch) {
+ return requestClient.put('/mes/pro/batch/fill-info', data);
+}
+
/** 鏂板鐢熶骇鎵规锛堣嚜鍔ㄧ敓鎴愭壒娆″彿锛� */
export function createBatch(data: MesProBatchApi.Batch) {
return requestClient.post<number>('/mes/pro/batch/create', data);
diff --git a/src/api/mes/pro/pallet/index.ts b/src/api/mes/pro/pallet/index.ts
index 2fef83b..7ae540b 100644
--- a/src/api/mes/pro/pallet/index.ts
+++ b/src/api/mes/pro/pallet/index.ts
@@ -7,7 +7,8 @@
/** 鎵樼洏鐮� */
export interface Pallet {
id?: number; // 缂栧彿
- code?: string; // 鎵樼洏鐮�
+ code?: string; // 鎵樼洏鐮侊紙缁戝畾鎵规鍚庣敓鎴愶級
+ tempCode?: string; // 涓存椂鎵樼洏鐮侊紙棰勭敓鎴愪簩缁寸爜闃舵浣跨敤锛屾壂鐮佽拷婧吋瀹癸級
batchId?: number; // 鐢熶骇鎵规缂栧彿
batchCode?: string; // 鎵规鍙�
palletNo?: number; // 鎵规鍐呮墭鐩樺簭鍙�
@@ -21,6 +22,7 @@
/** 鎵樼洏鐮佸垎椤垫煡璇㈠弬鏁� */
export interface PageParams extends PageParam {
code?: string;
+ tempCode?: string;
batchId?: number;
batchCode?: string;
status?: number;
@@ -30,7 +32,8 @@
/** 鎵樼洏鐮佹壂鐮佽拷婧� */
export interface PalletTrace {
id?: number; // 缂栧彿
- code?: string; // 鎵樼洏鐮侊紙浜岀淮鐮佸唴瀹癸級
+ code?: string; // 鎵樼洏鐮侊紙缁戝畾鎵规鍚庣殑姝e紡鎵樼洏鐮侊級
+ tempCode?: string; // 涓存椂鎵樼洏鐮侊紙浜岀淮鐮佸唴瀹癸紱鏈粦瀹氭壒娆℃椂灞曠ず锛�
palletNo?: number; // 鎵规鍐呮墭鐩樺簭鍙�
capacity?: number; // 鍙琚嬫暟
bagCount?: number; // 宸茬粦瀹氳鐮佹暟閲�
@@ -58,11 +61,34 @@
capacity?: number; // 鍙琚嬫暟
remark?: string; // 澶囨敞
}
+
+ /** 棰勭敓鎴愭墭鐩樹簩缁寸爜杩斿洖椤� */
+ export interface PreGenerateResult {
+ id: number; // 鎵樼洏鐮佺紪鍙�
+ tempCode: string; // 涓存椂鎵樼洏鐮侊紙浜岀淮鐮佸唴瀹癸級
+ }
}
/** 鎵归噺鐢熸垚鎵樼洏鐮侊紙杩斿洖鐢熸垚鐨勬墭鐩樼紪鍙峰垪琛級 */
export function batchCreatePallet(data: MesProPalletApi.BatchCreateParams) {
return requestClient.post<number[]>('/mes/pro/pallet/batch-create', data);
+}
+
+/** 棰勭敓鎴愭墭鐩樹复鏃朵簩缁寸爜锛堜笉缁戝畾鐢熶骇鎵规锛� */
+export function preGeneratePallet(data: {
+ count: number;
+ capacity?: number;
+ remark?: string;
+}) {
+ return requestClient.post<MesProPalletApi.PreGenerateResult[]>(
+ '/mes/pro/pallet/pre-generate',
+ data,
+ );
+}
+
+/** 鎵樼洏鐮佺粦瀹氱敓浜ф壒娆★紙鐢熸垚姝e紡鎵樼洏鐮侊級 */
+export function bindPalletBatch(data: { ids: number[]; batchId: number }) {
+ return requestClient.put('/mes/pro/pallet/bind-batch', data);
}
/** 鍒犻櫎鎵樼洏鐮� */
@@ -108,3 +134,11 @@
export function exportPalletQr(batchId: number) {
return requestClient.download(`/mes/pro/pallet/export-qr?batchId=${batchId}`);
}
+
+/** 鎸夋墭鐩樼爜缂栧彿鍒楄〃鎵归噺瀵煎嚭浜岀淮鐮佸浘鐗� ZIP */
+export function exportPalletQrByIds(ids: number[]) {
+ return requestClient.download('/mes/pro/pallet/export-qr-by-ids', {
+ method: 'POST',
+ data: { ids },
+ });
+}
diff --git a/src/views/mes/pro/bagCode/data.ts b/src/views/mes/pro/bagCode/data.ts
index a2b312e..caacb5f 100644
--- a/src/views/mes/pro/bagCode/data.ts
+++ b/src/views/mes/pro/bagCode/data.ts
@@ -133,7 +133,7 @@
},
{
title: '鎿嶄綔',
- width: 200,
+ width: 350,
fixed: 'right',
slots: { default: 'actions' },
},
diff --git a/src/views/mes/pro/bagCode/index.vue b/src/views/mes/pro/bagCode/index.vue
index 910602c..58621ab 100644
--- a/src/views/mes/pro/bagCode/index.vue
+++ b/src/views/mes/pro/bagCode/index.vue
@@ -14,11 +14,13 @@
exportBagCodeExcel,
exportBagQr,
getBagCodePage,
+ bindBagCodeBatch,
unbindBagCodePallet,
} from "#/api/mes/pro/bagCode";
import { $t } from "#/locales";
import { useGridColumns, useGridFormSchema } from "./data";
+ import BindBatchModal from "./modules/bind-batch.vue";
import BindPalletModal from "./modules/bind-pallet.vue";
import GenerateModal from "./modules/generate-form.vue";
import ReplaceModal from "./modules/replace-form.vue";
@@ -28,6 +30,11 @@
const [GenerateFormModal, generateFormModalApi] = useVbenModal({
connectedComponent: GenerateModal,
+ destroyOnClose: true,
+ });
+
+ const [BindBatchFormModal, bindBatchFormModalApi] = useVbenModal({
+ connectedComponent: BindBatchModal,
destroyOnClose: true,
});
@@ -178,10 +185,25 @@
.open();
}
+ /** 鎵归噺褰曞叆鐢熶骇鎵规 */
+ function handleBindBatch() {
+ const records = getSelectedRecords();
+ if (!records) return;
+ if (records.some((record) => record.status !== MesProBagCodeStatusEnum.GENERATED || record.batchId)) {
+ message.warning("璇烽�夋嫨鏈綍鍏ユ壒娆′笖鐘舵�佷负宸茬敓鎴愮殑琚嬬爜");
+ return;
+ }
+ bindBatchFormModalApi.setData({ ids: records.map((record) => record.id!) }).open();
+ }
+
/** 鎵归噺缁戝畾鎵樼洏 */
function handleBindPallet() {
const records = getSelectedRecords();
if (!records) return;
+ if (records.some((record) => !record.batchId)) {
+ message.warning("璇峰厛褰曞叆鐢熶骇鎵规锛屽啀缁戝畾鎵樼洏");
+ return;
+ }
const batchIds = new Set(records.map((record) => record.batchId));
if (batchIds.size > 1) {
message.warning("璇烽�夋嫨鍚屼竴鎵规涓嬬殑琚嬬爜杩涜缁戝畾");
@@ -281,6 +303,7 @@
<template>
<Page auto-content-height>
<GenerateFormModal @success="handleRefresh" />
+ <BindBatchFormModal @success="handleRefresh" />
<BindPalletFormModal @success="handleRefresh" />
<ReplaceFormModal @success="handleReplaceSuccess" />
<QrTraceQueryModal />
@@ -295,6 +318,12 @@
onClick: handleGenerate,
},
{
+ label: '褰曞叆鎵规',
+ type: 'primary',
+ auth: ['mes:pro-bag-code:update'],
+ onClick: handleBindBatch,
+ },
+ {
label: '缁戝畾鎵樼洏',
type: 'primary',
auth: ['mes:pro-bag-code:update'],
diff --git a/src/views/mes/pro/bagCode/modules/bind-batch.vue b/src/views/mes/pro/bagCode/modules/bind-batch.vue
new file mode 100644
index 0000000..9e2683e
--- /dev/null
+++ b/src/views/mes/pro/bagCode/modules/bind-batch.vue
@@ -0,0 +1,62 @@
+<script lang="ts" setup>
+ import type { VbenFormSchema } from "#/adapter/form";
+
+ import { useVbenModal } from "@vben/common-ui";
+ import { MesProBatchStatusEnum } from "@vben/constants";
+ import { message } from "ant-design-vue";
+
+ import { useVbenForm } from "#/adapter/form";
+ import { bindBagCodeBatch } from "#/api/mes/pro/bagCode";
+ import { getBatchSimpleList } from "#/api/mes/pro/batch";
+ import { $t } from "#/locales";
+
+ defineOptions({ name: "MesProBagCodeBindBatch" });
+
+ interface ModalData { ids: number[] }
+ const emit = defineEmits(["success"]);
+
+ const [Form, formApi] = useVbenForm({
+ commonConfig: { componentProps: { class: "w-full" }, labelWidth: 100 },
+ layout: "horizontal", schema: [], showDefaultActions: false,
+ });
+
+ const [Modal, modalApi] = useVbenModal({
+ async onConfirm() {
+ const { valid } = await formApi.validate();
+ if (!valid) return;
+ const data = modalApi.getData<ModalData>();
+ const values = await formApi.getValues();
+ modalApi.lock();
+ try {
+ await bindBagCodeBatch({ batchId: values.batchId, ids: data.ids });
+ message.success($t("ui.actionMessage.operationSuccess"));
+ emit("success");
+ await modalApi.close();
+ } finally { modalApi.unlock(); }
+ },
+ async onOpenChange(isOpen: boolean) {
+ if (!isOpen) return;
+ modalApi.lock();
+ try {
+ const batches = await getBatchSimpleList();
+ // 浠呭凡琛ュ綍姝e紡淇℃伅锛堟壒娆″彿闈炵┖锛変笖鐢熶骇涓殑鎵规鍏佽褰曞叆琚嬬爜
+ const options = batches
+ .filter(
+ (batch) =>
+ batch.status === MesProBatchStatusEnum.PRODUCING && batch.code,
+ )
+ .map((batch) => ({ label: batch.code!, value: batch.id! }));
+ const schema: VbenFormSchema[] = [{
+ fieldName: "batchId", label: "鐢熶骇鎵规", component: "Select",
+ componentProps: { options, optionFilterProp: "label", placeholder: "璇烽�夋嫨鐢熶骇涓殑鎵规", showSearch: true },
+ rules: "selectRequired",
+ }];
+ await formApi.setState({ schema });
+ } finally { modalApi.unlock(); }
+ },
+ });
+</script>
+
+<template>
+ <Modal title="褰曞叆鐢熶骇鎵规" class="w-2/5"><Form class="mx-4" /></Modal>
+</template>
diff --git a/src/views/mes/pro/bagCode/modules/generate-form.vue b/src/views/mes/pro/bagCode/modules/generate-form.vue
index 6ea36bc..316e9fd 100644
--- a/src/views/mes/pro/bagCode/modules/generate-form.vue
+++ b/src/views/mes/pro/bagCode/modules/generate-form.vue
@@ -3,33 +3,18 @@
import type { MesProBagCodeApi } from "#/api/mes/pro/bagCode";
import { useVbenModal } from "@vben/common-ui";
- import { MesProBatchStatusEnum } from "@vben/constants";
import { message } from "ant-design-vue";
import { useVbenForm } from "#/adapter/form";
import { generateBagCodes } from "#/api/mes/pro/bagCode";
- import { getBatchSimpleList } from "#/api/mes/pro/batch";
defineOptions({ name: "MesProBagCodeGenerateForm" });
const emit = defineEmits(["success"]);
- /** 鏋勫缓琛ㄥ崟锛堟壒娆′笅鎷夐�夐」鐢卞閮ㄥ姞杞芥敞鍏ワ級 */
- function buildSchema(batchOptions: { label: string; value: number }[]): VbenFormSchema[] {
+ function buildSchema(): VbenFormSchema[] {
return [
- {
- fieldName: "batchId",
- label: "鐢熶骇鎵规",
- component: "Select",
- componentProps: {
- options: batchOptions,
- optionFilterProp: "label",
- placeholder: "璇烽�夋嫨鐢熶骇涓殑鎵规",
- showSearch: true,
- },
- rules: "selectRequired",
- },
{
fieldName: "count",
label: "鐢熸垚琚嬫暟",
@@ -86,17 +71,7 @@
if (!isOpen) return;
modalApi.lock();
try {
- // 浠呯敓浜т腑鐨勬壒娆″厑璁哥敓鎴愯鐮�
- const batches = await getBatchSimpleList();
- const options = batches
- .filter(
- (batch) => batch.status === MesProBatchStatusEnum.PRODUCING
- )
- .map((batch) => ({
- label: batch.code!,
- value: batch.id!,
- }));
- await formApi.setState({ schema: buildSchema(options) });
+ await formApi.setState({ schema: buildSchema() });
} finally {
modalApi.unlock();
}
diff --git a/src/views/mes/pro/batch/data.ts b/src/views/mes/pro/batch/data.ts
index 1b765a7..673aedc 100644
--- a/src/views/mes/pro/batch/data.ts
+++ b/src/views/mes/pro/batch/data.ts
@@ -12,8 +12,8 @@
import { UserSelect } from '#/views/system/user/components';
import { getRangePickerDefaultProps } from '#/utils';
-/** 琛ㄥ崟绫诲瀷 */
-export type FormType = 'create' | 'detail' | 'update';
+/** 琛ㄥ崟绫诲瀷锛坒ill锛氫复鏃舵壒娆$爜琛ュ綍姝e紡淇℃伅锛� */
+export type FormType = 'create' | 'detail' | 'update' | 'fill';
/** 鏂板/淇敼鐨勮〃鍗� */
export function useFormSchema(formType: FormType): VbenFormSchema[] {
@@ -33,11 +33,24 @@
component: 'Input',
componentProps: {
disabled: true,
- placeholder: '淇濆瓨鍚庤嚜鍔ㄧ敓鎴�',
+ placeholder: '琛ュ綍鍚庤嚜鍔ㄧ敓鎴�',
},
dependencies: {
triggerFields: [''],
show: () => formType !== 'create',
+ },
+ },
+ {
+ fieldName: 'tempCode',
+ label: '涓存椂鎵规鐮�',
+ component: 'Input',
+ componentProps: {
+ disabled: true,
+ placeholder: '棰勭敓鎴愪簩缁寸爜闃舵浣跨敤鐨勪复鏃剁爜',
+ },
+ dependencies: {
+ triggerFields: [''],
+ show: () => formType === 'fill',
},
},
{
@@ -273,7 +286,7 @@
},
{
title: '鎿嶄綔',
- width: 300,
+ width: 350,
fixed: 'right',
slots: { default: 'actions' },
},
diff --git a/src/views/mes/pro/batch/index.vue b/src/views/mes/pro/batch/index.vue
index 73dfe65..99ff585 100644
--- a/src/views/mes/pro/batch/index.vue
+++ b/src/views/mes/pro/batch/index.vue
@@ -6,7 +6,7 @@
import { MesProBatchStatusEnum } from "@vben/constants";
import { downloadFileFromBlobPart } from "@vben/utils";
- import { Button, message } from "ant-design-vue";
+ import { Button, message, Modal, Tag } from "ant-design-vue";
import { ACTION_ICON, TableAction, useVbenVxeGrid } from "#/adapter/vxe-table";
import {
@@ -20,10 +20,16 @@
import { useGridColumns, useGridFormSchema } from "./data";
import Form from "./modules/form.vue";
+ import PreGenerateModal from "./modules/pre-generate.vue";
import QrTraceModal from "../components/qr-trace-modal.vue";
const [FormModal, formModalApi] = useVbenModal({
connectedComponent: Form,
+ destroyOnClose: true,
+ });
+
+ const [PreGenerateModalApi, preGenerateModalApi] = useVbenModal({
+ connectedComponent: PreGenerateModal,
destroyOnClose: true,
});
@@ -42,23 +48,47 @@
qrTraceQueryModalApi.open();
}
- /** 鏌ョ湅浜岀淮鐮侊紙琛屽唴棰勫~鐮佸�硷級 */
+ /** 鑾峰彇鎵规鏄剧ず鐢ㄧ殑鐮佸�硷紙姝e紡鎵规鍙蜂紭鍏堬紝鍏舵涓存椂鎵规鐮侊級 */
+ function getDisplayCode(row: MesProBatchApi.Batch) {
+ return row.code || row.tempCode || "";
+ }
+
+ /** 鏌ョ湅浜岀淮鐮侊紙琛屽唴棰勫~鐮佸�硷紝涓存椂鎵规鐢ㄤ复鏃舵壒娆$爜锛� */
function handleViewQr(row: MesProBatchApi.Batch) {
- qrTraceQueryModalApi.setData({ code: row.code }).open();
+ qrTraceQueryModalApi.setData({ code: getDisplayCode(row) }).open();
}
/** 鎵撳嵃鏁村浜岀淮鐮侊紙鎵规鍥� + 鍏ㄩ儴鎵樼洏鍥� ZIP锛� */
async function handlePrintQrSet(row: MesProBatchApi.Batch) {
const data = await exportBatchQr(row.id!);
downloadFileFromBlobPart({
- fileName: `鎵规浜岀淮鐮�-${row.code}.zip`,
+ fileName: `鎵规浜岀淮鐮�-${getDisplayCode(row)}.zip`,
source: data,
+ });
+ }
+
+ /** 棰勭敓鎴愭壒娆′簩缁寸爜鎴愬姛锛氬睍绀虹敓鎴愮殑涓存椂鎵规鐮� */
+ function handlePreGenerateSuccess(result: { id: number; tempCode: string }[]) {
+ Modal.success({
+ title: "棰勭敓鎴愪复鏃舵壒娆$爜鎴愬姛",
+ content: result.map((item) => item.tempCode).join("\n"),
+ centered: true,
});
}
/** 鏂板鎵规 */
function handleCreate() {
formModalApi.setData({ formType: "create" }).open();
+ }
+
+ /** 涓存椂鎵规琛ュ綍姝e紡淇℃伅 */
+ function handleFillInfo(row: MesProBatchApi.Batch) {
+ formModalApi.setData({ formType: "fill", id: row.id }).open();
+ }
+
+ /** 棰勭敓鎴愭壒娆′簩缁寸爜 */
+ function handlePreGenerate() {
+ preGenerateModalApi.open();
}
/** 鏌ョ湅璇︽儏 */
@@ -74,7 +104,7 @@
/** 鍒犻櫎鎵规 */
async function handleDelete(row: MesProBatchApi.Batch) {
await deleteBatch(row.id!);
- message.success($t("ui.actionMessage.deleteSuccess", [row.code]));
+ message.success($t("ui.actionMessage.deleteSuccess", [getDisplayCode(row)]));
handleRefresh();
}
@@ -129,10 +159,17 @@
<template>
<Page auto-content-height>
<FormModal @success="handleRefresh" />
+ <PreGenerateModalApi @success="handlePreGenerateSuccess" />
<QrTraceQueryModal />
<Grid table-title="鐢熶骇鎵规鍒楄〃">
<template #toolbar-tools>
<TableAction :actions="[
+ {
+ label: '棰勭敓鎴愪簩缁寸爜',
+ icon: ACTION_ICON.ADD,
+ auth: ['mes:pro-batch:create'],
+ onClick: handlePreGenerate,
+ },
{
label: $t('ui.actionTitle.create', ['鎵规']),
type: 'primary',
@@ -157,8 +194,9 @@
</template>
<template #code="{ row }">
<Button type="link" @click="handleDetail(row)">
- {{ row.code }}
+ {{ getDisplayCode(row) }}
</Button>
+ <Tag v-if="!row.code" color="warning">寰呰ˉ褰�</Tag>
</template>
<template #actions="{ row }">
<TableAction :actions="[
@@ -169,13 +207,22 @@
onClick: handleViewQr.bind(null, row),
},
{
+ label: '琛ュ綍淇℃伅',
+ type: 'link',
+ icon: ACTION_ICON.EDIT,
+ auth: ['mes:pro-batch:update'],
+ ifShow: !row.code,
+ onClick: handleFillInfo.bind(null, row),
+ },
+ {
label: $t('common.edit'),
type: 'link',
icon: ACTION_ICON.EDIT,
auth: ['mes:pro-batch:update'],
ifShow:
- row.status === MesProBatchStatusEnum.DRAFT ||
- row.status === MesProBatchStatusEnum.PRODUCING,
+ (row.status === MesProBatchStatusEnum.DRAFT ||
+ row.status === MesProBatchStatusEnum.PRODUCING) &&
+ !!row.code,
onClick: handleEdit.bind(null, row),
},
{
@@ -188,7 +235,7 @@
row.status === MesProBatchStatusEnum.DRAFT ||
row.status === MesProBatchStatusEnum.CANCELED,
popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.code]),
+ title: $t('ui.actionMessage.deleteConfirm', [getDisplayCode(row)]),
confirm: handleDelete.bind(null, row),
},
},
@@ -197,7 +244,7 @@
{
label: '寮�濮嬬敓浜�',
auth: ['mes:pro-batch:update'],
- ifShow: row.status === MesProBatchStatusEnum.DRAFT,
+ ifShow: row.status === MesProBatchStatusEnum.DRAFT && !!row.code,
popConfirm: {
title: '纭寮�濮嬬敓浜ц鎵规鍚楋紵',
confirm: () =>
diff --git a/src/views/mes/pro/batch/modules/form.vue b/src/views/mes/pro/batch/modules/form.vue
index 2e45243..6242291 100644
--- a/src/views/mes/pro/batch/modules/form.vue
+++ b/src/views/mes/pro/batch/modules/form.vue
@@ -15,7 +15,12 @@
import { useVbenForm } from "#/adapter/form";
import { TableAction, useVbenVxeGrid } from "#/adapter/vxe-table";
- import { createBatch, getBatch, updateBatch } from "#/api/mes/pro/batch";
+ import {
+ createBatch,
+ fillBatchInfo,
+ getBatch,
+ updateBatch,
+ } from "#/api/mes/pro/batch";
import { $t } from "#/locales";
import { UserSelect } from "#/views/system/user/components";
@@ -33,7 +38,7 @@
const formData = ref<MesProBatchApi.Batch>();
const isEditable = computed(() =>
- ["create", "update"].includes(formType.value)
+ ["create", "update", "fill"].includes(formType.value)
);
const getTitle = computed(() => {
@@ -43,6 +48,9 @@
}
case "update": {
return $t("ui.actionTitle.edit", ["鐢熶骇鎵规"]);
+ }
+ case "fill": {
+ return "琛ュ綍鎵规淇℃伅";
}
default: {
return $t("ui.actionTitle.create", ["鐢熶骇鎵规"]);
@@ -177,7 +185,9 @@
modalApi.lock();
try {
const data = (await formApi.getValues()) as MesProBatchApi.Batch;
- if (formData.value?.id) {
+ if (formType.value === "fill") {
+ await fillBatchInfo({ ...data, id: formData.value!.id, workers });
+ } else if (formData.value?.id) {
await updateBatch({ ...data, id: formData.value.id, workers });
} else {
await createBatch({ ...data, workers });
diff --git a/src/views/mes/pro/batch/modules/pre-generate.vue b/src/views/mes/pro/batch/modules/pre-generate.vue
new file mode 100644
index 0000000..ebb1725
--- /dev/null
+++ b/src/views/mes/pro/batch/modules/pre-generate.vue
@@ -0,0 +1,80 @@
+<script lang="ts" setup>
+ import type { VbenFormSchema } from "#/adapter/form";
+ import type { MesProBatchApi } from "#/api/mes/pro/batch";
+
+ import { useVbenModal } from "@vben/common-ui";
+
+ import { message } from "ant-design-vue";
+
+ import { useVbenForm } from "#/adapter/form";
+ import { preGenerateBatch } from "#/api/mes/pro/batch";
+
+ defineOptions({ name: "MesProBatchPreGenerate" });
+
+ const emit = defineEmits(["success"]);
+
+ const [Form, formApi] = useVbenForm({
+ commonConfig: {
+ componentProps: {
+ class: "w-full",
+ },
+ labelWidth: 100,
+ },
+ layout: "horizontal",
+ schema: [],
+ showDefaultActions: false,
+ });
+
+ const [Modal, modalApi] = useVbenModal({
+ async onConfirm() {
+ const { valid } = await formApi.validate();
+ if (!valid) return;
+ modalApi.lock();
+ try {
+ const values = await formApi.getValues();
+ const result = await preGenerateBatch({
+ count: values.count,
+ remark: values.remark,
+ });
+ message.success(`宸茬敓鎴� ${result.length} 涓复鏃舵壒娆$爜`);
+ emit("success", result);
+ await modalApi.close();
+ } finally {
+ modalApi.unlock();
+ }
+ },
+ onOpenChange(isOpen: boolean) {
+ if (!isOpen) return;
+ const schema: VbenFormSchema[] = [
+ {
+ fieldName: "count",
+ label: "鐢熸垚涓暟",
+ component: "InputNumber",
+ componentProps: {
+ class: "!w-full",
+ min: 1,
+ placeholder: "璇疯緭鍏ラ渶瑕佺敓鎴愮殑鎵规涓暟",
+ precision: 0,
+ },
+ rules: "required",
+ },
+ {
+ fieldName: "remark",
+ label: "澶囨敞",
+ component: "Textarea",
+ componentProps: {
+ placeholder: "璇疯緭鍏ュ娉�",
+ rows: 2,
+ },
+ },
+ ];
+ formApi.setState({ schema });
+ },
+ });
+</script>
+
+<template>
+ <Modal title="棰勭敓鎴愭壒娆′簩缁寸爜" class="w-2/5">
+ <Form class="mx-4" />
+ </Modal>
+</template>
\ No newline at end of file
diff --git a/src/views/mes/pro/components/qr-trace-modal.vue b/src/views/mes/pro/components/qr-trace-modal.vue
index 710a2e7..f94946a 100644
--- a/src/views/mes/pro/components/qr-trace-modal.vue
+++ b/src/views/mes/pro/components/qr-trace-modal.vue
@@ -35,13 +35,19 @@
const traceTypeLabel = ref("");
- /** 璇嗗埆浜岀淮鐮佸唴瀹圭被鍨嬶細鎵规鍙� / 鎵樼洏鐮� / 琚嬬爜 */
+ /** 璇嗗埆浜岀淮鐮佸唴瀹圭被鍨嬶細鎵规鍙凤紙鍚复鏃舵壒娆$爜锛�/ 鎵樼洏鐮侊紙鍚复鏃舵墭鐩樼爜锛�/ 琚嬬爜 */
function resolveCodeType(raw: string): TraceType | undefined {
const value = raw.trim().toUpperCase();
+ if (/^PB-\d{8}$/.test(value)) {
+ return "batch";
+ }
+ if (/^PL-\d{8}$/.test(value)) {
+ return "pallet";
+ }
if (/^.*-P\d{2}$/.test(value)) {
return "pallet";
}
- if (/^.*-\d{4}$/.test(value)) {
+ if (/^BAG-\d{8}$/.test(value) || /^.*-\d{4}$/.test(value)) {
return "bag";
}
return "batch";
@@ -125,7 +131,7 @@
if (traceType.value === "pallet" && palletTrace.value) {
const d = palletTrace.value;
return [
- { label: "鎵樼洏鐮�", value: d.code || "" },
+ { label: "鎵樼洏鐮�", value: d.code || d.tempCode || "" },
{ label: "鎵樼洏搴忓彿", value: d.palletNo ? String(d.palletNo) : "" },
{ label: "鎵规鍙�", value: d.batchCode || "" },
{ label: "鍝佺", value: d.itemName || "" },
@@ -141,7 +147,7 @@
if (batchTrace.value) {
const d = batchTrace.value;
return [
- { label: "鎵规鍙�", value: d.code || "" },
+ { label: "鎵规鍙�", value: d.code || d.tempCode || "" },
{ label: "鍝佺", value: d.itemName || "" },
{ label: "瑙勬牸", value: d.itemSpecification || "" },
{
@@ -357,7 +363,12 @@
schema: [
{
field: "code",
- label: "鎵樼洏鐮侊紙浜岀淮鐮佸唴瀹癸級",
+ label: "鎵樼洏鐮侊紙姝e紡鎵樼洏鐮侊級",
+ span: 2,
+ },
+ {
+ field: "tempCode",
+ label: "涓存椂鎵樼洏鐮侊紙鏈粦瀹氭壒娆★級",
span: 2,
},
{
@@ -419,7 +430,12 @@
schema: [
{
field: "code",
- label: "鎵规鍙凤紙浜岀淮鐮佸唴瀹癸級",
+ label: "鎵规鍙凤紙姝e紡鎵规鍙凤級",
+ span: 2,
+ },
+ {
+ field: "tempCode",
+ label: "涓存椂鎵规鐮侊紙寰呰ˉ褰曪級",
span: 2,
},
{
@@ -502,6 +518,22 @@
<p class="text-lg font-bold break-all">{{ currentCode }}</p>
<p class="mt-1 text-xs text-gray-500">
鐮佺被鍨嬶細{{ traceTypeLabel }}
+ <Tag
+ v-if="traceType === 'batch' && batchTrace && !batchTrace.code"
+ color="warning"
+ class="ml-2"
+ >
+ 寰呰ˉ褰�
+ </Tag>
+ <Tag
+ v-else-if="
+ traceType === 'pallet' && palletTrace && !palletTrace.code
+ "
+ color="warning"
+ class="ml-2"
+ >
+ 鏈粦瀹氭壒娆�
+ </Tag>
</p>
</div>
</div>
diff --git a/src/views/mes/pro/pallet/data.ts b/src/views/mes/pro/pallet/data.ts
index c7f1ac0..7ac44fb 100644
--- a/src/views/mes/pro/pallet/data.ts
+++ b/src/views/mes/pro/pallet/data.ts
@@ -53,11 +53,13 @@
/** 鍒楄〃鐨勫瓧娈� */
export function useGridColumns(): VxeTableGridOptions<MesProPalletApi.Pallet>['columns'] {
return [
+ { type: 'checkbox', width: 50 },
{
field: 'code',
title: '鎵樼洏鐮�',
fixed: 'left',
minWidth: 210,
+ slots: { default: 'code' },
},
{
field: 'palletNo',
@@ -68,6 +70,7 @@
field: 'batchCode',
title: '鎵规鍙�',
minWidth: 190,
+ slots: { default: 'batchCode' },
},
{
field: 'capacity',
@@ -101,7 +104,7 @@
},
{
title: '鎿嶄綔',
- width: 200,
+ width: 350,
fixed: 'right',
slots: { default: 'actions' },
},
diff --git a/src/views/mes/pro/pallet/index.vue b/src/views/mes/pro/pallet/index.vue
index 403a339..a34a272 100644
--- a/src/views/mes/pro/pallet/index.vue
+++ b/src/views/mes/pro/pallet/index.vue
@@ -5,18 +5,20 @@
import { Page, useVbenModal } from "@vben/common-ui";
import { downloadFileFromBlobPart } from "@vben/utils";
- import { message } from "ant-design-vue";
+ import { message, Modal, Tag } from "ant-design-vue";
import { ACTION_ICON, TableAction, useVbenVxeGrid } from "#/adapter/vxe-table";
import {
deletePallet,
exportPalletExcel,
exportPalletQr,
+ exportPalletQrByIds,
getPalletPage,
} from "#/api/mes/pro/pallet";
import { $t } from "#/locales";
import { useGridColumns, useGridFormSchema } from "./data";
+ import BindBatchModal from "./modules/bind-batch.vue";
import GenerateModal from "./modules/generate-form.vue";
import QrTraceModal from "../components/qr-trace-modal.vue";
@@ -24,6 +26,11 @@
const [GenerateFormModal, generateFormModalApi] = useVbenModal({
connectedComponent: GenerateModal,
+ destroyOnClose: true,
+ });
+
+ const [BindBatchFormModal, bindBatchFormModalApi] = useVbenModal({
+ connectedComponent: BindBatchModal,
destroyOnClose: true,
});
@@ -37,9 +44,18 @@
gridApi.query();
}
- /** 鎵归噺鐢熸垚鎵樼洏鐮� */
+ /** 鎵归噺棰勭敓鎴愭墭鐩樼爜 */
function handleCreate() {
generateFormModalApi.open();
+ }
+
+ /** 棰勭敓鎴愭垚鍔燂細灞曠ず鐢熸垚鐨勪复鏃舵墭鐩樼爜 */
+ function handlePreGenerateSuccess(result: { id: number; tempCode: string }[]) {
+ Modal.success({
+ title: "棰勭敓鎴愪复鏃舵墭鐩樼爜鎴愬姛",
+ content: result.map((item) => item.tempCode).join("\n"),
+ centered: true,
+ });
}
/** 鎵爜杩芥函 */
@@ -47,9 +63,44 @@
qrTraceQueryModalApi.open();
}
- /** 鏌ョ湅浜岀淮鐮侊紙琛屽唴棰勫~鐮佸�硷級 */
+ /** 鑾峰彇鎵樼洏鏄剧ず鐢ㄧ殑鐮佸�硷紙姝e紡鎵樼洏鐮佷紭鍏堬紝鍏舵涓存椂鎵樼洏鐮侊級 */
+ function getDisplayCode(row: MesProPalletApi.Pallet) {
+ return row.code || row.tempCode || "";
+ }
+
+ /** 鏌ョ湅浜岀淮鐮侊紙琛屽唴棰勫~鐮佸�硷紝涓存椂鎵樼洏鐢ㄤ复鏃舵墭鐩樼爜锛� */
function handleViewQr(row: MesProPalletApi.Pallet) {
- qrTraceQueryModalApi.setData({ code: row.code }).open();
+ qrTraceQueryModalApi.setData({ code: getDisplayCode(row) }).open();
+ }
+
+ /** 鑾峰彇鍕鹃�夌殑涓存椂鎵樼洏璁板綍 */
+ function getSelectedTempPallets(): MesProPalletApi.Pallet[] | undefined {
+ const records = [
+ ...(gridApi.grid.getCheckboxReserveRecords?.() ?? []),
+ ...(gridApi.grid.getCheckboxRecords?.() ?? []),
+ ] as MesProPalletApi.Pallet[];
+ const uniqueRecords = [
+ ...new Map(records.map((record) => [record.id, record])).values(),
+ ];
+ const tempRecords = uniqueRecords.filter((record) => !record.batchId);
+ if (uniqueRecords.length === 0) {
+ message.warning("璇疯嚦灏戝嬀閫変竴鏉℃墭鐩樼爜璁板綍");
+ return undefined;
+ }
+ if (tempRecords.length === 0) {
+ message.warning("鍕鹃�夌殑璁板綍鍧囧凡缁戝畾鎵规锛屾棤闇�缁戝畾");
+ return undefined;
+ }
+ return tempRecords;
+ }
+
+ /** 缁戝畾鎵规 */
+ function handleBindBatch() {
+ const records = getSelectedTempPallets();
+ if (!records) return;
+ bindBatchFormModalApi
+ .setData({ ids: records.map((record) => record.id!) })
+ .open();
}
/** 瀵煎嚭浜岀淮鐮� ZIP锛堟寜褰撳墠鏌ヨ鏉′欢鐨勬壒娆★級 */
@@ -63,10 +114,19 @@
downloadFileFromBlobPart({ fileName: "鎵樼洏鐮佷簩缁寸爜.zip", source: data });
}
+ /** 瀵煎嚭鍗曚釜鎵樼洏鐮佷簩缁寸爜 ZIP锛堟敮鎸佹湭缁戝畾鎵规鐨勪复鏃舵墭鐩橈級 */
+ async function handleExportQrById(row: MesProPalletApi.Pallet) {
+ const data = await exportPalletQrByIds([row.id!]);
+ downloadFileFromBlobPart({
+ fileName: `鎵樼洏鐮佷簩缁寸爜-${getDisplayCode(row)}.zip`,
+ source: data,
+ });
+ }
+
/** 鍒犻櫎鎵樼洏鐮� */
async function handleDelete(row: MesProPalletApi.Pallet) {
await deletePallet(row.id!);
- message.success($t("ui.actionMessage.deleteSuccess", [row.code]));
+ message.success($t("ui.actionMessage.deleteSuccess", [getDisplayCode(row)]));
handleRefresh();
}
@@ -81,6 +141,10 @@
schema: useGridFormSchema(),
},
gridOptions: {
+ checkboxConfig: {
+ highlight: true,
+ reserve: true,
+ },
columns: useGridColumns(),
height: "auto",
keepSource: true,
@@ -109,17 +173,24 @@
<template>
<Page auto-content-height>
- <GenerateFormModal @success="handleRefresh" />
+ <GenerateFormModal @success="handlePreGenerateSuccess" />
+ <BindBatchFormModal @success="handleRefresh" />
<QrTraceQueryModal />
<Grid table-title="鎵樼洏鐮佸垪琛�">
<template #toolbar-tools>
<TableAction :actions="[
{
- label: '鎵归噺鐢熸垚',
+ label: '棰勭敓鎴愪簩缁寸爜',
type: 'primary',
icon: ACTION_ICON.ADD,
auth: ['mes:pro-pallet:create'],
onClick: handleCreate,
+ },
+ {
+ label: '缁戝畾鎵规',
+ icon: ACTION_ICON.EDIT,
+ auth: ['mes:pro-pallet:update'],
+ onClick: handleBindBatch,
},
{
label: '鎵爜杩芥函',
@@ -142,6 +213,14 @@
},
]" />
</template>
+ <template #code="{ row }">
+ <span>{{ getDisplayCode(row) }}</span>
+ <Tag v-if="!row.code" color="warning">鏈粦瀹氭壒娆�</Tag>
+ </template>
+ <template #batchCode="{ row }">
+ <span v-if="row.batchCode">{{ row.batchCode }}</span>
+ <Tag v-else color="warning">鏈粦瀹氭壒娆�</Tag>
+ </template>
<template #actions="{ row }">
<TableAction :actions="[
{
@@ -151,6 +230,13 @@
onClick: handleViewQr.bind(null, row),
},
{
+ label: '瀵煎嚭浜岀淮鐮�',
+ type: 'link',
+ icon: ACTION_ICON.DOWNLOAD,
+ auth: ['mes:pro-pallet:export'],
+ onClick: handleExportQrById.bind(null, row),
+ },
+ {
label: $t('common.delete'),
type: 'link',
danger: true,
@@ -158,7 +244,7 @@
auth: ['mes:pro-pallet:delete'],
ifShow: !row.bagCount,
popConfirm: {
- title: $t('ui.actionMessage.deleteConfirm', [row.code]),
+ title: $t('ui.actionMessage.deleteConfirm', [getDisplayCode(row)]),
confirm: handleDelete.bind(null, row),
},
},
diff --git a/src/views/mes/pro/pallet/modules/bind-batch.vue b/src/views/mes/pro/pallet/modules/bind-batch.vue
new file mode 100644
index 0000000..426168d
--- /dev/null
+++ b/src/views/mes/pro/pallet/modules/bind-batch.vue
@@ -0,0 +1,88 @@
+<script lang="ts" setup>
+ import type { VbenFormSchema } from "#/adapter/form";
+
+ import { useVbenModal } from "@vben/common-ui";
+ import { MesProBatchStatusEnum } from "@vben/constants";
+
+ import { message } from "ant-design-vue";
+
+ import { useVbenForm } from "#/adapter/form";
+ import { getBatchSimpleList } from "#/api/mes/pro/batch";
+ import { bindPalletBatch } from "#/api/mes/pro/pallet";
+ import { $t } from "#/locales";
+
+ defineOptions({ name: "MesProPalletBindBatch" });
+
+ interface ModalData {
+ ids: number[];
+ }
+
+ const emit = defineEmits(["success"]);
+
+ const [Form, formApi] = useVbenForm({
+ commonConfig: {
+ componentProps: {
+ class: "w-full",
+ },
+ labelWidth: 100,
+ },
+ layout: "horizontal",
+ schema: [],
+ showDefaultActions: false,
+ });
+
+ const [Modal, modalApi] = useVbenModal({
+ async onConfirm() {
+ const { valid } = await formApi.validate();
+ if (!valid) return;
+ const data = modalApi.getData<ModalData>();
+ const values = await formApi.getValues();
+ modalApi.lock();
+ try {
+ await bindPalletBatch({ batchId: values.batchId, ids: data.ids });
+ message.success($t("ui.actionMessage.operationSuccess"));
+ emit("success");
+ await modalApi.close();
+ } finally {
+ modalApi.unlock();
+ }
+ },
+ async onOpenChange(isOpen: boolean) {
+ if (!isOpen) return;
+ modalApi.lock();
+ try {
+ // 浠呭凡琛ュ綍姝e紡淇℃伅涓旂敓浜т腑鐨勬壒娆″厑璁哥粦瀹�
+ const batches = await getBatchSimpleList();
+ const options = batches
+ .filter(
+ (batch) =>
+ batch.status === MesProBatchStatusEnum.PRODUCING && batch.code,
+ )
+ .map((batch) => ({ label: batch.code!, value: batch.id! }));
+ const schema: VbenFormSchema[] = [
+ {
+ fieldName: "batchId",
+ label: "鐢熶骇鎵规",
+ component: "Select",
+ componentProps: {
+ options,
+ optionFilterProp: "label",
+ placeholder: "璇烽�夋嫨宸茶ˉ褰曚笖鐢熶骇涓殑鎵规",
+ showSearch: true,
+ },
+ rules: "selectRequired",
+ },
+ ];
+ await formApi.setState({ schema });
+ } finally {
+ modalApi.unlock();
+ }
+ },
+ });
+</script>
+
+<template>
+ <Modal title="鎵樼洏鐮佺粦瀹氱敓浜ф壒娆�" class="w-2/5">
+ <Form class="mx-4" />
+ </Modal>
+</template>
\ No newline at end of file
diff --git a/src/views/mes/pro/pallet/modules/generate-form.vue b/src/views/mes/pro/pallet/modules/generate-form.vue
index c34f952..e094e17 100644
--- a/src/views/mes/pro/pallet/modules/generate-form.vue
+++ b/src/views/mes/pro/pallet/modules/generate-form.vue
@@ -1,69 +1,16 @@
<script lang="ts" setup>
import type { VbenFormSchema } from "#/adapter/form";
- import type { MesProPalletApi } from "#/api/mes/pro/pallet";
import { useVbenModal } from "@vben/common-ui";
- import { MesProBatchStatusEnum } from "@vben/constants";
import { message } from "ant-design-vue";
import { useVbenForm } from "#/adapter/form";
- import { getBatchSimpleList } from "#/api/mes/pro/batch";
- import { batchCreatePallet } from "#/api/mes/pro/pallet";
+ import { preGeneratePallet } from "#/api/mes/pro/pallet";
defineOptions({ name: "MesProPalletGenerateForm" });
const emit = defineEmits(["success"]);
-
- /** 鏋勫缓琛ㄥ崟锛堟壒娆′笅鎷夐�夐」鐢卞閮ㄥ姞杞芥敞鍏ワ級 */
- function buildSchema(batchOptions: { label: string; value: number }[]): VbenFormSchema[] {
- return [
- {
- fieldName: "batchId",
- label: "鐢熶骇鎵规",
- component: "Select",
- componentProps: {
- options: batchOptions,
- optionFilterProp: "label",
- placeholder: "璇烽�夋嫨鐢熶骇涓殑鎵规",
- showSearch: true,
- },
- rules: "selectRequired",
- },
- {
- fieldName: "count",
- label: "鐢熸垚鏁伴噺",
- component: "InputNumber",
- componentProps: {
- class: "!w-full",
- min: 1,
- placeholder: "璇疯緭鍏ラ渶瑕佺敓鎴愮殑鎵樼洏鏁伴噺",
- precision: 0,
- },
- rules: "required",
- },
- {
- fieldName: "capacity",
- label: "鍙琚嬫暟",
- component: "InputNumber",
- componentProps: {
- class: "!w-full",
- min: 1,
- placeholder: "璇疯緭鍏ユ瘡鎵樼洏鍙琚嬫暟锛堣/鎵樼洏锛�",
- precision: 0,
- },
- },
- {
- fieldName: "remark",
- label: "澶囨敞",
- component: "Textarea",
- componentProps: {
- placeholder: "璇疯緭鍏ュ娉�",
- rows: 2,
- },
- },
- ];
- }
const [Form, formApi] = useVbenForm({
commonConfig: {
@@ -83,40 +30,62 @@
if (!valid) return;
modalApi.lock();
try {
- const values =
- (await formApi.getValues()) as MesProPalletApi.BatchCreateParams;
- const ids = await batchCreatePallet(values);
- message.success(`宸叉垚鍔熺敓鎴� ${ids.length} 涓墭鐩樼爜`);
- emit("success");
+ const values = await formApi.getValues();
+ const result = await preGeneratePallet({
+ count: values.count,
+ capacity: values.capacity,
+ remark: values.remark,
+ });
+ message.success(`宸茬敓鎴� ${result.length} 涓复鏃舵墭鐩樼爜`);
+ emit("success", result);
await modalApi.close();
} finally {
modalApi.unlock();
}
},
- async onOpenChange(isOpen: boolean) {
+ onOpenChange(isOpen: boolean) {
if (!isOpen) return;
- modalApi.lock();
- try {
- // 浠呯敓浜т腑鐨勬壒娆″厑璁哥敓鎴愭墭鐩樼爜
- const batches = await getBatchSimpleList();
- const options = batches
- .filter(
- (batch) => batch.status === MesProBatchStatusEnum.PRODUCING
- )
- .map((batch) => ({
- label: batch.code!,
- value: batch.id!,
- }));
- await formApi.setState({ schema: buildSchema(options) });
- } finally {
- modalApi.unlock();
- }
+ const schema: VbenFormSchema[] = [
+ {
+ fieldName: "count",
+ label: "鐢熸垚鏁伴噺",
+ component: "InputNumber",
+ componentProps: {
+ class: "!w-full",
+ min: 1,
+ placeholder: "璇疯緭鍏ラ渶瑕佺敓鎴愮殑鎵樼洏鏁伴噺",
+ precision: 0,
+ },
+ rules: "required",
+ },
+ {
+ fieldName: "capacity",
+ label: "鍙琚嬫暟",
+ component: "InputNumber",
+ componentProps: {
+ class: "!w-full",
+ min: 1,
+ placeholder: "璇疯緭鍏ユ瘡鎵樼洏鍙琚嬫暟锛堣/鎵樼洏锛�",
+ precision: 0,
+ },
+ },
+ {
+ fieldName: "remark",
+ label: "澶囨敞",
+ component: "Textarea",
+ componentProps: {
+ placeholder: "璇疯緭鍏ュ娉�",
+ rows: 2,
+ },
+ },
+ ];
+ formApi.setState({ schema });
},
});
</script>
<template>
- <Modal title="鎵归噺鐢熸垚鎵樼洏鐮�" class="w-2/5">
+ <Modal title="棰勭敓鎴愭墭鐩樹簩缁寸爜" class="w-2/5">
<Form class="mx-4" />
</Modal>
-</template>
+</template>
\ No newline at end of file
--
Gitblit v1.9.3