From 6fc42b742367a9a042104a5ef9231ba639a8752a Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期三, 03 六月 2026 13:44:02 +0800
Subject: [PATCH] 英泽防锈 1.审批管理页面添加逻辑修改 2.车辆管理页面开发联调

---
 src/views/officeProcessAutomation/ApproveManage/vehicle-apply/index.vue |  263 +++++++++++++++++++++++++++++++++++----------------
 1 files changed, 179 insertions(+), 84 deletions(-)

diff --git a/src/views/officeProcessAutomation/ApproveManage/vehicle-apply/index.vue b/src/views/officeProcessAutomation/ApproveManage/vehicle-apply/index.vue
index 3d18260..5c47ef3 100644
--- a/src/views/officeProcessAutomation/ApproveManage/vehicle-apply/index.vue
+++ b/src/views/officeProcessAutomation/ApproveManage/vehicle-apply/index.vue
@@ -19,7 +19,7 @@
             </el-tag>
           </template>
         </el-table-column>
-        <el-table-column prop="currentMileage" label="褰撳墠鍏噷鏁�" width="120" align="center" />
+        <el-table-column prop="returnMileage" label="褰撳墠鍏噷鏁�" width="120" align="center" />
         <el-table-column label="鎿嶄綔" width="150" align="center" fixed="right">
           <template #default="scope">
             <el-button link type="primary" size="small" @click="openVehicleDialog(scope.row)">缂栬緫</el-button>
@@ -162,9 +162,9 @@
             <el-option label="淇濆吇涓�" value="maintenance" />
           </el-select>
         </el-form-item>
-        <el-form-item label="褰撳墠鍏噷鏁�" prop="currentMileage">
+        <el-form-item label="褰撳墠鍏噷鏁�" prop="returnMileage">
           <el-input-number
-            v-model="vehicleForm.currentMileage"
+            v-model="vehicleForm.returnMileage"
             :min="0"
             :precision="1"
             :step="0.1"
@@ -175,8 +175,8 @@
         </el-form-item>
       </el-form>
       <template #footer>
-        <el-button @click="vehicleDialog.visible = false">鍙栨秷</el-button>
         <el-button type="primary" :loading="vehicleSaveLoading" @click="saveVehicle">淇濆瓨</el-button>
+        <el-button @click="vehicleDialog.visible = false">鍙栨秷</el-button>
       </template>
     </el-dialog>
 
@@ -245,6 +245,17 @@
             style="width: 100%"
           />
         </el-form-item>
+        <el-form-item label="鍏噷鏁�" prop="mileage" required>
+          <el-input-number
+            v-model="returnForm.mileage"
+            :min="0"
+            :precision="1"
+            :step="0.1"
+            controls-position="right"
+            style="width: 100%"
+            placeholder="璇疯緭鍏ュ綊杩樻椂鍏噷鏁�"
+          />
+        </el-form-item>
         <el-form-item label="闄勪欢">
           <AttachmentUploadImage
             v-model:fileList="returnForm.returnStorageBlobDTOs"
@@ -256,6 +267,80 @@
       <template #footer>
         <el-button type="primary" :loading="returnLoading" @click="submitReturn">纭褰掕繕</el-button>
         <el-button @click="returnDialog.visible = false">鍙栨秷</el-button>
