From 5d75fcaea0a3774052b7484a4ffe755258502363 Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期六, 06 十二月 2025 20:49:11 +0800
Subject: [PATCH] fix:开始执行人员就绪按钮

---
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskServiceImpl.java |   92 +++++++++++
 app/api/task.js                                                                  |    8 +
 app/config.js                                                                    |    6 
 ruoyi-system/src/main/resources/mapper/system/SysTaskAssigneeMapper.xml          |    6 
 sql/add_assignee_ready_status.sql                                                |   11 +
 ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskController.java   |   18 ++
 ruoyi-system/src/main/java/com/ruoyi/system/service/ISysTaskService.java         |   18 ++
 app/pagesTask/detail.vue                                                         |  266 ++++++++++++++++++++++++++++----
 ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTaskAssignee.java          |   25 +++
 9 files changed, 410 insertions(+), 40 deletions(-)

diff --git a/app/api/task.js b/app/api/task.js
index 258c34e..742c650 100644
--- a/app/api/task.js
+++ b/app/api/task.js
@@ -149,3 +149,11 @@
     method: 'get'
   })
 }
+
+// 鏍囪鎵ц浜哄氨缁�
+export function setAssigneeReady(taskId) {
+  return request({
+    url: '/task/' + taskId + '/assignee/ready',
+    method: 'post'
+  })
+}
diff --git a/app/config.js b/app/config.js
index 6ec3f59..b122f66 100644
--- a/app/config.js
+++ b/app/config.js
@@ -59,5 +59,11 @@
         url: "/pages/mine/user-agreement/index"
       }
     ]
+  },
+  
+  // 鍔熻兘寮�鍏�
+  features: {
+    // 鏄惁鏄剧ず鎵ц浜衡�滃氨缁�濇寜閽�
+    showAssigneeReadyButton: true
   }
 }
diff --git a/app/pagesTask/detail.vue b/app/pagesTask/detail.vue
index 277d825..c84acb7 100644
--- a/app/pagesTask/detail.vue
+++ b/app/pagesTask/detail.vue
@@ -59,6 +59,15 @@
                 >
                   {{ getUserTypeLabel(assignee.userType) }}
                 </view>
+                <view 
+                  class="ready-badge"
+                  :class="{
+                    'ready': isAssigneeReady(assignee),
+                    'unready': !isAssigneeReady(assignee)
+                  }"
+                >
+                  {{ isAssigneeReady(assignee) ? '宸插氨缁�' : '鏈氨缁�' }}
+                </view>
               </view>
             </view>
           </view>
@@ -362,18 +371,27 @@
         >
           淇敼
         </button>
-        <button 
-          class="action-btn primary" 
-          @click="handleTaskAction('depart')"
-        >
-          鍑哄彂
-        </button>
-        <button 
-          class="action-btn cancel" 
-          @click="handleTaskAction('cancel')"
-        >
-          鍙栨秷
-        </button>
+        <template v-if="isCurrentUserAssignee()">
+          <button 
+            v-if="showAssigneeReadyFeature() && isMultipleAssignees() && !isCurrentUserReady()"
+            class="action-btn primary" 
+            @click="handleReadyAction()"
+          >
+            灏辩华
+          </button>
+          <button 
+            class="action-btn primary" 
+            @click="handleDepartAction()"
+          >
+            鍑哄彂
+          </button>
+          <button 
+            class="action-btn cancel" 
+            @click="handleTaskAction('cancel')"
+          >
+            鍙栨秷
+          </button>
+        </template>
       </template>
       
       <!-- 鍑哄彂涓姸鎬�: 鏄剧ず缂栬緫銆佸凡鍒拌揪銆佸己鍒剁粨鏉� -->
@@ -384,18 +402,20 @@
         >
           淇敼
         </button>
