From 142878cdca997ab014d8ce98f9d8d617087191f6 Mon Sep 17 00:00:00 2001
From: xiebin <vip_xiaobin810@163.com>
Date: Thu, 24 Apr 2025 17:59:13 +0800
Subject: [PATCH] Merge branch 'test' into prod

---
 src/views/tickets/ticket.vue |  234 ++++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 184 insertions(+), 50 deletions(-)

diff --git a/src/views/tickets/ticket.vue b/src/views/tickets/ticket.vue
index d47f2cf..c3934b7 100644
--- a/src/views/tickets/ticket.vue
+++ b/src/views/tickets/ticket.vue
@@ -131,13 +131,22 @@
             </el-col>
             <el-col :span="12">
               <el-form-item label="附件图片" prop="photos" required class="upload-wrapper">
-                <el-upload ref="upload" :action="'#'" :auto-upload="false" list-type="picture-card"
-                  :on-change="handleFileChange" :on-remove="handleUploadRemove" :before-upload="beforeUpload"
-                  :file-list="form.photos" :limit="1" accept="image/*" class="uploader">
-                  <span
-                    style="font-size: 32px; display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;">+</span>
+                <el-upload ref="upload" 
+                  :action="'#'" 
+                  :auto-upload="false" 
+                  list-type="picture-card"
+                  :on-change="handleFileChange" 
+                  :on-remove="handleUploadRemove" 
+                  :before-upload="beforeUpload"
+                  :file-list="form.photos" 
+                  :limit="1" 
+                  accept="image/*" 
+                  class="create-upload">
+                  <template v-if="form.photos.length < 1">
+                    <i class="el-icon-plus">+</i>
+                  </template>
                 </el-upload>
-                <div class="upload-tip">支持jpg/png格式图片,单张不超过5MB</div>
+                <div class="upload-tip">需上传含有地址信息的照片(jpg、jpeg、png),且不超过5M</div>
               </el-form-item>
             </el-col>
           </el-row>
@@ -213,41 +222,42 @@
 
         <!-- 基本信息表格 -->
         <el-table :show-header="false" :data="formattedDetailFields" border style="width: 100%; margin-bottom: 20px;">
-          <el-table-column prop="label1" label="基本信息" width="150" />
+          <el-table-column prop="label1" label="基本信息" width="150">
+            <template #default="{ row }">
+              <!-- 添加必填星号的标签 -->
+              <span v-if="currentDetail.status === 0 && row.label1 === '工单名称'" class="required-label">
+                <span class="required-star">*</span>{{ row.label1 }}
+              </span>
+              <span v-else>{{ row.label1 }}</span>
+            </template>
+          </el-table-column>
           <el-table-column>
             <template #default="{ row }">
-              <!-- 修复工单名称可编辑 -->
               <template v-if="currentDetail.status === 0 && row.label1 === '工单名称' && hasProcessingBtnPermission()">
-                <el-input v-model="currentDetail.orderName" placeholder="请输入工单名称" />
-              </template>
-              <!-- 修复任务接收单位为下拉框 -->
-              <template v-else-if="currentDetail.status === 0 && row.label1 === '发起单位'">
-                <el-select v-model="currentDetail.department" placeholder="请选择任务接收单位" @change="handleDepartmentChange">
-                  <el-option v-for="item in departments" :key="item.value" :label="item.label" :value="item.value" />
-                </el-select>
+                <el-input v-model="currentDetail.orderName" placeholder="请输入工单名称" class="required-input" />
               </template>
               <template v-else>{{ row.value1 }}</template>
             </template>
           </el-table-column>
-          <el-table-column prop="label2" label="基本信息" width="150" />
+          <el-table-column prop="label2" label="基本信息" width="150">
+            <template #default="{ row }">
+              <!-- 添加必填星号的标签 -->
+              <span v-if="currentDetail.status === 0 && (row.label2 === '工单类型' || row.label2 === '工单内容')" class="required-label">
+                <span class="required-star">*</span>{{ row.label2 }}
+              </span>
+              <span v-else>{{ row.label2 }}</span>
+            </template>
+          </el-table-column>
           <el-table-column>
             <template #default="{ row }">
