Bläddra i källkod

fix:隐患工单bug修改

null 4 veckor sedan
förälder
incheckning
603bddd906

+ 9 - 0
src/api/work/order.js

@@ -60,3 +60,12 @@ export function cancelWorkOrder(orderId) {
     method: 'delete'
   })
 }
+
+/** 验收通过/结案 */
+export function closeWorkOrder(data) {
+  return request({
+    url: '/api/work-order/close',
+    method: 'put',
+    data
+  })
+}

+ 70 - 1
src/views/subSystem/basic/BusinessWorkOrder.vue

@@ -126,6 +126,7 @@
                   </div>
                   <div class="order-desc" v-if="order.orderDesc">{{ order.orderDesc }}</div>
                   <div class="device-code">设备编号:{{ order.deviceCode || '-' }}</div>
+                  <div class="device-code" v-if="order.hazardNo">关联隐患:{{ order.hazardNo }}</div>
                   <div class="create-time">创建:{{ formatDate(order.createTime) }}</div>
                 </div>
               </div>
@@ -204,6 +205,7 @@
                     >已驳回</el-tag>
                   </el-descriptions-item>
                   <el-descriptions-item label="关联案件编号">{{ selectedOrder.caseNo || '-' }}</el-descriptions-item>
+                  <el-descriptions-item label="关联隐患编号">{{ selectedOrder.hazardNo || '-' }}</el-descriptions-item>
                   <el-descriptions-item label="设备编号">{{ selectedOrder.deviceCode || '-' }}</el-descriptions-item>
                   <el-descriptions-item label="优先级">
                     <el-tag 
@@ -274,6 +276,12 @@
                       icon="Checked"
                       @click="handleComplete"
                     >提交验收</el-button>
+                    <el-button 
+                      v-if="canClose()" 
+                      type="success" 
+                      icon="CircleCheck"
+                      @click="handleClose"
+                    >验收通过</el-button>
                     <el-button 
                       v-if="canReject()" 
                       type="info" 
@@ -286,6 +294,7 @@
               
               <!-- 处理历史 -->
               <el-tab-pane label="处理历史" name="history">
+                <div class="timeline-scroll">
                 <el-timeline v-if="currentOrderLogs && currentOrderLogs.length > 0">
                   <el-timeline-item 
                     v-for="log in currentOrderLogs" 
@@ -297,6 +306,7 @@
                   >
                     <el-card shadow="hover">
                       <div class="timeline-content">
+                        <div class="timestamp">{{ formatDate(log.operTime) }}</div>
                         <div class="operator-info">
                           <span class="operator-name">{{ log.operUserName }}</span>
                           <span class="oper-type">· {{ getOperTypeLabel(log.operType) }}</span>
@@ -307,6 +317,7 @@
                   </el-timeline-item>
                 </el-timeline>
                 <el-empty v-else description="暂无处理记录" :image-size="100"></el-empty>
+                </div>
               </el-tab-pane>
             </el-tabs>
           </div>
@@ -394,13 +405,26 @@
         <el-button type="primary" @click="submitComplete">提交</el-button>
       </template>
     </el-dialog>
+    
+    <!-- 验收通过/结案弹窗 -->
+    <el-dialog v-model="closeDialogVisible" title="验收通过" width="500px">
+      <el-form label-width="80px">
+        <el-form-item label="验收结果">
+          <el-input v-model="closeForm.result" type="textarea" :rows="4" placeholder="请输入验收结果/整改反馈" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="closeDialogVisible = false">取消</el-button>
+        <el-button type="primary" @click="submitClose">确认验收</el-button>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
 <script setup name="BusinessWorkOrder">
 import { ElMessage } from 'element-plus'
 import ImagePreview from '@/components/ImagePreview'
