HD_wangm пре 7 месеци
родитељ
комит
648ea7da91

+ 76 - 15
ygtx-gxt/src/main/java/com/ygtx/gxt/controller/GxtWorkOrderController.java

@@ -154,18 +154,18 @@ public class GxtWorkOrderController extends BaseController
         return toAjax(gxtWorkOrderService.acceptByWorkGroupMember(id));
     }
 
-    /**
-     * 挂起工单
-     */
-    @PreAuthorize("@ss.hasPermi('gxt:maintenance:order:suspend')")
-    @Log(title = "挂起工单", businessType = BusinessType.UPDATE)
-    @PutMapping("/suspend/{id}")
-    public AjaxResult suspend(
-            @PathVariable("id") Long id,
-            @RequestParam("suspendReason") String suspendReason)
-    {
-        return toAjax(gxtWorkOrderService.suspendWorkOrder(id, suspendReason));
-    }
+//    /**
+//     * 挂起工单
+//     */
+//    @PreAuthorize("@ss.hasPermi('worklog:maintenance:order:suspend')")
+//    @Log(title = "挂起工单", businessType = BusinessType.UPDATE)
+//    @PutMapping("/suspend/{id}")
+//    public AjaxResult suspend(
+//            @PathVariable("id") Long id,
+//            @RequestParam("suspendReason") String suspendReason)
+//    {
+//        return toAjax(gxtWorkOrderService.suspendWorkOrder(id, suspendReason));
+//    }
 
     /**
      * 重启工单
@@ -183,10 +183,11 @@ public class GxtWorkOrderController extends BaseController
      */
     @PreAuthorize("@ss.hasPermi('gxt:maintenance:order:complete')")
     @Log(title = "完成工单", businessType = BusinessType.UPDATE)
-    @PutMapping("/complete/{id}")
-    public AjaxResult complete(@PathVariable("id") Long id)
+    @PostMapping("/complete/{id}")
+    public AjaxResult complete(@PathVariable("id") Long id, @RequestBody GxtWorkOrder gxtWorkOrder)
     {
-        return toAjax(gxtWorkOrderService.completeWorkOrder(id));
+        gxtWorkOrder.setId(id);
+        return toAjax(gxtWorkOrderService.completeWorkOrder(gxtWorkOrder));
     }
 
     /**
@@ -211,4 +212,64 @@ public class GxtWorkOrderController extends BaseController
         gxtWorkOrder.setId(id);
         return toAjax(gxtWorkOrderService.acceptOrder(gxtWorkOrder));
     }
+
+    /**
+     * 开始处理工单
+     */
+    @PreAuthorize("@ss.hasPermi('gxt:maintenance:order:start')")
+    @Log(title = "开始处理", businessType = BusinessType.UPDATE)
+    @PostMapping("/start/{id}")
+    public AjaxResult start(@PathVariable("id") Long id, @RequestBody GxtWorkOrder gxtWorkOrder)
+    {
+        gxtWorkOrder.setId(id);
+        return toAjax(gxtWorkOrderService.startWorkOrder(gxtWorkOrder));
+    }
+
+    /**
+     * 暂停工单
+     */
+    @PreAuthorize("@ss.hasPermi('gxt:maintenance:order:pause')")
+    @Log(title = "暂停工单", businessType = BusinessType.UPDATE)
+    @PostMapping("/pause/{id}")
+    public AjaxResult pause(@PathVariable("id") Long id, @RequestBody GxtWorkOrder gxtWorkOrder)
+    {
+        gxtWorkOrder.setId(id);
+        return toAjax(gxtWorkOrderService.pauseWorkOrder(gxtWorkOrder));
+    }
+
+    /**
+     * 继续处理工单
+     */
+    @PreAuthorize("@ss.hasPermi('gxt:maintenance:order:resume')")
+    @Log(title = "继续处理", businessType = BusinessType.UPDATE)
+    @PostMapping("/resume/{id}")
+    public AjaxResult resume(@PathVariable("id") Long id, @RequestBody GxtWorkOrder gxtWorkOrder)
+    {
+        gxtWorkOrder.setId(id);
+        return toAjax(gxtWorkOrderService.resumeWorkOrder(gxtWorkOrder));
+    }
+
+    /**
+     * 挂起工单申请
+     */
+    @PreAuthorize("@ss.hasPermi('gxt:maintenance:order:suspend')")
+    @Log(title = "申请挂起", businessType = BusinessType.UPDATE)
+    @PostMapping("/suspend/{id}")
+    public AjaxResult suspend(@PathVariable("id") Long id, @RequestBody GxtWorkOrder gxtWorkOrder)
+    {
+        gxtWorkOrder.setId(id);
+        return toAjax(gxtWorkOrderService.suspendWorkOrder(gxtWorkOrder));
+    }
+
+    /**
+     * 审批挂起申请
+     */
+    @PreAuthorize("@ss.hasPermi('gxt:maintenance:order:approve')")
+    @Log(title = "审批挂起", businessType = BusinessType.UPDATE)
+    @PostMapping("/approve/{id}")
+    public AjaxResult approve(@PathVariable("id") Long id, @RequestBody GxtWorkOrder gxtWorkOrder)
+    {
+        gxtWorkOrder.setId(id);
+        return toAjax(gxtWorkOrderService.approveWorkOrder(gxtWorkOrder));
+    }
 }

+ 14 - 0
ygtx-gxt/src/main/java/com/ygtx/gxt/domain/GxtWorkOrder.java

@@ -133,6 +133,9 @@ public class GxtWorkOrder extends BaseEntity
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date suspendTime;
 
+    /** 驳回原因 */
+    private String rejectionReason;
+
     /** 暂停原因 */
     private String pauseReason;
 
@@ -450,6 +453,16 @@ public class GxtWorkOrder extends BaseEntity
         return suspendTime;
     }
 
+    public void setRejectionReason(String rejectionReason)
+    {
+        this.rejectionReason = rejectionReason;
+    }
+
+    public String getRejectionReason()
+    {
+        return rejectionReason;
+    }
+
     public String getPauseReason() {
         return pauseReason;
     }
@@ -583,6 +596,7 @@ public class GxtWorkOrder extends BaseEntity
             .append("workGroupMemberName", getWorkGroupMemberName())
             .append("suspendReason", getSuspendReason())
             .append("suspendTime", getSuspendTime())
+            .append("rejectionReason", getRejectionReason())
             .append("pauseReason", getPauseReason())
             .append("pauseTime", getPauseTime())
             .append("restartTime", getRestartTime())

+ 37 - 6
ygtx-gxt/src/main/java/com/ygtx/gxt/service/IGxtWorkOrderService.java

@@ -105,13 +105,44 @@ public interface IGxtWorkOrderService
     public int acceptOrder(GxtWorkOrder gxtWorkOrder);
 
     /**
-     * 挂起工单
+     * 开始处理工单
      *
-     * @param id 工单ID
-     * @param suspendReason 挂起原因
+     * @param gxtWorkOrder 工单对象,包含工单状态和其他信息
+     * @return 结果
+     */
+    public int startWorkOrder(GxtWorkOrder gxtWorkOrder);
+
+    /**
+     * 暂停工单
+     *
+     * @param gxtWorkOrder 工单对象,包含暂停原因不会
+     * @return 结果
+     */
+    public int pauseWorkOrder(GxtWorkOrder gxtWorkOrder);
+
+    /**
+     * 继续处理工单
+     *
+     * @param gxtWorkOrder 工单对象仅包含工单ID
      * @return 结果
      */
-    public int suspendWorkOrder(Long id, String suspendReason);
+    public int resumeWorkOrder(GxtWorkOrder gxtWorkOrder);
+
+    /**
+     * 审批挂起申请
+     *
+     * @param gxtWorkOrder 工单对象,包含审批结果不会
+     * @return 结果
+     */
+    public int approveWorkOrder(GxtWorkOrder gxtWorkOrder);
+
+    /**
+     * 挂起工单申请
+     *
+     * @param gxtWorkOrder 工单对象,包含挂起原因不会
+     * @return 结果
+     */
+    public int suspendWorkOrder(GxtWorkOrder gxtWorkOrder);
 
     /**
      * 重启工单
@@ -124,10 +155,10 @@ public interface IGxtWorkOrderService
     /**
      * 完成工单
      *
-     * @param id 工单ID
+     * @param gxtWorkOrder 工单对象,仅包含工单ID
      * @return 结果
      */
-    public int completeWorkOrder(Long id);
+    public int completeWorkOrder(GxtWorkOrder gxtWorkOrder);
 
     /**
      * 查询工单流转记录

+ 301 - 34
ygtx-gxt/src/main/java/com/ygtx/gxt/service/impl/GxtWorkOrderServiceImpl.java

@@ -338,43 +338,141 @@ public class GxtWorkOrderServiceImpl implements IGxtWorkOrderService
      * @param suspendReason 挂起原因
      * @return 结果
      */