-              <!-- 修复工单内容可编辑 -->
-              <template v-if="currentDetail.status === 0 && row.label2 === '工单内容' && hasProcessingBtnPermission()">
-                <el-input type="textarea" v-model="currentDetail.content" placeholder="请输入工单内容" />
-              </template>
-              <!-- 修复工单类型为下拉框 -->
-              <template v-else-if="currentDetail.status === 0 && row.label2 === '工单类型' && hasProcessingBtnPermission()">
-                <el-select v-model="currentDetail.type" placeholder="请选择工单类型">
+              <!-- 修改工单类型和工单内容的显示 -->
+              <template v-if="currentDetail.status === 0 && row.label2 === '工单类型' && hasProcessingBtnPermission()">
+                <el-select v-model="currentDetail.type" placeholder="请选择工单类型" class="required-input">
                   <el-option v-for="item in types" :key="item.value" :label="item.label" :value="item.value" />
                 </el-select>
               </template>
-              <!-- 修复任务处理人为下拉框 -->
-              <template v-else-if="currentDetail.status === 0 && row.label2 === '任务处理人'">
-                <el-select v-model="currentDetail.handler" placeholder="请选择任务处理人" @change="handleHandlerChange">
-                  <el-option v-for="user in departmentUsers[currentDetail.department] || []" :key="user.id"
-                    :label="user.name" :value="user.id" />
-                </el-select>
+              <template v-else-if="currentDetail.status === 0 && row.label2 === '工单内容' && hasProcessingBtnPermission()">
+                <el-input type="textarea" v-model="currentDetail.content" placeholder="请输入工单内容" class="required-input" />
               </template>
               <template v-else>{{ row.value2 }}</template>
             </template>
@@ -256,7 +266,17 @@
 
         <!-- 事件处理详情 -->
         <div v-if="[3, 4, 5].includes(currentDetail.status)" class="form-section">
-          <div class="section-title">事件处理详情</div>
+          <div class="section-title">
+            <!-- 处理中状态显示必填星号 -->
+            <template v-if="currentDetail.status === 3">
+              <span class="required-label">
+                <span class="required-star">*</span>事件处理详情
+              </span>
+            </template>
+            <template v-else>
+              事件处理详情
+            </template>
+          </div>
           <!-- 处理中状态显示输入框 -->
           <template v-if="currentDetail.status === 3 && hasProcessedAndOverBtnPermission()">
             <el-input type="textarea" v-model="currentDetail.processingDetail" placeholder="请输入事件处理详情" :rows="4"
@@ -272,17 +292,38 @@
 
         <!-- 上传图片 -->
         <div v-if="[3, 4].includes(currentDetail.status)" class="form-section" style="margin-bottom: 32px;">
-          <div class="section-title" v-if="hasProcessedAndOverBtnPermission()">上传图片</div>
-          <el-upload v-if="hasProcessedAndOverBtnPermission()" ref="upload" :action="'#'" :auto-upload="false"
-            list-type="picture-card" :on-change="handleFileChange" :on-remove="handleUploadRemove"
-            :before-upload="beforeUpload" :file-list="[]" :limit="1" accept="image/*">
-            <span
-              style="font-size: 32px; display: flex; align-items: center; justify-content: center; width: 100%; height: 100%;">+</span>
+          <div class="section-title" v-if="hasProcessedAndOverBtnPermission()">
+            <!-- 已完成状态显示必填星号 -->
+            <template v-if="currentDetail.status === 4">
+              <span class="required-label">
+                <span class="required-star">*</span>上传图片
+              </span>
+            </template>
+            <template v-else>
+              上传图片
+            </template>
+          </div>
+          <el-upload v-if="hasProcessedAndOverBtnPermission()" 
+            ref="upload" 
+            :action="'#'" 
+            :auto-upload="false"
+            list-type="picture-card" 
+            :on-change="handleFileChange" 
+            :on-remove="handleUploadRemove"
+            :before-upload="beforeUpload" 
+            :file-list="currentDetail.photos || []" 
+            :limit="1"
+            accept="image/*"
+            class="detail-upload">
+            <template v-if="!currentDetail.photos || currentDetail.photos.length < 1">
+              <i class="el-icon-plus">+</i>
+            </template>
           </el-upload>
           <div class="el-upload__tip" style="margin-top: 12px;" v-if="hasProcessedAndOverBtnPermission()">
