wlzboy
2025-12-04 4f2925f1974844b66225ac70ae35065b8262b315
app/pagesTask/edit-emergency.vue
@@ -47,27 +47,14 @@
        />
      </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
              type="closeempty"
              size="20"
              color="#ff4d4f"
              @click="removeStaff(index)"
            ></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="false"
        :current-user-removable="true"
        @change="onStaffChange"
      />
      
      <view class="form-section-title">患者信息</view>
      <view class="form-item">
@@ -198,80 +185,6 @@
        ></map-selector>
      </view>
    </uni-popup>
    <!-- 人员选择器弹窗 -->
    <uni-popup ref="staffPopup" type="bottom" :mask-click="false">
      <view class="staff-popup-container">
        <view class="popup-header">
          <view class="popup-title">选择执行人员</view>
          <view class="close-btn" @click="closeStaffSelector">
            <uni-icons type="closeempty" size="20" color="#999"></uni-icons>
          </view>
        </view>
        <view class="search-bar">
          <input
            class="search-input"
            placeholder="搜索姓名或电话"
            v-model="staffSearchKeyword"
            @input="onStaffSearch"
          />
        </view>
        <view class="filter-tabs">
          <view
            class="filter-tab"
            :class="{ active: staffFilterType === 'driver' }"
            @click="filterStaff('driver')"
          >
            司机
          </view>
          <view
            class="filter-tab"
            :class="{ active: staffFilterType === 'doctor' }"
            @click="filterStaff('doctor')"
          >
            医生
          </view>
          <view
            class="filter-tab"
            :class="{ active: staffFilterType === 'nurse' }"
            @click="filterStaff('nurse')"
          >
            护士
          </view>
        </view>
        <scroll-view class="staff-list-scroll" scroll-y="true">
          <view
            class="staff-list-item"
            v-for="staff in filteredStaffList"
            :key="staff.userId"
            @click="toggleStaffSelection(staff)"
          >
            <view class="staff-item-info">
              <text class="staff-item-name">{{ staff.nickName }}</text>
              <text class="staff-item-dept">{{ staff.deptName }}</text>
            </view>
            <view class="staff-item-check">
              <uni-icons
                v-if="isStaffSelected(staff.userId)"
                type="checkmarkempty"
                size="24"
                color="#007AFF"
              ></uni-icons>
            </view>
          </view>
          <view v-if="filteredStaffList.length === 0" class="empty-tip">
            暂无人员数据
          </view>
        </scroll-view>
        <view class="popup-footer">
          <button class="confirm-btn" @click="confirmStaffSelection">确定(已选{{ selectedStaff.length }})</button>
        </view>
      </view>
    </uni-popup>
  </scroll-view>