+//    @Override
+//    @Transactional
+//    public int suspendWorkOrder(Long id, String suspendReason)
+//    {
+//        GxtWorkOrder order = gxtWorkOrderMapper.selectGxtWorkOrderById(id);
+//        if (order == null)
+//        {
+//            throw new ServiceException("工单不存在");
+//        }
+//
+//        // 仅有处理中的工单才能挂起
+//        if (!"processing".equals(order.getWorkOrderStatus()) && !"paused".equals(order.getWorkOrderStatus()))
+//        {
+//            throw new ServiceException("只有处理中的工单才能挂起");
+//        }
+//
+//        // 验证是否为班组组长或工作组成员
+//        Long currentUserId = SecurityUtils.getUserId();
+//        if (!currentUserId.equals(order.getTeamLeaderId()) && !currentUserId.equals(order.getWorkGroupMemberId()))
+//        {
+//            throw new ServiceException("只有班组组长或工作组成员才能挂起工单");
+//        }
+//
+//        String oldStatus = order.getWorkOrderStatus();
+//
+//        order.setSuspendReason(suspendReason);
+//        order.setSuspendTime(DateUtils.getNowDate());
+//        order.setWorkOrderStatus("suspended");
+//        order.setUpdateTime(DateUtils.getNowDate());
+//
+//        int result = gxtWorkOrderMapper.updateGxtWorkOrder(order);
+//
+//        // 记录流转
+//        if (result > 0)
+//        {
+//            recordWorkOrderFlow(id, order.getWorkOrderProjectNo(), "suspend", oldStatus, "suspended",
+//                    "挂起工单,原因:" + suspendReason);
+//        }
+//
+//        return result;
+//    }
+
+    /**
+     * 挂起工单申请
+     *
+     * @param gxtWorkOrder 工单对象,包含挂起原因不会
+     * @return 结果
+     */
     @Override
     @Transactional
-    public int suspendWorkOrder(Long id, String suspendReason)
+    public int suspendWorkOrder(GxtWorkOrder gxtWorkOrder)
     {
+        Long id = gxtWorkOrder.getId();
         GxtWorkOrder order = gxtWorkOrderMapper.selectGxtWorkOrderById(id);
         if (order == null)
         {
             throw new ServiceException("工单不存在");
         }
 
-        // 只有处理中的工单才能挂起
-        if (!"processing".equals(order.getWorkOrderStatus()) && !"paused".equals(order.getWorkOrderStatus()))
+        // 仅有处理中状态才能申请挂起
+        if (!"processing".equals(order.getWorkOrderStatus()))
         {
-            throw new ServiceException("只有处理中的工单才能挂起");
+            throw new ServiceException("当前工单状态不允许申请挂起");
         }
 
-        // 验证是否为班组组长或工作组成员
-        Long currentUserId = SecurityUtils.getUserId();
-        if (!currentUserId.equals(order.getTeamLeaderId()) && !currentUserId.equals(order.getWorkGroupMemberId()))
+        String oldStatus = order.getWorkOrderStatus();
+
+        // 更新工单信息 - 挂起申请后状态变为TO_APPROVE,待审批通过才能正式挂起
+        order.setSuspendReason(gxtWorkOrder.getSuspendReason());
+        order.setSuspendTime(DateUtils.getNowDate());
+        order.setWorkOrderStatus("to_approve");
+        order.setUpdateTime(DateUtils.getNowDate());
+
+        int result = gxtWorkOrderMapper.updateGxtWorkOrder(order);
+
+        if (result > 0)
+        {
+            // 记录流转
+            recordWorkOrderFlow(id, order.getWorkOrderProjectNo(), "suspend", oldStatus, "to_approve",
+                    "申请挂起,原因: " + gxtWorkOrder.getSuspendReason());
+        }
+
+        return result;
+    }
+
+    /**
+     * 审批挂起申请
+     *
+     * @param gxtWorkOrder 工单对象,包含审批结果和驳回理由
+     * @return 结果
+     */
+    @Override
+    @Transactional
+    public int approveWorkOrder(GxtWorkOrder gxtWorkOrder)
+    {
+        Long id = gxtWorkOrder.getId();
+        GxtWorkOrder order = gxtWorkOrderMapper.selectGxtWorkOrderById(id);
+        if (order == null)
+        {
+            throw new ServiceException("工单不存在");
+        }
+
+        // 仅有待审批状态才能审批
+        if (!"to_approve".equals(order.getWorkOrderStatus()))
         {
-            throw new ServiceException("只有班组组长或工作组成员才能挂起工单");
+            throw new ServiceException("当前工单状态不允许审批");
         }
 
         String oldStatus = order.getWorkOrderStatus();
+        String newStatus = gxtWorkOrder.getWorkOrderStatus();
+        String actionRemark;
 
-        order.setSuspendReason(suspendReason);
-        order.setSuspendTime(DateUtils.getNowDate());
-        order.setWorkOrderStatus("suspended");
+        // 根据工单状态判断审批结果
+        if ("suspended".equals(newStatus))
+        {
+            actionRemark = "审批挂起申请通过,工单已挂起";
+        }
+        else if ("accepted".equals(newStatus))
+        {
+            actionRemark = "审批挂起申请驳回,驳回原因: " + gxtWorkOrder.getRejectionReason();
+        }
+        else
+        {
+            throw new ServiceException("无效的工单状态");
+        }
+
+        order.setWorkOrderStatus(newStatus);
         order.setUpdateTime(DateUtils.getNowDate());
 
         int result = gxtWorkOrderMapper.updateGxtWorkOrder(order);
 
-        // 记录流转
         if (result > 0)
         {
-            recordWorkOrderFlow(id, order.getWorkOrderProjectNo(), "suspend", oldStatus, "suspended",
-                    "挂起工单,原因:" + suspendReason);
+            // 记录流转
+            recordWorkOrderFlow(id, order.getWorkOrderProjectNo(), "approve", oldStatus, newStatus, actionRemark);
         }
 
         return result;
@@ -435,43 +533,90 @@ public class GxtWorkOrderServiceImpl implements IGxtWorkOrderService
      */
     @Override
     @Transactional
-    public int completeWorkOrder(Long id)
+    public int completeWorkOrder(GxtWorkOrder gxtWorkOrder)
     {
+        Long id = gxtWorkOrder.getId();
         GxtWorkOrder order = gxtWorkOrderMapper.selectGxtWorkOrderById(id);
         if (order == null)
         {
             throw new ServiceException("工单不存在");
         }
 
-        // 只有处理中的工单才能完成
-        if (!"processing".equals(order.getWorkOrderStatus()))
+        String targetStatus = gxtWorkOrder.getWorkOrderStatus();
+
+        // 判断是结束还是结单还是评分
+        if ("to_finish".equals(targetStatus))
         {
-            throw new ServiceException("只有处理中的工单才能完成");
-        }
+            // 结束:仅有处理中的工单才能结束
+            if (!"processing".equals(order.getWorkOrderStatus()))
+            {
+                throw new ServiceException("仅有处理中的工单才能结束");
+            }
 
-        // 验证是否为工作组成员或班组组长
-        Long currentUserId = SecurityUtils.getUserId();
-        if (!currentUserId.equals(order.getWorkGroupMemberId()) && !currentUserId.equals(order.getTeamLeaderId()))
+            String oldStatus = order.getWorkOrderStatus();
+            order.setWorkOrderStatus("to_finish");
+            order.setRealEndTime(DateUtils.getNowDate());
+            order.setUpdateTime(DateUtils.getNowDate());
+
+            int result = gxtWorkOrderMapper.updateGxtWorkOrder(order);
+
+            if (result > 0)
+            {
+                recordWorkOrderFlow(id, order.getWorkOrderProjectNo(), "complete", oldStatus, "to_finish",
+                        "处理完成,工单状态变为待结单");
+            }
+
+            return result;
+        }
+        else if ("completed".equals(targetStatus))
         {
-            throw new ServiceException("只有工作组成员或班组组长才能完成工单");
+            // 结单:仅有待结单的工单才能结单
+            if (!"to_finish".equals(order.getWorkOrderStatus()))
+            {
+                throw new ServiceException("仅有待结单的工单才能结单");
+            }
+
+            String oldStatus = order.getWorkOrderStatus();
+            order.setWorkOrderStatus("completed");
+            order.setCompleteTime(DateUtils.getNowDate());
+            order.setUpdateTime(DateUtils.getNowDate());
+
+            int result = gxtWorkOrderMapper.updateGxtWorkOrder(order);
+
+            if (result > 0)
+            {
+                recordWorkOrderFlow(id, order.getWorkOrderProjectNo(), "finish", oldStatus, "completed",
+                        "工单完成,工单状态变为已完成");
+            }
+
+            return result;
         }
+        else if ("to_archive".equals(targetStatus))
+        {
+            // 评分:仅有已完成的工单才能评分
+            if (!"completed".equals(order.getWorkOrderStatus()))
+            {
+                throw new ServiceException("仅有已完成的工单才能评分");
+            }
 
-        String oldStatus = order.getWorkOrderStatus();
+            String oldStatus = order.getWorkOrderStatus();
+            order.setWorkOrderStatus("to_archive");
+            order.setUpdateTime(DateUtils.getNowDate());
 
-        order.setCompleteTime(DateUtils.getNowDate());
-        order.setWorkOrderStatus("completed");
-        order.setUpdateTime(DateUtils.getNowDate());
+            int result = gxtWorkOrderMapper.updateGxtWorkOrder(order);
 
-        int result = gxtWorkOrderMapper.updateGxtWorkOrder(order);
+            if (result > 0)
+            {
+                recordWorkOrderFlow(id, order.getWorkOrderProjectNo(), "rate", oldStatus, "to_archive",
+                        "工单已评分,工单状态变为待归档");
+            }
 
-        // 记录流转
-        if (result > 0)
+            return result;
+        }
+        else
         {
-            recordWorkOrderFlow(id, order.getWorkOrderProjectNo(), "complete", oldStatus, "completed",
-                    "工单完成");
+            throw new ServiceException("当前的工单状态不允许此操作");
         }
-
-        return result;
     }
 
     /**
@@ -588,4 +733,126 @@ public class GxtWorkOrderServiceImpl implements IGxtWorkOrderService
 
         gxtWorkOrderFlowMapper.insertGxtWorkOrderFlow(flow);
     }
+
+    /**
+     * 开始处理工单
+     *
+     * @param gxtWorkOrder 工单对象,包含工单状态和其他信息
+     * @return 结果
+     */
+    @Override
+    @Transactional
+    public int startWorkOrder(GxtWorkOrder gxtWorkOrder)
+    {
+        Long id = gxtWorkOrder.getId();
+        GxtWorkOrder order = gxtWorkOrderMapper.selectGxtWorkOrderById(id);
+        if (order == null)
+        {
+            throw new ServiceException("工单不存在");
+        }
+
+        // 仅有已接单状态才能开始处理
+        if (!"accepted".equals(order.getWorkOrderStatus()) && !"suspended".equals(order.getWorkOrderStatus()))
+        {
+            throw new ServiceException("当前工单状态不允许开始处理");
+        }
+
+        String oldStatus = order.getWorkOrderStatus();
+
+        // 更新工单信息
+        order.setRealStartTime(DateUtils.getNowDate());
+        order.setWorkOrderStatus("processing");
+        order.setUpdateTime(DateUtils.getNowDate());
+
+        int result = gxtWorkOrderMapper.updateGxtWorkOrder(order);
+
+        if (result > 0)
+        {
+            // 记录流转
+            recordWorkOrderFlow(id, order.getWorkOrderProjectNo(), "start", oldStatus, "processing",
+                    "开始处理");
+        }
+
+        return result;
+    }
+
+    /**
+     * 暂停工单
+     *
+     * @param gxtWorkOrder 工单对象,包含暂停原因不会
+     * @return 结果
+     */
+    @Override
+    @Transactional
+    public int pauseWorkOrder(GxtWorkOrder gxtWorkOrder)
+    {
+        Long id = gxtWorkOrder.getId();
+        GxtWorkOrder order = gxtWorkOrderMapper.selectGxtWorkOrderById(id);
+        if (order == null)
+        {
+            throw new ServiceException("工单不存在");
+        }
+
+        // 仅有处理中或已接单状态才能暂停
+        if (!"processing".equals(order.getWorkOrderStatus()) && !"accepted".equals(order.getWorkOrderStatus()))
+        {
+            throw new ServiceException("当前工单状态不允许暂停");
+        }
+
+        String oldStatus = order.getWorkOrderStatus();
+
+        // 更新工单信息
+        order.setPauseTime(DateUtils.getNowDate());
+        order.setPauseReason(gxtWorkOrder.getPauseReason());
+        order.setWorkOrderStatus("paused");
+        order.setUpdateTime(DateUtils.getNowDate());
+
+        int result = gxtWorkOrderMapper.updateGxtWorkOrder(order);
+
+        if (result > 0)
+        {
+            // 记录流转
+            recordWorkOrderFlow(id, order.getWorkOrderProjectNo(), "pause", oldStatus, "paused",
+                    "暂停原因: " + gxtWorkOrder.getPauseReason());
+        }
+
+        return result;
+    }
+
+    /**
+     * 继续处理工单
+     *
+     * @param gxtWorkOrder 工单对象,仅包含工单ID
+     * @return 结果
+     */
+    @Override
+    @Transactional
+    public int resumeWorkOrder(GxtWorkOrder gxtWorkOrder) {
+        Long id = gxtWorkOrder.getId();
+        GxtWorkOrder order = gxtWorkOrderMapper.selectGxtWorkOrderById(id);
+        if (order == null) {
+            throw new ServiceException("工单不存在");
+        }
+
+        // 仅有暂停中状态才能继续处理
+        if (!"paused".equals(order.getWorkOrderStatus())) {
+            throw new ServiceException("当前工单状态不允许继续处理");
+        }
+
+        String oldStatus = order.getWorkOrderStatus();
+
+        // 更新工单信息
+        order.setWorkOrderStatus("processing");
+        order.setUpdateTime(DateUtils.getNowDate());
+
+        int result = gxtWorkOrderMapper.updateGxtWorkOrder(order);
+
+        if (result > 0) {
+            // 记录流转
+            recordWorkOrderFlow(id, order.getWorkOrderProjectNo(), "resume", oldStatus, "processing",
+                    "继续处理");
+        }
+
+        return result;
+    }
 }