-            支持 jpg/png 格式图片,单张不超过 5MB
+            (上传照片即可完结工单,只能上传jpg、jpeg、png照片,且不超过5M)
           </div>
         </div>
+
         <!-- 图片和地图部分 -->
         <div class="media-section">
           <el-row :gutter="20">
@@ -291,7 +332,7 @@
                 <div class="media-title">事件图片</div>
                 <div class="media-content">
                   <el-image v-if="currentDetail.mediaUrl" :src="getThumbUrl(currentDetail.mediaUrl)"
-                    :preview-src-list="[currentDetail.mediaUrl]" fit="contain"
+                    :preview-src-list="[getPreviewUrl(currentDetail.mediaUrl)]" fit="contain"
                     style="width: 700px; height: 520px; cursor: pointer;">
                     <template #placeholder>
                       <div class="image-placeholder">
@@ -317,7 +358,7 @@
                   <div class="media-title">工单处理图片</div>
                   <div class="media-content">
                     <el-image v-if="currentDetail.updatePhotoUrl" :src="getThumbUrl(currentDetail.updatePhotoUrl)"
-                      :preview-src-list="[currentDetail.updatePhotoUrl]" fit="fill"
+                      :preview-src-list="[getPreviewUrl(currentDetail.updatePhotoUrl)]" fit="fill"
                       style="width: 700px; height: 520px; cursor: pointer;">
                       <template #placeholder>
                         <div class="image-placeholder">
@@ -524,7 +565,7 @@
         column: [
           // { label: "序号", prop: "id", width: 70 },
           { label: "工单编号", prop: "orderNumber", width: 150 },
-          { label: "工单名称", prop: "orderName", width: 150 },
+          { label: "工单名称", prop: "orderName", width: 170, overHidden: true, tooltip: true },
           { label: "所属单位", prop: "department", width: 100 },
           { label: "发起时间", prop: "startTime", width: 160 },
           { label: "关联算法", prop: "aiType", width: 160 },
@@ -722,7 +763,7 @@
       const fields = [
         { label: "工单名称", value: this.currentDetail.orderName },
         { label: "工单类型", value: this.currentDetail.type },
-        { label: "关联任务", value: this.currentDetail.job_name || '暂无关联航线' },
+        { label: "关联任务", value: this.currentDetail.job_name || '/' },
         { label: "任务发起人", value: this.currentDetail.creator },
         { label: "当前状态", value: this.mapStatus(this.currentDetail.status) },
         { label: "事件地址", value: this.currentDetail.address }, // 包含经纬度信息
@@ -847,7 +888,6 @@
           isPass: 0,
           eventNum: currentItem.orderNumber,
           eventName: currentItem.orderName,
-          eventType: currentItem.type,
         };
 
         const response = await flowEvent(data);
@@ -1533,10 +1573,6 @@
           status: this.currentDetail.status,
           isPass: 0, // 0 表示通过
           eventNum: this.currentDetail.orderNumber,
-          eventName: this.currentDetail.orderName, // 工单名称
-          eventType: this.currentDetail.type, // 工单类型
-          departmentId: this.dispatchForm.department, // 派发部门 ID
-          handlerId: this.dispatchForm.handler, // 处理人 ID
         };
 
         const file = this.currentDetail.file || null; // 如果没有文件,则为 null
