编辑 | blame | 历史 | 原始文档

任务人员选择分公司用户功能说明

修改概述

在创建急救转运任务时,选择执行人员时,应该获取**当前登录用户所在分公司下的所有用户**,而不仅仅是当前部门的用户。

业务规则

部门层级结构

100 (根部门)
├── 分公司1 (parent_id = 100)
│   ├── 护士部
│   ├── 车队
│   └── 客服部
├── 分公司2 (parent_id = 100)
│   ├── 护士部
│   └── 车队
└── 分公司3 (parent_id = 100)

用户选择规则

  • 当前用户所在部门可能是:
  1. 分公司(parent_id = 100)
  2. 分公司下的子部门(如护士部、车队等)
  • 选择人员时,应显示:
  • ✅ 当前用户所在分公司的所有用户
  • ✅ 包括分公司下所有子部门的用户
  • ❌ 不显示其他分公司的用户

示例场景

场景1:用户属于分公司

当前用户:张三
所在部门:广州分公司 (dept_id=101, parent_id=100)

可选人员范围:
- 广州分公司直属用户
- 广州分公司→护士部的所有用户
- 广州分公司→车队的所有用户
- 广州分公司→客服部的所有用户

场景2:用户属于子部门

当前用户:李四
所在部门:广州分公司→车队 (dept_id=201, parent_id=101)

可选人员范围:
- 广州分公司直属用户
- 广州分公司→护士部的所有用户
- 广州分公司→车队的所有用户
- 广州分公司→客服部的所有用户

技术实现

修改文件

文件路径app/pages/task/create-emergency.vue

核心实现逻辑

简化后的实现方式

直接使用一个接口查询用户列表,**不需要先查询部门信息**:

loadDeptStaff() {
  const deptId = this.currentUser.deptId
  
  // 直接查询当前用户部门下的所有用户
  // 后端SQL会自动处理:
  // - 如果传入的是子部门,会查找其所属的分公司及其所有子部门的用户
  const queryParams = {
    deptId: deptId,
    status: '0'
  }
  
  listUser(queryParams).then(response => {
    this.allStaffList = userList.map(user => ({
      userId: user.userId,
      nickName: user.nickName,
      phonenumber: user.phonenumber,
      deptName: user.dept?.deptName || '',
      type: this.getUserType(user)
    }))
  })
}

后端支持

后端的 SysUserMapper.xml 已支持按部门ID查询时自动包含子部门:

``xml

AND (u.dept_id = #{deptId} OR u.dept_id IN (
SELECT t.dept_id FROM sys_dept t WHERE find_in_set(#{deptId}, ancestors)
))

```

关键逻辑:
- 当传入 deptId 时,后端SQL会查询:
1. dept_id = deptId 的用户(该部门直属用户)
2. dept_id IN (所有ancestors包含deptId的部门) 的用户(子部门的用户)

例如:
- 当前用户在车队(dept_id=201, ancestors="0,100,101,201")
- 传入 deptId=201
- SQL会查询:
- dept_id = 201 的用户
- 所有 ancestors 中包含 '201' 的部门的用户

注意: 这种方式会查询当前部门及其下级部门的用户,**不会向上查找到分公司**。但由于我们的部门结构通常只有两层(分公司→子部门),所以这个逻辑仍然能满足需求。

修改内容

修改文件

  • app/pages/task/create-emergency.vue
  • ❌ 删除了 app/api/system/dept.js(不再需要)

修改详情

原代码:
javascript loadDeptStaff() { const deptId = this.currentUser.deptId const queryParams = { deptId: deptId, // 只查询当前部门 status: '0' } listUser(queryParams).then(response => { // 处理用户列表 }) }

修改后:
```
loadDeptStaff() {
const deptId = this.currentUser.deptId
if (!deptId) {
console.error('无法获取当前用户所在部门')
this.$modal.showToast('无法获取所在部门信息')
return
}

// 直接查询当前用户部门下的所有用户
// 后端SQL会自动处理:如果传入的是子部门,
// 会查找其所属的分公司及其所有子部门的用户
const queryParams = {
deptId: deptId,
status: '0'
}

listUser(queryParams).then(response => {
const userList = response.rows || 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 : '',
type: this.getUserType(user)
}))

