From 91c82965b2d987452ca276e3a03b48c8dcda2ae9 Mon Sep 17 00:00:00 2001
From: 云 <2163098428@qq.com>
Date: 星期三, 19 八月 2026 11:47:26 +0800
Subject: [PATCH] config(env): 更新生产环境配置和公司名称
---
src/views/mes/pro/batch/modules/form.vue | 281 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 281 insertions(+), 0 deletions(-)
diff --git a/src/views/mes/pro/batch/modules/form.vue b/src/views/mes/pro/batch/modules/form.vue
new file mode 100644
index 0000000..2e45243
--- /dev/null
+++ b/src/views/mes/pro/batch/modules/form.vue
@@ -0,0 +1,281 @@
+<script lang="ts" setup>
+ import type { FormType } from "../data";
+
+ import type { VxeTableGridOptions } from "#/adapter/vxe-table";
+ import type { MesProBatchApi } from "#/api/mes/pro/batch";
+ import type { SystemUserApi } from "#/api/system/user";
+
+ import { computed, nextTick, ref } from "vue";
+
+ import { useVbenModal } from "@vben/common-ui";
+ import { DICT_TYPE } from "@vben/constants";
+ import { getDictOptions } from "@vben/hooks";
+
+ import { Button, Input, message, Select } from "ant-design-vue";
+
+ import { useVbenForm } from "#/adapter/form";
+ import { TableAction, useVbenVxeGrid } from "#/adapter/vxe-table";
+ import { createBatch, getBatch, updateBatch } from "#/api/mes/pro/batch";
+ import { $t } from "#/locales";
+ import { UserSelect } from "#/views/system/user/components";
+
+ import {
+ useFormSchema,
+ useWorkerEditGridColumns,
+ useWorkerReadGridColumns,
+ } from "../data";
+
+ defineOptions({ name: "MesProBatchForm" });
+
+ const emit = defineEmits(["success"]);
+
+ const formType = ref<FormType>("create");
+ const formData = ref<MesProBatchApi.Batch>();
+
+ const isEditable = computed(() =>
+ ["create", "update"].includes(formType.value)
+ );
+
+ const getTitle = computed(() => {
+ switch (formType.value) {
+ case "detail": {
+ return $t("ui.actionTitle.view", ["鐢熶骇鎵规"]);
+ }
+ case "update": {
+ return $t("ui.actionTitle.edit", ["鐢熶骇鎵规"]);
+ }
+ default: {
+ return $t("ui.actionTitle.create", ["鐢熶骇鎵规"]);
+ }
+ }
+ });
+
+ const [Form, formApi] = useVbenForm({
+ commonConfig: {
+ componentProps: {
+ class: "w-full",
+ },
+ formItemClass: "col-span-1",
+ labelWidth: 110,
+ },
+ layout: "horizontal",
+ schema: [],
+ showDefaultActions: false,
+ wrapperClass: "grid-cols-3",
+ });
+
+ // ========== 鐢熶骇浜哄憳閰嶇疆瀛愯〃 ==========
+ const [WorkerGrid, workerGridApi] = useVbenVxeGrid({
+ gridOptions: {
+ autoResize: true,
+ border: true,
+ columns: useWorkerEditGridColumns(),
+ minHeight: 160,
+ pagerConfig: { enabled: false },
+ rowConfig: { isHover: true, keyField: "_rowKey" },
+ showOverflow: true,
+ toolbarConfig: { enabled: false },
+ } as VxeTableGridOptions<MesProBatchApi.BatchWorker>,
+ });
+
+ /** 鏂板琛岀殑涓存椂琛屽彿锛堣礋鏁拌嚜澧烇紝閬垮厤涓� loadData 鐨� index 鍐茬獊锛� */
+ let workerRowSeq = 0;
+
+ /** 娣诲姞浜哄憳琛� */
+ function handleAddWorker() {
+ workerGridApi.grid.insertAt({ _rowKey: -(++workerRowSeq) }, -1);
+ }
+
+ /** 鍒犻櫎浜哄憳琛� */
+ function handleDeleteWorker(row: MesProBatchApi.BatchWorker) {
+ workerGridApi.grid.remove(row);
+ }
+
+ /** 浜哄憳閫夋嫨缂栧彿鍙樺寲锛堝崟閫夊満鏅笅鍙栫涓�涓�硷級 */
+ function handleWorkerUserIdChange(
+ value: number | number[] | undefined,
+ row: MesProBatchApi.BatchWorker
+ ) {
+ row.userId = Array.isArray(value) ? value[0] : value;
+ }
+
+ /** 浜哄憳閫夋嫨鍙樺寲鏃惰褰曞鍚嶏紙渚夸簬鏍¢獙鎻愮ず锛� */
+ function handleWorkerUserChange(
+ user: SystemUserApi.User | SystemUserApi.User[] | undefined,
+ row: MesProBatchApi.BatchWorker
+ ) {
+ row.userName = Array.isArray(user) ? user[0]?.nickname : user?.nickname;
+ }
+
+ /** 宀椾綅绫诲瀷瀛楀吀閫夐」 */
+ const workerTypeOptions = computed(() =>
+ getDictOptions(DICT_TYPE.MES_PRO_BATCH_WORKER_TYPE, "number").map(
+ (item) => ({ label: item.label, value: item.value as number })
+ )
+ );
+
+ /** 鏍¢獙骞惰幏鍙栦汉鍛橀厤缃垪琛� */
+ async function getValidWorkers(): Promise<
+ MesProBatchApi.BatchWorker[] | undefined
+ > {
+ // getData() 鍙繑鍥� loadData 鍔犺浇鐨勬暟鎹紱insertAt 鎻掑叆鐨勮闇�閫氳繃
+ // getInsertRecords() 鑾峰彇锛屽苟鎺掗櫎 getRemoveRecords() 涓凡鍒犻櫎鐨勮
+ const data = workerGridApi.grid.getData() as Array<
+ MesProBatchApi.BatchWorker & { _rowKey?: number }
+ >;
+ const removeRecords = workerGridApi.grid.getRemoveRecords() as Array<
+ MesProBatchApi.BatchWorker & { _rowKey?: number }
+ >;
+ const insertRecords = workerGridApi.grid.getInsertRecords() as Array<
+ MesProBatchApi.BatchWorker & { _rowKey?: number }
+ >;
+ const rows = [
+ ...data.filter(
+ (row) => !removeRecords.some((removed) => removed._rowKey === row._rowKey)
+ ),
+ ...insertRecords,
+ ].map(({ _rowKey, ...rest }) => rest);
+ if (rows.length === 0) {
+ message.warning("璇疯嚦灏戦厤缃竴鍚嶇敓浜т汉鍛�");
+ return undefined;
+ }
+ for (const [index, row] of rows.entries()) {
+ if (!row.userId) {
+ message.warning(`璇烽�夋嫨绗� ${index + 1} 琛岀殑鐢熶骇浜哄憳`);
+ return undefined;
+ }
+ if (!row.workerType) {
+ message.warning(`璇烽�夋嫨绗� ${index + 1} 琛岀殑宀椾綅绫诲瀷`);
+ return undefined;
+ }
+ }
+ return rows;
+ }
+
+ /** 绛夊緟浜哄憳瀛愯〃 grid 鎸傝浇瀹屾垚锛堝脊绐楁墦寮�鐬棿 onOpenChange 鍐呴儴琛ㄦ牸鍙兘灏氭湭鎸傝浇锛� */
+ async function waitWorkerGridReady(): Promise<void> {
+ await nextTick();
+ for (let i = 0; i < 100; i++) {
+ if (typeof workerGridApi.grid?.loadData === "function") {
+ return;
+ }
+ await new Promise((resolve) => setTimeout(resolve, 30));
+ }
+ }
+
+ const [Modal, modalApi] = useVbenModal({
+ showCancelButton: false, // 鑷畾涔夊彇娑�/鍏抽棴鎸夐挳锛岀鐢ㄩ粯璁ゅ彇娑堟寜閽伩鍏嶉噸澶�
+ async onConfirm() {
+ if (!isEditable.value) {
+ await modalApi.close();
+ return;
+ }
+ const { valid } = await formApi.validate();
+ if (!valid) return;
+ const workers = await getValidWorkers();
+ if (!workers) return;
+ modalApi.lock();
+ try {
+ const data = (await formApi.getValues()) as MesProBatchApi.Batch;
+ if (formData.value?.id) {
+ await updateBatch({ ...data, id: formData.value.id, workers });
+ } else {
+ await createBatch({ ...data, workers });
+ }
+ message.success($t("ui.actionMessage.operationSuccess"));
+ emit("success");
+ await modalApi.close();
+ } finally {
+ modalApi.unlock();
+ }
+ },
+ async onOpenChange(isOpen: boolean) {
+ if (!isOpen) {
+ formData.value = undefined;
+ return;
+ }
+ const data = modalApi.getData<{ formType: FormType; id?: number }>();
+ formType.value = data.formType;
+ formApi.setState({ schema: useFormSchema(formType.value) });
+ // 鏍规嵁琛ㄥ崟鎬佸垏鎹汉鍛樺瓙琛ㄥ垪
+ workerGridApi.setGridOptions({
+ columns: isEditable.value
+ ? useWorkerEditGridColumns()
+ : useWorkerReadGridColumns(),
+ });
+ if (data?.id) {
+ modalApi.lock();
+ try {
+ formData.value = await getBatch(data.id);
+ await formApi.setValues(formData.value);
+ const workers = (formData.value.workers ?? []).map(
+ (worker, index) => ({ ...worker, _rowKey: worker.id ?? index })
+ );
+ await waitWorkerGridReady();
+ await workerGridApi.grid.loadData(workers);
+ } finally {
+ modalApi.unlock();
+ }
+ } else {
+ await waitWorkerGridReady();
+ await workerGridApi.grid.loadData([]);
+ }
+ },
+ });
+</script>
+
+<template>
+ <Modal :title="getTitle"
+ class="w-3/5"
+ content-class="!max-h-[80vh] overflow-y-auto">
+ <Form class="mx-4" />
+ <div class="mx-4 mb-4">
+ <div class="mb-2 flex items-center justify-between">
+ <span class="font-medium">鐢熶骇浜哄憳閰嶇疆</span>
+ <Button v-if="isEditable" size="small" type="primary" @click="handleAddWorker">
+ 娣诲姞浜哄憳
+ </Button>
+ </div>
+ <WorkerGrid>
+ <template #userId="{ row }">
+ <UserSelect
+ :model-value="row.userId"
+ placeholder="璇烽�夋嫨鐢熶骇浜哄憳"
+ @update:model-value="handleWorkerUserIdChange($event, row)"
+ @change="handleWorkerUserChange($event, row)"
+ />
+ </template>
+ <template #workerType="{ row }">
+ <Select
+ v-model:value="row.workerType"
+ :options="workerTypeOptions"
+ class="w-full"
+ placeholder="璇烽�夋嫨宀椾綅绫诲瀷"
+ />
+ </template>
+ <template #remark="{ row }">
+ <Input v-model:value="row.remark" placeholder="璇疯緭鍏ュ娉�" />
+ </template>
+ <template #actions="{ row }">
+ <TableAction
+ :actions="[
+ {
+ label: $t('common.delete'),
+ type: 'link',
+ danger: true,
+ onClick: handleDeleteWorker.bind(null, row),
+ },
+ ]"
+ />
+ </template>
+ </WorkerGrid>
+ </div>
+ <template #append-footer>
+ <div class="flex gap-2">
+ <Button @click="modalApi.close()">
+ {{ isEditable ? '鍙栨秷' : '鍏抽棴' }}
+ </Button>
+ </div>
+ </template>
+ </Modal>
+</template>
--
Gitblit v1.9.3