</template>
@@ -280,7 +193,6 @@
import uniDatetimePicker from '@/uni_modules/uni-datetime-picker/components/uni-datetime-picker/uni-datetime-picker.vue'
import uniPopup from '@/uni_modules/uni-popup/components/uni-popup/uni-popup.vue'
import { getTask, updateTask } from "@/api/task"
import { listBranchUsers } from "@/api/system/user"
import { baiduDistanceByAddress } from "@/api/map"
import { calculateTransferPrice } from "@/api/price"
import MapSelector from './components/map-selector.vue'
@@ -289,6 +201,7 @@
import HospitalSelector from './components/HospitalSelector.vue'
import DiseaseSelector from './components/DiseaseSelector.vue'
import DepartureSelector from './components/DepartureSelector.vue'
import StaffSelector from './components/StaffSelector.vue'
import distanceCalculator from '@/mixins/distanceCalculator.js'
export default {
@@ -300,7 +213,8 @@
    OrganizationSelector,
    HospitalSelector,
    DiseaseSelector,
    DepartureSelector
    DepartureSelector,
    StaffSelector
  },
  mixins: [distanceCalculator],
  data() {
@@ -325,10 +239,6 @@
      departureLatitude: null,
      selectedDiseases: [], // 已选择的病情列表(确保初始化为空数组)
      selectedStaff: [], // 已选择的人员列表(确保初始化为空数组)
      allStaffList: [], // 所有人员列表
      filteredStaffList: [], // 过滤后的人员列表
      staffSearchKeyword: '', // 人员搜索关键词
      staffFilterType: 'driver', // 人员筛选类型
      taskForm: {
        transferTime: '',
        patient: {
@@ -375,7 +285,6 @@
    if (options.id) {
      this.taskId = options.id
      this.loadTaskDetail()
      this.loadDeptStaff() // 加载人员列表
    } else {
      this.$modal.showToast('任务ID不能为空')
      setTimeout(() => {
@@ -429,8 +338,10 @@
          this.taskForm.hospitalOut.id = info.hospitalOutId || null
          this.taskForm.hospitalOut.name = info.hospitalOutName || ''
          this.taskForm.hospitalOut.department = info.hospitalOutDepartment || ''
          this.taskForm.hospitalOut.departmentId = info.hospitalOutDepartmentId || null
          this.taskForm.hospitalOut.bedNumber = info.hospitalOutBedNumber || ''
          this.taskForm.hospitalOut.address = info.hospitalOutAddress || ''
          console.log('转出医院科室ID:', info.hospitalOutDepartmentId)
          
          // 加载转出医院GPS坐标(不显示,但保存在数据中)
          if (info.hospitalOutLongitude && info.hospitalOutLatitude) {
@@ -445,8 +356,10 @@
          this.taskForm.hospitalIn.id = info.hospitalInId || null
          this.taskForm.hospitalIn.name = info.hospitalInName || ''
          this.taskForm.hospitalIn.department = info.hospitalInDepartment || ''
          this.taskForm.hospitalIn.departmentId = info.hospitalInDepartmentId || null
          this.taskForm.hospitalIn.bedNumber = info.hospitalInBedNumber || ''
          this.taskForm.hospitalIn.address = info.hospitalInAddress || ''
          console.log('转入医院科室ID:', info.hospitalInDepartmentId)
          
          // 加载转入医院GPS坐标(不显示,但保存在数据中)
          if (info.hospitalInLongitude && info.hospitalInLatitude) {
@@ -627,154 +540,10 @@
      // 组件已经通过 v-model 更新了 selectedDiseases
    },
    
    // 加载当前用户所在分公司的所有人员
    loadDeptStaff() {
      console.log('开始加载人员列表')
      listBranchUsers().then(response => {
        console.log('人员列表API响应:', response)
        const userList = response.data || []
        console.log('解析出的用户列表:', 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 || ''
      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'
    },
    getUserTypeName(staffType) {
      switch(staffType) {
        case 'nurse':
          return '护士'
        case 'doctor':
          return '医生'
        case 'driver':
          return '司机'
        default:
          return '司机'
      }
    },
    // 显示人员选择弹窗
    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
    },
    // 切换人员选中状态
    toggleStaffSelection(staff) {
      const index = this.selectedStaff.findIndex(s => s.userId === staff.userId)
      if (index > -1) {
        // 已选中,移除
        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) {
      this.selectedStaff.splice(index, 1)
    // 人员变化
    onStaffChange(staff) {
      console.log('选中人员变化:', staff)
      // 组件已经通过 v-model 更新了 selectedStaff
    },
    
    // 解析病情信息(从字符串解析出ICD-10疾病列表)- 修复:与创建界面保持一致
@@ -1088,6 +857,9 @@
      this.$modal.confirm('确定要保存修改吗?').then(() => {
        this.loading = true
        const submitData = this.buildSubmitData()
        console.log('提交数据 - 转出医院科室ID:', submitData.hospitalOut.departmentId)
        console.log('提交数据 - 转入医院科室ID:', submitData.hospitalIn.departmentId)
        
        updateTask(submitData).then(response => {
          this.loading = false
@@ -1451,133 +1223,6 @@
        display: flex;
        align-items: center;
        justify-content: center;
      }
    }
  }
  .staff-popup-container {
    height: 80vh;
    background-color: white;
    border-top-left-radius: 20rpx;
    border-top-right-radius: 20rpx;
    display: flex;
    flex-direction: column;
    .popup-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 20rpx 30rpx;
      border-bottom: 1rpx solid #f0f0f0;
      .popup-title {
        font-size: 32rpx;
        font-weight: bold;
        color: #333;
      }
      .close-btn {
        width: 50rpx;
        height: 50rpx;
        display: flex;
        align-items: center;
        justify-content: center;
      }
    }
    .search-bar {
      padding: 20rpx 30rpx;
      border-bottom: 1rpx solid #f0f0f0;
      .search-input {
        height: 70rpx;
        padding: 0 20rpx;
        background-color: #f5f5f5;
        border-radius: 10rpx;
        font-size: 28rpx;
      }
    }
    .filter-tabs {
      display: flex;
      padding: 20rpx 30rpx;
      gap: 20rpx;
      border-bottom: 1rpx solid #f0f0f0;
      .filter-tab {
        flex: 1;
        height: 60rpx;
        line-height: 60rpx;
        text-align: center;
        background-color: #f5f5f5;
        border-radius: 10rpx;
        font-size: 28rpx;
        color: #666;
        &.active {
          background-color: #007AFF;
          color: white;
        }
      }
    }
    .staff-list-scroll {
      flex: 1;
      padding: 20rpx 30rpx;
      .staff-list-item {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 20rpx;
        margin-bottom: 15rpx;
        background-color: #f8f8f8;
        border-radius: 10rpx;
        .staff-item-info {
          flex: 1;
          .staff-item-name {
            display: block;
            font-size: 30rpx;
            color: #333;
            margin-bottom: 8rpx;
          }
          .staff-item-dept {
            display: block;
            font-size: 24rpx;
            color: #999;
          }
        }
        .staff-item-check {
          width: 50rpx;
          display: flex;
          align-items: center;
          justify-content: center;
        }
      }
      .empty-tip {
        text-align: center;
        padding: 100rpx 0;
        color: #999;
        font-size: 28rpx;
      }
    }
    .popup-footer {
      padding: 20rpx 30rpx;
      border-top: 1rpx solid #f0f0f0;
      .confirm-btn {
        width: 100%;
        height: 80rpx;
        background-color: #007AFF;
        color: white;
        border-radius: 10rpx;
        font-size: 32rpx;
      }
    }
  }