+      </template>
+    </el-dialog>
+
+    <!-- 鍊熷嚭璁板綍璇︽儏瀵硅瘽妗� -->
+    <el-dialog
+      v-model="borrowDetailDialog.visible"
+      title="鍊熷嚭璁板綍璇︽儏"
+      width="700px"
+      :close-on-click-modal="false"
+    >
+      <el-descriptions :column="2" border v-loading="borrowDetailDialog.loading">
+        <el-descriptions-item label="鍊熷嚭鍗曞彿" :span="1">
+          {{ borrowDetailDialog.data.borrowNo || '鈥�' }}
+        </el-descriptions-item>
+        <el-descriptions-item label="杞︾墝鍙�" :span="1">
+          {{ borrowDetailDialog.data.vehiclePlateNumber || '鈥�' }}
+        </el-descriptions-item>
+        <el-descriptions-item label="鐢宠浜�" :span="1">
+          {{ borrowDetailDialog.data.applicantName || '鈥�' }}
+        </el-descriptions-item>
+        <el-descriptions-item label="鍊熷嚭鐘舵��" :span="1">
+          <el-tag :type="borrowStatusTagType(borrowDetailDialog.data.borrowStatus)" size="small">
+            {{ borrowStatusLabel(borrowDetailDialog.data.borrowStatus) }}
+          </el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="鍊熷嚭鍘熷洜" :span="2">
+          {{ borrowDetailDialog.data.borrowReason || '鈥�' }}
+        </el-descriptions-item>
+        <el-descriptions-item label="鍊熷嚭鏃堕棿" :span="1">
+          {{ borrowDetailDialog.data.borrowStartTime || '鈥�' }}
+        </el-descriptions-item>
+        <el-descriptions-item label="璁″垝褰掕繕" :span="1">
+          {{ borrowDetailDialog.data.plannedReturnTime || '鈥�' }}
+        </el-descriptions-item>
+        <el-descriptions-item label="瀹為檯褰掕繕" :span="1">
+          {{ borrowDetailDialog.data.actualReturnTime || '鈥�' }}
+        </el-descriptions-item>
+        <el-descriptions-item label="寤舵湡鐘舵��" :span="1">
+          <el-tag :type="extendStatusTagType(borrowDetailDialog.data.extendStatus)" size="small">
+            {{ extendStatusLabel(borrowDetailDialog.data.extendStatus) }}
+          </el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="鍒涘缓鏃堕棿" :span="1">
+          {{ borrowDetailDialog.data.createTime || '鈥�' }}
+        </el-descriptions-item>
+        <el-descriptions-item label="鍊熷嚭闄勪欢" :span="2">
+          <template v-if="borrowDetailDialog.data.borrowStorageBlobVOList?.length">
+            <el-tag
+              v-for="(file, i) in borrowDetailDialog.data.borrowStorageBlobVOList"
+              :key="'borrow-' + i"
+              class="mr8 mb8"
+              type="info"
+            >
+              {{ file.fileName || file.blobName || '闄勪欢' + (i + 1) }}
+            </el-tag>
+          </template>
+          <span v-else>鏃�</span>
+        </el-descriptions-item>
+        <el-descriptions-item label="褰掕繕闄勪欢" :span="2">
+          <template v-if="borrowDetailDialog.data.returnStorageBlobVOList?.length">
+            <el-tag
+              v-for="(file, i) in borrowDetailDialog.data.returnStorageBlobVOList"
+              :key="'return-' + i"
+              class="mr8 mb8"
+              type="info"
+            >
+              {{ file.fileName || file.blobName || '闄勪欢' + (i + 1) }}
+            </el-tag>
+          </template>
+          <span v-else>鏃�</span>
+        </el-descriptions-item>
+      </el-descriptions>
+      <template #footer>
+        <el-button @click="borrowDetailDialog.visible = false">鍏� 闂�</el-button>
       </template>
     </el-dialog>
   </div>
@@ -275,12 +360,15 @@
   saveBorrow,
   listBorrowPage,
   deleteBorrow,
+  returnVehicle,
+  delayBorrow,
 } from "@/api/officeProcessAutomation/vehicle.js";
 import FormPayloadFields from "../approve-list/components/FormPayloadFields.vue";
 import ApprovalInstanceDetailDialog from "../approve-shared/components/ApprovalInstanceDetailDialog.vue";
 import ApprovalInstanceSubmitDialog from "../approve-shared/components/ApprovalInstanceSubmitDialog.vue";
 import ApprovalTemplateBindDialog from "../approve-shared/components/ApprovalTemplateBindDialog.vue";
 import { buildInstanceTableColumns } from "../approve-shared/approvalInstanceFormConfigTable.js";