+ 55 - 12
ygtx-ui/src/api/gxt/gxtOrder.js

@@ -84,13 +84,11 @@ export function acceptByWorkGroupMember(id) {
 }
 
 // 挂起工单
-export function suspendWorkOrder(id, suspendReason) {
+export function suspendWorkOrder(id, gxtWorkOrder) {
   return request({
     url: '/gxt/order/suspend/' + id,
-    method: 'put',
-    params: {
-      suspendReason: suspendReason
-    }
+    method: 'post',
+    data: gxtWorkOrder
   })
 }
 
@@ -102,13 +100,13 @@ export function restartWorkOrder(id) {
   })
 }
 
-// 完成工单
-export function completeWorkOrder(id) {
-  return request({
-    url: '/gxt/order/complete/' + id,
-    method: 'put'
-  })
-}
+// // 完成工单
+// export function completeWorkOrder(id) {
+//   return request({
+//     url: '/gxt/order/complete/' + id,
+//     method: 'put'
+//   })
+// }
 
 // 查询工单流转记录
 export function getWorkOrderFlow(orderId) {
@@ -126,3 +124,48 @@ export function acceptOrder(id, gxtWorkOrder) {
     data: gxtWorkOrder
   })
 }
+
+// 开始处理工单
+export function startWorkOrder(id, gxtWorkOrder) {
+  return request({
+    url: '/gxt/order/start/' + id,
+    method: 'post',
+    data: gxtWorkOrder
+  })
+}
+
+// 暂停工单
+export function pauseWorkOrder(id, gxtWorkOrder) {
+  return request({
+    url: '/gxt/order/pause/' + id,
+    method: 'post',
+    data: gxtWorkOrder
+  })
+}
+
+// 继续处理工单
+export function resumeWorkOrder(id, gxtWorkOrder) {
+  return request({
+    url: '/gxt/order/resume/' + id,
+    method: 'post',
+    data: gxtWorkOrder
+  })
+}
+
+// 审批挂起申请
+export function approveWorkOrder(id, gxtWorkOrder) {
+  return request({
+    url: '/gxt/order/approve/' + id,
+    method: 'post',
+    data: gxtWorkOrder
+  })
+}
+
+// 结束工单
+export function completeWorkOrder(id, gxtWorkOrder) {
+  return request({
+    url: '/gxt/order/complete/' + id,
+    method: 'post',
+    data: gxtWorkOrder
+  })
+}

+ 649 - 113
ygtx-ui/src/views/gxt/gxtOrder/index.vue

@@ -91,7 +91,13 @@
     </el-row>
 
     <el-table v-loading="loading" :data="orderList" @selection-change="handleSelectionChange">
-      <el-table-column label="工单编码" align="center" prop="workOrderProjectNo" width="140" />
+      <el-table-column label="工单编码" align="center" prop="workOrderProjectNo" width="140">
+        <template #default="scope">
+          <el-button link type="primary" @click="handleDetail(scope.row)">
+            {{ scope.row.workOrderProjectNo }}
+          </el-button>
+        </template>
+      </el-table-column>
       <el-table-column label="工单状态" align="center" prop="workOrderStatus" width="100">
         <template #default="scope">
           <dict-tag :options="gxt_work_order_status" :value="scope.row.workOrderStatus"/>
