From 771cd475a2aad9938f4e2085ca018ba31bdc1d7f Mon Sep 17 00:00:00 2001
From: 张含笑 <zhx18749296735@163.com>
Date: Thu, 20 Nov 2025 14:11:03 +0800
Subject: [PATCH] feat:工单详情

---
 src/views/tickets/ticket.vue |  471 ++++++++--------------------------------------------------
 1 files changed, 71 insertions(+), 400 deletions(-)

diff --git a/src/views/tickets/ticket.vue b/src/views/tickets/ticket.vue
index a38190d..644cb20 100644
--- a/src/views/tickets/ticket.vue
+++ b/src/views/tickets/ticket.vue
@@ -9,7 +9,6 @@
       >
         <basic-main-content>
           <!-- 查询条件筛选栏 -->
-          <!-- 查询条件筛选栏 -->
           <div class="ztzf-form-search">
             <el-form :model="filters" inline>
               <el-row :gutter="24">
@@ -26,33 +25,7 @@
                   </el-form-item>
                 </el-col>
 
-                <!-- <el-select
-                  v-model="filters.department"
-                  placeholder="请选择所属部门"
-                  class="filter-item"
-                  clearable
-                >
-                  <el-option
-                    v-for="item in departments"
-                    :key="item.value"
-                    :label="item.label"
-                    :value="item.value"
-                  />
-                </el-select> -->
-                <!-- <el-select
-                  v-model="filters.type"
-                  placeholder="请选择工单类型"
-                  class="filter-item"
-                  clearable
-                  @change="handleSearch"
-                >
-                  <el-option
-                    v-for="item in types"
-                    :key="item.value"
-                    :label="item.label"
-                    :value="item.value"
-                  />
-                </el-select> -->
+
                 <el-col :span="5">
                   <el-form-item label="选择日期:">
                   <el-date-picker
@@ -87,34 +60,6 @@
                   </el-form-item>
                 </el-col>
 
-                <!-- <el-select
-                  v-model="filters.algorithm"
-                  placeholder="请选择关联算法"
-                  class="filter-item"
-                  clearable
-                  @change="handleSearch"
-                >
-                  <el-option
-                    v-for="item in algorithms"
-                    :key="item.dict_key"
-                    :label="item.dict_value"
-                    :value="item.dict_key"
-                  />
-                </el-select> -->
-                <!-- <el-tree-select
-                  popper-class="custom-tree-select"
-                  :style="{ width: pxToRem(186) }"
-                  placeholder="请选择关联算法"
-                  v-model="dictKey"
-                  :data="dataList"
-                  :default-expanded-keys="[dictKey]"
-                  check-strictly
-                  node-key="id"
-                  :props="treePropsSF"
-                  @node-click="handleSFNodeClick"
-                  clearable
-                  @clear="handleClear"
-                /> -->
                 <el-col :span="4">
                   <el-form-item label="选择算法:">
                   <el-tree-select
@@ -270,37 +215,37 @@
     </el-tabs>
 
     <!-- 新建工单对话框 -->
-   <create-ticket-dialog
-  v-model="dialogVisible"
-  :departments="departments"
-  :department-users="departmentUsers"
-  :types="types"
-  :all-algorithms="allAlgorithms"
-  :edit-data="editFormData"
-  :map-center="inputMapShowDefaultCenter"
-  @create-success="handleCreateSuccess"
-  @draft-success="handleDraftSuccess"
-  @create-error="handleCreateError"
-/>
+        <create-ticket-dialog
+        v-model="dialogVisible"
+        :departments="departments"
+        :department-users="departmentUsers"
+        :types="types"
+        :all-algorithms="allAlgorithms"
+        :edit-data="editFormData"
+        :map-center="inputMapShowDefaultCenter"
+        @create-success="handleCreateSuccess"
+        @draft-success="handleDraftSuccess"
+        @create-error="handleCreateError"
+      />
 
     <!-- 工单详情对话框 -->