-import { listWorkOrder, getWorkOrderDetail, dispatchWorkOrder, verifyWorkOrder, processWorkOrder, completeWorkOrder } from '@/api/work/order'
+import { listWorkOrder, getWorkOrderDetail, dispatchWorkOrder, verifyWorkOrder, processWorkOrder, completeWorkOrder, closeWorkOrder } from '@/api/work/order'
 import { listDept } from '@/api/system/dept'
 import { listUser } from '@/api/system/user'
 import { handleTree } from '@/utils/ruoyi'
@@ -544,6 +568,7 @@ function canDispatch() { return selectedOrder.value.orderStatus === 1 }
 function canVerify() { return [2, 3].includes(selectedOrder.value.orderStatus) }
 function canProcess() { return [3, 4].includes(selectedOrder.value.orderStatus) }
 function canComplete() { return selectedOrder.value.orderStatus === 4 }
+function canClose() { return selectedOrder.value.orderStatus === 5 }
 function canReject() { return [1, 2].includes(selectedOrder.value.orderStatus) }
 
 function handleDispatch() {
@@ -626,6 +651,7 @@ async function submitAction() {
   }
 }
 
+
 /** 完成/验收相关 */
 const completeDialogVisible = ref(false)
 const completeForm = reactive({ result: '' })
@@ -664,6 +690,37 @@ function handleReject() {
   // TODO: 实现驳回逻辑
 }
 