@@ -149,40 +155,51 @@
           </el-button>
 
           <!-- 已接单状态:显示开始、暂停、挂起按钮 -->
-          <el-button link type="success" @click="handleStart(scope.row)" v-if="scope.row.workOrderStatus === 'accepted'">
+          <el-button link type="success" @click="handleStart(scope.row)" v-if="scope.row.workOrderStatus === 'accepted' || scope.row.workOrderStatus === 'suspended'">
             <i class="fa fa-play"></i>开始
           </el-button>
-          <el-button link type="warning" @click="handlePause(scope.row)" v-if="scope.row.workOrderStatus === 'accepted'">
-            <i class="fa fa-pause"></i>暂停
-          </el-button>
+<!--          <el-button link type="warning" @click="handlePause(scope.row)" v-if="scope.row.workOrderStatus === 'accepted'">-->
+<!--            <i class="fa fa-pause"></i>暂停-->
+<!--          </el-button>-->
           <el-button link type="danger" @click="handleSuspend(scope.row)" v-if="scope.row.workOrderStatus === 'accepted'">
             <i class="fa fa-stop"></i>挂起
           </el-button>
 
-          <!-- 处理中状态:显示暂停、挂起按钮 -->
-          <el-button link type="warning" @click="handlePause(scope.row)" v-if="scope.row.workOrderStatus === 'processing'">
-            <i class="fa fa-pause"></i>暂停
-          </el-button>
+          <!-- 处理中状态:显示暂停、挂起、结束按钮 -->
+<!--          <el-button link type="warning" @click="handlePause(scope.row)" v-if="scope.row.workOrderStatus === 'processing'">-->
+<!--            <i class="fa fa-pause"></i>暂停-->
+<!--          </el-button>-->
           <el-button link type="danger" @click="handleSuspend(scope.row)" v-if="scope.row.workOrderStatus === 'processing'">
             <i class="fa fa-stop"></i>挂起
           </el-button>
-
-          <!-- 暂停中状态:显示恢复按钮 -->
-          <el-button link type="success" @click="handleResume(scope.row)" v-if="scope.row.workOrderStatus === 'paused'">
-            <i class="fa fa-play"></i>恢复
+          <el-button link type="success" @click="handleComplete(scope.row)" v-if="scope.row.workOrderStatus === 'processing'">
+            <i class="fa fa-check"></i>结束
           </el-button>
 
-          <!-- 已挂起状态:显示重启按钮 -->
-          <el-button link type="primary" @click="handleRestart(scope.row)" v-if="scope.row.workOrderStatus === 'suspended'">
-            <i class="fa fa-refresh"></i>重启
-          </el-button>
+          <!-- 暂停中状态:显示继续按钮 -->
+<!--          <el-button link type="success" @click="handleResume(scope.row)" v-if="scope.row.workOrderStatus === 'paused'">-->
+<!--            <i class="fa fa-play"></i>继续-->
+<!--          </el-button>-->
+
+<!--          &lt;!&ndash; 已挂起状态:显示重启按钮 &ndash;&gt;-->
+<!--          <el-button link type="primary" @click="handleRestart(scope.row)" v-if="scope.row.workOrderStatus === 'suspended'">-->
+<!--            <i class="fa fa-refresh"></i>重启-->
+<!--          </el-button>-->
 
           <!-- 待审批状态:显示审批按钮 -->
           <el-button link type="primary" @click="handleApprove(scope.row)" v-if="scope.row.workOrderStatus === 'to_approve'">
             <i class="fa fa-check-circle"></i>审批
           </el-button>
 
-          <!-- 已完成状态:不显示操作按钮 -->
+          <!-- 待结单状态:显示结单按钮 -->
+          <el-button link type="success" @click="handleFinish(scope.row)" v-if="scope.row.workOrderStatus === 'to_finish'">
+            <i class="fa fa-check"></i>结单
+          </el-button>
+
+          <!-- 已完成状态:显示评分按钮 -->
+          <el-button link type="warning" @click="handleRate(scope.row)" v-if="scope.row.workOrderStatus === 'completed'">
+            <i class="fa fa-star"></i>评分
+          </el-button>
 
           <!-- 查看按钮对所有状态都显示 -->
           <el-button link type="info" @click="handleDetail(scope.row)" v-hasPermi="['gxt:maintenance:order:query']">
@@ -351,7 +368,7 @@
     </el-dialog>
 
     <!-- 派单对话框 -->
-    <el-dialog title="派单" v-model="assignDialogVisible" width="500px" append-to-body>
+    <el-dialog title="派单" v-model="assignDialogVisible" width="600px" append-to-body>
       <el-form ref="assignRef" :model="assignForm" :rules="assignRules" label-width="100px">
         <el-form-item label="派单给" prop="assignType">
           <el-radio-group v-model="assignForm.assignType">
@@ -389,23 +406,69 @@
     </el-dialog>
 
     <!-- 挂起对话框 -->
-    <el-dialog title="挂起工单" v-model="suspendDialogVisible" width="500px" append-to-body>
+    <el-dialog title="申请挂起工单" v-model="suspendDialogVisible" width="600px" append-to-body>
       <el-form ref="suspendRef" :model="suspendForm" :rules="suspendRules" label-width="100px">
+        <el-form-item label="工单编号">
+          <el-input v-model="suspendForm.orderCode" disabled />
+        </el-form-item>
         <el-form-item label="挂起原因" prop="suspendReason">
-          <el-input v-model="suspendForm.suspendReason" type="textarea" placeholder="请输入挂起原因" :rows="4" />
+          <el-select v-model="suspendForm.suspendReason" placeholder="请选择挂起原因" style="width: 100%">
+            <el-option label="天气异常" value="天气异常" />
+            <el-option label="缺备件" value="缺备件" />
+            <el-option label="风机非停时间" value="风机非停时间" />
+            <el-option label="其他原因" value="其他原因" />
+          </el-select>
         </el-form-item>
+        <el-form-item label="详细说明" prop="remark">
+          <el-input v-model="suspendForm.remark" type="textarea" placeholder="请详细说明挂起原因" :rows="4" />
+        </el-form-item>
+        <el-alert type="warning" :closable="false">
+          <template #default>
+            <i class="fa fa-exclamation-circle mr-2"></i>
+            申请挂起后,需场站班长审批通过才能正式挂起
+          </template>
+        </el-alert>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
-          <el-button type="primary" @click="submitSuspend">确 定</el-button>
           <el-button @click="suspendDialogVisible = false">取 消</el-button>
+          <el-button type="primary" @click="submitSuspend">提交申请</el-button>
+        </div>
+      </template>
+    </el-dialog>
+
+    <!-- 暂停对话框 -->
+    <el-dialog title="暂停工单" v-model="pauseDialogVisible" width="600px" append-to-body>
+      <el-form ref="pauseRef" :model="pauseForm" :rules="pauseRules" label-width="100px">
+        <el-form-item label="工单编号">
+          <el-input v-model="pauseForm.orderCode" disabled />
+        </el-form-item>
+        <el-form-item label="暂停原因" prop="pauseReason">
+          <el-select v-model="pauseForm.pauseReason" placeholder="请选择暂停原因" style="width: 100%">
+            <el-option
+              v-for="dict in gxt_pause_reasons"
+              :key="dict.value"
+              :label="dict.label"
+              :value="dict.value"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="详细说明">
+          <el-input v-model="pauseForm.remark" type="textarea" placeholder="请输入详细说明(可选)" :rows="3" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="pauseDialogVisible = false">取 消</el-button>
+          <el-button type="primary" @click="submitPause">确认暂停</el-button>
         </div>
       </template>
     </el-dialog>
 
     <!-- 接单对话框 -->
     <el-dialog :title="`接单 - ${acceptForm.workOrderProjectNo}`" v-model="acceptDialogVisible" width="800px" append-to-body>
-      <el-form ref="acceptRef" :model="acceptForm" :rules="acceptRules" label-width="120px">
+      <div style="max-height: 500px; overflow-y: auto; padding-right: 10px;">
+        <el-form ref="acceptRef" :model="acceptForm" :rules="acceptRules" label-width="120px">
         <el-row>
           <el-col :span="12">
             <el-form-item label="工单编码">
@@ -470,6 +533,7 @@
           </el-col>
         </el-row>
       </el-form>
+      </div>
       <template #footer>
         <div class="dialog-footer">
           <el-button type="primary" @click="submitAccept">确认接单</el-button>
@@ -478,6 +542,150 @@
       </template>
     </el-dialog>
 
