소스 검색

feat(repair): 增强维修工单功能并新增停机设备展示

- 工单详情页恢复"是否停机"字段并新增派工/接单时间步骤
- 维修表单和完成表单增加完成时间不早于开始时间的校验
- 故障大屏新增停机设备红色图例及点位渲染
- 工单列表增加维修开始时间、结束时间、耗时列
- 维修工时报表临时隐藏按月度统计页签
dazhaxie 1 주 전
부모
커밋
7cef2da26d

+ 13 - 13
public/hitch-screen/index.html

@@ -21,7 +21,7 @@
   <div class="title-icon">
     <label class="legend-item legend-normal"><input type="checkbox" id="filterNormal" checked> 正常设备</label>
     <label class="legend-item legend-yellow"><input type="checkbox" id="filterPlanned" checked> 问题设备</label>
-    <!--    <label class="legend-item legend-red"><input type="checkbox" id="filterUnplanned" checked> 非计划性维修设备</label>-->
+    <label class="legend-item legend-red"><input type="checkbox" id="filterStopped" checked> 停机设备</label>
   </div>
   <div style="display:flex;width:1920px;justify-content:space-between;align-items:center;">
     <div id="echart" class="echart"></div>
@@ -279,7 +279,7 @@
       data: [
       ]
     }, {
-      name: '红色非计划性报修异常点',
+      name: '红色停机设备异常点',
       type: 'effectScatter',
       coordinateSystem: 'geo',
       data: [
@@ -305,7 +305,7 @@
       },
       zlevel: 1
     }, {
-      name: '红色非计划性报修异常点编号',
+      name: '红色停机设备异常点编号',
       type: 'scatter',
       coordinateSystem: 'geo',
       symbol: 'pin', // 气泡
@@ -329,7 +329,7 @@
       data: [
       ]
     }, {
-      name: '黄色计划性报修异常点',
+      name: '黄色报修中异常点',
       type: 'effectScatter',
       coordinateSystem: 'geo',
       data: [
@@ -355,7 +355,7 @@
       },
       zlevel: 1
     }, {
-      name: '黄色计划性报修异常点编号',
+      name: '黄色报修中异常点编号',
       type: 'scatter',
       coordinateSystem: 'geo',
       symbol: 'pin', // 气泡
@@ -539,30 +539,30 @@
     };
     option.series[0].data = normalSbInfoList;// 正常数据:
     option.series[1].data = normalSbInfoList;// 正常数据的编号
-    option.series[2].data = repairSbInfoListRed;// 非计划性报修 红色编号
-    option.series[3].data = repairSbInfoListRed;// 非计划性报修 红色
-    option.series[4].data = repairSbInfoListYellow;// 计划性报修 黃色编号
-    option.series[5].data = repairSbInfoListYellow;// 计划性报修 黃色
+    option.series[2].data = repairSbInfoListRed;// 停机设备 红色编号
+    option.series[3].data = repairSbInfoListRed;// 停机设备 红色
+    option.series[4].data = repairSbInfoListYellow;// 有进行中报修单 黃色编号
+    option.series[5].data = repairSbInfoListYellow;// 有进行中报修单 黃色
     applyFilter();
   }
 
   function applyFilter() {
     const showNormal = $('#filterNormal').is(':checked');
     const showPlanned = $('#filterPlanned').is(':checked');
-    const showUnplanned = $('#filterUnplanned').is(':checked');
+    const showStopped = $('#filterStopped').is(':checked');
     const orig = option._originalData || { normal: [], red: [], yellow: [] };
 
     option.series[0].data = showNormal ? orig.normal : [];
     option.series[1].data = showNormal ? orig.normal : [];
-    option.series[2].data = showUnplanned ? orig.red : [];
-    option.series[3].data = showUnplanned ? orig.red : [];
+    option.series[2].data = showStopped ? orig.red : [];
+    option.series[3].data = showStopped ? orig.red : [];
     option.series[4].data = showPlanned ? orig.yellow : [];
     option.series[5].data = showPlanned ? orig.yellow : [];
 
     myChart.setOption(option, true);
   }
 
