6.1 用户管理
概述
用户模块(goframe_user,租户级表)是机制最全的模块:唯一校验(按行现租户)、租户用户上限、角色全量重写、城市编解码、Excel 导入导出、数据权限接线、批量名称回填。路由前缀 /api/user。
接口清单
| 方法 | 路由 | 权限 | 说明 |
|---|---|---|---|
| GET | /api/user/page | sys:user:page | 分页(关键词/状态/部门/角色/职级/岗位筛选) |
| GET | /api/user/list | sys:user:list | 全量列表(下拉选择用) |
| GET | /api/user/detail/:id | sys:user:detail | 详情(含角色 ID 数组与四级区划编码) |
| POST | /api/user/add | sys:user:add | 新增(返回新记录 ID) |
| PUT | /api/user/update | sys:user:update | 修改(密码留空不改) |
| PUT | /api/user/status | sys:user:status | 状态切换 |
| PUT | /api/user/resetPwd | sys:user:resetPwd | 重置密码(logType=reset) |
| DELETE | /api/user/delete/:id | sys:user:delete | 软删(清理 user_role) |
| DELETE | /api/user/batchDelete | sys:user:batchDelete | 批量删除 |
| POST | /api/user/import | sys:user:import | Excel 导入 |
| GET | /api/user/export | sys:user:export | Excel 导出 |
| GET | /api/user/document/:id | sys:user:detail | 打印信息 |
核心机制
唯一校验(手写,按行现租户)
text
usernameExists / mobileExists 按 (username|mobile, tenant_id, 排除自身) 查;
Update 时先读被改行的 tenant_id 再校验——校验范围必须等于
uk_tenant_username / uk_tenant_mobile 索引范围(含 del_flag 由 dao.Ctx 恒过滤保证)。
历史教训:用 GetTenantID(超管=默认租户)会漏报 1062——必须按行现租户。角色同步(AssignRoles)
text
AssignRoles(userId, roleIds):全量重写 user_role(先删后插)
→ clearIdentityCache(userId)
Add/Update 均经此方法;Update 改 dept_id 也在该路径清缓存——部门变更即时生效
(数据权限无需等 300s 缓存过期)租户用户上限(checkTenantUserMax)
统计租户现有用户数 vs tenant.max_user_num,超限返回 1007。在 user.Add 生效。
用户编码(genUserCode)
text
前缀=租户 code(平台/超管为 "SYS"),序号=该租户现有用户数+1
格式 "{prefix}-%06d",如 T0001-000001数据权限接线
userSpec 声明 DataScope: ApplyDataScope("dept_id")——user 是当前唯一接线模块(全库仅 user 表有 dept_id 列)。
列表名称回填(userExpandNames)
列表行批量补 dept/level/position/role 名称与城市文本(namesById/dictName 批查防 N+1)。
导入导出
text
Import(POST /api/user/import):
excel.ReadSheet → 表头映射 → 逐行:唯一校验 / 租户上限 / 默认密码 bcrypt
(事务外预计算)/ 角色与城市解析 → 批量插入 → 返回成功/失败统计
城市列经 ResolveCityCodes(名称串) 转编码入库
Export(GET /api/user/export):
与列表同筛选(userFilter + DataScope,applyFilters 同链)
→ ChunkQuery 500/页 → excel.WriteSheet
导出可见集 = 列表可见集(导出=所见)城市编解码接入
Add/Update/Import/Detail 均接入包级函数:写侧 ResolveCityCodes(名称串 → 四级编码入库),读侧 ResolveCityNames(编码 → 名称还原)。机制见 6.9 行政区划管理。
字段与安全边界
text
password/salt:bcrypt 双重加盐;接口永不返回
密码留空 = 不修改(Update 语义)
删除守卫:userDeleteGuard / 关联清理(user_role)
SerializeMaps:status → user_status({field}Text 字典填充)
FileFields: avatar + FileSaveDir: "user"(两段式上传自动转正)