Browse Source

维修工单调整

ouyj 7 months ago
parent
commit
274d0b0ef2

+ 1 - 1
ygtx-gxt/src/main/java/com/ygtx/gxt/domain/GxtRepairOrderFlow.java

@@ -28,7 +28,7 @@ public class GxtRepairOrderFlow extends BaseEntity
     @Excel(name = "工单编码")
     private String orderCode;
 
-    /** 操作类型:create-创建工单,assign-下发工单,accept-接单,process-处理工单,pause-暂停,suspend-挂起,restart-重启,approve-审批,complete-完成工单,create_to_assign-创建并下发工单,to_approve-申请挂起工单,approved-挂起审批通过,rejected-挂起审批驳回,rating-工单评分,restart-设备复运 */
+    /** 操作类型:create-创建工单,assign-下发工单,accept-接单,process-处理工单,pause-暂停,suspend-挂起,restart-重启,approve-审批,complete-完成工单,create_to_assign-创建并下发工单,to_approve-申请挂起工单,approved-挂起审批通过,rejected-挂起审批驳回,rating-工单评分,restart-设备复运行,archive-工单归档 */
     //@Excel(name = "操作类型:create-创建工单,assign-下发工单,accept-接单,process-处理工单,pause-暂停,suspend-挂起,restart-重启,approve-审批,complete-完成工单,create_to_assign-创建并下发工单,to_approve-申请挂起工单,approved-挂起审批通过,rejected-挂起审批驳回,rating-工单评分")
     private String actionType;
 

+ 3 - 3
ygtx-gxt/src/main/java/com/ygtx/gxt/service/impl/GxtRepairOrderServiceImpl.java

@@ -447,7 +447,7 @@ public class GxtRepairOrderServiceImpl implements IGxtRepairOrderService
             flow.setOperatorId(SecurityUtils.getUserId());
             flow.setOperatorName(nickName);
             flow.setActionTime(DateUtils.getNowDate());
-            flow.setActionRemark("对维修工单进行评分");
+            flow.setActionRemark("对维修工单进行评分。分数:"+gxtRepairOrder.getScore());
             gxtRepairOrderFlowService.insertGxtRepairOrderFlow(flow);
         }
         
@@ -590,7 +590,7 @@ public class GxtRepairOrderServiceImpl implements IGxtRepairOrderService
             flow.setOperatorId(SecurityUtils.getUserId());
             flow.setOperatorName(nickName);
             flow.setActionTime(DateUtils.getNowDate());
-            flow.setActionRemark("完成维修工单");
+            flow.setActionRemark("完成维修工单。维修人员:"+memberNames);
             gxtRepairOrderFlowService.insertGxtRepairOrderFlow(flow);
         }
         return result;
@@ -626,7 +626,7 @@ public class GxtRepairOrderServiceImpl implements IGxtRepairOrderService
             flow.setOperatorId(SecurityUtils.getUserId());
             flow.setOperatorName(nickName);
             flow.setActionTime(DateUtils.getNowDate());
-            flow.setActionRemark("复运维修工单");
+            flow.setActionRemark("设备恢复运行");
             gxtRepairOrderFlowService.insertGxtRepairOrderFlow(flow);
         }
         return result;

+ 132 - 0
ygtx-gxt/src/main/java/com/ygtx/gxt/task/RepairOrderArchiveTask.java