-<ticket-detail-dialog
-  v-model="detailVisible"
-  :current-detail="currentDetail"
-  :current-index="currentIndex"
-  :total-items="tableData.length"
-  :algorithms="algorithms"
-  :types="types"
-  :permission="permission"
-  :step-status-list="stepStatusList"
-  :work-type="workType"
-  @detail-success="handleDetailSuccess"
-  @detail-error="handleDetailError"
-  @prev-item="handlePrevItem"
-  @next-item="handleNextItem"
-  @update:current-detail="handleCurrentDetailUpdate"
-  @approve-and-dispatch="handleApproveAndDispatch"
-/>
+      <ticket-detail-dialog
+        v-model="detailVisible"
+        :current-detail="currentDetail"
+        :current-index="currentIndex"
+        :total-items="tableData.length"
+        :algorithms="algorithms2"
+        :types="types"
+        :permission="permission"
+        :step-status-list="stepStatusList"
+        :work-type="workType"
+        @detail-success="handleDetailSuccess"
+        @detail-error="handleDetailError"
+        @prev-item="handlePrevItem"
+        @next-item="handleNextItem"
+        @update:current-detail="handleCurrentDetailUpdate"
+        @approve-and-dispatch="handleApproveAndDispatch"
+      />
 
     <!-- 派发工单对话框 -->
       <dispatch-dialog
@@ -418,8 +363,6 @@
   flowEvent,
   getstatusCount,
   getStepInfo,
-  getReviewById,
-  getCreateEventJob,
   exportTheTicket
 } from '@/api/tickets/ticket';
 import { getSFDictionaryTree } from '@/api/job/task';