-        <button 
-          class="action-btn primary" 
-          @click="handleTaskAction('arrive')"
-        >
-          宸插埌杈�
-        </button>
-        <button 
-          class="action-btn cancel" 
-          @click="handleTaskAction('forceCancel')"
-        >
-          寮哄埗缁撴潫
-        </button>
+        <template v-if="isCurrentUserAssignee()">
+          <button 
+            class="action-btn primary" 
+            @click="handleTaskAction('arrive')"
+          >
+            宸插埌杈�
+          </button>
+          <button 
+            class="action-btn cancel" 
+            @click="handleTaskAction('forceCancel')"
+          >
+            寮哄埗缁撴潫
+          </button>
+        </template>
       </template>
       
       <!-- 宸插埌杈剧姸鎬�: 鏄剧ず缂栬緫銆佸凡杩旂▼ -->
@@ -406,12 +426,14 @@
         >
           淇敼
         </button>
-        <button 
-          class="action-btn primary" 
-          @click="handleTaskAction('return')"
-        >
-          宸茶繑绋�
-        </button>
+        <template v-if="isCurrentUserAssignee()">
+          <button 
+            class="action-btn primary" 
+            @click="handleTaskAction('return')"
+          >
+            宸茶繑绋�
+          </button>
+        </template>
       </template>
       
       <!-- 杩旂▼涓姸鎬�: 鏄剧ず缂栬緫銆佸凡瀹屾垚 -->
@@ -422,12 +444,14 @@
         >
           淇敼
         </button>
-        <button 
-          class="action-btn primary" 
-          @click="handleTaskAction('complete')"
-        >
-          宸插畬鎴�
-        </button>
+        <template v-if="isCurrentUserAssignee()">
+          <button 
+            class="action-btn primary" 
+            @click="handleTaskAction('complete')"
+          >
+            宸插畬鎴�
+          </button>
+        </template>
       </template>
       
       <!-- 宸插畬鎴�/宸插彇娑�: 涓嶆樉绀烘寜閽紝浣嗗鏋滄槸杞繍浠诲姟鍒欐樉绀虹粨绠楁寜閽� -->
@@ -445,12 +469,13 @@
 </template>
 
 <script>
-  import { getTask, changeTaskStatus } from '@/api/task'
+  import { getTask, changeTaskStatus, setAssigneeReady } from '@/api/task'
   import { checkVehicleActiveTasks } from '@/api/task'
   import { getPaymentInfo } from '@/api/payment'
   import { formatDateTime } from '@/utils/common'
   import { validateTaskForDepart, validateTaskForSettlement, getTaskVehicleId, checkTaskCanDepart } from '@/utils/taskValidator'
   import AttachmentUpload from './components/AttachmentUpload.vue'