@@ -0,0 +1,132 @@
+package com.ygtx.gxt.task;
+
+import java.util.Date;
+import java.util.List;
+
+import com.ygtx.common.utils.DateUtils;
+import com.ygtx.gxt.domain.GxtRepairOrder;
+import com.ygtx.gxt.domain.GxtRepairOrderFlow;
+import com.ygtx.gxt.service.IGxtRepairOrderService;
+import com.ygtx.gxt.service.IGxtRepairOrderFlowService;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.EnableScheduling;
+import org.springframework.scheduling.annotation.Scheduled;
+import org.springframework.stereotype.Component;
+
+/**
+ * 维修工单自动归档任务
+ * 每小时执行,将已完成复运操作且评分3天后的工单自动归档
+ *
+ * @author lingma
+ * @date 2025-11-04
+ */
+@EnableScheduling
+@Component("repairOrderArchiveTask")
+public class RepairOrderArchiveTask {
+
+    private static final Logger log = LoggerFactory.getLogger(RepairOrderArchiveTask.class);
+
+    @Autowired
+    private IGxtRepairOrderService repairOrderService;
+
+    @Autowired
+    private IGxtRepairOrderFlowService repairOrderFlowService;
+
+    /**
+     * 每小时执行定时任务
+     * 查找已完成复运操作且评分为非空的工单,并进行归档
+     */
+    @Scheduled(cron = "0 0 * * * ?")
+    public void archiveRepairOrders() {
+        log.info("开始执行维修工单自动归档任务");
+
+        try {
+            // 构造查询条件:已完成复运操作且评分为非空的工单
+            GxtRepairOrder queryOrder = new GxtRepairOrder();
+            queryOrder.setWorkOrderStatus("to_archive"); // 待归档状态
+            List<GxtRepairOrder> orders = repairOrderService.selectGxtRepairOrderList(queryOrder);
+
+            int archiveCount = 0;
+            for (GxtRepairOrder order : orders) {
+                // 检查是否满足归档条件(最后操作时间已过去3天)
+                if (shouldArchive(order)) {
+                    // 执行归档操作
+                    archiveOrder(order);
+                    archiveCount++;
+                }
+            }
+
+            log.info("维修工单自动归档任务执行完成,共归档 {} 个工单", archiveCount);
+        } catch (Exception e) {
+            log.error("执行维修工单自动归档任务时发生异常", e);
+        }
+    }
+
+    /**
+     * 判断工单是否满足归档条件
+     * 条件:已完成复运操作且评分3天后(以较晚的时间为准)
+     *
+     * @param order 维修工单
+     * @return 是否满足归档条件
+     */
+    private boolean shouldArchive(GxtRepairOrder order) {
+        // 获取工单的复运时间和评分时间
+        Date restartTime = order.getRestartTime();
+        Date scoreTime = null;
+        
+        // 通过查询工单流转记录获取评分时间
+        GxtRepairOrderFlow flowQuery = new GxtRepairOrderFlow();
+        flowQuery.setOrderId(order.getId());
+        flowQuery.setActionType("rating");
+        List<GxtRepairOrderFlow> flows = repairOrderFlowService.selectGxtRepairOrderFlowList(flowQuery);
+        
+        if (!flows.isEmpty()) {
+            // 获取最后一次评分的时间
+            scoreTime = flows.get(flows.size() - 1).getActionTime();
+        }
+
+        // 如果没有复运时间或评分时间,则不满足归档条件
+        if (restartTime == null || scoreTime == null) {
+            return false;
+        }
+
+        // 取复运时间和评分时间中较晚的一个作为基准时间
+        Date lastOperationTime = restartTime.after(scoreTime) ? restartTime : scoreTime;
+
+        // 检查最后操作时间是否已过去3天
+        Date now = DateUtils.getNowDate();
+        Date threeDaysAfterLastOperation = DateUtils.addDays(lastOperationTime, 3);
+
+        return now.after(threeDaysAfterLastOperation);
+    }
+
+    /**
+     * 对工单进行归档操作
+     *
+     * @param order 需要归档的工单
+     */
+    private void archiveOrder(GxtRepairOrder order) {
+        // 更新工单状态为已归档
+        order.setWorkOrderStatus("archived");
+        repairOrderService.updateGxtRepairOrder(order);
+
+        // 添加归档流程记录
+        GxtRepairOrderFlow flow = new GxtRepairOrderFlow();
+        flow.setOrderId(order.getId());
+        flow.setOrderCode(order.getWorkOrderProjectNo());
+        flow.setActionType("archive");
+        flow.setFromStatus("to_archive");
+        flow.setToStatus("archived");
+        flow.setOperatorId(1L); // 系统自动操作,使用系统用户ID
+        flow.setOperatorName("系统自动");
+        flow.setActionTime(DateUtils.getNowDate());
+        flow.setActionRemark("系统自动归档工单");
+
+        repairOrderFlowService.insertGxtRepairOrderFlow(flow);
+
+        log.info("工单 {} 已成功归档", order.getWorkOrderProjectNo());
+    }
+}

+ 6 - 1
ygtx-gxt/src/main/resources/mapper/gxt/GxtRepairOrderMapper.xml

@@ -51,10 +51,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         <result property="relatedOrderCode"    column="related_order_code"    />
         <result property="relatedOrderContent"    column="related_order_content"    />
         <result property="misOrderNo"    column="mis_order_no"    />