+import { buildInstanceFormConfigJson } from "../approve-list/approveListConstants.js";
 import { APPROVAL_MODULE_KEYS } from "../approve-shared/approvalModuleRegistry.js";
 import { useApprovalInstanceModule } from "../approve-shared/useApprovalInstanceModule.js";
 import { useFlowUserOptions } from "../approve-shared/useFlowUserOptions.js";
@@ -304,7 +392,7 @@
   id: null,
   plateNumber: "",
   status: "idle",
-  currentMileage: 0,
+	returnMileage: 0,
 });
 const vehicleRules = {
   plateNumber: [{ required: true, message: "璇疯緭鍏ヨ溅鐗屽彿", trigger: "blur" }],
@@ -324,7 +412,7 @@
         id: item.id,
         plateNumber: item.plateNumber,
         status: mapVehicleStatusFromApi(item.status),
-        currentMileage: item.mileage || 0,
+				returnMileage: item.mileage || 0,
       }));
       vehiclePage.total = res.data?.total || 0;
     }
@@ -383,12 +471,12 @@
     vehicleForm.id = row.id;
     vehicleForm.plateNumber = row.plateNumber;
     vehicleForm.status = row.status;
-    vehicleForm.currentMileage = row.currentMileage;
+    vehicleForm.returnMileage = row.returnMileage;
   } else {
     vehicleForm.id = null;
     vehicleForm.plateNumber = "";
     vehicleForm.status = "idle";
-    vehicleForm.currentMileage = 0;
+    vehicleForm.returnMileage = 0;
   }
   vehicleDialog.visible = true;
 }
@@ -402,7 +490,7 @@
     try {
       const apiData = {
         plateNumber: vehicleForm.plateNumber,
-        mileage: vehicleForm.currentMileage,
+        mileage: vehicleForm.returnMileage,
         status: mapVehicleStatusToApi(vehicleForm.status),
       };
       
@@ -698,15 +786,9 @@
   return labelMap[status] || status;
 }
 
-// 鍒ゆ柇鏄惁鍙互寤舵湡锛堝�熷嚭涓笖鏈敵璇峰欢鏈熸垨寤舵湡宸查┏鍥烇級
+// 鍒ゆ柇鏄惁鍙互寤舵湡锛堝�熷嚭涓嵆鍙欢鏈燂級
 function canExtendBorrow(row) {
-  if (row.borrowStatus !== "BORROWING") return false;
-  if (row.extendStatus === "PENDING" || row.extendStatus === "APPROVED") return false;
-  // 杩囦簡璁″垝褰掕繕鏃堕棿鎵嶈兘寤舵湡
-  if (row.plannedReturnTime) {
-    return dayjs().isAfter(dayjs(row.plannedReturnTime));
-  }
-  return false;
+  return row.borrowStatus === "BORROWING";
 }
 
 // 鍒ゆ柇鏄惁鍙互褰掕繕锛堝�熷嚭涓級
@@ -747,8 +829,13 @@
     label: "鎿嶄綔",
     align: "center",
     fixed: "right",