+/** 验收通过/结案相关 */
+const closeDialogVisible = ref(false)
+const closeForm = reactive({ result: '' })
+
+function handleClose() {
+  if (selectedOrder.value.orderStatus !== 5) {
+    ElMessage.warning('当前工单不允许验收通过')
+    return
+  }
+  closeForm.result = ''
+  closeDialogVisible.value = true
+}
+
+async function submitClose() {
+  if (!closeForm.result.trim()) {
+    ElMessage.warning('请填写验收结果')
+    return
+  }
+  try {
+    await closeWorkOrder({
+      orderId: selectedOrder.value.orderId,
+      result: closeForm.result
+    })
+    ElMessage.success('验收通过,关联隐患已同步为已整改')
+    closeDialogVisible.value = false
+    handleSearch()
+  } catch (e) {
+    ElMessage.error('验收失败')
+  }
+}
+
 /** 辅助函数 */
 function getOrderTypeText(type) {
   const map = { 1: '故障维修', 2: '日常巡检', 3: '设备保养' }
@@ -849,6 +906,12 @@ onMounted(() => {
     margin-top: 16px;
   }
   
+  .timeline-scroll {
+    max-height: calc(100vh - 340px);
+    overflow-y: auto;
+    padding-right: 8px;
+  }
+  
   .image-section {
     margin-top: 24px;
     padding-top: 24px;
@@ -884,6 +947,12 @@ onMounted(() => {
   }
   
   .timeline-content {
+    .timestamp {
+      font-size: 12px;
+      color: #909399;
+      margin-bottom: 6px;
+    }
+    
     .operator-info {
       font-size: 14px;
       margin-bottom: 8px;

+ 67 - 1
src/views/subSystem/drainage/DrainageWorkOrder.vue

@@ -274,6 +274,12 @@
                       icon="Checked"
                       @click="handleComplete"
                     >提交验收</el-button>
+                    <el-button 
+                      v-if="canClose()" 
+                      type="success" 
+                      icon="CircleCheck"
+                      @click="handleClose"
+                    >验收通过</el-button>
                     <el-button 
                       v-if="canReject()" 
                       type="info" 
@@ -286,6 +292,7 @@
               
               <!-- 处理历史 -->
               <el-tab-pane label="处理历史" name="history">
+                <div class="timeline-scroll">
                 <el-timeline v-if="currentOrderLogs && currentOrderLogs.length > 0">
                   <el-timeline-item 
                     v-for="log in currentOrderLogs" 
@@ -297,6 +304,7 @@
                   >
                     <el-card shadow="hover">
                       <div class="timeline-content">
+                        <div class="timestamp">{{ formatDate(log.operTime) }}</div>
                         <div class="operator-info">
                           <span class="operator-name">{{ log.operUserName }}</span>
                           <span class="oper-type">· {{ getOperTypeLabel(log.operType) }}</span>
@@ -307,6 +315,7 @@
                   </el-timeline-item>
                 </el-timeline>
                 <el-empty v-else description="暂无处理记录" :image-size="100"></el-empty>
+                </div>
               </el-tab-pane>
             </el-tabs>
           </div>
@@ -394,13 +403,26 @@
         <el-button type="primary" @click="submitComplete">提交</el-button>
       </template>
     </el-dialog>
+    
+    <!-- 验收通过/结案弹窗 -->
+    <el-dialog v-model="closeDialogVisible" title="验收通过" width="500px">
+      <el-form label-width="80px">
+        <el-form-item label="验收结果">
+          <el-input v-model="closeForm.result" type="textarea" :rows="4" placeholder="请输入验收结果/整改反馈" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="closeDialogVisible = false">取消</el-button>
+        <el-button type="primary" @click="submitClose">确认验收</el-button>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
 <script setup name="DrainageWorkOrder">
 import { ElMessage } from 'element-plus'
 import ImagePreview from '@/components/ImagePreview/index.vue'
-import { listWorkOrder, getWorkOrderDetail, dispatchWorkOrder, verifyWorkOrder, processWorkOrder, completeWorkOrder } from '@/api/work/order.js'
+import { listWorkOrder, getWorkOrderDetail, dispatchWorkOrder, verifyWorkOrder, processWorkOrder, completeWorkOrder, closeWorkOrder } from '@/api/work/order.js'
 import { listDept } from '@/api/system/dept.js'
 import { listUser } from '@/api/system/user.js'
 import { handleTree } from '@/utils/ruoyi.js'
@@ -544,6 +566,7 @@ function canDispatch() { return selectedOrder.value.orderStatus === 1 }
 function canVerify() { return [2, 3].includes(selectedOrder.value.orderStatus) }
 function canProcess() { return [3, 4].includes(selectedOrder.value.orderStatus) }
 function canComplete() { return selectedOrder.value.orderStatus === 4 }
+function canClose() { return selectedOrder.value.orderStatus === 5 }
 function canReject() { return [1, 2].includes(selectedOrder.value.orderStatus) }
 
 function handleDispatch() {
@@ -664,6 +687,37 @@ function handleReject() {
   // TODO: 实现驳回逻辑
 }
 
+/** 验收通过/结案相关 */
+const closeDialogVisible = ref(false)
+const closeForm = reactive({ result: '' })
+
+function handleClose() {
+  if (selectedOrder.value.orderStatus !== 5) {
+    ElMessage.warning('当前工单不允许验收通过')
+    return
+  }
+  closeForm.result = ''
+  closeDialogVisible.value = true
+}
+
+async function submitClose() {
+  if (!closeForm.result.trim()) {
+    ElMessage.warning('请填写验收结果')
+    return
+  }
+  try {
+    await closeWorkOrder({
+      orderId: selectedOrder.value.orderId,
+      result: closeForm.result
+    })
+    ElMessage.success('验收通过,关联隐患已同步为已整改')
+    closeDialogVisible.value = false
+    handleSearch()
+  } catch (e) {
+    ElMessage.error('验收失败')
+  }
+}
+
 /** 辅助函数 */
 function getOrderTypeText(type) {
   const map = { 1: '故障维修', 2: '日常巡检', 3: '设备保养' }
@@ -849,6 +903,12 @@ onMounted(() => {
     margin-top: 16px;
   }
   
+  .timeline-scroll {
+    max-height: calc(100vh - 340px);
+    overflow-y: auto;
+    padding-right: 8px;
+  }
+  
   .image-section {
     margin-top: 24px;
     padding-top: 24px;
@@ -884,6 +944,12 @@ onMounted(() => {
   }
   
   .timeline-content {
+    .timestamp {
+      font-size: 12px;
+      color: #909399;
+      margin-bottom: 6px;
+    }
+    
     .operator-info {
       font-size: 14px;
       margin-bottom: 8px;

+ 3 - 3
src/views/subSystem/hidden/HazardList.vue

@@ -307,7 +307,7 @@ const rules = {
 
 const formData = reactive({
   hazardId: '', hazardNo: '', hazardType: '', hazardLevel: '', hazardDesc: '',
-  hazardSource: '', hazardStatus: '2', reportUnit: '', reportTime: '',
+  hazardSource: '', hazardStatus: '待核查', reportUnit: '', reportTime: '',
   rectifyPlan: '', rectifyDeadline: '', rectifyPerson: '',
   networkId: '', equipmentId: '', longitude: null, latitude: null,
   hazardImages: ''
@@ -342,7 +342,7 @@ function levelTag(value) {
   return map[value] || 'info'
 }
 function statusTag(value) {
-  const map = { '0': 'info', '1': 'success', '2': 'warning', '3': '' }
+  const map = { '待核查': 'info', '整改中': 'warning', '已整改': 'success', '已闭环': '' }
   return map[value] || 'info'
 }
 
@@ -444,7 +444,7 @@ function generateHazardNo() {
 }
 function handleAdd() {
   dialogTitle.value = '新增'
-  Object.assign(formData, { hazardId: '', hazardNo: generateHazardNo(), hazardType: '', hazardLevel: '', hazardDesc: '', hazardSource: '', hazardStatus: '2', reportUnit: '', reportTime: '', rectifyPlan: '', rectifyDeadline: '', rectifyPerson: '', networkId: '', equipmentId: '', longitude: null, latitude: null, hazardImages: '' })
+  Object.assign(formData, { hazardId: '', hazardNo: generateHazardNo(), hazardType: '', hazardLevel: '', hazardDesc: '', hazardSource: '', hazardStatus: '待核查', reportUnit: '', reportTime: '', rectifyPlan: '', rectifyDeadline: '', rectifyPerson: '', networkId: '', equipmentId: '', longitude: null, latitude: null, hazardImages: '', isSubmitted: null, submitTime: null, verifyPerson: null, verifyTime: null })
   imageList.value = []
   imageUrls.value = []
   dialogVisible.value = true

+ 8 - 7
src/views/subSystem/hidden/HazardMap.vue

@@ -144,12 +144,12 @@ function levelTag(level) {
   return map[String(level)] || ''
 }
 function statusTag(status) {
-  const map = { '1': 'danger', '2': 'warning', '3': 'success' }
-  return map[String(status)] || 'info'
+  const map = { '待核查': 'info', '整改中': 'warning', '已整改': 'success', '已闭环': '' }
+  return map[status] || 'info'
 }
 function statusTabColor(status) {
-  const map = { '1': '#f56c6c', '2': '#e6a23c', '3': '#67c23a' }
-  return map[String(status)] || '#409eff'
+  const map = { '待核查': '#909399', '整改中': '#e6a23c', '已整改': '#67c23a', '已闭环': '#409eff' }
+  return map[status] || '#409eff'
 }
 function switchStatusTab(val) {
   listStatusTab.value = val
@@ -351,9 +351,10 @@ async function loadDicts() {
       { dictValue: '3', dictLabel: '低风险' }
     ]
     hazardStatusDict.value = [
-      { dictValue: '1', dictLabel: '待整改' },
-      { dictValue: '2', dictLabel: '整改中' },
-      { dictValue: '3', dictLabel: '已整改' }
+      { dictValue: '待核查', dictLabel: '待核查' },
+      { dictValue: '整改中', dictLabel: '整改中' },
+      { dictValue: '已整改', dictLabel: '已整改' },
+      { dictValue: '已闭环', dictLabel: '已闭环' }
     ]
   }
 }