+  import config from '@/config'
   
   export default {
     components: {
@@ -771,8 +796,7 @@
       handleTaskAction(action) {
         switch (action) {
           case 'depart':
-            // 鍑哄彂 -> 妫�鏌ヨ溅杈嗘槸鍚︽湁鍏朵粬姝e湪杩涜涓殑浠诲姟
-            this.checkVehicleAndDepart();
+            this.ensureReadyThenDepart();
             break;
             
           case 'cancel':
@@ -1235,6 +1259,145 @@
       // 闄勪欢鍒犻櫎鎴愬姛鍥炶皟
       onAttachmentDeleted(attachmentId) {
         console.log('闄勪欢鍒犻櫎鎴愬姛:', attachmentId)
+      },
+
+      // 鏄惁鏄剧ず鈥滃氨缁�濆姛鑳斤紙閰嶇疆寮�鍏筹級
+      showAssigneeReadyFeature() {
+        return !!(config && config.features && config.features.showAssigneeReadyButton)
+      },
+
+      // 褰撳墠鐢ㄦ埛鏄惁涓鸿鎵ц浜�
+      isAssigneeSelf(assignee) {
+        const userId = this.$store && this.$store.state && this.$store.state.user && this.$store.state.user.userId
+        return assignee && (assignee.userId === userId || assignee.oaUserId === userId)
+      },
+
+      // 鎵ц浜虹偣鍑烩�滃氨缁��
+      markAssigneeReady(assignee) {
+        if (!assignee || !this.taskDetail) {
+          this.$modal.showToast('鎵ц浜烘垨浠诲姟淇℃伅涓嶅瓨鍦�')
+          return
+        }
+        const userId = assignee.userId || assignee.oaUserId
+        if (!userId) {
+          this.$modal.showToast('鏃犳硶璇嗗埆鎵ц浜篒D')
+          return
+        }
+        this.$modal.showLoading && this.$modal.showLoading('鎻愪氦涓�...')
+        setAssigneeReady(this.taskId).then(() => {
+          this.$modal.hideLoading && this.$modal.hideLoading()
+          this.$modal.showToast('宸插氨缁�')
+          // 鍒锋柊浠诲姟璇︽儏
+          this.loadTaskDetail()
+        }).catch(err => {
+          this.$modal.hideLoading && this.$modal.hideLoading()
+          console.error('鏍囪灏辩华澶辫触:', err)
+          this.$modal.showToast('鏍囪灏辩华澶辫触')
+        })
+      },
+
+      // 鏄惁褰撳墠鐢ㄦ埛鏄换鍔℃墽琛屼汉
+      isCurrentUserAssignee() {
+        const userId = this.$store && this.$store.state && this.$store.state.user && this.$store.state.user.userId;
+        console.log("褰撳墠鐢ㄦ埛ID:", userId)
+        const list = (this.taskDetail && Array.isArray(this.taskDetail.assignees)) ? this.taskDetail.assignees : []
+        return list.some(a => a && (a.userId === userId || a.oaUserId === userId))
+      },
+
+      // 鏄惁澶氫汉鎵ц
+      isMultipleAssignees() {
+        const list = (this.taskDetail && Array.isArray(this.taskDetail.assignees)) ? this.taskDetail.assignees : []
+        return list.length > 1
+      },
+
+      // 鎵ц浜烘槸鍚﹀凡灏辩华
+      isAssigneeReady(assignee) {
+        if (!assignee) return false
+        return assignee.isReady === '1' || assignee.ready === true || assignee.readyStatus === 'READY' || assignee.readyFlag === 'Y'
+      },
+
+      // 鎵�鏈夋墽琛屼汉鏄惁宸插氨缁�
+      areAllAssigneesReady() {
+        const list = (this.taskDetail && Array.isArray(this.taskDetail.assignees)) ? this.taskDetail.assignees : []
+        if (list.length === 0) return false
+        return list.every(a => this.isAssigneeReady(a))
+      },
+
+      // 鑾峰彇褰撳墠鐢ㄦ埛瀵瑰簲鐨勬墽琛屼汉璁板綍
+      getCurrentUserAssignee() {
+        const userId = this.$store && this.$store.state && this.$store.state.user && this.$store.state.user.userId
+        console.log('userId', userId)
+        const list = (this.taskDetail && Array.isArray(this.taskDetail.assignees)) ? this.taskDetail.assignees : []
+        return list.find(a => a && (a.userId === userId || a.oaUserId === userId)) || null
+      },
+
+      // 鎿嶄綔鍖哄氨缁寜閽紙澶氫汉浠诲姟锛�
+      markCurrentAssigneeReady() {
+        const me = this.getCurrentUserAssignee()
+        if (!me) {
+          this.$modal.showToast('浠呬换鍔℃墽琛屼汉鍙搷浣�')
+          return
+        }
+        this.markAssigneeReady(me)
+      },
+
+      // 褰撳墠鐢ㄦ埛鏄惁宸插氨缁�
+      isCurrentUserReady() {
+        const me = this.getCurrentUserAssignee()
+        return me ? this.isAssigneeReady(me) : false
+      },
+
+      // 澶勭悊灏辩华鎸夐挳鐐瑰嚮
+      async handleReadyAction() {
+        const me = this.getCurrentUserAssignee()
+        if (!me) {
+          this.$modal.showToast('浠呬换鍔℃墽琛屼汉鍙搷浣�')
+          return
+        }
+        try {
+          await setAssigneeReady(this.taskId)
+          this.$modal.showToast('宸插氨缁�')
+          // 鍒锋柊浠诲姟璇︽儏
+          await this.loadTaskDetail()
+        } catch (err) {
+          console.error('鏍囪灏辩华澶辫触:', err)
+          this.$modal.showToast('鏍囪灏辩华澶辫触')
+        }
+      },
+
+      // 澶勭悊鍑哄彂鎸夐挳鐐瑰嚮
+      async handleDepartAction() {
+        if (!this.taskDetail) return
+        
+        const list = (this.taskDetail && Array.isArray(this.taskDetail.assignees)) ? this.taskDetail.assignees : []
+        
+        // 濡傛灉寮�鍚簡灏辩华鍔熻兘涓旀槸澶氫汉浠诲姟锛岄渶瑕佹鏌ユ墍鏈変汉鏄惁灏辩华
+        if (this.showAssigneeReadyFeature() && list.length > 1) {
+          if (!this.areAllAssigneesReady()) {
+            this.$modal.showToast('鍏朵粬浜烘湭灏辩华锛屾墍鏈変汉灏辩华鍚庢墠鑳藉嚭鍙�')
+            return
+          }
+        }
+        
+        // 鍗曚汉浠诲姟鎴栨湭寮�鍚氨缁姛鑳斤細鑷姩鏍囪灏辩华
+        if (this.showAssigneeReadyFeature() && list.length === 1) {
+          const me = this.getCurrentUserAssignee()
+          if (me && !this.isAssigneeReady(me)) {
+            try {
+              await setAssigneeReady(this.taskId)
+            } catch (e) {
+              console.error('鑷姩灏辩华澶辫触:', e)
+            }
+          }
+        }
+        
+        // 鎵ц鍑哄彂娴佺▼
+        this.checkVehicleAndDepart()
+      },
+
+      // 鍑哄彂鍓嶄繚璇佸氨缁紙淇濈暀鍚戝悗鍏煎锛�
+      async ensureReadyThenDepart() {
+        this.handleDepartAction()
       }
     }
   }
@@ -1383,6 +1546,31 @@
                   background-color: #AF52DE;
                 }
               }