+    <!-- 开始处理对话框 -->
+    <el-dialog title="开始处理工单" v-model="startDialogVisible" width="600px" append-to-body>
+      <div class="text-center py-6">
+        <div class="inline-flex items-center justify-center w-16 h-16 rounded-full bg-blue-500 text-white mb-4">
+          <i class="fa fa-play text-2xl"></i>
+        </div>
+        <h4 class="text-lg font-medium mb-2">确定要开始处理工单吗?</h4>
+        <p class="text-gray-500 mb-4">工单编号:{{ startForm.orderCode }}</p>
+        <p class="text-gray-500 text-sm">开始后,工单状态将变为"处理中"</p>
+      </div>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="startDialogVisible = false">取 消</el-button>
+          <el-button type="primary" @click="submitStart">确认开始</el-button>
+        </div>
+      </template>
+    </el-dialog>
+
+    <!-- 继续处理对话框 -->
+    <el-dialog title="继续处理工单" v-model="resumeDialogVisible" width="600px" append-to-body>
+      <div class="text-center py-6">
+        <div class="inline-flex items-center justify-center w-16 h-16 rounded-full bg-green-100 text-green-600 mb-4">
+          <i class="fa fa-play text-2xl"></i>
+        </div>
+        <h4 class="text-lg font-medium mb-2">确定要继续处理工单吗?</h4>
+        <p class="text-gray-500 mb-4">工单编号:{{ resumeForm.orderCode }}</p>
+        <p class="text-gray-500 text-sm">继续后,工单状态将变为"处理中"</p>
+      </div>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="resumeDialogVisible = false">取 消</el-button>
+          <el-button type="primary" @click="submitResume">确认继续</el-button>
+        </div>
+      </template>
+    </el-dialog>
+
+    <!-- 结束工单对话框 -->
+    <el-dialog title="结束工单" v-model="completeDialogVisible" width="600px" append-to-body>
+      <div class="text-center py-6">
+        <div class="inline-flex items-center justify-center w-16 h-16 rounded-full bg-blue-100 text-blue-600 mb-4">
+          <i class="fa fa-stop text-2xl"></i>
+        </div>
+        <h4 class="text-lg font-medium mb-2">确定要结束工单吗?</h4>
+        <p class="text-gray-500 mb-4">工单编号:{{ completeForm.orderCode }}</p>
+        <p class="text-gray-500 text-sm">结束后,工单状态将变为"待结单"</p>
+      </div>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="completeDialogVisible = false">取 消</el-button>
+          <el-button type="primary" @click="submitComplete">确认结束</el-button>
+        </div>
+      </template>
+    </el-dialog>
+
+    <!-- 结单对话框 -->
+    <el-dialog title="结单" v-model="finishDialogVisible" width="600px" append-to-body>
+      <div class="text-center py-6">
+        <div class="inline-flex items-center justify-center w-16 h-16 rounded-full bg-green-100 text-green-600 mb-4">
+          <i class="fa fa-check text-2xl"></i>
+        </div>
+        <h4 class="text-lg font-medium mb-2">确定要结单工单吗?</h4>
+        <p class="text-gray-500 mb-4">工单编号:{{ finishForm.orderCode }}</p>
+        <p class="text-gray-500 text-sm">结单后,工单状态将变为"已完成"</p>
+      </div>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="finishDialogVisible = false">取 消</el-button>
+          <el-button type="primary" @click="submitFinish">确认结单</el-button>
+        </div>
+      </template>
+    </el-dialog>
+
+    <!-- 评分对话框 -->
+    <el-dialog title="评分" v-model="rateDialogVisible" width="600px" append-to-body>
+      <el-form ref="rateRef" :model="rateForm" label-width="100px">
+        <el-form-item label="工单编号">
+          <el-input v-model="rateForm.orderCode" disabled />
+        </el-form-item>
+        <el-form-item label="评分" required>
+          <el-rate v-model="rateForm.rating" allow-half show-score text-color="#ff9900" />
+        </el-form-item>
+        <el-form-item label="评价妨訨">
+          <el-input v-model="rateForm.comment" type="textarea" placeholder="请输入评价妨訨" :rows="3" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="rateDialogVisible = false">取 消</el-button>
+          <el-button type="primary" @click="submitRate">提交评分</el-button>
+        </div>
+      </template>
+    </el-dialog>
+
+    <!-- 审批挂起对话框 -->
+    <el-dialog title="审批挂起申请" v-model="approveDialogVisible" width="700px" append-to-body>
+      <el-form ref="approveRef" :model="approveForm" :rules="approveRules" label-width="100px">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="工单编码">
+              <el-input v-model="approveForm.workOrderProjectNo" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="风机编号">
+              <el-input v-model="approveForm.pcsDeviceName" disabled />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="工单类型">
+              <el-input v-model="approveForm.orderType" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="工作负责人">
+              <el-input v-model="approveForm.acceptUserName" disabled />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="挂起原因">
+          <el-input v-model="approveForm.suspendReason" disabled />
+        </el-form-item>
+        <el-form-item label="详细说明">
+          <el-input v-model="approveForm.remark" type="textarea" :rows="3" disabled />
+        </el-form-item>
+        <el-form-item label="审批结果" prop="workOrderStatus">
+          <el-radio-group v-model="approveForm.workOrderStatus">
+            <el-radio label="suspended">通过</el-radio>
+            <el-radio label="accepted">驳回</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item v-if="approveForm.workOrderStatus === 'accepted'" label="驳回理由" prop="rejectionReason">
+          <el-input v-model="approveForm.rejectionReason" type="textarea" placeholder="请输入驳回理由" :rows="3" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="approveDialogVisible = false">取 消</el-button>
+          <el-button type="primary" @click="submitApprove">提交审批</el-button>
+        </div>
+      </template>
+    </el-dialog>
+
     <!-- 流转记录对话框 -->
     <el-dialog title="工单流转记录" v-model="flowDialogVisible" width="900px" append-to-body>
       <el-timeline>
@@ -498,49 +706,150 @@
     </el-dialog>
 
     <!-- 详情对话框 -->