@@ -448,12 +391,6 @@
   data() {
     return {
       currentIndex: null, // 当前显示的数据索引
-  
- 
-      approveLoading: false,
-      rejectLoading: false,
-      dispatchLoading: false,
-      completeLoading: false,
       finalizeLoading: false,
       createoredit: '',
       activeTab: 'all',
@@ -486,6 +423,7 @@
 
       algorithms: [],
       algorithms2: [],
+      algorithms3: [],
       statuses: [
         { label: '待审核', value: '2' },
         { label: '待处理', value: '0' },
@@ -604,7 +542,6 @@
   },
   created() {
     this.inputMapShowDefaultCenter = null;
-
     this.loadAMapScripts();
     this.fetchDropdownData();
   },
@@ -691,134 +628,7 @@
         ? this.departmentUsers[this.dispatchForm.department] || []
         : [];
     },
-    detailTableData() {
-      return [
-        {
-          label: '工单名称',
-          value: this.currentDetail.orderName,
-          editable: this.currentDetail.status === 0,
-          type: 'input',
-        },
-        {
-          label: '关键任务',
-          value: this.currentDetail.keyData,
-          editable: false,
-        },
-        {
-          label: '工单创建人',
-          value: this.currentDetail.creator,
-          editable: false,
-        },
-        {
-          label: '当前状态',
-          value: this.mapStatus(this.currentDetail.status),
-          editable: false,
-        },
-        {
-          label: '事件地址',
-          value: this.currentDetail.address,
-          editable: false,
-        },
-        {
-          label: '工单类型',
-          value: this.currentDetail.type,
-          editable: this.currentDetail.status === 0,
-          type: 'select',
-          options: this.types,
-        },
-        {
-          label: '关联算法',
-          value: this.currentDetail.aiType,
-          editable: false,
-        },
-        {
-          label: '发起单位',
-          value: this.currentDetail.department,
-          editable: false,
-        },
-        {
-          label: '发起任务时间',
-          value: this.currentDetail.startTime,
-          editable: false,
-        },
-        {
-          label: '工单内容',
-          value: this.currentDetail.content,
-          editable: this.currentDetail.status === 0,
-          type: 'textarea',
-        },
-      ];
-    },
-    detailFields() {
-      return [
-        {
-          label: '工单名称',
-          value: this.currentDetail.orderName,
-          editable: this.currentDetail.status === 0,
-          type: 'input',
-        },
-        { label: '关键任务', value: this.currentDetail.keyData, editable: false },
-        { label: '工单创建人', value: this.currentDetail.creator, editable: false },
-        { label: '当前状态', value: this.mapStatus(this.currentDetail.status), editable: false },
-        { label: '事件地址', value: this.currentDetail.address, editable: false },
-        {
-          label: '工单类型',
-          value: this.currentDetail.type,
-          editable: this.currentDetail.status === 0,
-          type: 'select',
-          options: this.types,
-        },
-        { label: '关联算法', value: this.currentDetail.aiType, editable: false },
-        { label: '发起单位', value: this.currentDetail.department, editable: false },
-        { label: '发起任务时间', value: this.currentDetail.startTime, editable: false },
-        {
-          label: '工单内容',
-          value: this.currentDetail.content,
-          editable: this.currentDetail.status === 0,
-          type: 'textarea',
-        },
-      ];
-    },
-    formattedDetailFields() {
-      const fields = [
-        { label: '工单名称', value: this.currentDetail.orderName },
-        {
-          label: '工单类型',
-          // 修改这里:使用 types 数组查找对应的 label
-          value:
-            this.types.find(t => t.value === this.currentDetail.type)?.label ||
-            this.currentDetail.type,
-        },
-        { label: '关联任务', value: this.currentDetail.job_name || '/' },
-        { label: '工单创建人', value: this.currentDetail.creator },
-        { label: '当前状态', value: this.mapStatus(this.currentDetail.status) },
-        { label: '事件地址', value: this.currentDetail.address || this.currentDetail.latAndLon }, // 包含经纬度信息
-        {
-          label: '关联算法',
-          value:
-            this.algorithms.find(t => t.value === this.currentDetail.aiType)?.label ||
-            this.currentDetail.aiType,
-        },
-        { label: '发起单位', value: this.currentDetail.department },
-        { label: '发起任务时间', value: this.currentDetail.startTime },
-        { label: '工单内容', value: this.currentDetail.content },
-      ];
 
-      // 过滤掉值为 '/' 的列
-      const filteredFields = fields.filter(field => field.value !== '/');
-      // 将字段分成两列
-      const formattedFields = [];
-      for (let i = 0; i < filteredFields.length; i += 2) {
-        formattedFields.push({
-          label1: filteredFields[i]?.label || '',
-          value1: filteredFields[i]?.value || (filteredFields[i]?.label ? '暂无数据' : ''),
-          label2: filteredFields[i + 1]?.label || '',
-          value2: filteredFields[i + 1]?.value || (filteredFields[i + 1]?.label ? '暂无数据' : ''),
-        });
-      }
-
-      return formattedFields;
-    },
     dynamicFixedStatuses() {
       // 直接使用接口返回的 stepInfos
       return this.stepInfos.map(step => String(step.status));
@@ -962,7 +772,6 @@
     // 更新当前详情
     updateCurrentDetail() {  
       this.currentDetail = this.tableData[this.currentIndex];
-      console.log('当前',this.currentDetail);    
       this.currentDetail.mediaUrl = this.currentDetail.photo_url;
       this.currentDetail.updatePhotoUrl = this.currentDetail.update_photo_url;
       this.currentDetail.processingDetail = this.currentDetail.processingDetail;
@@ -981,9 +790,7 @@
       this.currentDetail = detail;
       this.dispatchDialogVisible = true;
     },
-    async handleQRCode(val) {
-      val.showQR = !val.showQR;
-    },
+
     async loadAMapScripts() {
       try {
         const areaCode = this.userInfo.detail.areaCode;
@@ -1015,7 +822,6 @@
         this.$message.error('地图加载失败,请检查网络或API Key配置');
       }
     },
-
     async fetchDropdownData() {
       try {
         const response = await getTicketInfo();
@@ -1067,7 +873,7 @@
       }
     },
 
-
+    // 获取表格数据
     async fetchTableData() {
       if (this.isFetching) return;
       this.isFetching = true;
@@ -1172,7 +978,41 @@
       }
     },
 
+ handleTypeChange(typeValue) {
+      // this.form.algorithm = [];
+      if (!typeValue) {
+        // 未选择类型时清空算法列表
+        this.algorithms2 = [];
+        this.algorithms3 = [];
+        return;
+      }
 
+      const matchedCategory = this.allAlgorithms.find(category => category.dict_key === typeValue);
+
+      if (
+        !matchedCategory ||
+        !matchedCategory.algorithms ||
+        matchedCategory.algorithms.length === 0
+      ) {
+        // 无匹配的算法时清空
+        this.algorithms2 = [];
+         this.algorithms3 = [];
+        this.$message.info('该工单类型暂无关联算法');
+        return;
+      }
+      this.algorithms2 = matchedCategory.algorithms.map(algo => ({
+        label: algo.dict_value,
+        value: algo.dict_key,
+        dict_key: algo.dict_key,
+        dict_value: algo.dict_value,
+      }));
+        this.algorithms3 = matchedCategory.algorithms.map(algo => ({
+        label: algo.dict_value,
+        value: algo.dict_key,
+        dict_key: algo.dict_key,
+        dict_value: algo.dict_value,
+      }));
+    },
     formatDate(date) {
       if (!date) return undefined;
       const d = new Date(date);
@@ -1294,13 +1134,6 @@
     },
 
 
-    formatLocation(location) {
-      if (!Array.isArray(location)) {
-        return '未知位置';
-      }
-      return `${location[0].toFixed(6)}, ${location[1].toFixed(6)}`;
-    },
-
 async getStepInfoData(val) {
   try {
   const orderNum = val
@@ -1331,8 +1164,6 @@
         };
       });
     }