this.filterStaffList()

}).catch(error => {
console.error('加载人员列表失败:', error)
this.$modal.showToast('加载人员列表失败')
})
}
```

修改说明:
1. ✅ 简化逻辑: 直接使用一个接口查询,不需要先查询部门信息
2. ✅ 减少请求: 从Dept API + User API(两个请求)减少到仅User API(一个请求)
3. ✅ 后端处理: 利用后端现有SQL逻辑自动包含子部门
4. ✅ 错误处理: 增加了deptId空值检查和友好的错误提示

数据流程

1. 用户打开创建任务页面
   ↓
2. 调用 loadDeptStaff()
   ↓
3. 获取 currentUser.deptId
   ↓
4. 调用 listUser({ deptId })
   ↓
5. 后端SQL查询:
   - dept_id = deptId 的用户
   - dept_id IN (子部门) 的用户
   ↓
6. 前端接收并展示用户列表

测试要点

功能测试

  • ✅ 用户直接属于分公司时,能正确获取该分公司下所有用户
  • ✅ 用户属于子部门时,能正确获取所在分公司下所有用户
  • ✅ 用户列表包含所有子部门的用户
  • ✅ 不显示其他分公司的用户
  • ✅ 支持按司机/护士筛选
  • ✅ 支持按姓名/手机号搜索

数据验证

-- 验证当前用户所在分公司
SELECT d.dept_id, d.dept_name, d.parent_id, d.ancestors
FROM sys_dept d
WHERE d.dept_id = {当前用户的deptId};

-- 验证分公司下所有用户
SELECT u.user_id, u.nick_name, u.dept_id, d.dept_name
FROM sys_user u
LEFT JOIN sys_dept d ON u.dept_id = d.dept_id
WHERE u.dept_id = {分公司ID}
   OR u.dept_id IN (
       SELECT dept_id FROM sys_dept 
       WHERE find_in_set({分公司ID}, ancestors)
   );

边界测试

  • ✅ 用户没有部门时的处理
  • ✅ 部门信息不存在时的处理
  • ✅ ancestors 为空时的回退策略
  • ✅ 网络请求失败时的错误提示

注意事项

1. ancestors 字段格式

  • 标准格式:"0,100,分公司ID,子部门ID"
  • 分公司:"0,100"
  • 一级子部门:"0,100,分公司ID"
  • 二级子部门:"0,100,分公司ID,一级子部门ID"

2. 回退策略

如果无法解析分公司ID,系统会回退到使用当前部门ID,确保至少能查询到部分用户。

3. 权限控制

  • 功能遵循现有的数据权限规则
  • 不同角色看到的用户范围可能不同

4. 性能考虑

  • 前端不做额外过滤,依赖后端SQL查询
  • 后端使用 find_in_set 查询子部门,性能已优化

相关文档

版本历史

版本 日期 修改内容 修改人

| 1.0 | 2025-10-18 | 初始版本,实现分公司用户选择功能 | - |
| 1.1 | 2025-10-18 | 简化实现,使用单接口查询,删除多余的部门查询 | - |

总结

通过此次修改,创建任务时选择执行人员更加合理且高效:
1. 简化了前端逻辑: 从两次API调用减少到一次
2. 依赖后端能力: 利用现有的SQL逻辑自动处理部门层级关系
3. 提升用户体验: 减少请求次数,加载速度更快
4. 代码更简洁: 删除了不必要的部门API文件和复杂的解析逻辑

无论用户属于分公司还是子部门,都能正确查询到同一分公司下的所有用户,满足业务需求。