+        <result property="restartTime"    column="restart_time"    />
     </resultMap>
 
     <sql id="selectGxtRepairOrderVo">
-        select id, work_order_project_no, work_order_status, gxt_center_id, gxt_center, pcs_station_id, pcs_station_name, pcs_device_id, pcs_device_name, brand, model, fault_code, fault_desc, assign_time, assign_user_id, assign_user_name, accept_time, accept_user_id, accept_user_name, real_start_time, real_end_time, team_leader_id, team_leader_name, work_group_member_id, work_group_member_name, create_by, create_time, update_by, update_time, remark, content, plan_hour, priority_type, score, review_content, maintenance_type, occur_time, fault_barcode, suspend_reason, suspend_description, approval_status, rejection_reason, finalization_remark, related_order_code, related_order_content, mis_order_no from gxt_repair_order
+        select id, work_order_project_no, work_order_status, gxt_center_id, gxt_center, pcs_station_id, pcs_station_name, pcs_device_id, pcs_device_name, brand, model, fault_code, fault_desc, assign_time, assign_user_id, assign_user_name, accept_time, accept_user_id, accept_user_name, real_start_time, real_end_time, team_leader_id, team_leader_name, work_group_member_id, work_group_member_name, create_by, create_time, update_by, update_time, remark, content, plan_hour, priority_type, score, review_content, maintenance_type, occur_time, fault_barcode, suspend_reason, suspend_description, approval_status, rejection_reason, finalization_remark, related_order_code, related_order_content, mis_order_no, restart_time from gxt_repair_order
     </sql>
 
     <select id="selectGxtRepairOrderList" parameterType="GxtRepairOrder" resultMap="GxtRepairOrderResult">
@@ -100,6 +101,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="relatedOrderCode != null  and relatedOrderCode != ''"> and related_order_code = #{relatedOrderCode}</if>
             <if test="relatedOrderContent != null  and relatedOrderContent != ''"> and related_order_content = #{relatedOrderContent}</if>
             <if test="misOrderNo != null  and misOrderNo != ''"> and mis_order_no = #{misOrderNo}</if>
+            <if test="restartTime != null "> and restart_time = #{restartTime}</if>
         </where>
         order by id desc
     </select>
@@ -157,6 +159,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="relatedOrderCode != null">related_order_code,</if>
             <if test="relatedOrderContent != null">related_order_content,</if>
             <if test="misOrderNo != null">mis_order_no,</if>
+            <if test="restartTime != null">restart_time,</if>
          </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
             <if test="workOrderProjectNo != null and workOrderProjectNo != ''">#{workOrderProjectNo},</if>
@@ -204,6 +207,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="relatedOrderCode != null">#{relatedOrderCode},</if>
             <if test="relatedOrderContent != null">#{relatedOrderContent},</if>
             <if test="misOrderNo != null">#{misOrderNo},</if>
+            <if test="restartTime != null">#{restartTime},</if>
          </trim>
     </insert>
 
@@ -255,6 +259,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="relatedOrderCode != null">related_order_code = #{relatedOrderCode},</if>
             <if test="relatedOrderContent != null">related_order_content = #{relatedOrderContent},</if>
             <if test="misOrderNo != null">mis_order_no = #{misOrderNo},</if>
+            <if test="restartTime != null">restart_time = #{restartTime},</if>
         </trim>
         where id = #{id}
     </update>

+ 45 - 26
ygtx-ui/src/views/gxt/repairOrder/index.vue

@@ -167,7 +167,7 @@
           <dict-tag :options="gxt_order_priority_type" :value="scope.row.priorityType" />
         </template>
       </el-table-column>-->
-      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" min-width="300" fixed="right">
+      <el-table-column label="操作" align="center" class-name="small-padding fixed-width" min-width="220" fixed="right">
         <template #default="scope">
           <el-button 
             v-if="scope.row.workOrderStatus === 'to_issue'"
@@ -1005,24 +1005,24 @@
     </el-dialog>
     
     <!-- 复运对话框 -->
-    <el-dialog title="复运" v-model="restartDialogVisible" width="500px" append-to-body @close="closeRestartDialog">
+    <el-dialog title="复运" v-model="restartDialogVisible" width="800px" append-to-body @close="closeRestartDialog">
       <el-form ref="restartFormRef" :model="restartForm" :rules="restartRules" label-width="120px">
         <el-row>