-    <el-dialog title="工单详情" v-model="detailDialogVisible" width="900px" append-to-body>
-      <el-descriptions :column="2" border>
-        <el-descriptions-item label="工单编码">{{ detailData.workOrderProjectNo }}</el-descriptions-item>
-        <el-descriptions-item label="工单状态">
-          <dict-tag :options="gxt_work_order_status" :value="detailData.workOrderStatus"/>
-        </el-descriptions-item>
-        <el-descriptions-item label="维保中心ID">{{ detailData.gxtCenterId }}</el-descriptions-item>
-        <el-descriptions-item label="维保中心">{{ detailData.gxtCenter }}</el-descriptions-item>
-        <el-descriptions-item label="风电场ID">{{ detailData.pcsStationId }}</el-descriptions-item>
-        <el-descriptions-item label="风电场">{{ detailData.pcsStationName }}</el-descriptions-item>
-        <el-descriptions-item label="风机设备ID">{{ detailData.pcsDeviceId }}</el-descriptions-item>
-        <el-descriptions-item label="风机编号">{{ detailData.pcsDeviceName }}</el-descriptions-item>
-        <el-descriptions-item label="风机品牌">{{ detailData.brand }}</el-descriptions-item>
-        <el-descriptions-item label="风机型号">{{ detailData.model }}</el-descriptions-item>
-        <el-descriptions-item label="检查类型">{{ detailData.inspectionTypeId }}</el-descriptions-item>
-        <el-descriptions-item label="维保计划编号">{{ detailData.workPlanNo }}</el-descriptions-item>
-        <el-descriptions-item label="计划检修日期">{{ parseTime(detailData.planStartTime, '{y}-{m}-{d} {h}:{i}') }}</el-descriptions-item>
-        <el-descriptions-item label="计划结束时间">{{ parseTime(detailData.planEndTime, '{y}-{m}-{d} {h}:{i}') }}</el-descriptions-item>
-        <el-descriptions-item label="工单来源">{{ detailData.orderSource }}</el-descriptions-item>
-        <el-descriptions-item label="派单时间">{{ parseTime(detailData.assignTime, '{y}-{m}-{d} {h}:{i}') }}</el-descriptions-item>
-        <el-descriptions-item label="派单人">{{ detailData.assignUserName }}</el-descriptions-item>
-        <el-descriptions-item label="接单时间">{{ parseTime(detailData.acceptTime, '{y}-{m}-{d} {h}:{i}') }}</el-descriptions-item>
-        <el-descriptions-item label="接单人">{{ detailData.acceptUserName }}</el-descriptions-item>
-        <el-descriptions-item label="实际开始时间" v-if="detailData.realStartTime">{{ parseTime(detailData.realStartTime, '{y}-{m}-{d} {h}:{i}') }}</el-descriptions-item>
-        <el-descriptions-item label="实际结束时间" v-if="detailData.realEndTime">{{ parseTime(detailData.realEndTime, '{y}-{m}-{d} {h}:{i}') }}</el-descriptions-item>
-        <el-descriptions-item label="班组组长ID">{{ detailData.teamLeaderId }}</el-descriptions-item>
-        <el-descriptions-item label="班组组长">{{ detailData.teamLeaderName }}</el-descriptions-item>
-        <el-descriptions-item label="工作组成员ID">{{ detailData.workGroupMemberId }}</el-descriptions-item>
-        <el-descriptions-item label="工作组成员">{{ detailData.workGroupMemberName }}</el-descriptions-item>
-        <el-descriptions-item label="挂起原因" :span="2" v-if="detailData.suspendReason">{{ detailData.suspendReason }}</el-descriptions-item>
-        <el-descriptions-item label="挂起时间" v-if="detailData.suspendTime">{{ parseTime(detailData.suspendTime, '{y}-{m}-{d} {h}:{i}') }}</el-descriptions-item>
-        <el-descriptions-item label="暂停原因" :span="2" v-if="detailData.pauseReason">{{ detailData.pauseReason }}</el-descriptions-item>
-        <el-descriptions-item label="暂停时间" v-if="detailData.pauseTime">{{ parseTime(detailData.pauseTime, '{y}-{m}-{d} {h}:{i}') }}</el-descriptions-item>
-        <el-descriptions-item label="重启时间" v-if="detailData.restartTime">{{ parseTime(detailData.restartTime, '{y}-{m}-{d} {h}:{i}') }}</el-descriptions-item>
-        <el-descriptions-item label="完成时间" v-if="detailData.completeTime">{{ parseTime(detailData.completeTime, '{y}-{m}-{d} {h}:{i}') }}</el-descriptions-item>
-        <el-descriptions-item label="预计工时(小时)">{{ detailData.planHour }}</el-descriptions-item>
-        <el-descriptions-item label="维保内容" :span="2">{{ detailData.content }}</el-descriptions-item>
-        <el-descriptions-item label="故障代码">{{ detailData.faultCode }}</el-descriptions-item>
-        <el-descriptions-item label="优先级">{{ detailData.priorityType }}</el-descriptions-item>
-        <el-descriptions-item label="故障描述" :span="2">{{ detailData.faultDesc }}</el-descriptions-item>
-        <el-descriptions-item label="工单类型">{{ detailData.orderType }}</el-descriptions-item>
-        <el-descriptions-item label="备注" :span="2">{{ detailData.remark }}</el-descriptions-item>
-      </el-descriptions>
+    <el-dialog title="查看维保工单" v-model="detailDialogVisible" width="800px" append-to-body>
+      <el-row :gutter="20">
+        <!-- 工单信息 -->
+        <el-col :span="8">
+          <h4 class="text-sm font-medium text-gray-500 mb-4">工单信息</h4>
+          <div class="space-y-4">
+            <div>
+              <p class="text-xs text-gray-500 mb-1">工单编码</p>
+              <p style="font-weight: bold; color: #000;">{{ detailData.workOrderProjectNo }}</p>
+            </div>
+            <div>
+              <p class="text-xs text-gray-500 mb-1">风机编号</p>
+              <p style="font-weight: bold; color: #000;">{{ detailData.pcsDeviceName }}</p>
+            </div>
+            <div>
+              <p class="text-xs text-gray-500 mb-1">工单类型</p>
+              <p style="font-weight: bold; color: #000;">{{ detailData.orderType }}</p>
+            </div>
+            <div>
+              <p class="text-xs text-gray-500 mb-1">工单状态</p>
+              <p style="font-weight: bold; color: #000;">
+                <dict-tag :options="gxt_work_order_status" :value="detailData.workOrderStatus"/>
+              </p>
+            </div>
+            <div>
+              <p class="text-xs text-gray-500 mb-1">维保中心</p>
+              <p style="font-weight: bold; color: #000;">{{ detailData.gxtCenter }}</p>
+            </div>
+            <div>
+              <p class="text-xs text-gray-500 mb-1">风电场</p>
+              <p style="font-weight: bold; color: #000;">{{ detailData.pcsStationName }}</p>
+            </div>
+          </div>
+        </el-col>
+
+        <!-- 处理信息 -->
+        <el-col :span="8">
+          <h4 class="text-sm font-medium text-gray-500 mb-4">处理信息</h4>
+          <div class="space-y-4">
+            <div>
+              <p class="text-xs text-gray-500 mb-1">风机品牌</p>
+              <p style="font-weight: bold; color: #000;">{{ detailData.brand || '-' }}</p>
+            </div>
+            <div>
+              <p class="text-xs text-gray-500 mb-1">维保计划编号</p>
+              <p style="font-weight: bold; color: #000;">{{ detailData.workPlanNo || '-' }}</p>
+            </div>
+            <div>
+              <p class="text-xs text-gray-500 mb-1">计划检修日期</p>
+              <p style="font-weight: bold; color: #000;">{{ parseTime(detailData.planStartTime, '{y}-{m}-{d} {h}:{i}') || '-' }}</p>
+            </div>
+            <div>
+              <p class="text-xs text-gray-500 mb-1">派单人</p>
+              <p style="font-weight: bold; color: #000;">{{ detailData.assignUserName || '-' }}</p>
+            </div>
+            <div>
+              <p class="text-xs text-gray-500 mb-1">派单时间</p>
+              <p style="font-weight: bold; color: #000;">{{ parseTime(detailData.assignTime, '{y}-{m}-{d} {h}:{i}') || '-' }}</p>
+            </div>
+            <div>
+              <p class="text-xs text-gray-500 mb-1">接单人</p>
+              <p style="font-weight: bold; color: #000;">{{ detailData.acceptUserName || '-' }}</p>
+            </div>
+            <div>
+              <p class="text-xs text-gray-500 mb-1">接单时间</p>
+              <p style="font-weight: bold; color: #000;">{{ parseTime(detailData.acceptTime, '{y}-{m}-{d} {h}:{i}') || '-' }}</p>
+            </div>
+            <div>
+              <p class="text-xs text-gray-500 mb-1">工作负责人</p>
+              <p style="font-weight: bold; color: #000;">{{ detailData.acceptUserName || '-' }}</p>
+            </div>
+          </div>
+        </el-col>
+
+        <!-- 工单流转 -->
+        <el-col :span="8">
+          <h4 class="text-sm font-medium text-gray-500 mb-4">工单流转</h4>
+          <div class="space-y-3">
+            <!-- 待派单 -->
+            <div class="flex">
+              <div class="mr-3 flex flex-col items-center">
+                <div :class="['w-6 h-6 rounded-full text-white flex items-center justify-center text-xs font-medium', detailData.workOrderStatus !== 'draft' && detailData.workOrderStatus !== 'to_assign' ? 'bg-blue-500' : 'bg-gray-300']">1</div>
+                <div v-if="['assigned', 'accepted', 'processing', 'paused', 'suspended', 'to_approve', 'completed'].includes(detailData.workOrderStatus)" class="w-0.5 h-8 bg-gray-200 mt-1"></div>
+              </div>
+              <div>
+                <p :class="['text-sm font-medium', detailData.workOrderStatus !== 'draft' && detailData.workOrderStatus !== 'to_assign' ? 'text-gray-900' : 'text-gray-400']">待派单</p>
+                <p :class="['text-xs', detailData.workOrderStatus !== 'draft' && detailData.workOrderStatus !== 'to_assign' ? 'text-gray-500' : 'text-gray-400']">工单已创建</p>
+              </div>
+            </div>
+
+            <!-- 已派单 -->
+            <div class="flex">
+              <div class="mr-3 flex flex-col items-center">
+                <div :class="['w-6 h-6 rounded-full text-white flex items-center justify-center text-xs font-medium', ['accepted', 'processing', 'paused', 'suspended', 'to_approve', 'completed'].includes(detailData.workOrderStatus) ? 'bg-blue-500' : 'bg-gray-300']">2</div>
+                <div v-if="['accepted', 'processing', 'paused', 'suspended', 'to_approve', 'completed'].includes(detailData.workOrderStatus)" class="w-0.5 h-8 bg-gray-200 mt-1"></div>
+              </div>
+              <div>
+                <p :class="['text-sm font-medium', ['accepted', 'processing', 'paused', 'suspended', 'to_approve', 'completed'].includes(detailData.workOrderStatus) ? 'text-gray-900' : 'text-gray-400']">已派单</p>
+                <p :class="['text-xs', ['accepted', 'processing', 'paused', 'suspended', 'to_approve', 'completed'].includes(detailData.workOrderStatus) ? 'text-gray-500' : 'text-gray-400']">已派单给场站</p>
+              </div>
+            </div>
+
+            <!-- 已接单 -->
+            <div class="flex">
+              <div class="mr-3 flex flex-col items-center">
+                <div :class="['w-6 h-6 rounded-full text-white flex items-center justify-center text-xs font-medium', ['processing', 'paused', 'suspended', 'to_approve', 'completed'].includes(detailData.workOrderStatus) ? 'bg-blue-500' : 'bg-gray-300']">3</div>
+                <div v-if="['processing', 'paused', 'suspended', 'to_approve', 'completed'].includes(detailData.workOrderStatus)" class="w-0.5 h-8 bg-gray-200 mt-1"></div>
+              </div>
+              <div>
+                <p :class="['text-sm font-medium', ['processing', 'paused', 'suspended', 'to_approve', 'completed'].includes(detailData.workOrderStatus) ? 'text-gray-900' : 'text-gray-400']">已接单</p>
+                <p :class="['text-xs', ['processing', 'paused', 'suspended', 'to_approve', 'completed'].includes(detailData.workOrderStatus) ? 'text-gray-500' : 'text-gray-400']">场站已接单</p>
+              </div>
+            </div>
+
+            <!-- 处理中 -->
+            <div class="flex">
+              <div class="mr-3 flex flex-col items-center">
+                <div :class="['w-6 h-6 rounded-full text-white flex items-center justify-center text-xs font-medium', ['paused', 'suspended', 'to_approve', 'completed'].includes(detailData.workOrderStatus) ? 'bg-blue-500' : detailData.workOrderStatus === 'processing' ? 'bg-blue-500' : 'bg-gray-300']">4</div>
+                <div v-if="['paused', 'suspended', 'to_approve', 'completed'].includes(detailData.workOrderStatus) || detailData.workOrderStatus === 'processing'" class="w-0.5 h-8 bg-gray-200 mt-1"></div>
+              </div>
+              <div>
+                <p :class="['text-sm font-medium', ['paused', 'suspended', 'to_approve', 'completed'].includes(detailData.workOrderStatus) || detailData.workOrderStatus === 'processing' ? 'text-gray-900' : 'text-gray-400']">处理中</p>
+                <p :class="['text-xs', ['paused', 'suspended', 'to_approve', 'completed'].includes(detailData.workOrderStatus) || detailData.workOrderStatus === 'processing' ? 'text-gray-500' : 'text-gray-400']">处理中...</p>
+              </div>
+            </div>
+
+            <!-- 已完成 -->
+            <div class="flex">
+              <div class="mr-3 flex flex-col items-center">
+                <div :class="['w-6 h-6 rounded-full text-white flex items-center justify-center text-xs font-medium', detailData.workOrderStatus === 'completed' ? 'bg-blue-500' : 'bg-gray-300']">5</div>
+              </div>
+              <div>
+                <p :class="['text-sm font-medium', detailData.workOrderStatus === 'completed' ? 'text-gray-900' : 'text-gray-400']">已完成</p>
+                <p :class="['text-xs', detailData.workOrderStatus === 'completed' ? 'text-gray-500' : 'text-gray-400']">处理完成</p>
+              </div>
+            </div>
+          </div>
+        </el-col>
+      </el-row>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="detailDialogVisible = false">关闭</el-button>
+        </div>
+      </template>
     </el-dialog>
   </div>
 </template>