-    width: 150,
+    width: 210,
     operation: [
+      {
+        name: "璇︽儏",
+        type: "text",
+        clickFun: (row) => openBorrowDetail(row),
+      },
       {
         name: "寤舵湡",
         type: "text",
@@ -790,25 +877,25 @@
       // 浠庤〃鍗曟暟鎹腑鑾峰彇鍊熷嚭淇℃伅
       const formPayload = submitForm.formPayload || {};
       const fields = submitForm.formFieldDefs || [];
-      
+
       // 鏌ユ壘杞﹁締閫夋嫨瀛楁锛堝厛灏濊瘯浣跨敤椤圭洰涓凡鏈夌殑鏌ユ壘鏂瑰紡锛屽啀鍏煎鐩存帴鍙栧�硷級
       const vehicleField = findVehicleNoField(fields);
-      
+
       // 杞﹁締閫夋嫨瀛楁鐨勫�兼槸杞︾墝鍙凤紝闇�瑕佷粠vehicleList涓牴鎹溅鐗屽彿鏌ユ壘瀵瑰簲鐨勮溅杈咺D
       // 浼樺厛浠� formPayload.vehiclePlateNumber 鑾峰彇锛屽鏋滀笉瀛樺湪鍒欓�氳繃瀛楁key鑾峰彇
-      const selectedPlateNumber = formPayload.vehiclePlateNumber || 
+      const selectedPlateNumber = formPayload.vehiclePlateNumber ||
         (vehicleField?.key ? formPayload[vehicleField.key] : null);
-      
+
       let vehicleId = null;
       if (selectedPlateNumber) {
         const selectedVehicle = vehicleList.value.find(v => v.plateNumber === selectedPlateNumber);
         vehicleId = selectedVehicle?.id;
       }
-      
+
       // 鐩存帴浣跨敤琛ㄥ崟涓殑鏃堕棿瀛楁
       const borrowStartTime = formPayload.borrowStartTime;
       const plannedReturnTime = formPayload.plannedReturnTime;
-      
+
       if (!vehicleId) {
         ElMessage.warning("璇烽�夋嫨杞﹁締");
         return;
@@ -817,16 +904,13 @@
         ElMessage.warning("璇烽�夋嫨杞﹁締浣跨敤鏃堕棿");
         return;
       }
-      
-      // 鍙皟鐢� saveBorrow 鎺ュ彛锛屼笉鍐嶈皟鐢ㄥ鎵瑰疄渚嬫彁浜�
-      // formConfig 鏄ā鏉胯鎯呮帴鍙h繑鍥炵殑鍘熷 JSON 瀛楃涓�
-      console.log('=== submitForm debug ===', {
-        templateId: submitForm.templateId,
-        templateKey: submitForm.templateKey,
-        templateSnapshotTemplateId: submitForm.templateSnapshot?.templateId,
-        formConfig: submitForm.formConfig || submitForm.templateSnapshot?.formConfig || activeTemplate.value?.formConfig,
-        'formConfig type': typeof submitForm.formConfig,
-      });
+
+      // 鏋勫缓 formConfig锛屽寘鍚ā鏉垮瓧娈靛畾涔夊拰鐢ㄦ埛濉啓鐨勮〃鍗曟暟鎹�
+      const formConfig = buildInstanceFormConfigJson(
+        submitForm.templateSnapshot || activeTemplate.value,
+        formPayload
+      );
+
       const submitData = {
         vehicleId: vehicleId,
         borrowReason: formPayload.borrowReason || formPayload.reason || '',
@@ -835,16 +919,15 @@
         borrowStatus: 'IN_APPROVAL',
         approvalTemplateId: submitForm.templateId || submitForm.templateSnapshot?.templateId || submitForm.templateKey,
         borrowStorageBlobDTOs: submitForm.storageBlobDTOs || [],
-        formConfig: submitForm.formConfig,
+        formConfig: formConfig,
       };
-      console.log('=== saveBorrow submitData ===', JSON.parse(JSON.stringify(submitData)));
       const borrowRes = await saveBorrow(submitData);
-      
+
       if (borrowRes.code !== 200) {
         ElMessage.error(borrowRes.msg || "淇濆瓨鍊熷嚭璁板綍澶辫触");
         return;
       }
-      
+
       ElMessage.success("鎻愪氦鎴愬姛");
       submitDialog.visible = false;
       fetchBorrowList();
@@ -872,6 +955,8 @@
   flowNodes: [],
   storageBlobDTOs: [],
   formFieldDefs: [],
+  formConfig: null,
+  templateSnapshot: null,
 });
 const extendSubmitFormRules = reactive({});
 const extendSubmitFormFields = ref([]);
