From 7c790c248c137a2fa5525bf66ed04c25043cded7 Mon Sep 17 00:00:00 2001
From: wlzboy <66905212@qq.com>
Date: 星期三, 03 十二月 2025 09:32:19 +0800
Subject: [PATCH] feat:用户附加同步

---
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysTaskServiceImpl.java            |    6 
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImpl.java |   14 
 app/pagesTask/components/StaffSelector.vue                                                  |  661 ++++++++++++++++++++++++++++++++++++++
 app/pagesTask/create-emergency.vue                                                          |  315 -----------------
 ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacySystemSyncServiceImpl.java   |    6 
 5 files changed, 686 insertions(+), 316 deletions(-)

diff --git a/app/pagesTask/components/StaffSelector.vue b/app/pagesTask/components/StaffSelector.vue
new file mode 100644
index 0000000..6cc7446
--- /dev/null
+++ b/app/pagesTask/components/StaffSelector.vue
@@ -0,0 +1,661 @@
+<template>
+  <view class="staff-selector-component">
+    <view class="form-item">
+      <view class="form-label" :class="{ required: required }">{{ label }}</view>
+      <view class="staff-list">
+        <view class="staff-item" v-for="(staff, index) in selectedStaff" :key="staff.userId">
+          <view class="staff-info">
+            <text class="staff-name">{{ staff.nickName }}</text>
+            <view class="staff-roles">
+              <text class="staff-role" v-for="(roleType, idx) in staff.types" :key="idx">
+                {{ getUserTypeName(roleType) }}
+              </text>
+            </view>
+          </view>
+          <uni-icons 
+            v-if="canRemove(index)"
+            type="closeempty" 
+            size="20" 
+            color="#ff4d4f"
+            @click="removeStaff(index)"
+          ></uni-icons>
+          <uni-icons 
+            v-else
+            type="checkmarkempty" 
+            size="20" 
+            color="#007AFF"
+          ></uni-icons>
+        </view>
+        <view class="add-staff" @click="showStaffSelector">
+          <uni-icons type="plusempty" size="20" color="#007AFF"></uni-icons>
+          <text>娣诲姞浜哄憳</text>
+        </view>
+      </view>
+    </view>
+    
+    <!-- 浜哄憳閫夋嫨寮圭獥 -->
+    <uni-popup ref="staffPopup" type="bottom" :safe-area="true">
+      <view class="staff-selector-popup">
+        <view class="popup-header">
+          <view class="popup-title">閫夋嫨鎵ц浜哄憳</view>
+          <view class="popup-close" @click="closeStaffSelector">
+            <uni-icons type="closeempty" size="24" color="#333"></uni-icons>
+          </view>
+        </view>
+        
+        <view class="search-box">
+          <uni-icons type="search" size="18" color="#999"></uni-icons>
+          <input 
+            class="search-input" 
+            placeholder="鎼滅储濮撳悕銆佹墜鏈哄彿" 
+            v-model="staffSearchKeyword"
+            @input="onStaffSearch"
+          />
+        </view>
+        
+        <view class="staff-filter">
+          <view 
+            class="filter-item" 
+            :class="{ active: staffFilterType === 'all' }"
+            @click="filterStaff('all')"
+          >鍏ㄩ儴</view>
+          <view 
+            class="filter-item" 
+            :class="{ active: staffFilterType === 'driver' }"
+            @click="filterStaff('driver')"
+          >鍙告満</view>
+          <view 
+            class="filter-item" 
+            :class="{ active: staffFilterType === 'doctor' }"
+            @click="filterStaff('doctor')"
+          >鍖荤敓</view>
+          <view 
+            class="filter-item" 
+            :class="{ active: staffFilterType === 'nurse' }"
+            @click="filterStaff('nurse')"
+          >鎶ゅ+</view>
+        </view>
+        
+        <scroll-view class="staff-list-popup" scroll-y="true">
+          <view 
+            class="staff-item-popup" 
+            v-for="staff in filteredStaffList" 
+            :key="staff.userId"
+            @click="toggleStaffSelection(staff)"
+          >
+            <view class="staff-info">
+              <view class="staff-name-row">
+                <text class="staff-name">{{ staff.nickName }}</text>
+                <text class="staff-phone">{{ staff.phonenumber }}</text>
+              </view>
+              <view class="staff-detail-row">
+                <text class="staff-dept">{{ staff.deptName }}</text>
+                <view class="staff-types">
+                  <text 
+                    class="type-tag" 
+                    :class="'type-' + type"
+                    v-for="(type, idx) in staff.types" 
+                    :key="idx"
+                  >
+                    {{ getUserTypeName(type) }}
+                  </text>
+                </view>
+              </view>
+            </view>
+            <uni-icons 
+              v-if="isStaffSelected(staff.userId)" 
+              type="checkmarkempty" 
+              size="24" 
+              color="#007AFF"
+            ></uni-icons>
+            <view v-else class="checkbox-empty"></view>
+          </view>
+          
+          <view class="no-data" v-if="filteredStaffList.length === 0">
+            <uni-icons type="info" size="40" color="#ccc"></uni-icons>
+            <text>鏆傛棤浜哄憳鏁版嵁</text>
+          </view>
+        </scroll-view>
+        
+        <view class="popup-footer">
+          <button class="cancel-btn" @click="closeStaffSelector">鍙栨秷</button>
+          <button class="confirm-btn" @click="confirmStaffSelection">纭畾(宸查�墈{ selectedStaff.length }})</button>
+        </view>
+      </view>
+    </uni-popup>
+  </view>
+</template>
+
+<script>
+import { mapState } from 'vuex'
+import uniPopup from '@/uni_modules/uni-popup/components/uni-popup/uni-popup.vue'
+import { listBranchUsers } from "@/api/system/user"
+
+export default {
+  name: 'StaffSelector',
+  components: {
+    uniPopup
+  },
+  props: {
+    // 宸查�夋嫨鐨勪汉鍛樺垪琛�
+    value: {
+      type: Array,
+      default: () => []
+    },
+    // 鏍囩鏂囨湰
+    label: {
+      type: String,
+      default: '鎵ц浠诲姟浜哄憳'
+    },
+    // 鏄惁蹇呭~
+    required: {
+      type: Boolean,
+      default: false
+    },
+    // 鏄惁鑷姩娣诲姞褰撳墠鐢ㄦ埛
+    autoAddCurrentUser: {
+      type: Boolean,
+      default: true
+    },
+    // 褰撳墠鐢ㄦ埛鏄惁鍙Щ闄�
+    currentUserRemovable: {
+      type: Boolean,
+      default: false
+    }
+  },
+  data() {
+    return {
+      selectedStaff: [],
+      allStaffList: [],
+      filteredStaffList: [],
+      staffSearchKeyword: '',
+      staffFilterType: 'all'
+    }
+  },
+  computed: {
+    ...mapState({
+      currentUser: state => ({
+        userId: state.user.userId,
+        nickName: state.user.nickName || '寮犱笁',
+        phonenumber: state.user.phonenumber || '',
+        deptId: state.user.deptId || 100,
+        posts: state.user.posts || [],
+        roles: state.user.roles || [],
+        dept: state.user.dept || null
+      })
+    })
+  },
+  watch: {
+    value: {
+      handler(newVal) {
+        if (newVal && Array.isArray(newVal)) {
+          this.selectedStaff = [...newVal]
+        }
+      },
+      immediate: true,
+      deep: true
+    }
+  },
+  mounted() {
+    this.loadStaffList()
+    
+    // 濡傛灉闇�瑕佽嚜鍔ㄦ坊鍔犲綋鍓嶇敤鎴蜂笖閫変腑浜哄憳涓虹┖
+    if (this.autoAddCurrentUser && this.selectedStaff.length === 0) {
+      this.initWithCurrentUser()
+    }
+  },
+  methods: {
+    // 鍒濆鍖栭�変腑鐨勪汉鍛橈紙榛樿鍖呭惈褰撳墠鐢ㄦ埛锛�
+    initWithCurrentUser() {
+      const currentUserStaff = {
+        userId: this.currentUser.userId,
+        nickName: this.currentUser.nickName,
+        phonenumber: this.currentUser.phonenumber,
+        deptId: this.currentUser.deptId,
+        posts: this.currentUser.posts || [],
+        roles: this.currentUser.roles || [],
+        dept: this.currentUser.dept || null
+      }
+      
+      // 鑾峰彇褰撳墠鐢ㄦ埛鐨勬墍鏈夎鑹茬被鍨嬶紙鍙兘鏈夊涓級
+      currentUserStaff.types = this.getUserTypes(currentUserStaff)
+      currentUserStaff.type = currentUserStaff.types[0] || 'driver' // 涓昏绫诲瀷
+      
+      this.selectedStaff = [currentUserStaff]
+      this.emitChange()
+    },
+    
+    // 鍔犺浇浜哄憳鍒楄〃
+    loadStaffList() {
+      listBranchUsers().then(response => {
+        const userList = response.data || []
+        
+        this.allStaffList = userList.map(user => ({
+          userId: user.userId,
+          nickName: user.nickName,
+          phonenumber: user.phonenumber,
+          deptName: user.dept?.deptName || '',
+          postName: user.posts && user.posts.length > 0 ? user.posts[0].postName : '',
+          roleName: user.roles && user.roles.length > 0 ? user.roles[0].roleName : '',
+          posts: user.posts || [],
+          roles: user.roles || [],
+          dept: user.dept || null,
+          // 鏀寔澶氱绫诲瀷
+          types: this.getUserTypes(user),
+          type: this.getUserTypes(user)[0] || 'driver' // 涓昏绫诲瀷锛堢敤浜庡悜鍚庡吋瀹癸級
+        }))
+        
+        this.filterStaffList()
+      }).catch(error => {
+        console.error('鍔犺浇浜哄憳鍒楄〃澶辫触:', error)
+        this.$modal.showToast('鍔犺浇浜哄憳鍒楄〃澶辫触')
+      })
+    },
+    
+    // 鏍规嵁鐢ㄦ埛鐨勫矖浣嶆垨瑙掕壊鍒ゆ柇鎵�鏈夌被鍨嬶紙鏀寔澶氱韬唤锛�
+    getUserTypes(user) {
+      const types = []
+      const postNames = user.posts ? user.posts.map(p => p.postName).join('') : ''
+      const roleNames = user.roles ? user.roles.map(r => r.roleName).join('') : ''
+      const deptName = user.dept?.deptName || ''
+      
+      // 鍒ゆ柇鏄惁涓哄徃鏈�
+      if (postNames.includes('鍙告満') || roleNames.includes('鍙告満') || 
+          deptName.includes('杞﹂槦') || deptName.includes('鍙告満')) {
+        types.push('driver')
+      }
+      
+      // 鍒ゆ柇鏄惁涓哄尰鐢�
+      if (postNames.includes('鍖荤敓') || roleNames.includes('鍖荤敓') || 
+          deptName.includes('鍖荤敓') || deptName.includes('鍖绘姢')) {
+        types.push('doctor')
+      }
+      
+      // 鍒ゆ柇鏄惁涓烘姢澹�
+      if (postNames.includes('鎶ゅ+') || roleNames.includes('鎶ゅ+') || deptName.includes('鎶ゅ+')) {
+        types.push('nurse')
+      }
+      
+      // 濡傛灉娌℃湁鍖归厤鍒颁换浣曠被鍨嬶紝榛樿涓哄徃鏈�
+      if (types.length === 0) {
+        types.push('driver')
+      }
+      
+      return types
+    },
+    
+    // 鑾峰彇绫诲瀷鍚嶇О
+    getUserTypeName(staffType) {
+      const typeMap = {
+        'driver': '鍙告満',
+        'doctor': '鍖荤敓',
+        'nurse': '鎶ゅ+'
+      }
+      return typeMap[staffType] || staffType || '鍙告満'
+    },
+    
+    // 鏄剧ず浜哄憳閫夋嫨寮圭獥
+    showStaffSelector() {
+      this.$refs.staffPopup.open()
+      this.filterStaffList()
+    },
+    
+    // 鍏抽棴浜哄憳閫夋嫨寮圭獥
+    closeStaffSelector() {
+      this.$refs.staffPopup.close()
+      this.staffSearchKeyword = ''
+      this.staffFilterType = 'all'
+    },
+    
+    // 浜哄憳鎼滅储
+    onStaffSearch(e) {
+      this.staffSearchKeyword = e.detail.value
+      this.filterStaffList()
+    },
+    
+    // 绛涢�変汉鍛樼被鍨�
+    filterStaff(type) {
+      this.staffFilterType = type
+      this.filterStaffList()
+    },
+    
+    // 杩囨护浜哄憳鍒楄〃
+    filterStaffList() {
+      let list = [...this.allStaffList]
+      
+      // 鎸夌被鍨嬭繃婊わ紙鏀寔澶氱被鍨嬶級
+      if (this.staffFilterType !== 'all') {
+        list = list.filter(staff => staff.types.includes(this.staffFilterType))
+      }
+      
+      // 鎸夊叧閿瘝鎼滅储
+      if (this.staffSearchKeyword && this.staffSearchKeyword.trim() !== '') {
+        const keyword = this.staffSearchKeyword.trim().toLowerCase()
+        list = list.filter(staff => {
+          return staff.nickName.toLowerCase().includes(keyword) || 
+                 (staff.phonenumber && staff.phonenumber.includes(keyword))
+        })
+      }
+      
+      this.filteredStaffList = list
+    },
+    
+    // 鍒囨崲浜哄憳閫変腑鐘舵��
+    toggleStaffSelection(staff) {
+      const index = this.selectedStaff.findIndex(s => s.userId === staff.userId)
+      
+      if (index > -1) {
+        // 濡傛灉鏄涓�涓笖涓嶅彲绉婚櫎锛堝綋鍓嶇敤鎴凤級锛屼笉鍏佽绉婚櫎
+        if (!this.canRemove(index)) {
+          this.$modal.showToast('褰撳墠鐢ㄦ埛涓嶈兘绉婚櫎')
+          return
+        }
+        // 宸查�変腑锛岀Щ闄�
+        this.selectedStaff.splice(index, 1)
+      } else {
+        // 鏈�変腑锛屾坊鍔�
+        this.selectedStaff.push(staff)
+      }
+    },
+    
+    // 鍒ゆ柇浜哄憳鏄惁宸查�変腑
+    isStaffSelected(userId) {
+      return this.selectedStaff.some(staff => staff.userId === userId)
+    },
+    
+    // 鍒ゆ柇鏄惁鍙互绉婚櫎
+    canRemove(index) {
+      // 濡傛灉鏄涓�涓笖褰撳墠鐢ㄦ埛涓嶅彲绉婚櫎
+      if (index === 0 && !this.currentUserRemovable) {
+        return false
+      }
+      return true
+    },
+    
+    // 纭浜哄憳閫夋嫨
+    confirmStaffSelection() {
+      if (this.selectedStaff.length === 0) {
+        this.$modal.showToast('璇疯嚦灏戦�夋嫨涓�鍚嶄汉鍛�')
+        return
+      }
+      this.emitChange()
+      this.closeStaffSelector()
+    },
+    
+    // 绉婚櫎浜哄憳
+    removeStaff(index) {
+      if (!this.canRemove(index)) {
+        this.$modal.showToast('褰撳墠鐢ㄦ埛涓嶈兘绉婚櫎')
+        return
+      }
+      this.selectedStaff.splice(index, 1)
+      this.emitChange()
+    },
+    
+    // 瑙﹀彂change浜嬩欢
+    emitChange() {
+      this.$emit('input', this.selectedStaff)
+      this.$emit('change', this.selectedStaff)
+    }
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.staff-selector-component {
+  .form-item {
+    margin-bottom: 40rpx;
+    
+    .form-label {
+      font-size: 28rpx;
+      margin-bottom: 15rpx;
+      color: #333;
+      
+      &.required::before {
+        content: '*';
+        color: #ff4d4f;
+        margin-right: 4rpx;
+        font-weight: bold;
+      }
+    }
+    
+    .staff-list {
+      .staff-item {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        padding: 20rpx;
+        background-color: #f9f9f9;
+        border-radius: 10rpx;
+        margin-bottom: 20rpx;
+        
+        .staff-info {
+          flex: 1;
+          
+          .staff-name {
+            font-size: 28rpx;
+            color: #333;
+            margin-right: 10rpx;
+            display: block;
+            margin-bottom: 8rpx;
+          }
+          
+          .staff-roles {
+            display: flex;
+            flex-wrap: wrap;
+            gap: 8rpx;
+            
+            .staff-role {
+              font-size: 22rpx;
+              color: white;
+              background-color: #007AFF;
+              padding: 4rpx 12rpx;
+              border-radius: 6rpx;
+            }
+          }
+        }
+      }
+      
+      .add-staff {
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        padding: 20rpx;
+        border: 1rpx dashed #007AFF;
+        border-radius: 10rpx;
+        color: #007AFF;
+        
+        text {
+          margin-left: 10rpx;
+        }
+      }
+    }
+  }
+}
+
+// 浜哄憳閫夋嫨寮圭獥鏍峰紡
+.staff-selector-popup {
+  background-color: white;
+  border-radius: 20rpx 20rpx 0 0;
+  max-height: 80vh;
+  display: flex;
+  flex-direction: column;
+  
+  .popup-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 30rpx;
+    border-bottom: 1rpx solid #f0f0f0;
+    flex-shrink: 0;
+    
+    .popup-title {
+      font-size: 32rpx;
+      font-weight: bold;
+      color: #333;
+    }
+    
+    .popup-close {
+      padding: 10rpx;
+    }
+  }
+  
+  .search-box {
+    display: flex;
+    align-items: center;
+    margin: 20rpx 30rpx;
+    padding: 15rpx 20rpx;
+    background-color: #f5f5f5;
+    border-radius: 10rpx;
+    flex-shrink: 0;
+    
+    .search-input {
+      flex: 1;
+      margin-left: 10rpx;
+      font-size: 28rpx;
+    }
+  }
+  
+  .staff-filter {
+    display: flex;
+    padding: 0 30rpx 20rpx;
+    gap: 15rpx;
+    flex-shrink: 0;
+    
+    .filter-item {
+      flex: 1;
+      text-align: center;
+      padding: 15rpx 0;
+      background-color: #f5f5f5;
+      border-radius: 10rpx;
+      font-size: 26rpx;
+      color: #666;
+      
+      &.active {
+        background-color: #007AFF;
+        color: white;
+      }
+    }
+  }
+  
+  .staff-list-popup {
+    flex: 1;
+    overflow-y: auto;
+    padding: 0 30rpx;
+    
+    .staff-item-popup {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      padding: 25rpx 20rpx;
+      border-bottom: 1rpx solid #f0f0f0;
+      
+      &:active {
+        background-color: #f5f5f5;
+      }
+      
+      .staff-info {
+        flex: 1;
+        
+        .staff-name-row {
+          display: flex;
+          align-items: center;
+          margin-bottom: 10rpx;
+          
+          .staff-name {
+            font-size: 30rpx;
+            font-weight: bold;
+            color: #333;
+            margin-right: 20rpx;
+          }
+          
+          .staff-phone {
+            font-size: 24rpx;
+            color: #999;
+          }
+        }
+        
+        .staff-detail-row {
+          display: flex;
+          align-items: center;
+          flex-wrap: wrap;
+          
+          .staff-dept {
+            font-size: 24rpx;
+            color: #666;
+            margin-right: 15rpx;
+          }
+          
+          .staff-types {
+            display: flex;
+            gap: 8rpx;
+            
+            .type-tag {
+              font-size: 20rpx;
+              color: white;
+              padding: 4rpx 10rpx;
+              border-radius: 6rpx;
+              
+              &.type-driver {
+                background-color: #007AFF;
+              }
+              
+              &.type-doctor {
+                background-color: #34C759;
+              }
+              
+              &.type-nurse {
+                background-color: #AF52DE;
+              }
+            }
+          }
+        }
+      }
+      
+      .checkbox-empty {
+        width: 40rpx;
+        height: 40rpx;
+        border: 2rpx solid #ddd;
+        border-radius: 50%;
+      }
+    }
+    
+    .no-data {
+      text-align: center;
+      padding: 100rpx 0;
+      color: #999;
+      
+      text {
+        display: block;
+        margin-top: 20rpx;
+        font-size: 28rpx;
+      }
+    }
+  }
+  
+  .popup-footer {
+    display: flex;
+    padding: 20rpx 30rpx;
+    border-top: 1rpx solid #f0f0f0;
+    gap: 20rpx;
+    flex-shrink: 0;
+    
+    button {
+      flex: 1;
+      height: 80rpx;
+      border-radius: 10rpx;
+      font-size: 30rpx;
+    }
+    
+    .cancel-btn {
+      background-color: #f5f5f5;
+      color: #666;
+    }
+    
+    .confirm-btn {
+      background-color: #007AFF;
+      color: white;
+    }
+  }
+}
+</style>
diff --git a/app/pagesTask/create-emergency.vue b/app/pagesTask/create-emergency.vue
index a0f819e..8fb53ae 100644
--- a/app/pagesTask/create-emergency.vue
+++ b/app/pagesTask/create-emergency.vue
@@ -59,34 +59,14 @@
           </view>
         </picker>
       </view>
-      <view class="form-item">
-        <view class="form-label">鎵ц浠诲姟浜哄憳</view>
-        <view class="staff-list">
-          <view class="staff-item" v-for="(staff, index) in selectedStaff" :key="staff.userId">
-            <view class="staff-info">
-              <text class="staff-name">{{ staff.nickName }}</text>
-              <text class="staff-role">({{ getUserTypeName(staff.type) || '鏈煡鑱屼綅' }})</text>
-            </view>
-            <uni-icons 
-              v-if="index > 0" 
-              type="closeempty" 
-              size="20" 
-              color="#ff4d4f"
-              @click="removeStaff(index)"
-            ></uni-icons>
-            <uni-icons 
-              v-else
-              type="checkmarkempty" 
-              size="20" 
-              color="#007AFF"
-            ></uni-icons>
-          </view>
-          <view class="add-staff" @click="showStaffSelector">
-            <uni-icons type="plusempty" size="20" color="#007AFF"></uni-icons>
-            <text>娣诲姞浜哄憳</text>
-          </view>
-        </view>
-      </view>
+      <StaffSelector
+        v-model="selectedStaff"
+        label="鎵ц浠诲姟浜哄憳"
+        :required="false"
+        :auto-add-current-user="true"
+        :current-user-removable="false"
+        @change="onStaffChange"
+      />
       
     
       
@@ -213,82 +193,6 @@
       </view>
     </view>
     
-    <!-- 浜哄憳閫夋嫨寮圭獥 -->
-    <uni-popup ref="staffPopup" type="bottom" :safe-area="true">
-      <view class="staff-selector-popup">
-        <view class="popup-header">
-          <view class="popup-title">閫夋嫨鎵ц浜哄憳</view>
-          <view class="popup-close" @click="closeStaffSelector">
-            <uni-icons type="closeempty" size="24" color="#333"></uni-icons>
-          </view>
-        </view>
-        
-        <view class="search-box">
-          <uni-icons type="search" size="18" color="#999"></uni-icons>
-          <input 
-            class="search-input" 
-            placeholder="鎼滅储濮撳悕銆佹墜鏈哄彿" 
-            v-model="staffSearchKeyword"
-            @input="onStaffSearch"
-          />
-        </view>
-        
-        <view class="staff-filter">
-          <view 
-            class="filter-item" 
-            :class="{ active: staffFilterType === 'driver' }"
-            @click="filterStaff('driver')"
-          >鍙告満</view>
-          <view 
-            class="filter-item" 
-            :class="{ active: staffFilterType === 'doctor' }"
-            @click="filterStaff('doctor')"
-          >鍖荤敓</view>
-          <view 
-            class="filter-item" 
-            :class="{ active: staffFilterType === 'nurse' }"
-            @click="filterStaff('nurse')"
-          >鎶ゅ+</view>
-        </view>
-        
-        <scroll-view class="staff-list-popup" scroll-y="true">
-          <view 
-            class="staff-item-popup" 
-            v-for="staff in filteredStaffList" 
-            :key="staff.userId"
-            @click="toggleStaffSelection(staff)"
-          >
-            <view class="staff-info">
-              <view class="staff-name-row">
-                <text class="staff-name">{{ staff.nickName }}</text>
-                <text class="staff-phone">{{ staff.phonenumber }}</text>
-              </view>
-              <view class="staff-detail-row">
-                <text class="staff-dept">{{ staff.deptName }}</text>
-                <text class="staff-post">{{ staff.postName || staff.roleName  || '鏈煡鑱屼綅' }}</text>
-              </view>
-            </view>
-            <uni-icons 
-              v-if="isStaffSelected(staff.userId)" 
-              type="checkmarkempty" 
-              size="24" 
-              color="#007AFF"
-            ></uni-icons>
-            <view v-else class="checkbox-empty"></view>
-          </view>
-          
-          <view class="no-data" v-if="filteredStaffList.length === 0">
-            <uni-icons type="info" size="40" color="#ccc"></uni-icons>
-            <text>鏆傛棤浜哄憳鏁版嵁</text>
-          </view>
-        </scroll-view>
-        
-        <view class="popup-footer">
-          <button class="cancel-btn" @click="closeStaffSelector">鍙栨秷</button>
-          <button class="confirm-btn" @click="confirmStaffSelection">纭畾(宸查�墈{ selectedStaff.length }})</button>
-        </view>
-      </view>
-    </uni-popup>
     
    <!-- 鏅鸿兘璇嗗埆寮圭獥 -->
     <uni-popup ref="smartParsePopup" type="bottom" :safe-area="true">