@@ -561,17 +870,15 @@ import {
   completeWorkOrder,
   getWorkOrderFlow,
   acceptOrder,
-  // startWorkOrder,
-  // pauseWorkOrder,
-  // resumeWorkOrder,
-  // approveWorkOrder
+  startWorkOrder,
+  pauseWorkOrder,
+  resumeWorkOrder,
+  approveWorkOrder
 } from "@/api/gxt/gxtOrder"
 import { listUser } from "@/api/system/user"
-import { getDicts } from "@/api/system/dict/data"
 
 const { proxy } = getCurrentInstance()
-const { gxt_work_order_status, gxt_inspection_type } = proxy.useDict("gxt_work_order_status", "gxt_inspection_type")
-
+const { gxt_work_order_status, gxt_inspection_type, gxt_pause_reasons } = proxy.useDict("gxt_work_order_status", "gxt_inspection_type", "gxt_pause_reasons")
 const orderList = ref([])
 const open = ref(false)
 const loading = ref(true)
@@ -583,6 +890,13 @@ const total = ref(0)
 const title = ref("")
 const assignDialogVisible = ref(false)
 const suspendDialogVisible = ref(false)
+const pauseDialogVisible = ref(false)
+const startDialogVisible = ref(false)
+const resumeDialogVisible = ref(false)
+const completeDialogVisible = ref(false)
+const finishDialogVisible = ref(false)
+const rateDialogVisible = ref(false)
+const approveDialogVisible = ref(false)
 const flowDialogVisible = ref(false)
 const detailDialogVisible = ref(false)
 const acceptDialogVisible = ref(false)