@@ -888,10 +973,8 @@
 function openExtendDialog(row) {
   // 淇濆瓨鍘熷鎵逛俊鎭�
   extendSourceRow.id = row.id;
-  extendSourceRow.instanceNo = row.instanceNo || "";
-  // 灏濊瘯浠庡涓彲鑳界殑瀛楁鍚嶄腑鑾峰彇杞︾墝鍙�
-  const payload = row.formPayload || {};
-  extendSourceRow.vehiclePlateNumber = payload.vehicleNo || payload.plateNumber || payload.vehiclePlateNumber || payload.carNo || "";
+  extendSourceRow.instanceNo = row.instanceNo || row.borrowNo || "";
+  extendSourceRow.vehiclePlateNumber = row.vehiclePlateNumber || "";
   // 浠庤溅杈嗕娇鐢ㄦ椂闂磋绠楀師鍒版湡鏃ユ湡
   const useTimeField = findVehicleUseTimeField(row.formFieldDefs || []);
   if (useTimeField?.key && row.formPayload?.[useTimeField.key]) {
@@ -906,17 +989,18 @@
 
 // 寤舵湡妯℃澘缁戝畾纭
 function onExtendTemplateBound(payload) {
-  const { templateId, templateName, formFieldDefs, formPayload, flowNodes, templateAttachments, storageBlobDTOs } = payload;
+  const { templateId, templateName, formFieldDefs, formPayload, flowNodes, templateAttachments, storageBlobDTOs, formConfig, templateSnapshot } = payload;
   extendActiveTemplate.value = { id: templateId, name: templateName, fields: formFieldDefs };
   extendSubmitForm.templateId = templateId;
   extendSubmitForm.templateName = templateName;
   extendSubmitForm.formFieldDefs = formFieldDefs || [];
   extendSubmitFormFields.value = formFieldDefs || [];
-  // 鍒濆鍖栬〃鍗曟暟鎹�
   extendSubmitForm.formPayload = formPayload || {};
   extendSubmitForm.flowNodes = flowNodes || [];
   extendSubmitForm.templateAttachments = templateAttachments || [];
   extendSubmitForm.storageBlobDTOs = storageBlobDTOs || [];
+  extendSubmitForm.formConfig = formConfig || null;
+  extendSubmitForm.templateSnapshot = templateSnapshot || null;
   // 鎵撳紑鎻愪氦瀵硅瘽妗�
   extendSubmitDialog.visible = true;
 }
@@ -928,37 +1012,47 @@
 
 // 鎻愪氦寤舵湡鐢宠
 async function onExtendSubmit() {
-  if (!extendSubmitFormRef.value) return;
-
   extendSubmitSaving.value = true;
   try {
-    // 鏋勫缓鎻愪氦鏁版嵁
-    // formConfig 鏄ā鏉胯鎯呮帴鍙h繑鍥炵殑鍘熷 JSON 瀛楃涓�
-    const payload = {
-      ...extendSubmitForm.formPayload,
-      originalInstanceNo: extendSourceRow.instanceNo,
-      vehiclePlateNumber: extendSourceRow.vehiclePlateNumber,
-      originalEndDate: extendSourceRow.originalEndDate,
-      formConfig: extendSubmitForm.formConfig,
-    };
+    const formPayload = extendSubmitForm.formPayload || {};
 
-    // 杩欓噷璋冪敤鍒涘缓寤舵湡瀹℃壒瀹炰緥鐨凙PI
-    // await createVehicleDelayApproval({
-    //   templateId: extendSubmitForm.templateId,
-    //   formPayload: payload,
-    //   flowNodes: extendSubmitForm.flowNodes,
-    //   storageBlobDTOs: extendSubmitForm.storageBlobDTOs,
-    //   formConfig: extendSubmitForm.formFieldDefs || [],
-    // });
+    // 鏋勫缓 formConfig锛屽寘鍚ā鏉垮瓧娈靛畾涔夊拰鐢ㄦ埛濉啓鐨勮〃鍗曟暟鎹�
+    const formConfig = buildInstanceFormConfigJson(
+      extendSubmitForm.templateSnapshot,
+      formPayload
+    );
 
-    ElMessage.success("寤舵湡鐢宠宸叉彁浜�");
-    extendSubmitDialog.visible = false;
-    onSearch();
+    const res = await delayBorrow({
+      id: extendSourceRow.id,
+      extendTargetReturnTime: formPayload.extendTargetReturnTime || formPayload.newEndDate || '',
+      extendReason: formPayload.extendReason || '',
+      formConfig: formConfig,
+    });
+
+    if (res.code === 200) {
+      ElMessage.success("寤舵湡鐢宠宸叉彁浜�");
+      extendSubmitDialog.visible = false;
+      onSearch();
+    } else {
+      ElMessage.error(res.msg || "鎻愪氦澶辫触");
+    }
   } catch (error) {
     ElMessage.error(error?.message || "鎻愪氦澶辫触");
   } finally {
     extendSubmitSaving.value = false;
   }
+}
+
+// ==================== 鍊熷嚭璁板綍璇︽儏 ====================
+const borrowDetailDialog = reactive({
+  visible: false,
+  loading: false,
+  data: {},
+});
+
+function openBorrowDetail(row) {
+  borrowDetailDialog.data = { ...row };
+  borrowDetailDialog.visible = true;
 }
 
 // ==================== 褰掕繕杞﹁締 ====================
@@ -972,20 +1066,21 @@
   instanceNo: "",
   vehiclePlateNumber: "",
   actualReturnTime: "",
+  mileage: null,
   returnStorageBlobDTOs: [],
 });
 const returnRules = {
   actualReturnTime: [{ required: true, message: "璇烽�夋嫨瀹為檯褰掕繕鏃堕棿", trigger: "change" }],
+  mileage: [{ required: true, message: "璇疯緭鍏ュ叕閲屾暟", trigger: "blur" }],
 };
 
 // 鎵撳紑褰掕繕杞﹁締瀵硅瘽妗�
 function openReturnDialog(row) {
   returnForm.id = row.id;
-  returnForm.instanceNo = row.instanceNo || "";
-  // 灏濊瘯浠庡涓彲鑳界殑瀛楁鍚嶄腑鑾峰彇杞︾墝鍙�
-  const payload = row.formPayload || {};
-  returnForm.vehiclePlateNumber = payload.vehicleNo || payload.plateNumber || payload.vehiclePlateNumber || payload.carNo || "";
+  returnForm.instanceNo = row.borrowNo || row.instanceNo || "";
+  returnForm.vehiclePlateNumber = row.vehiclePlateNumber || "";
   returnForm.actualReturnTime = dayjs().format("YYYY-MM-DD HH:mm:ss");
+  returnForm.mileage = null;
   returnForm.returnStorageBlobDTOs = [];
   returnDialog.visible = true;
 }