@@ -1649,8 +1685,23 @@
     },
     async approveAndDispatch() {
       if (this.dispatchLoading) return;
-      // this.dispatchLoading = true;
-      this.dispatchDialogVisible = true; // 打开派发对话框
+      
+      // 添加必填项检查
+      if (!this.currentDetail.orderName || !this.currentDetail.orderName.trim()) {
+        this.$message.warning('请填写工单名称');
+        return;
+      }
+      if (!this.currentDetail.type) {
+        this.$message.warning('请选择工单类型');
+        return;
+      }
+      if (!this.currentDetail.content || !this.currentDetail.content.trim()) {
+        this.$message.warning('请填写工单内容');
+        return;
+      }
+      
+      // 通过验证后,打开派发对话框
+      this.dispatchDialogVisible = true;
     },
     hasProcessingBtnPermission() {
       // undefined 或 false 都返回 false,只有 true 返回 true
@@ -1965,7 +2016,6 @@
           status: currentItem.status,
           isPass: 0,
           eventNum: currentItem.orderNumber,
-          eventName: currentItem.orderName,
         };
         console.log('删除前:', this.selections)
         const response = await flowEvent(data);
@@ -2073,7 +2123,7 @@
     // 获取所有图片列表用于预览
     getImageList() {
       return this.selections
-        .map(item => item.photo_url)
+        .map(item => this.getPreviewUrl(item.photo_url))
         .filter(url => url); // 过滤掉空值
     },
 
@@ -2108,6 +2158,14 @@
       const lastDot = url.lastIndexOf('.');
       if (lastDot === -1) return url;
       return url.slice(0, lastDot) + '_small' + url.slice(lastDot);
+    },
+
+    // 添加新方法:获取预览图地址
+    getPreviewUrl(url) {
+      if (!url) return '';
+      const lastDot = url.lastIndexOf('.');
+      if (lastDot === -1) return url;
+      return url.slice(0, lastDot) + '_show' + url.slice(lastDot);
     },
   },
 };
@@ -2489,6 +2547,10 @@
   margin-bottom: 8px;
 }
 
+.no-media {
+  border: 1px dashed #d9d9d9;
+}
+
 .info-table {
   margin-bottom: 20px;
 }
@@ -2729,4 +2791,76 @@
     }
   }
 }
+
+/* 新建工单和处理工单的上传组件样式 */
+.create-upload,
+.detail-upload {
+  :deep(.el-upload--picture-card) {
+    width: 120px;
+    height: 100px;
+    line-height: 100px;
+  }
+  
+  /* 隐藏额外的上传按钮 */
+  :deep(.el-upload.el-upload--picture-card) {
+    display: none;
+  }
+  
+  /* 当没有图片时显示上传按钮 */
+  :deep(.el-upload.el-upload--picture-card:first-child) {
+    display: flex;
+  }
+
+  /* 上传组件的预览图片样式 */
+  :deep(.el-upload-list--picture-card .el-upload-list__item) {
+    width: 120px;
+    height: 100px;
+  }
+}
+
+/* 事件图片和处理图片的预览样式 */
+.media-content {
+  :deep(.el-image) {
+    width: 700px !important;
+    height: 520px !important;
+    
+    .el-image__inner {
+      width: 100%;
+      height: 100%;
+      object-fit: contain;
+    }
+  }
+}
+
+/* 原有图片预览的样式 */
+.el-image-viewer__wrapper {
+  :deep(.el-image-viewer__img) {
+    max-width: 100%;
+    max-height: 100%;
+    object-fit: contain;
+  }
+}
+
+/* 必填项样式 */
+.required-label {
+  position: relative;
+  display: inline-block;
+  
+  .required-star {
+    color: #F56C6C;
+    margin-right: 4px;
+  }
+}
+
+/* 必填输入框样式 */
+.required-input {
+  width: 100%;
+  
+  :deep(.el-input__inner),
+  :deep(.el-textarea__inner) {
+    &:focus {
+      border-color: #409EFF;
+    }
+  }
+}
 </style>
\ No newline at end of file

--
Gitblit v1.9.3