@@ -621,10 +935,73 @@ const data = reactive({
   },
   suspendForm: {
     orderId: undefined,
-    suspendReason: undefined
+    orderCode: undefined,
+    suspendReason: undefined,
+    remark: undefined
   },
   suspendRules: {
-    suspendReason: [{ required: true, message: "请输入挂起原因", trigger: "blur" }]
+    suspendReason: [{ required: true, message: "请选择挂起原因", trigger: "change" }],
+    remark: [{ required: true, message: "请输入详细说明", trigger: "blur" }]
+  },
+  pauseForm: {
+    orderId: undefined,
+    orderCode: undefined,
+    pauseReason: undefined,
+    remark: undefined
+  },
+  pauseRules: {
+    pauseReason: [{ required: true, message: "请选择暂停原因", trigger: "change" }]
+  },
+  startForm: {
+    orderId: undefined,
+    orderCode: undefined,
+    pcsDeviceName: undefined
+  },
+  resumeForm: {
+    orderId: undefined,
+    orderCode: undefined
+  },
+  completeForm: {
+    orderId: undefined,
+    orderCode: undefined
+  },
+  finishForm: {
+    orderId: undefined,
+    orderCode: undefined
+  },
+  rateForm: {
+    orderId: undefined,
+    orderCode: undefined,
+    rating: undefined,
+    comment: undefined
+  },
+  approveForm: {
+    orderId: undefined,
+    workOrderProjectNo: undefined,
+    pcsDeviceName: undefined,
+    orderType: undefined,
+    acceptUserName: undefined,
+    suspendReason: undefined,
+    remark: undefined,
+    workOrderStatus: 'suspended',
+    rejectionReason: undefined
+  },
+  approveRules: {
+    workOrderStatus: [{ required: true, message: "请选择审批结果", trigger: "change" }],
+    rejectionReason: [
+      {
+        required: true,
+        message: "请输入驳回理由",
+        trigger: "blur",
+        validator: (rule, value, callback) => {
+          if (data.approveForm.workOrderStatus === 'accepted' && !value) {
+            callback(new Error("驳回理由必填"))
+          } else {
+            callback()
+          }
+        }
+      }
+    ]
   },
   acceptForm: {
     orderId: undefined,
@@ -646,7 +1023,7 @@ const data = reactive({
   }
 })
 
-const { queryParams, form, rules, assignForm, assignRules, suspendForm, suspendRules, acceptForm, acceptRules } = toRefs(data)
+const { queryParams, form, rules, assignForm, assignRules, suspendForm, suspendRules, pauseForm, pauseRules, startForm, resumeForm, completeForm, finishForm, rateForm, approveForm, approveRules, acceptForm, acceptRules } = toRefs(data)
 
 /** 查询维保工单列表 */
 function getList() {
@@ -770,42 +1147,102 @@ function handleDetail(row) {
 
 /** 开始处理 */
 function handleStart(row) {
-  proxy.$modal.confirm('确认开始处理工单?').then(function() {
-    // return startWorkOrder(row.id)
-  }).then(() => {
-    getList()
-    proxy.$modal.msgSuccess("工单已开始处理")
-  }).catch(() => {})
+  startForm.value.orderId = row.id
+  startForm.value.orderCode = row.workOrderProjectNo
+  startForm.value.pcsDeviceName = row.pcsDeviceName
+  startDialogVisible.value = true
 }
 
 /** 暂停处理 */
 function handlePause(row) {
-  proxy.$modal.confirm('确认暂停工单?').then(function() {
-    // return pauseWorkOrder(row.id)
-  }).then(() => {
-    getList()
-    proxy.$modal.msgSuccess("工单已暂停")
-  }).catch(() => {})
+  pauseForm.value.orderId = row.id
+  pauseForm.value.orderCode = row.workOrderProjectNo
+  pauseForm.value.pauseReason = undefined
+  pauseForm.value.remark = undefined
+  pauseDialogVisible.value = true
 }
 
-/** 恢复处理 */
+/** 继续处理 */
 function handleResume(row) {
-  proxy.$modal.confirm('确认恢复工单?').then(function() {
-    // return resumeWorkOrder(row.id)
-  }).then(() => {
+  resumeForm.value.orderId = row.id
+  resumeForm.value.orderCode = row.workOrderProjectNo
+  resumeDialogVisible.value = true
+}
+
+/** 提交结束 */
+function submitComplete() {
+  const gxtWorkOrder = {
+    id: completeForm.value.orderId,
+    workOrderStatus: 'to_finish'
+  }
+
+  completeWorkOrder(completeForm.value.orderId, gxtWorkOrder).then(response => {
+    completeDialogVisible.value = false
+    proxy.$modal.msgSuccess("工单结束成功")
     getList()
-    proxy.$modal.msgSuccess("工单已恢复")
-  }).catch(() => {})
+  }).catch(error => {
+    proxy.$modal.msgError("工单结束失败:" + (error?.response?.data?.msg || "未知错误"))
+  })
 }
 
-/** 审批工单 */
-function handleApprove(row) {
-  proxy.$modal.confirm('确认审批通过工单?').then(function() {
-    // return approveWorkOrder(row.id)
-  }).then(() => {
+/** 结束工单 */
+function handleComplete(row) {
+  completeForm.value.orderId = row.id
+  completeForm.value.orderCode = row.workOrderProjectNo
+  completeDialogVisible.value = true
+}
+
+/** 待结单状态:结单按钮 */
+function handleFinish(row) {
+  finishForm.value.orderId = row.id
+  finishForm.value.orderCode = row.workOrderProjectNo
+  finishDialogVisible.value = true
+}
+
+/** 提交结单 */
+function submitFinish() {
+  const gxtWorkOrder = {
+    id: finishForm.value.orderId,
+    workOrderStatus: 'completed'
+  }
+
+  completeWorkOrder(finishForm.value.orderId, gxtWorkOrder).then(response => {
+    finishDialogVisible.value = false
+    proxy.$modal.msgSuccess("结单成功")
     getList()
-    proxy.$modal.msgSuccess("工单审批通过")
-  }).catch(() => {})
+  }).catch(error => {
+    proxy.$modal.msgError("结单失败:" + (error?.response?.data?.msg || "未知错误"))
+  })
+}
+
+/** 评分 */
+function handleRate(row) {
+  rateForm.value.orderId = row.id
+  rateForm.value.orderCode = row.workOrderProjectNo
+  rateForm.value.rating = undefined
+  rateForm.value.comment = undefined
+  rateDialogVisible.value = true
+}
+
+/** 提交评分 */
+function submitRate() {
+  if (!rateForm.value.rating) {
+    proxy.$modal.msgWarning("评分不能为空")
+    return
+  }
+
+  const gxtWorkOrder = {
+    id: rateForm.value.orderId,
+    workOrderStatus: 'to_archive'
+  }
+
+  completeWorkOrder(rateForm.value.orderId, gxtWorkOrder).then(response => {
+    rateDialogVisible.value = false
+    proxy.$modal.msgSuccess("评分成功")
+    getList()
+  }).catch(error => {
+    proxy.$modal.msgError("评分失败:" + (error?.response?.data?.msg || "未知错误"))
+  })
 }
 
 /** 下拉菜单命令处理 */
@@ -909,7 +1346,9 @@ function handleAccept(row) {
 /** 挂起 */
 function handleSuspend(row) {
   suspendForm.value.orderId = row.id
+  suspendForm.value.orderCode = row.workOrderProjectNo
   suspendForm.value.suspendReason = undefined
+  suspendForm.value.remark = undefined
   suspendDialogVisible.value = true
 }
 
@@ -943,7 +1382,7 @@ function submitAccept() {
         acceptUserName: acceptForm.value.responsiblePersonName,
         workOrderPersonList: acceptForm.value.workOrderPersonList
       }
-      
+
       acceptOrder(acceptForm.value.orderId, gxtWorkOrder).then(response => {
         proxy.$modal.msgSuccess("接单成功")
         acceptDialogVisible.value = false
@@ -955,14 +1394,97 @@ function submitAccept() {
   })
 }
 
+/** 提交开始处理 */
+function submitStart() {
+  const gxtWorkOrder = {
+    id: startForm.value.orderId,
+    workOrderStatus: 'processing'
+  }
+
+  startWorkOrder(startForm.value.orderId, gxtWorkOrder).then(response => {
+    proxy.$modal.msgSuccess("开始处理成功")
+    startDialogVisible.value = false
+    getList()
+  }).catch(error => {
+    proxy.$modal.msgError("开始处理失败:" + (error?.response?.data?.msg || "未知错误"))
+  })
+}
+
 /** 提交挂起 */
 function submitSuspend() {
   proxy.$refs["suspendRef"].validate(valid => {
     if (valid) {
-      suspendWorkOrder(suspendForm.value.orderId, suspendForm.value.suspendReason).then(response => {
-        proxy.$modal.msgSuccess("挂起成功")
+      const gxtWorkOrder = {
+        id: suspendForm.value.orderId,
+        suspendReason: suspendForm.value.suspendReason,
+        remark: suspendForm.value.remark
+      }
+
+      suspendWorkOrder(suspendForm.value.orderId, gxtWorkOrder).then(response => {
+        proxy.$modal.msgSuccess("挂起申请已提交")
         suspendDialogVisible.value = false
         getList()
+      }).catch(error => {
+        proxy.$modal.msgError("挂起申请失败:" + (error?.response?.data?.msg || "未知错误"))
+      })
+    }
+  })
+}
+
+/** 提交继续处理 */
+function submitResume() {
+  const gxtWorkOrder = {
+    id: resumeForm.value.orderId,
+    workOrderStatus: 'processing'
+  }
+
+  resumeWorkOrder(resumeForm.value.orderId, gxtWorkOrder).then(response => {
+    proxy.$modal.msgSuccess("继续处理成功")
+    resumeDialogVisible.value = false
+    getList()
+  }).catch(error => {
+    proxy.$modal.msgError("继续处理失败:" + (error?.response?.data?.msg || "未知错误"))
+  })
+}
+
+/** 提交挂起审批 */
+function submitApprove() {
+  proxy.$refs["approveRef"].validate(valid => {
+    if (valid) {
+      const gxtWorkOrder = {
+        id: approveForm.value.orderId,
+        workOrderStatus: approveForm.value.workOrderStatus,
+        rejectionReason: approveForm.value.rejectionReason
+      }
+
+      approveWorkOrder(approveForm.value.orderId, gxtWorkOrder).then(response => {
+        const msg = approveForm.value.workOrderStatus === 'suspended' ? '挂起审批通过' : '挂起审批驳回'
+        proxy.$modal.msgSuccess(msg + "成功")
+        approveDialogVisible.value = false
+        getList()
+      }).catch(error => {
+        proxy.$modal.msgError("审批失败:" + (error?.response?.data?.msg || "未知错误"))
+      })
+    }
+  })
+}
+
+/** 提交暂停 */
+function submitPause() {
+  proxy.$refs["pauseRef"].validate(valid => {
+    if (valid) {
+      const gxtWorkOrder = {
+        id: pauseForm.value.orderId,
+        pauseReason: pauseForm.value.pauseReason,
+        remark: pauseForm.value.remark
+      }
+
+      pauseWorkOrder(pauseForm.value.orderId, gxtWorkOrder).then(response => {
+        proxy.$modal.msgSuccess("暂停成功")
+        pauseDialogVisible.value = false
+        getList()
+      }).catch(error => {
+        proxy.$modal.msgError("暂停失败:" + (error?.response?.data?.msg || "未知错误"))
       })
     }
   })
@@ -978,15 +1500,15 @@ function handleRestart(row) {
   }).catch(() => {})
 }
 
-/** 完成 */
-function handleComplete(row) {
-  proxy.$modal.confirm('确认完成工单?').then(function() {
-    return completeWorkOrder(row.id)
-  }).then(() => {
-    getList()
-    proxy.$modal.msgSuccess("工单已完成")
-  }).catch(() => {})
-}
+// /** 完成 */
+// function handleComplete(row) {
+//   proxy.$modal.confirm('确认完成工单?').then(function() {
+//     return completeWorkOrder(row.id)
+//   }).then(() => {
+//     getList()
+//     proxy.$modal.msgSuccess("工单已完成")
+//   }).catch(() => {})
+// }
 
 /** 流转记录 */
 function handleFlow(row) {
@@ -996,6 +1518,20 @@ function handleFlow(row) {
   })
 }
 
+/** 审批挂起申请 */
+function handleApprove(row) {
+  approveForm.value.orderId = row.id
+  approveForm.value.workOrderProjectNo = row.workOrderProjectNo
+  approveForm.value.pcsDeviceName = row.pcsDeviceName
+  approveForm.value.orderType = row.orderType
+  approveForm.value.acceptUserName = row.acceptUserName
+  approveForm.value.suspendReason = row.suspendReason
+  approveForm.value.remark = row.remark
+  approveForm.value.workOrderStatus = 'suspended'
+  approveForm.value.rejectionReason = undefined
+  approveDialogVisible.value = true
+}
+
 /** 获取操作类型名称 */
 function getActionTypeName(actionType) {
   const actionTypeMap = {