| | |
| | | <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> |
| | | <text class="staff-name">{{ getStaffDisplayName(staff) }}</text> |
| | | </view> |
| | | <uni-icons |
| | | v-if="canRemove(index)" |
| | |
| | | <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> |
| | | <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 |
| | |
| | | <script> |
| | | import { mapState } from 'vuex' |
| | | import uniPopup from '@/uni_modules/uni-popup/components/uni-popup/uni-popup.vue' |
| | | import { listBranchUsers } from "@/api/system/user" |
| | | import { listUsersByBranchDepts } from "@/api/system/user" |
| | | |
| | | export default { |
| | | name: 'StaffSelector', |
| | |
| | | currentUserRemovable: { |
| | | type: Boolean, |
| | | default: false |
| | | }, |
| | | // 分公司ID列表(外部传入,用于指定加载哪些分公司的用户) |
| | | branchDeptIds: { |
| | | type: Array, |
| | | default: null |
| | | }, |
| | | // 单个分公司ID(仅传一个时更便捷) |
| | | branchDeptId: { |
| | | type: [Number, String], |
| | | default: null |
| | | } |
| | | }, |
| | | data() { |
| | |
| | | allStaffList: [], |
| | | filteredStaffList: [], |
| | | staffSearchKeyword: '', |
| | | staffFilterType: 'all' |
| | | staffFilterType: 'driver', // 默认选中司机 |
| | | staffListCache: {}, // 缓存: { key: { data: [], timestamp: 0 } } |
| | | cacheExpireTime: 5 * 60 * 1000 // 缓存过期时间:5分钟 |
| | | } |
| | | }, |
| | | computed: { |
| | |
| | | }, |
| | | immediate: true, |
| | | deep: true |
| | | }, |
| | | // 监听分公司ID数组变化,重新加载用户列表 |
| | | branchDeptIds: { |
| | | handler(newVal, oldVal) { |
| | | if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) { |
| | | console.log('分公司ID变化,重新加载用户:', newVal) |
| | | this.loadStaffList() |
| | | } |
| | | }, |
| | | deep: true |
| | | }, |
| | | // 监听单个分公司ID变化 |
| | | branchDeptId(newVal, oldVal) { |
| | | if (newVal !== oldVal) { |
| | | console.log('分公司ID变化,重新加载用户:', newVal) |
| | | this.loadStaffList() |
| | | } |
| | | } |
| | | }, |
| | | mounted() { |
| | |
| | | |
| | | // 加载人员列表 |
| | | loadStaffList() { |
| | | listBranchUsers().then(response => { |
| | | // 获取所有部门ID |
| | | let deptIds = [] |
| | | if (this.branchDeptIds && this.branchDeptIds.length > 0) { |
| | | deptIds = this.branchDeptIds |
| | | } else if (this.branchDeptId) { |
| | | deptIds = [this.branchDeptId] |
| | | } |
| | | |
| | | if (deptIds.length > 0) { |
| | | console.log('根据分公司ID加载用户:', deptIds) |
| | | this.loadStaffByBranchDepts(deptIds) |
| | | } else { |
| | | console.log('未传入分公司ID,组件不加载人员列表') |
| | | this.$modal && this.$modal.showToast && this.$modal.showToast('请传入分公司ID') |
| | | } |
| | | }, |
| | | |
| | | // 根据分公司ID数组加载用户(支持缓存) |
| | | loadStaffByBranchDepts(deptIds) { |
| | | // 生成缓存key(按排序后id拼接) |
| | | const cacheKey = [...deptIds].sort((a, b) => a - b).join(',') |
| | | const cached = this.staffListCache[cacheKey] |
| | | const now = Date.now() |
| | | |
| | | // 检查缓存是否有效 |
| | | if (cached && (now - cached.timestamp) < this.cacheExpireTime) { |
| | | console.log('使用缓存的人员列表:', cacheKey) |
| | | this.processUserList(cached.data) |
| | | return |
| | | } |
| | | |
| | | // 缓存失效或不存在,调用接口 |
| | | console.log('加载人员列表:', deptIds) |
| | | listUsersByBranchDepts(deptIds).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() |
| | | // 更新缓存 |
| | | this.staffListCache[cacheKey] = { |
| | | data: userList, |
| | | timestamp: now |
| | | } |
| | | this.processUserList(userList) |
| | | }).catch(error => { |
| | | console.error('加载人员列表失败:', error) |
| | | this.$modal.showToast('加载人员列表失败') |
| | | }) |
| | | }, |
| | | |
| | | |
| | | |
| | | // 处理用户列表数据 |
| | | processUserList(userList) { |
| | | 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() |
| | | }, |
| | | |
| | | // 根据用户的岗位或角色判断所有类型(支持多种身份) |
| | |
| | | closeStaffSelector() { |
| | | this.$refs.staffPopup.close() |
| | | this.staffSearchKeyword = '' |
| | | this.staffFilterType = 'all' |
| | | this.staffFilterType = 'driver' // 重置为默认司机 |
| | | }, |
| | | |
| | | // 人员搜索 |
| | |
| | | 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() |
| | |
| | | (staff.phonenumber && staff.phonenumber.includes(keyword)) |
| | | }) |
| | | } |
| | | |
| | | // 根据选中的类型,将有该身份的人排在前面 |
| | | list.sort((a, b) => { |
| | | const aHasType = a.types.includes(this.staffFilterType) |
| | | const bHasType = b.types.includes(this.staffFilterType) |
| | | |
| | | if (aHasType && !bHasType) return -1 // a有该身份,排前面 |
| | | if (!aHasType && bHasType) return 1 // b有该身份,排前面 |
| | | return 0 // 都有或都没有,保持原顺序 |
| | | }) |
| | | |
| | | this.filteredStaffList = list |
| | | }, |
| | |
| | | this.selectedStaff.splice(index, 1) |
| | | } else { |
| | | // 未选中,添加 |
| | | this.selectedStaff.push(staff) |
| | | this.selectedStaff.push({ ...staff }) |
| | | } |
| | | }, |
| | | |
| | |
| | | emitChange() { |
| | | this.$emit('input', this.selectedStaff) |
| | | this.$emit('change', this.selectedStaff) |
| | | }, |
| | | |
| | | // 获取人员显示名称(优先显示姓名,如果姓名为空则显示手机号) |
| | | getStaffDisplayName(staff) { |
| | | if (!staff) { |
| | | return '未知人员' |
| | | } |
| | | // 优先显示 nickName,如果为空则显示手机号,都为空则显示 userId |
| | | if (staff.nickName && staff.nickName.trim()) { |
| | | return staff.nickName |
| | | } |
| | | if (staff.phonenumber && staff.phonenumber.trim()) { |
| | | return staff.phonenumber |
| | | } |
| | | return `用户${staff.userId || ''}` |
| | | } |
| | | } |
| | | } |