-  $('#filterNormal, #filterPlanned, #filterUnplanned').on('change', function () {
+  $('#filterNormal, #filterPlanned, #filterStopped').on('change', function () {
     applyFilter();
   });
   function getHeader() {

+ 31 - 0
src/views/hitch-screen/index.vue

@@ -19,6 +19,7 @@
           <div class="title-icon">
             <label class="legend-item legend-normal"><input type="checkbox" v-model="showNormal"> 正常设备</label>
             <label class="legend-item legend-yellow"><input type="checkbox" v-model="showPlanned"> 问题设备</label>
+            <label class="legend-item legend-red"><input type="checkbox" v-model="showStopped"> 停机设备</label>
           </div>
         </div>
 
@@ -36,6 +37,12 @@
             <span class="dot"></span>
             <span class="no-label">{{ item.no }}</span>
           </div>
+          <div v-for="item in visibleRedList" :key="'red-' + item.no" class="sb-point red"
+            :style="pointStyle(item)" @mouseenter="handlePointEnter(item)" @mouseleave="handlePointLeave">
+            <span class="ripple"></span>
+            <span class="dot"></span>
+            <span class="no-label">{{ item.no }}</span>
+          </div>
           <div v-if="tooltip.visible" class="sb-tooltip" :style="tooltipStyle">
             <div>设备编号:{{ tooltip.info.no }}</div>
             <div>设备名称:{{ tooltip.info.name }}</div>
@@ -100,6 +107,7 @@ export default {
       mapName: null,
       showNormal: true,
       showPlanned: true,
+      showStopped: true,
       screenData: null,
       jobData: {},
       tooltip: { visible: false, left: '0%', top: '0%', info: {} },
@@ -120,6 +128,11 @@ export default {
       if (!this.showPlanned || !this.screenData) return []
       return this.screenData.repairSbInfoListYellow || []
     },
+    // 停机(停用中)设备,后端已排除同时有进行中报修单的设备,所以不会与黄点重复
+    visibleRedList() {
+      if (!this.showStopped || !this.screenData) return []
+      return this.screenData.repairSbInfoListRed || []
+    },
     weekList() {
       return this.jobData.weekList || []
     },
@@ -270,6 +283,11 @@ export default {
     box-shadow: 0 0 6px yellow;
   }
 
+  label.legend-red::before {
+    background-color: red;
+    box-shadow: 0 0 6px red;
+  }
+
   input[type='checkbox'] {
     margin-right: 5px;
     cursor: pointer;
@@ -359,6 +377,19 @@ export default {
       box-shadow: 0 0 6px yellow;
     }
   }
+
+  &.red {
+
+    .dot,
+    .no-label {
+      background: red;
+    }
+
+    .ripple {
+      border-color: red;
+      box-shadow: 0 0 6px red;
+    }
+  }
 }
 
 @keyframes ripple {

+ 21 - 0
src/views/repair/application-form/RepairApplicationForm.vue

@@ -224,6 +224,27 @@ export default {
           scopedSlots: { customRender: 'needStop' }
         },
         {
+          title: '维修开始时间',
+          checked: true,
+          width: '200px',
+          dataIndex: 'repairStartTime'
+        },
+        {
+          title: '维修结束时间',
+          checked: true,
+          width: '200px',
+          dataIndex: 'repairEndTime'
+        },
+        {
+          title: '维修耗时',
+          checked: true,
+          width: '100px',
+          dataIndex: 'repairMinutes',
+          customRender: (text, record, index) => {
+            return text ? text + '小时' : '/'
+          }
+        },
+        {
           title: '紧急程度',
           checked: true,
           width: '120px',

+ 24 - 0
src/views/repair/application-form/RepairForm.vue

@@ -290,6 +290,30 @@ export default {
           scopedSlots: { customRender: 'needStop' }
         },
         {
+          title: '维修开始时间',
+          checked: true,
+          align: 'center',
+          width: '200px',
+          dataIndex: 'repairStartTime'
+        },
+        {
+          title: '维修结束时间',
+          checked: true,
+          align: 'center',
+          width: '200px',
+          dataIndex: 'repairEndTime'
+        },
+        {
+          title: '维修耗时',
+          checked: true,
+          align: 'center',
+          width: '100px',
+          dataIndex: 'repairMinutes',
+          customRender: (text, record, index) => {
+            return text ? text + '小时' : '/'
+          }
+        },
+        {
           title: '紧急程度',
           checked: true,
           align: 'center',

+ 2 - 2
src/views/repair/application-form/modules/Detail.vue

@@ -19,8 +19,7 @@
             <detail-list-item term="使用位置">{{ model.sbCph }}</detail-list-item>
             <!--<detail-list-item term="部件名称">{{ model.partName }}</detail-list-item>-->
             <detail-list-item term="工单类别">{{ BaseTool.Object.getField(planFlagMap, model.category) }}</detail-list-item>
-            <!--            <detail-list-item term="是否停机">{{ BaseTool.Object.getField(needStopMap,model.needStop) }}</detail-list-item>-->
-
+            <detail-list-item term="是否停机">{{ BaseTool.Object.getField(needStopMap, model.needStop) }}</detail-list-item>
             <detail-list-item term="报修人">{{ model.actualUser }}</detail-list-item>
             <detail-list-item term="报修来源">{{ BaseTool.Object.getField(this.sourceMap, model.source)
             }}</detail-list-item>
@@ -103,6 +102,7 @@
           <div style="margin-top: 30px;margin-left: 30px;">
             <a-steps progress-dot :current="6" direction="vertical">
               <a-step title="报修时间:" :description="'' + model.applyTime ? model.applyTime : ''" />
+              <a-step title="派工/接单时间:" :description="'' + model.repairDispatchTime ? model.repairDispatchTime : ''" />
               <a-step title="维修开始时间:" :description="'' + model.repairStartTime ? model.repairStartTime : ''" />
               <a-step title="维修结束时间:" :description="'' + model.repairEndTime ? model.repairEndTime : ''" />
               <a-step title="审核开始时间:" :description="'' + model.checkStartTime ? model.checkStartTime : ''" />

+ 2 - 1
src/views/repair/application-form/modules/DetailCheck.vue

@@ -30,7 +30,7 @@
             <detail-list-item term="使用位置">{{ model.sbCph }}</detail-list-item>
             <!--<detail-list-item term="部件名称">{{ model.partName }}</detail-list-item>-->
             <detail-list-item term="工单类别">{{ BaseTool.Object.getField(planFlagMap, model.category) }}</detail-list-item>
-            <!--            <detail-list-item term="是否停机">{{ BaseTool.Object.getField(needStopMap,model.needStop) }}</detail-list-item>-->
+            <detail-list-item term="是否停机">{{ BaseTool.Object.getField(needStopMap, model.needStop) }}</detail-list-item>
             <detail-list-item term="报修人">{{ model.actualUser }}</detail-list-item>
             <detail-list-item term="紧急程度">
               <badge :text="BaseTool.Object.getField(levelMap, model.level)"
@@ -114,6 +114,7 @@
           <div style="margin-top: 30px;margin-left: 30px;">
             <a-steps progress-dot :current="6" direction="vertical">
               <a-step title="报修时间:" :description="'' + model.applyTime ? model.applyTime : ''" />
+              <a-step title="派工/接单时间:" :description="'' + model.repairDispatchTime ? model.repairDispatchTime : ''" />
               <a-step title="维修开始时间:" :description="'' + model.repairStartTime ? model.repairStartTime : ''" />
               <a-step title="维修结束时间:" :description="'' + model.repairEndTime ? model.repairEndTime : ''" />
               <a-step title="审核开始时间:" :description="'' + model.checkStartTime ? model.checkStartTime : ''" />

+ 1 - 1
src/views/repair/application-form/modules/DetailRepair.vue

@@ -60,7 +60,7 @@
             <detail-list-item term="预留维修时间">{{ model.limitHours }}</detail-list-item>
             <detail-list-item term="使用位置">{{ model.sbCph }}</detail-list-item>
             <detail-list-item term="工单类别">{{ BaseTool.Object.getField(planFlagMap, model.category) }}</detail-list-item>
-            <!--            <detail-list-item term="是否停机">{{ BaseTool.Object.getField(needStopMap,model.needStop) }}</detail-list-item>-->
+            <detail-list-item term="是否停机">{{ BaseTool.Object.getField(needStopMap, model.needStop) }}</detail-list-item>
             <detail-list-item term="报修人">{{ model.actualUser }}</detail-list-item>
             <detail-list-item term="紧急程度">
               <badge :text="BaseTool.Object.getField(levelMap, model.level)"

+ 7 - 0
src/views/repair/application-form/modules/EditForm.vue

@@ -165,6 +165,13 @@ export default {
           this.confirmLoading = false
           return
         }
+        // 校验:完成时间不能早于接收(维修开始)时间
+        if (values.repairEndTime && values.repairStartTime &&
+          values.repairEndTime.isBefore(values.repairStartTime)) {
+          this.$message.error('完成时间不能早于维修开始时间')
+          this.confirmLoading = false
+          return
+        }
         // 日期处理
         values.repairFileList = this.repairFileList
         values.repairStartTime = this.BaseTool.Date.formatter(values.repairStartTime, this.BaseTool.Date.PICKER_NORM_DATETIME_PATTERN)

+ 9 - 0
src/views/repair/application-form/modules/FinishForm.vue

@@ -108,6 +108,7 @@
 
 <script>
 import pick from 'lodash.pick'
+import moment from 'moment'
 import { finish } from '@/api/repair/application-form'
 import { queryUser } from '@/api/upms/user'
 import { fetchErrorTypeTree } from '@/api/repair/errortype'
@@ -226,6 +227,14 @@ export default {
           this.confirmLoading = false
           return
         }
+        // 校验:完成时间不能早于维修开始时间
+        if (values.repairEndTime && this.model && this.model.repairStartTime) {
+          if (moment(values.repairEndTime).isBefore(moment(this.model.repairStartTime))) {
+            this.$message.error('完成时间不能早于维修开始时间')
+            this.confirmLoading = false
+            return
+          }
+        }
         // 日期处理
         values.repairFileList = this.repairFileList
         values.repairEndTime = this.BaseTool.Date.formatter(values.repairEndTime, this.BaseTool.Date.PICKER_NORM_DATETIME_PATTERN)

+ 3 - 1
src/views/report/repairworkhour/RepairWorkHour.vue

@@ -4,7 +4,9 @@
       <a-tabs v-model="activeTab" @change="handleTabChange">
         <a-tab-pane tab="按维修人统计" key="user"></a-tab-pane>
         <a-tab-pane tab="按设备统计" key="sb"></a-tab-pane>
+        <!-- 按月度统计功能暂不正确,先隐藏页签,逻辑代码保留待修复后恢复
         <a-tab-pane tab="按月度统计(设备平均维修工时)" key="month"></a-tab-pane>
+        -->
       </a-tabs>
 
       <div class="table-page-search-wrapper" @keyup.enter="handleSearch">
@@ -116,7 +118,7 @@ export default {
   },
   data () {
     return {
-      // 当前统计维度:user-按维修人,sb-按设备,month-按月度统计
+      // 当前统计维度:user-按维修人,sb-按设备,month-按月度统计(月度页签已临时隐藏,逻辑保留)
       activeTab: 'user',
       // 查询参数
       queryParam: {