+              
+              .assignee-ready-btn {
+                margin-left: 12rpx;
+                padding: 8rpx 16rpx;
+                font-size: 24rpx;
+                border-radius: 6rpx;
+                background-color: #34C759;
+                color: #fff;
+                border: none;
+              }
+              .ready-badge {
+                display: inline-block;
+                margin-left: 12rpx;
+                padding: 4rpx 12rpx;
+                font-size: 22rpx;
+                border-radius: 6rpx;
+                &.ready {
+                  background-color: #e6ffed;
+                  color: #34C759;
+                }
+                &.unready {
+                  background-color: #f0f0f0;
+                  color: #999;
+                }
+              }
             }
           }
         }
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskController.java
index fb8d9c0..4181398 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/task/SysTaskController.java
@@ -353,6 +353,24 @@
     }
 
     /**
+     * 鎵ц浜虹偣鍑诲氨缁紙APP绔級
+     */
+    @PostMapping("/{taskId}/assignee/ready")
+    public AjaxResult setAssigneeReady(@PathVariable Long taskId) {
+        Long userId = getUserId();
+        return sysTaskService.setAssigneeReady(taskId, userId);
+    }
+
+    /**
+     * 鎵ц浜哄彇娑堝氨缁紙APP绔級
+     */
+    @PostMapping("/{taskId}/assignee/cancel-ready")
+    public AjaxResult cancelAssigneeReady(@PathVariable Long taskId) {
+        Long userId = getUserId();
+        return sysTaskService.cancelAssigneeReady(taskId, userId);
+    }
+
+    /**
      * 鍒嗛厤浠诲姟璇锋眰瀵硅薄
      */
     public static class AssignTaskRequest {
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTaskAssignee.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTaskAssignee.java
index 27644bc..683c066 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTaskAssignee.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysTaskAssignee.java
@@ -39,6 +39,15 @@
     @Excel(name = "鏄惁涓轰富瑕佹墽琛屼汉", readConverterExp = "0=鍚�,1=鏄�")
     private String isPrimary;
 
+    /** 鏄惁宸插氨缁細0-鏈氨缁紝1-宸插氨缁� */
+    @Excel(name = "鏄惁宸插氨缁�", readConverterExp = "0=鏈氨缁�,1=宸插氨缁�")
+    private String isReady;
+
+    /** 灏辩华鏃堕棿 */
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @Excel(name = "灏辩华鏃堕棿", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss")
+    private Date readyTime;
+
     /** 鎺掑簭椤哄簭锛堢敤浜庣‘瀹氶闃燂級 */
     @Excel(name = "鎺掑簭椤哄簭")
     private Integer sortOrder;
@@ -98,4 +107,20 @@
     public void setSortOrder(Integer sortOrder) {
         this.sortOrder = sortOrder;
     }
+
+    public String getIsReady() {
+        return isReady;
+    }
+
+    public void setIsReady(String isReady) {
+        this.isReady = isReady;
+    }
+
+    public Date getReadyTime() {
+        return readyTime;
+    }
+
+    public void setReadyTime(Date readyTime) {
+        this.readyTime = readyTime;
+    }
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysTaskService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysTaskService.java
index d0630b0..5664186 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysTaskService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysTaskService.java
@@ -284,4 +284,22 @@
      */
     public com.ruoyi.common.core.domain.AjaxResult checkTaskCanDepart(Long taskId);
 
+    /**
+     * 鎵ц浜虹偣鍑诲氨缁�
+     * 
+     * @param taskId 浠诲姟ID
+     * @param userId 鐢ㄦ埛ID
+     * @return 缁撴灉
+     */
+    public com.ruoyi.common.core.domain.AjaxResult setAssigneeReady(Long taskId, Long userId);
+
+    /**
+     * 鍙栨秷鎵ц浜哄氨缁�
+     * 
+     * @param taskId 浠诲姟ID
+     * @param userId 鐢ㄦ埛ID
+     * @return 缁撴灉
+     */
+    public com.ruoyi.common.core.domain.AjaxResult cancelAssigneeReady(Long taskId, Long userId);
+
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskServiceImpl.java
index b983222..a6bca50 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskServiceImpl.java
@@ -36,6 +36,7 @@
 import com.ruoyi.system.service.ISysTaskEmergencyService;
 import com.ruoyi.system.service.ITaskAttachmentSyncService;
 import com.ruoyi.system.service.IMapService;
+import com.ruoyi.system.service.ISysConfigService;
 import com.ruoyi.system.event.TaskCreatedEvent;
 import com.ruoyi.system.event.TaskAssignedEvent;
 import com.ruoyi.system.event.TaskStatusChangedEvent;
@@ -99,6 +100,9 @@
 
     @Autowired(required = false)
     private IMapService mapService;
+
+    @Autowired
+    private ISysConfigService configService;
 
     /**
      * 鏌ヨ浠诲姟绠$悊
@@ -2344,6 +2348,22 @@
             }
         }
         
+        // 3. 妫�鏌ユ墽琛屼汉鏄惁鍏ㄩ儴灏辩华锛堝彈閰嶇疆寮�鍏虫帶鍒讹級
+        String readyCheckEnabled = configService.selectConfigByKey("task.assignee.ready.check.enabled");
+        if ("true".equalsIgnoreCase(readyCheckEnabled)) {
+             assignees = task.getAssignees();
+            if (assignees != null && !assignees.isEmpty()) {
+                boolean allReady = assignees.stream()
+                    .allMatch(a -> "1".equals(a.getIsReady()));
+                if (!allReady) {
+                    Map<String, Object> conflict = new HashMap<>();
+                    conflict.put("type", "assigneeReady");
+                    conflict.put("message", "瀛樺湪鏈氨缁殑鎵ц浜猴紝璇风瓑寰呮墍鏈夋墽琛屼汉鐐瑰嚮灏辩华鍚庡啀鍑鸿溅");
+                    conflicts.add(conflict);
+                }
+            }
+        }
+        
         // 杩斿洖缁撴灉
         Map<String, Object> result = new HashMap<>();
         result.put("valid", conflicts.isEmpty());
@@ -2351,5 +2371,77 @@
         
         return com.ruoyi.common.core.domain.AjaxResult.success(result);
     }
+
+    /**
+     * 鎵ц浜虹偣鍑诲氨缁�
+     * 
+     * @param taskId 浠诲姟ID
+     * @param userId 鐢ㄦ埛ID
+     * @return 缁撴灉
+     */
+    @Override
+    @Transactional
+    public com.ruoyi.common.core.domain.AjaxResult setAssigneeReady(Long taskId, Long userId) {
+        // 1. 鏌ヨ鎵ц浜哄叧鑱斾俊鎭�
+        List<SysTaskAssignee> assignees = sysTaskAssigneeMapper.selectSysTaskAssigneeByTaskId(taskId);
+        SysTaskAssignee targetAssignee = assignees.stream()
+            .filter(a -> a.getUserId().equals(userId))
+            .findFirst()
+            .orElse(null);
+        
+        if (targetAssignee == null) {
+            return com.ruoyi.common.core.domain.AjaxResult.error("鎮ㄤ笉鏄浠诲姟鐨勬墽琛屼汉");
+        }
+        
+        // 2. 鏇存柊灏辩华鐘舵��
+        targetAssignee.setIsReady("1");
+        targetAssignee.setReadyTime(new Date());
+        targetAssignee.setUpdateBy(SecurityUtils.getUsername());
+        targetAssignee.setUpdateTime(new Date());
+        
+        sysTaskAssigneeMapper.updateSysTaskAssignee(targetAssignee);
+        
+        // 3. 妫�鏌ユ槸鍚︽墍鏈夋墽琛屼汉閮藉凡灏辩华
+        boolean allReady = assignees.stream()
+            .allMatch(a -> a.getUserId().equals(userId) || "1".equals(a.getIsReady()));
+        
+        Map<String, Object> result = new HashMap<>();
+        result.put("allReady", allReady);
+        result.put("message", "灏辩华鎴愬姛");
+        
+        return com.ruoyi.common.core.domain.AjaxResult.success(result);
+    }
+
+    /**
+     * 鍙栨秷鎵ц浜哄氨缁�
+     * 
+     * @param taskId 浠诲姟ID
+     * @param userId 鐢ㄦ埛ID
+     * @return 缁撴灉
+     */
+    @Override
+    @Transactional
+    public com.ruoyi.common.core.domain.AjaxResult cancelAssigneeReady(Long taskId, Long userId) {
+        // 鏌ヨ鎵ц浜哄叧鑱斾俊鎭�
+        List<SysTaskAssignee> assignees = sysTaskAssigneeMapper.selectSysTaskAssigneeByTaskId(taskId);
+        SysTaskAssignee targetAssignee = assignees.stream()
+            .filter(a -> a.getUserId().equals(userId))
+            .findFirst()
+            .orElse(null);
+        
+        if (targetAssignee == null) {
+            return com.ruoyi.common.core.domain.AjaxResult.error("鎮ㄤ笉鏄浠诲姟鐨勬墽琛屼汉");
+        }
+        
+        // 鏇存柊灏辩华鐘舵��
+        targetAssignee.setIsReady("0");
+        targetAssignee.setReadyTime(null);
+        targetAssignee.setUpdateBy(SecurityUtils.getUsername());
+        targetAssignee.setUpdateTime(new Date());
+        
+        sysTaskAssigneeMapper.updateSysTaskAssignee(targetAssignee);
+        
+        return com.ruoyi.common.core.domain.AjaxResult.success("宸插彇娑堝氨缁�");
+    }
    
 }
diff --git a/ruoyi-system/src/main/resources/mapper/system/SysTaskAssigneeMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysTaskAssigneeMapper.xml
index abe5104..67422e4 100644
--- a/ruoyi-system/src/main/resources/mapper/system/SysTaskAssigneeMapper.xml
+++ b/ruoyi-system/src/main/resources/mapper/system/SysTaskAssigneeMapper.xml
@@ -11,6 +11,8 @@
         <result property="userName"    column="user_name"    />
         <result property="userType"    column="user_type"    />
         <result property="isPrimary"    column="is_primary"    />
+        <result property="isReady"    column="is_ready"    />
+        <result property="readyTime"    column="ready_time"    />
         <result property="sortOrder"    column="sort_order"    />
         <result property="createTime"    column="create_time"    />
         <result property="createBy"    column="create_by"    />
@@ -19,7 +21,7 @@
     </resultMap>
 
     <sql id="selectSysTaskAssigneeVo">
-        select id, task_id, user_id, user_name, user_type, is_primary, sort_order, create_time, create_by, update_time, update_by
+        select id, task_id, user_id, user_name, user_type, is_primary, is_ready, ready_time, sort_order, create_time, create_by, update_time, update_by
         from sys_task_assignee
     </sql>
 
@@ -78,6 +80,8 @@
             <if test="userName != null and userName != ''">user_name = #{userName},</if>
             <if test="userType != null and userType != ''">user_type = #{userType},</if>
             <if test="isPrimary != null">is_primary = #{isPrimary},</if>
+            <if test="isReady != null">is_ready = #{isReady},</if>
+            <if test="readyTime != null">ready_time = #{readyTime},</if>
             <if test="sortOrder != null">sort_order = #{sortOrder},</if>
             <if test="updateTime != null">update_time = #{updateTime},</if>
             <if test="updateBy != null and updateBy != ''">update_by = #{updateBy},</if>
diff --git a/sql/add_assignee_ready_status.sql b/sql/add_assignee_ready_status.sql
new file mode 100644
index 0000000..0ff822c
--- /dev/null
+++ b/sql/add_assignee_ready_status.sql
@@ -0,0 +1,11 @@
+-- 涓烘墽琛屼汉琛ㄦ坊鍔犲氨缁姸鎬佸瓧娈�
+ALTER TABLE sys_task_assignee 
+ADD COLUMN is_ready CHAR(1) DEFAULT '0' COMMENT '鏄惁宸插氨缁紙0鏈氨缁� 1宸插氨缁級' AFTER is_primary,
+ADD COLUMN ready_time DATETIME COMMENT '灏辩华鏃堕棿' AFTER is_ready;
+
+-- 娣诲姞绯荤粺閰嶇疆锛氭槸鍚﹀惎鐢ㄦ墽琛屼汉灏辩华妫�鏌�
+INSERT INTO sys_config (config_name, config_key, config_value, config_type, remark, create_by, create_time, update_by, update_time) 
+VALUES ('鎵ц浜哄氨缁鏌ュ紑鍏�', 'task.assignee.ready.check.enabled', 'false', 'Y', '鏄惁鍚敤鎵ц浜哄氨缁鏌ュ姛鑳斤紙true鍚敤锛宖alse鍏抽棴锛�', 'admin', NOW(), 'admin', NOW());
+
+-- 涓哄凡瀛樺湪鐨勬墽琛屼汉鏁版嵁璁剧疆榛樿鍊硷紙鍙�夛級
+UPDATE sys_task_assignee SET is_ready = '0' WHERE is_ready IS NULL;

--
Gitblit v1.9.1