@@ -345,6 +249,7 @@
 import OrganizationSelector from './components/OrganizationSelector.vue'
 import HospitalSelector from './components/HospitalSelector.vue'
 import DiseaseSelector from './components/DiseaseSelector.vue'
+import StaffSelector from './components/StaffSelector.vue'
 
 export default {
   components: {
@@ -354,7 +259,8 @@
     OrganizationSelector,
     HospitalSelector,
     DiseaseSelector,
-    DepartureSelector
+    DepartureSelector,
+    StaffSelector
   },
   data() {
     return {
@@ -373,10 +279,6 @@
       mapSelectorType: '',
       // 浜哄憳閫夋嫨鐩稿叧
       selectedStaff: [], // 宸查�夋嫨鐨勪汉鍛樺垪琛�
-      allStaffList: [], // 鎵�鏈変汉鍛樺垪琛�
-      filteredStaffList: [], // 杩囨护鍚庣殑浜哄憳鍒楄〃
-      staffSearchKeyword: '', // 浜哄憳鎼滅储鍏抽敭璇�
-      staffFilterType: 'driver', // 浜哄憳绛涢�夌被鍨嬶細driver/doctor/nurse锛岄粯璁ら�変腑鍙告満
       // 鐥呮儏閫夋嫨鐩稿叧
       selectedDiseases: [], // 宸查�夋嫨鐨勭梾鎯呭垪琛�
       taskForm: {
@@ -452,8 +354,6 @@
     this.getAvailableVehicles().then(() => {
       this.getUserBoundVehicleInfo()
     })
-    this.initSelectedStaff()
-    this.loadDeptStaff()
     // 鍔犺浇绉戝瀛楀吀鏁版嵁
     this.loadDepartments()
     // 鍔犺浇浠诲姟绫诲瀷鏁版嵁
@@ -592,18 +492,7 @@
       this.selectedEmergencyTaskType = selected.text
       this.selectedEmergencyTaskTypeId = selected.id
     },
-    getUserTypeName(staffType){
-      switch(staffType){
-        case "nurse":
-          return "鎶ゅ+";
-        case "doctor":          
-          return "鍖荤敓";
-        case "driver":
-          return "鍙告満";
-        default:
-          return "鍙告満";
-      }
-    },
+
     
     // 鍔犺浇鍗曟嵁绫诲瀷鏁版嵁
     loadDocumentTypes() {
@@ -684,182 +573,10 @@
       }
     },
     
-    // 鍒濆鍖栭�変腑鐨勪汉鍛橈紙榛樿鍖呭惈褰撳墠鐢ㄦ埛锛�
-    initSelectedStaff() {
-      // 鏋勫缓褰撳墠鐢ㄦ埛瀵硅薄锛屽寘鍚畬鏁寸殑瑙掕壊淇℃伅
-      const currentUserStaff = {
-        userId: this.currentUser.userId,
-        nickName: this.currentUser.nickName,
-        phonenumber: this.currentUser.phonenumber,
-        postName: this.currentUser.position,
-        deptId: this.currentUser.deptId,
-        posts: this.currentUser.posts || [],
-        roles: this.currentUser.roles || [],
-        dept: this.currentUser.dept || null
-      }
-      
-      // 涓哄綋鍓嶇敤鎴疯缃鑹茬被鍨�
-      currentUserStaff.type = this.getUserType(currentUserStaff)
-      
-      this.selectedStaff = [currentUserStaff]
-    },
-    
-    // 鍔犺浇褰撳墠鐢ㄦ埛鎵�鍦ㄥ垎鍏徃鐨勬墍鏈変汉鍛�
-    loadDeptStaff() {
-      console.log('寮�濮嬪姞杞戒汉鍛樺垪琛�')
-      
-      // 璋冪敤鏂版帴鍙o紝鑷姩鏍规嵁褰撳墠鐢ㄦ埛鐨刼aOrderClass鑾峰彇鍒嗗叕鍙镐笅鐨勭敤鎴�
-      listBranchUsers().then(response => {
-        console.log('浜哄憳鍒楄〃API鍝嶅簲:', response)
-        const userList = response.data || []
-        console.log('瑙f瀽鍑虹殑鐢ㄦ埛鍒楄〃:', userList, '鏁伴噺:', userList.length)
-        
-        this.allStaffList = userList.map(user => ({
-          userId: user.userId,
-          nickName: user.nickName,
-          phonenumber: user.phonenumber,
-          deptName: user.dept?.deptName || '',
-          postName: user.posts && user.posts.length > 0 ? user.posts[0].postName : '',
-          roleName: user.roles && user.roles.length > 0 ? user.roles[0].roleName : '',
-          // 鏍规嵁宀椾綅鍚嶇О鎴栬鑹插悕绉板垽鏂被鍨�
-          type: this.getUserType(user)
-        }))
-        
-        console.log('澶勭悊鍚庣殑浜哄憳鍒楄〃:', this.allStaffList, '鏁伴噺:', this.allStaffList.length)
-        
-        // 鍒濆鍖栬繃婊ゅ垪琛�
-        this.filterStaffList()
-      }).catch(error => {
-        console.error('鍔犺浇浜哄憳鍒楄〃澶辫触:', error)
-        this.$modal.showToast('鍔犺浇浜哄憳鍒楄〃澶辫触')
-      })
-    },
-    
-    // 鏍规嵁鐢ㄦ埛鐨勫矖浣嶆垨瑙掕壊鍒ゆ柇绫诲瀷
-    getUserType(user) {
-      const postName = user.posts && user.posts.length > 0 ? user.posts[0].postName : ''
-      const roleName = user.roles && user.roles.length > 0 ? user.roles[0].roleName : ''
-      const deptName = user.dept?.deptName || ''
-      // console.log("鑾峰彇鐢ㄦ埛绫诲瀷:", postName, roleName,user)
-      // 鍒ゆ柇鏄惁涓哄徃鏈�
-      if (postName.includes('鍙告満') || roleName.includes('鍙告満') || deptName.includes('杞﹂槦') || deptName.includes('鍙告満')) {
-        return 'driver'
-      }
-      // 鍒ゆ柇鏄惁涓烘姢澹�
-      if (postName.includes('鎶ゅ+') || roleName.includes('鎶ゅ+') || deptName.includes('鎶ゅ+')) {
-        return 'nurse'
-      }
-      // 鍒ゆ柇鏄惁涓哄尰鐢�
-      if (postName.includes('鍖荤敓') || roleName.includes('鍖荤敓') || deptName.includes('鍖荤敓') ) {
-        return 'doctor'
-      }
-      if( deptName.includes("鍖绘姢")){
-        return 'doctor'
-      }
-      
-      // 鍏朵粬绫诲瀷锛岄粯璁や负鍙告満
-      return 'driver'
-    },
-    
-    // 鏄剧ず浜哄憳閫夋嫨寮圭獥
-    showStaffSelector() {
-      this.$refs.staffPopup.open()
-      this.filterStaffList()
-    },
-    
-    // 鍏抽棴浜哄憳閫夋嫨寮圭獥
-    closeStaffSelector() {
-      this.$refs.staffPopup.close()
-      this.staffSearchKeyword = ''
-      this.staffFilterType = 'driver' // 閲嶇疆涓洪粯璁ょ殑鍙告満绫诲瀷
-    },
-    
-    // 浜哄憳鎼滅储
-    onStaffSearch(e) {
-      this.staffSearchKeyword = e.detail.value
-      this.filterStaffList()
-    },
-    
-    // 绛涢�変汉鍛樼被鍨�
-    filterStaff(type) {
-      this.staffFilterType = type
-      this.filterStaffList()
-    },
-    
-    // 杩囨护浜哄憳鍒楄〃
-    filterStaffList() {
-      console.log('寮�濮嬭繃婊や汉鍛樺垪琛紝鍘熷鏁伴噺:', this.allStaffList.length)
-      let list = [...this.allStaffList]
-      
-      // 鎸夌被鍨嬭繃婊�
-      if (this.staffFilterType === 'driver') {
-        list = list.filter(staff => staff.type === 'driver')
-      } else if (this.staffFilterType === 'doctor') {
-        list = list.filter(staff => staff.type === 'doctor')
-      } else if (this.staffFilterType === 'nurse') {
-        list = list.filter(staff => staff.type === 'nurse')
-      }
-      
-      console.log('鎸夌被鍨嬭繃婊ゅ悗:', this.staffFilterType, '鏁伴噺:', list.length)
-      
-      // 鎸夊叧閿瘝鎼滅储
-      if (this.staffSearchKeyword && this.staffSearchKeyword.trim() !== '') {
-        const keyword = this.staffSearchKeyword.trim().toLowerCase()
-        list = list.filter(staff => {
-          return staff.nickName.toLowerCase().includes(keyword) || 
-                 (staff.phonenumber && staff.phonenumber.includes(keyword))
-        })
-      }
-      
-      console.log('鎸夊叧閿瘝杩囨护鍚庯紝鏁伴噺:', list.length)
-      
-      this.filteredStaffList = list
-      // console.log('鏈�缁堣繃婊ょ粨鏋�:', this.filteredStaffList)
-    },
-    
-    // 鍒囨崲浜哄憳閫変腑鐘舵��
-    toggleStaffSelection(staff) {
-      const index = this.selectedStaff.findIndex(s => s.userId === staff.userId)
-      
-      if (index > -1) {
-        // 濡傛灉鏄涓�涓紙褰撳墠鐢ㄦ埛锛夛紝涓嶅厑璁哥Щ闄�
-        if (index === 0) {
-          this.$modal.showToast('褰撳墠鐢ㄦ埛涓嶈兘绉婚櫎')
-          return
-        }
-        // 宸查�変腑锛岀Щ闄�
-        this.selectedStaff.splice(index, 1)
-      } else {
-        // 鏈�変腑锛屾坊鍔�
-        this.selectedStaff.push(staff)
-      }
-    },
-    
-    // 鍒ゆ柇浜哄憳鏄惁宸查�変腑
-    isStaffSelected(userId) {
-      return this.selectedStaff.some(staff => staff.userId === userId)
-    },
-    
-    // 纭浜哄憳閫夋嫨
-    confirmStaffSelection() {
-      if (this.selectedStaff.length === 0) {
-        this.$modal.showToast('璇疯嚦灏戦�夋嫨涓�鍚嶄汉鍛�')
-        return
-      }
-      this.closeStaffSelector()
-    },
-    
-    // 绉婚櫎浜哄憳
-    removeStaff(index) {
-      if (index === 0) {
-        this.$modal.showToast('褰撳墠鐢ㄦ埛涓嶈兘绉婚櫎')
-        return
-      }
-      this.selectedStaff.splice(index, 1)
-    },
-    
-    addStaff() {
-      this.showStaffSelector()
+    // 浜哄憳鍙樺寲浜嬩欢
+    onStaffChange(staff) {
+      console.log('閫変腑浜哄憳鍙樺寲:', staff)
+      // 缁勪欢宸茬粡閫氳繃 v-model 鏇存柊浜� selectedStaff
     },
     calculateDistanceByManualAddress() {
       const fromAddress = this.taskForm.hospitalOut.address
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacySystemSyncServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacySystemSyncServiceImpl.java
index 25ac645..4646829 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacySystemSyncServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacySystemSyncServiceImpl.java
@@ -1193,16 +1193,16 @@
             String response = sendHttpPost(legacyConfig.getDispatchUpdateUrl(), params);
             log.info("閲嶆柊鍚屾璋冨害鍗曞埌鏃х郴缁熷搷搴�: ServiceOrdID:{},DispatchOrdId:{},Result: {}",emergency.getLegacyServiceOrdId(),emergency.getLegacyDispatchOrdId(), response);
             // 瑙f瀽鍝嶅簲
-            Long dispatchOrdId = parseResponse(response);
+//            Long dispatchOrdId = parseResponse(response);
             
-            if (dispatchOrdId != null && dispatchOrdId > 0) {
+            if (response != null && response.equals("OK")) {
                 // 閲嶆柊鍚屾鎴愬姛锛屾竻闄ら噸鏂板悓姝ユ爣璁�
                 emergency.setNeedResync(0);
                 emergency.setDispatchSyncTime(new Date());
                 emergency.setDispatchSyncErrorMsg(null);
                 sysTaskEmergencyService.updateSysTaskEmergency(emergency);
                 
-                log.info("璋冨害鍗曢噸鏂板悓姝ユ垚鍔燂紝浠诲姟ID: {}, DispatchOrdID: {}", taskId, dispatchOrdId);
+                log.info("璋冨害鍗曢噸鏂板悓姝ユ垚鍔燂紝浠诲姟ID: {}, DispatchOrdID: {}", taskId, emergency.getLegacyDispatchOrdId());
                 return true;
             } else {
                 // 閲嶆柊鍚屾澶辫触
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImpl.java
index fed2d84..e764723 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/LegacyTransferSyncServiceImpl.java
@@ -424,18 +424,10 @@
             
             // 璁剧疆鍖哄煙绫诲瀷
             String serviceOrdAreaType = getStringValue(order, "ServiceOrdAreaType");
-            if (StringUtils.isNotEmpty(serviceOrdAreaType)) {
-                // 鍙互鏍规嵁闇�瑕佸皢鍖哄煙绫诲瀷鏄犲皠鍒癟askCreateVO鐨勫叾浠栧瓧娈�
-                log.debug("鍖哄煙绫诲瀷: {}", serviceOrdAreaType);
-            }
-            
+
             // 璁剧疆鐢ㄦ埛ID
             Long serviceOrdUserID = getLongValue(order, "ServiceOrdUserID");
-            if (serviceOrdUserID != null) {
-                // 鍙互鏍规嵁闇�瑕佸皢鐢ㄦ埛ID鏄犲皠鍒癟askCreateVO鐨勫叾浠栧瓧娈�
-                log.debug("鐢ㄦ埛ID: {}", serviceOrdUserID);
-            }
-            
+
             // 璁剧疆鎮h�呬俊鎭�
             TaskCreateVO.PatientInfo patientInfo = new TaskCreateVO.PatientInfo();
             patientInfo.setName(getStringValue(order, "ServiceOrdPtName"));
@@ -525,7 +517,7 @@
             createTaskVo.setHospitalIn(hospitalInInfo);
             
             // 璁剧疆鍦板潃淇℃伅
-            createTaskVo.setDepartureAddress(getStringValue(order, "ServiceOrdTraVia"));
+            createTaskVo.setDepartureAddress(getStringValue(order, "ServiceOrdTraStreet"));
             createTaskVo.setDestinationAddress(getStringValue(order, "ServiceOrdTraEnd"));
             
             // 璁剧疆浠锋牸鍜岃窛绂讳俊鎭�
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 233a8cf..466e111 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
@@ -633,11 +633,11 @@
                 }
             }
         }
-        
+        // 鐢ㄤ簬璺熻釜鏄惁闇�瑕侀噸鏂板悓姝ワ紙杞﹁締銆佷汉鍛樸�佸湴鍧�銆佹垚浜や环鍙樻洿锛�
+        boolean needResync = true;
         int result = sysTaskMapper.updateSysTask(task);
         
-        // 鐢ㄤ簬璺熻釜鏄惁闇�瑕侀噸鏂板悓姝ワ紙杞﹁締銆佷汉鍛樸�佸湴鍧�銆佹垚浜や环鍙樻洿锛�
-        boolean needResync = false;
+
         
         // 鏇存柊杞﹁締鍏宠仈
         if (result > 0 && updateVO.getVehicleIds() != null && !updateVO.getVehicleIds().isEmpty()) {

--
Gitblit v1.9.1