-    console.log('stepInfos',this.stepInfos);
-    
     return true; // 表示成功获取数据
   } catch (error) {
     console.error('获取步骤信息失败:', error);
@@ -1367,10 +1198,8 @@
 
   // 获取步骤信息
   await this.getStepInfoData(row.orderNumber);
-  
   this.currentDetail.status = row.status;
-
-  console.log(detailData, 'detailDatadetailDatadetailData');
+ 
   this.currentDetail = {
     ...detailData,
     showQR: false,
@@ -1380,7 +1209,7 @@
   console.log('this.currentDetail', this.currentDetail);
 
   this.detailVisible = true;
-
+ this.handleTypeChange(this.currentDetail.type);
   // 重置上传组件的文件列表
   this.$nextTick(() => {
     if (this.$refs.MapContainer && this.$refs.MapContainer.initAddEntity) {
@@ -1397,41 +1226,7 @@
     handleDetailError(error) {
       console.error('工单操作失败:', error);
     },
-    getStepHandler(status) {
-      const step = this.stepInfos.find(step => step.status === status);
-      return step ? step.name : '';
-    },
 
-    getStepTime(status) {
-      const step = this.stepInfos.find(step => step.status === status);
-      // 如果 step 不存在或 step.time 为 0,返回 false
-      return step && step.time && step.time !== '0' ? step.time : false;
-    },
-    getStepCreateTime(status) {
-      const step = this.stepInfos.find(step => step.status === status);
-      return step ? step.create_time : null;
-    },
-    getActiveStep() {
-      // 步骤索引适配
-      const arr = this.stepStatusList;
-      const index = arr.indexOf(String(this.currentDetail.status));
-      return index !== -1 ? index + 2 : 1;
-    },
-
-    openMap() {
-      const areaCode = this.userInfo.detail.areaCode;
-      const subAreaCode = areaCode ? areaCode.substring(0, 6) : '';
-      getAdcodeObj(geoJson, 'adcode', subAreaCode);
-      this.$message.info('地图选址功能暂未实现');
-    },
-
-    handlePreview(file) {
-      this.$message.info(`预览图片:${file.name}`);
-    },
-
-    handleRemove(file) {
-      this.$message.info(`移除图片:${file.name}`);
-    },
 
     refreshChange() {
       if (this.isFetching) return;
@@ -1508,113 +1303,11 @@
         工单状态: this.mapStatus(Number(item.status || 0)),
       };
     },
-    async approveTicket() {
-      if (this.approveLoading) return;
-      this.approveLoading = true;
-      try {
-        const data = {
-          id: this.currentDetail.id,
-          status: this.currentDetail.status,
-          isPass: 0, // 0 表示通过
-          eventNum: this.currentDetail.orderNumber,
-        };
 
-        const file = this.currentDetail.file || null; // 如果没有文件,则为 null
-
-        const response = await flowEvent(data, file);
-        if (response.data.code === 0) {
-          this.$message.success('工单已通过');
-          this.detailVisible = false;
-          this.fetchTableData();
-        } else {
-          throw new Error(response.data.msg || '操作失败');
-        }
-      } catch (error) {
-        this.$message.error(error.message || '操作失败,请稍后重试');
-      } finally {
-        this.approveLoading = false;
-      }
-    },
-    async rejectTicket() {
-      if (this.rejectLoading) return;
-      this.rejectLoading = true;
-      try {
-        const data = {
-          id: this.currentDetail.id,
-          status: this.currentDetail.status,
-          isPass: 1, // 1 表示不通过
-        };
-
-        const response = await flowEvent(data);
-        if (response.data.code === 0) {
-          this.$message.success('工单未通过');
-          this.detailVisible = false;
-          this.fetchTableData();
-        } else {
-          throw new Error(response.data.msg || '操作失败');
-        }
-      } catch (error) {
-        this.$message.error(error.message || '操作失败,请稍后重试');
-      } finally {
-        this.rejectLoading = false;
-      }
-    },
-    async submitProcessing() {
-      if (this.currentDetail.status !== 3) {
-        this.$message.warning('只有处理中状态的工单可以提交处理详情');
-        return;
-      }
-
-      try {
-        const data = {
-          id: this.currentDetail.id, // 当前工单 ID
-          status: this.currentDetail.status, // 当前工单状态
-          processing_details: this.currentDetail.processingDetail, // 事件处理详情
-        };
-
-        // 如果有图片,添加 file 参数
-        const file = this.currentDetail.photos?.[0]?.raw || null;
-
-        const response = await flowEvent(data, file);
-        if (response.data.code === 0) {
-          this.$message.success('处理详情提交成功');
-          this.detailVisible = false;
-          this.fetchTableData();
-        } else {
-          throw new Error(response.data.msg || '提交失败');
-        }
-      } catch (error) {
-        console.error('处理详情提交失败:', error);
-        this.$message.error(error.message || '提交失败,请稍后重试');
-      }
-    },
     markAsCompleted() {
       this.$message.success('工单已标记为完成');
     },
-
-    async approveAndDispatch() {
-      if (this.dispatchLoading) return;
-
-      // 添加必填项检查
-      if (!this.currentDetail.orderName || !this.currentDetail.orderName.trim()) {
-        this.$message.warning('请填写工单名称');
-        return;
-      }
-      if (!this.currentDetail.aiType) {
-        this.$message.warning('请选择关联算法');
-        return;
-      }
-      if (!this.currentDetail.content || !this.currentDetail.content.trim()) {
-        this.$message.warning('请填写工单内容');
-        return;
-      }
-
-      // 通过验证后,打开派发对话框
-      this.dispatchDialogVisible = true;
-
-      console.log('受理', this.currentDetail);
-    },
-      // 派发成功回调
+    // 派发成功回调
     handleDispatchSuccess() {
       this.detailVisible = false;
       this.fetchTableData();
@@ -1625,21 +1318,7 @@
       // 可以在这里处理错误,或者保持空实现
       console.error('派发失败:', error);
     },
-    hasProcessingBtnPermission() {
-      // undefined 或 false 都返回 false,只有 true 返回 true
-      //  console.log('权限检查:', this.permission.tickets_processing_btn)
-      return this.permission && this.permission.tickets_processing_btn === true;
-    },
-    hasProcessedAndOverBtnPermission() {
-      // undefined 或 false 都返回 false,只有 true 返回 true
-      //console.log('权限检查:', this.permission)
-      return this.permission && this.permission.tickets_view_processedAndOver === true;
-    },
-    hasReviewBtnPermission() {
-      // undefined 或 false 都返回 false,只有 true 返回 true
-      // console.log('权限检查:', this.permission)
-      return this.permission && this.permission.tickets_review_btn === true;
-    },
+
     async finalizeTicket() {
       if (this.finalizeLoading) return;
       this.finalizeLoading = true;
@@ -2032,14 +1711,6 @@
 };
 </script>
 <style lang="scss">
-.custom-dialog {
-  max-height: 96vh;
-
-  .el-dialog__body {
-    border-top: 0.1rem solid #f0f0f0;
-  }
-}
-
 .custom-qrcode-popover {
   min-width: 160px !important;
   min-height: 140px !important;

--
Gitblit v1.9.3