-          <el-col :span="24">
+          <el-col :span="12">
             <el-form-item label="工单编码">{{ restartForm.workOrderProjectNo }}</el-form-item>
           </el-col>
-          <el-col :span="24">
+          <el-col :span="12">
             <el-form-item label="风机编号">{{ restartForm.pcsDeviceName }}</el-form-item>
           </el-col>
           <el-col :span="24">
+            <el-form-item label="维修内容">{{ restartForm.content }}</el-form-item>
+          </el-col>
+          <el-col :span="12">
             <el-form-item label="检修类型">
               <dict-tag :options="gxt_maintenance_type" :value="restartForm.maintenanceType" />
             </el-form-item>
           </el-col>
-          <el-col :span="24">
-            <el-form-item label="维修内容">{{ restartForm.content }}</el-form-item>
-          </el-col>
-          <el-col :span="24">
+          <el-col :span="12">
             <el-form-item label="恢复运行时间" prop="restartTime">
               <el-date-picker
                 v-model="restartForm.restartTime"
@@ -1129,30 +1129,24 @@
         
         <!-- 工单流转记录 -->
         <el-col :span="8">
-          <el-card>
-            <template #header>
-              <div class="card-header">
-                <span>工单流转记录</span>
-              </div>
-            </template>
-            <el-timeline>
-              <el-timeline-item
+          <div class="flow-history">
+            <h3>工单流转记录</h3>
+            <el-timeline style="margin-left: -30px">
+              <el-timeline-item type="primary"
                 v-for="(flow, index) in flowList"
                 :key="index"
-                :timestamp="parseTime(flow.actionTime, '{y}-{m}-{d} {h}:{i}:{s}')"
-                placement="top"
+                :timestamp="parseTime(flow.actionTime, '{y}-{m}-{d} {h}:{i}:{s}')" 
               >
-                <el-card>
-                  <h4>{{ flow.actionType }}</h4>
+                <div class="flow-item">
+                  <h4><dict-tag :options="gxt_repair_order_flow_action_type" :value="flow.actionType" /></h4>
                   <p>
-                    状态变更: {{ getDictLabel(gxt_work_order_status, flow.fromStatus) }} → {{ getDictLabel(gxt_work_order_status, flow.toStatus) }}<br>
-                    操作人: {{ flow.operatorName }}<br>
-                    备注: {{ flow.actionRemark }}
+<!--                    {{ flow.actionRemark }}<br>-->
+                    {{ flow.operatorName }}
                   </p>
-                </el-card>
+                </div>
               </el-timeline-item>
             </el-timeline>
-          </el-card>
+          </div>
         </el-col>
       </el-row>
       
@@ -1194,10 +1188,11 @@ import { listUser } from "@/api/system/user";
 import EquipmentSelectSingle from "@/components/equipmentSelect/single.vue"
 
 const { proxy } = getCurrentInstance()
-const { gxt_maintenance_type, gxt_work_order_status, gxt_order_priority_type } = proxy.useDict("gxt_maintenance_type", "gxt_work_order_status", "gxt_order_priority_type")
+const { gxt_maintenance_type, gxt_work_order_status, gxt_order_priority_type,gxt_repair_order_flow_action_type } = proxy.useDict("gxt_maintenance_type", "gxt_work_order_status", "gxt_order_priority_type","gxt_repair_order_flow_action_type")
 
 // 数据列表相关
 const repairOrderList = ref([])
+
 const openDialog = ref(false)
 const viewDialogVisible = ref(false)
 const loading = ref(true)
@@ -2233,4 +2228,28 @@ onUnmounted(() => {
   font-weight: bold;
   font-size: 16px;
 }
+
+.flow-history h3 {
+  font-weight: bold;
+  font-size: 16px;
+  margin-bottom: 15px;
+}
+
+.flow-item {
+  /*padding: 10px;
+  border-radius: 4px;*/
+}
+
+.flow-item h4 {
+  margin: 0 0 5px 0;
+  font-size: 14px;
+  font-weight: bold;
+}
+
+.flow-item p {
+  margin: 0;
+  font-size: 12px;
+  line-height: 1.4;
+  color: #606266;
+}
 </style>