@@ -995,23 +1090,23 @@
   if (!returnFormRef.value) return;
   await returnFormRef.value.validate(async (valid) => {
     if (!valid) return;
-    
+
     returnLoading.value = true;
     try {
-      // 杩欓噷璋冪敤褰掕繕杞﹁締鐨凙PI
-      // 1. 鏇存柊杞﹁締鍏噷鏁�
-      const vehicle = vehicleList.value.find((v) => v.plateNumber === returnForm.vehiclePlateNumber);
-      if (vehicle) {
-        vehicle.currentMileage += returnForm.mileage;
-        vehicle.status = returnForm.vehicleStatus === "good" ? "idle" : "repair";
+      const res = await returnVehicle({
+        id: returnForm.id,
+        actualReturnTime: returnForm.actualReturnTime,
+        mileage: returnForm.mileage,
+        returnStorageBlobDTOs: returnForm.returnStorageBlobDTOs,
+      });
+      if (res.code === 200) {
+        ElMessage.success("杞﹁締褰掕繕鎴愬姛");
+        returnDialog.visible = false;
+        fetchBorrowList();
+        fetchVehicleList();
+      } else {
+        ElMessage.error(res.msg || "褰掕繕澶辫触");
       }
-      
-      // 2. 鍒涘缓褰掕繕瀹℃壒璁板綍锛堝疄闄呴」鐩腑璋冪敤API锛�
-      // await createVehicleReturnApproval({...});
-      
-      ElMessage.success("杞﹁締褰掕繕鎴愬姛");
-      returnDialog.visible = false;
-      onSearch();
     } catch (error) {
       ElMessage.error(error?.message || "褰掕繕澶辫触");
     } finally {

--
Gitblit v1.9.3