主题
系统设置 · 详细设计
文档版本:1.00 | 最近核对日期:2026-11-02
本页整合原分主题设计。业务规则以需求分析为准;数据库快照见数据库设计,历史检查及限制见测试与验收。具体资料中的历史日期和验证范围保留,不能推定本次已重新验证。
用户管理
所属模块:系统设置 | 路由
/system/user| 接口前缀/system/user(个人中心/system/user/profile)
用户账号与权限设定基线:2026-09-04(开发环境)
1. 功能定位
用户管理是平台的账号台账:按部门树维护系统用户,覆盖新增/编辑/删除、状态启停、登录解锁、重置密码、分配角色、Excel 导入导出与详情查看。配套个人中心(/user/profile)供用户自助维护基本资料、密码、签名图片和在线设备。
- 用户台账:部门树 + 用户列表,管理端全生命周期维护;
- 个人中心(自助):当前登录用户维护自己的资料,其中签名图片在管理端编辑弹窗也可代维护。
- 名称约定:所有用户可见文案统一使用“姓名”;数据库列
NICK_NAME、接口字段nickName保持兼容,不改动字段语义。
2. 页面与交互
2.1 用户管理页(左右双栏)
- 左栏 · 部门树:按部门过滤用户(可折叠、可按名称搜索);选中部门后右侧显示该部门及其下级部门的所有用户;
- 筛选条件:登录账号、姓名、手机号码、状态(
sys_normal_disable字典)、创建时间区间;登录账号和手机号码均可作为登录标识。 - 工具栏:新增、修改(单选)、删除(多选)、解锁(单选)、「更多」下拉(下载模板 / 导入数据 / 导出数据);右侧列显隐(记忆键
sys_user_column_visible); - 表格列:选择列、用户编号(默认隐藏)、登录账号(点击打开详情抽屉)、姓名、部门、手机号码、状态(行内开关)、创建时间;
- 操作列:修改 / 删除 / 重置密码 / 分配角色;超级管理员由系统统一判定,不显示行内操作。
2.2 新增/编辑弹窗(600px)
- 字段:姓名、归属部门、手机号码、邮箱、登录账号、初始密码提示、用户性别、状态、岗位、角色、签名图片、备注;初始密码只显示“系统统一设置”的提示,不提供明文录入或回显。
- 账号规则:新增用户不填写登录账号,服务端按“姓名#两位序号”(如
张三#01,同名递增至张三#02)生成未占用账号;编辑时账号只读且保持不变。导入新用户同样由服务端生成账号,导入已有用户时可填写原登录账号用于匹配。 - 登录规则:登录标识支持“登录账号”或“手机号码”,两者均与密码组合认证;未绑定手机号的用户仍可使用登录账号登录。
- 密码规则:新增用户、Excel 导入用户和管理端“重置密码”统一使用系统初始密码,页面不回显或传入明文密码;个人中心的“修改密码”仍由用户自行设置。
- 自己编辑自己时隐藏归属部门/岗位/角色,提交时对应字段置空,不参与更新;
- 签名图片:点击缩略图(240×80)打开设置,可上传图片或在 PC 端画板手写;上传图片固定 3:1 矩形裁剪(300×100),手写和上传均输出透明 PNG;先传 OSS 得到
ossId,随表单一起保存;未上传显示虚线占位"点击上传签名"。
2.3 行内动作
- 状态开关:二次确认后调用
changeStatus,确认取消或接口失败时开关回滚; - 解锁:清除该用户的登录锁定状态(密码连续错误锁定);
- 重置密码:确认后将密码重置为系统统一初始密码,接口加密传输,页面不回显密码;
- 分配角色:跳转独立页
/system/user-auth/role/:userId(基本信息只读 + 角色表格勾选提交); - 导入:Excel 上传,可选"是否更新已经存在的用户数据"(
updateSupport),导入结果逐条反馈; - 详情抽屉:基本信息(登录账号/姓名/部门/手机/邮箱/性别/岗位/角色/状态)+ 审计信息(创建/更新时间、最后登录 IP 与时间、备注)。
2.4 当前初始化账号与权限(2026-09-04)
快照已过期(2026-10-12 回读修正):早期初始化曾仅保留 4 个启用的 superadmin 超级管理员账号(均归属部门 103);当前 Dev 实际为 30 个有效启用账号、1 个账号关联超级管理员角色、2 个有效角色。下方旧数量仅作历史记录,现行账号以开发环境实际数据与[仓库根 README「私有开发环境账号」章节]为准。新用户登录账号按「姓名#两位序号」(如 张三#01、张三#02)递增规则生成;具体账号与人员对照不在文档站记录,以开发环境实际数据与[仓库根 README「私有开发环境账号」章节]为准。
四个账号的新增/重置密码统一读取系统配置项 sys.user.initPassword;密码明文不记录在本文档或文档站。新增账号绑定唯一手机号后即可使用手机号登录。
注:2026-09-06 安全复核将本节的账号明文对照表移除,避免在公开文档站暴露登录凭据前半段与个人信息。
3. 个人中心(自助)
- 四个 Tab:基本资料、修改密码、签名图片、在线设备;第三方应用绑定已隐藏(组件保留,不再调用绑定列表接口);
- 基本资料:仅姓名 / 手机号码 / 邮箱 / 性别,服务端校验手机号与邮箱唯一;
- 签名图片:与头像同构的"点击 → 上传/手写 → 使用此签名"交互,签名保存成功即展示(无需额外保存按钮),展示固定为 3:1 矩形;建议使用透明底横版手写签名;
- 修改密码:旧密码校验 + 新旧不能相同,接口加密传输;
- 在线设备:当前账号的在线会话列表(
/monitor/online)。
3.1 默认头像
当用户没有上传头像(avatarUrl 为空或为空字符串)时,前端按用户性别选择默认头像;已有 avatarUrl 时始终优先展示用户已上传的头像。
| 性别值 | 默认资源 | 说明 |
|---|---|---|
0 | digital-construction-ui/src/assets/images/default-avatar-male.jpg | 精致男头像 |
1 | digital-construction-ui/src/assets/images/default-avatar-female.jpg | 精致女头像 |
2、空值或其他值 | digital-construction-ui/src/assets/images/profile.jpg | 保留原系统狮子头像,作为未知性别兜底 |
默认头像资源统一为 768 × 768 JPG,供导航栏、个人中心等位置进行圆形裁切。选择逻辑位于 src/store/modules/user.ts 的 resolveDefaultAvatar,对应回归测试为 src/store/modules/userAvatar.spec.ts。
4. 数据模型
4.1 用户表
实际字段和历史核验日期见数据库设计。
4.2 关联表
sys_user_role:用户-角色多对多(分配角色、编辑弹窗角色项);sys_user_post:用户-岗位多对多(编辑弹窗岗位项)。
4.3 签名图片机制
signature 与 avatar 同构:前端上传图片裁剪或 PC 端手写后上传 OSS,库内只存 ossId;列表/详情/个人中心接口通过 OSS_ID_TO_URL 翻译为 signatureUrl 返回,ossId 为空时不翻译。管理端走 PUT /system/user 随表单更新,个人中心走 PUT /system/user/profile(setIfPresent,未传不覆盖)。
5. 接口与权限点
接口前缀:/system/user
| 方法 | 路径 | 用途 | 权限点 |
|---|---|---|---|
| GET | /system/user/list | 用户分页列表(含部门及下级过滤) | system:user:list |
| GET | /system/user/{userId} | 用户详情 + 岗位/角色选项(新增时 userId 留空) | system:user:query |
| POST | /system/user | 新增用户(服务端生成账号;手机/邮箱唯一) | system:user:add |
| PUT | /system/user | 修改用户(账号保持不变;手机/邮箱唯一) | system:user:edit |
| DELETE | /system/user/{userIds} | 删除用户(逻辑删除;不能删除当前登录用户) | system:user:remove |
| PUT | /system/user/changeStatus | 启用/停用 | system:user:edit |
| GET | /system/user/unlock/{userId} | 登录解锁 | system:user:edit |
| PUT | /system/user/resetPwd | 重置为系统初始密码(加密传输) | system:user:resetPwd |
| GET/PUT | /system/user/authRole/{userId}、/system/user/authRole | 查询/保存授权角色 | system:user:query / system:user:edit |
| POST | /system/user/export | 导出用户 | system:user:export |
| POST | /system/user/importData | Excel 导入(updateSupport 控制更新已存在用户) | system:user:import |
| POST | /system/user/importTemplate | 下载导入模板 | 登录即可 |
| GET | /system/user/optionselect | 按 userIds 批量取用户基础信息 | system:user:query |
| GET | /system/user/list/dept/{deptId}、/system/user/deptTree | 部门用户 / 部门下拉树(供选择器复用) | system:user:list |
| GET/PUT | /system/user/profile | 个人中心查询 / 修改基本资料(含头像、签名) | 登录用户自助 |
| PUT | /system/user/profile/updatePwd | 个人中心修改密码(加密传输) | 登录用户自助 |
6. 验收要点
- 部门树选中某节点后,列表包含该部门及全部下级部门用户;重置筛选后恢复全量;
- 新增用户账号符合“姓名#两位序号”(如
张三#01、张三#02)格式且不重复;编辑不改变已有账号;登录支持登录账号或手机号 + 密码; - 新增、导入和管理端重置密码均使用系统初始密码,页面和文档不出现该密码明文;
- 超级管理员账号行内无操作按钮,且后端拒绝修改/删除超管、当前登录用户不能删除自己;
- 自己编辑自己时,归属部门/岗位/角色不显示也不更新;
- 状态开关取消确认或失败后回滚显示;
- 签名图片:个人中心上传或手写即保存并展示;用户管理编辑弹窗上传或手写后随表单保存、重开回显;删除签名暂不支持(
setIfPresent/updateById均忽略 null,需清空时另立专门接口); - 用户删除为逻辑删除(
del_flag);解锁即清除该账号的密码错误计数缓存(达到上限后的登录锁定随之解除)。
通用选人接口(2026-09-15)
- 业务办理中的「选择人员/选择部门」改用
/system/option/deptTree与/system/option/users,只要求登录,不再依赖system:user:list;接口只返回账号、姓名、所属部门等最小字段。 - 已选人员回显通过
/system/option/users?userIds=…完成,不要求系统管理权限。 - 用户管理列表、导出等系统管理接口保持原权限码不变(角色数据范围机制已于 2026-09-29 移除,列表不再按部门/创建人过滤,见角色管理第 8 节);工程树等业务范围选择仍按各自权限校验,不在此接口放开。
角色管理
所属模块:系统设置 · 路由
/system/role
当前状态:角色分类方案暂被移除。 当前角色管理按原脚手架的平面角色方案运行,不提供角色分类树、分类筛选、分类字段或分类维护入口。后续如需恢复角色分类,需重新确认数据模型、接口和页面交互。
清理记录:历史
SYS_ROLE_CATEGORY表及SYS_ROLE.CATEGORY_ID字段已于 2026-09-06 通过项目 DM8 MCP 删除并回读验证;此前该结构仅作兼容保留,当前角色管理代码不读写。
1. 功能定位
角色管理用于维护角色、菜单权限及角色授权用户。角色列表采用脚手架默认的平面台账;角色分类方案暂被移除,不属于当前角色授权模型。角色数据范围(@DataPermission)机制已于 2026-09-29 整体移除,见第 8 节。
2. 页面与交互
- 页面由筛选区和角色列表组成,支持角色名称、权限字符、状态和创建时间查询。
- 角色新增/编辑只维护角色基础信息;“分配权限”进入独立弹窗配置菜单权限(原“数据权限”页签已随角色数据范围机制于 2026-09-29 移除)。
- 角色列表支持新增、修改、删除、导出、状态切换、分配权限和分配用户。
- 授权用户页关闭时使用路由目标
{ path: '/system/role' }返回角色管理,避免将已解析路由对象传给页签 API。
3. 数据模型
角色表 sys_role 保存角色基础信息、状态和菜单树选择联动配置;菜单授权和用户授权分别保存在对应关联表中。sys_role.data_scope、dept_check_strictly 列与 sys_role_dept 表为角色数据范围机制的历史遗留,2026-09-29 机制移除后代码不再读写,物理对象保留(DDL 清理需单独授权)。当前设计不使用角色分类字段,历史分类结构已清理。
4. 接口
4.1 角色及授权用户(/system/role)
| 方法 | 路径 | 用途 |
|---|---|---|
| GET | /list | 分页查询角色列表 |
| GET | /{roleId} | 查询角色详情 |
| POST | / | 新增角色 |
| PUT | / | 修改角色基础信息 |
| PUT | /permission | 修改角色权限(菜单权限) |
| PUT | /changeStatus | 修改角色状态 |
| DELETE | /{roleIds} | 删除角色 |
| GET | /optionselect | 获取角色选择框列表 |
| GET | /authUser/allocatedList | 查询已分配用户 |
| GET | /authUser/unallocatedList | 查询未分配用户 |
| PUT | /authUser/cancel | 取消授权用户 |
| PUT | /authUser/cancelAll | 批量取消授权用户 |
| PUT | /authUser/selectAll | 批量选择用户授权 |
原 GET /deptTree/{roleId}(角色部门树)已随角色数据范围机制于 2026-09-29 移除。
5. 权限与审计
- 角色管理权限:
system:role:list / :add / :edit / :remove / :query / :export。 - 角色写操作使用
system:role:add / :edit / :remove / :export,后端同步执行权限校验、审计日志和重复提交保护。 - 角色侧授权用户入口(
/authUser/selectAll、/authUser/cancel、/authUser/cancelAll)与用户侧遵循同一保护规则(2026-09-30 起):不允许分配或回收超级管理员角色、不允许操作超级管理员用户,SysRoleServiceImplTest单测固定。 - 过渡期操作规则:在“可授菜单上限”服务端校验落地前,
system:role:edit只应授予可信的全局权限管理员——持有者可为其可操作角色授予任意菜单并分配用户;分级管理员需另行设计,属待决项。 - 角色矩阵设计任务(待决):当前开发库角色以测试与 E2E 残留为主(含同名同 key 重复记录),正式业务角色矩阵尚未建设。需按业务域 × 单位类型(集团职能 / 业主 / 施工 / 监理 / 设计 / 造价等)梳理“角色 → 菜单权限包 → 工程数据授权”清单并形成初始化数据,替代测试角色现状;矩阵属业务决策,需业务方参与,输出物为清单文档加初始化数据(经项目 MCP 写入并回读)。工程侧授权载体以工程基础管理 · 双核四维解耦架构方案的标段 / 工点 / 线路三轨授权为准,原工程授权模板三表随该方案退场。系统管理菜单的分配须按“授予系统管理菜单即全量管理权”收紧(见第 8 节)。
6. 验收要点
- 角色分类方案暂被移除,页面不出现分类树、分类筛选、分类字段或分类维护入口。
- 角色列表可按名称、权限字符、状态和创建时间查询。
- 新增/编辑只保存角色基础信息,不改变已有权限关联。
- “分配权限”弹窗仅配置菜单权限,不出现数据权限页签或部门树。
- 角色状态、删除、授权用户等操作保留后端“禁改超管角色”和关联校验;原基于数据范围的角色/用户/部门越权校验已随机制移除(2026-09-29),管理边界由功能权限约束。
7. 菜单权限
7.1 定义
菜单权限决定"角色能使用系统的哪些功能入口(菜单、按钮、接口)",属于功能级权限,只控制"能不能用",不涉及具体数据范围。
7.2 数据模型
- 角色-菜单多对多关联表
sys_role_menu(role_id, menu_id); - 菜单表
sys_menu.perms存放权限字符(如system:role:list); - 角色表
sys_role.role_key为角色权限字符串(如admin),用于@SaCheckRole场景。
7.3 配置入口
“分配权限”弹窗中的“菜单权限”树:
- 支持展开/折叠、全选/全不选;
- 父子联动开关
menu_check_strictly(0 父子不联动、1 父子联动); - 勾选结果以
menuIds[]提交,后端/permission在事务中先删除旧关联再批量插入sys_role_menu。
7.4 权限链路
用户登录 → 汇总其全部启用角色(sys_role.status='0')→ 经 sys_role_menu 关联菜单 → 收集 sys_menu.perms 去重为权限集合:
- 前端:
v-hasPermi控制菜单/按钮显隐; - 后端:
@SaCheckPermission("system:role:list")拦截接口访问; - 超级管理员:直接授予
*:*:*,跳过上述链路。
8. 角色数据范围(已于 2026-09-29 整体移除)
原有的角色数据范围机制——sys_role.data_scope 六种取值、自定义部门表 sys_role_dept、Mapper 上的 @DataPermission/@DataColumn 注解与 MyBatis-Plus 拦截器 SQL 改写、checkRoleDataScope/checkUserDataScope/checkDeptDataScope 越权防护、角色页“数据权限”页签及 GET /system/role/deptTree/{roleId} 接口——已按 2026-09-29 用户决定从前后端整体删除。平台数据级权限收敛为工程范围授权一个业务维度;系统管理域(用户、部门、岗位、角色、活跃度统计)的列表与操作由菜单/按钮权限约束,不再按部门或创建人过滤。
- 行为影响:具备系统管理菜单权限的非超管用户可见并操作全量用户/部门/岗位/角色数据,“授予系统管理菜单即全量管理权”,角色矩阵设计需据此收紧系统管理菜单的分配;分配角色时“非超管不得分配超管角色”的独立防护保留。
- 物理对象:
sys_role.data_scope、dept_check_strictly列与sys_role_dept表保留但不再读写;DDL 清理需单独授权。 - 移除范围清单与行为影响明细以本节记载为准。
9. 与工程数据权限的区别
角色数据范围已移除;工程数据授权按工程数据授权契约及工程基础需求执行。项目成员信息只读派生,不作为项目或招投标数据访问授权。
授权生效方式(2026-09-15)
- 菜单权限、角色权限与数据权限角色映射按用户缓存(
CacheNames.SYS_USER_PERMISSION)。角色授权、角色状态、用户角色关系变更后,平台按受影响用户失效缓存并写入失效标记;菜单或权限标识变更时全量失效。 - 命中失效标记的请求会按最新数据重算权限并回写登录态(
SaPermissionImpl),因此授权变更无需重新登录即可对接口生效。相关实现为OnlineUserSessionRefreshEvent+PermissionCacheInvalidationListener+SysPermissionServiceImpl.clearUserPermission。 - 本部署使用 JWT 无状态令牌,Redis 中不存在 token 值索引,无法按角色枚举在线会话:因此不做「踢出在线用户」,
系统监控 → 在线用户也不会列出登录用户。若后续需要在线用户列表与强制退出,需改用可枚举的会话模式后单独评估。 - 前端菜单与路由缓存仍在下一次刷新页面时更新;接口鉴权以最新权限数据为准。
- 回归验证:撤销某角色权限后,该角色用户的原会话再次请求受控接口立即返回 403,无需重新登录(2026-09-15 实测)。
10. 已废弃的易用性与权限呈现建议(2026-10-10)
2026-09-29 用户决定:角色数据范围(@DataPermission)机制整体移除,并已于同日实施完成——本页原数据范围机制描述已改写为移除记录(第 8 节),业务地图已同步修订;角色页“数据权限”页签及 SYS_ROLE.DATA_SCOPE、SYS_ROLE_DEPT 的读写已随机制删除(物理对象保留,DDL 清理需单独授权)。
此前讨论稿提出的“以人员为入口汇总功能角色、手工与模板工程授权、最终可见范围,以及按具体单据和动作解释适用的服务端授权判断”等易用性与权限呈现建议,已按用户 2026-10-10 决定随方案稿一并废弃,不再作为待办;工程基础管理与工程数据权限以工程基础管理 · 双核四维解耦架构方案为准。查看他人任务须单独鉴权、不能借权限诊断开放全量任务内容这一约束,在后续任何设计中继续适用。
组织架构
所属资料模块:系统设置 | 实际菜单:系统管理 → 组织架构 | 路由:
/system/dept最近核对:2026-10-14。本页只维护业主组织。参建单位、项目部子表、全局联合体及项目关系统一见工程基础管理模块。本页原有“双组织树、参建项目部组织节点、业务类型决定层级”等描述已退出,不作为当前实现规则。
1. 功能与边界
组织架构用于维护重庆城市交通开发投资(集团)有限公司及其部门、下属公司、直属分公司、公司下属分公司、合资公司和各级部门。业主和参建继续共用 SYS_DEPT,用户与岗位沿用组织 ID;两个管理入口按实际域分别校验,不能靠客户端 deptType 切换写入另一域。
当前页只有业主树,不提供参建 Tab、业主业务类别或手工上下级关系类型。负责人保留真实平台用户 ID 语义。参建“联系人”是另一页面的文本资料,不替换组织负责人。
2. 结构与根保护
| 父节点 | 合法子节点 |
|---|---|
集团 group | 公司 company、分公司 branch、合资公司 joint_venture、部门 dept |
公司 company | 分公司 branch、合资公司 joint_venture、部门 dept |
合资公司 joint_venture | 分公司 branch、部门 dept |
分公司 branch | 部门 dept |
部门 dept | 无,部门是叶子 |
“单位”由 group/company/branch/joint_venture 判定,“部门”由 dept 判定;deptCategory 不承担组织结构含义。集团直属分公司合法,例如数智科技分公司;交建公司下属分公司及其部门按同一矩阵维护。joint_venture(合资公司)表达 PPP 特许权公司等业主合资企业,与 company/branch 同为可承接用户与岗位的「单位」节点:集团及业主公司下均可直接新建合资公司,合资公司下可再挂分公司与部门;参建侧与项目参建主体同样接受 joint_venture,不需为满足筛选另建同名企业。
集团根身份按实际对象的 parentId=0、deptType=1、orgType=group 判定,不依赖名称或当前状态。根的普通资料可编辑,禁止调整父级、体系、组织类型、停用或删除;普通节点不能升为第二根。新写入口不创建 project_dept,项目部只属于参建单位子表。
本轮不迁移或清理开发库历史节点。业主结构变更固定锁定 ID 最小的既有集团根,避免历史重复根导致所有维护失效;新增第二根仍被拒绝。这是当前代码的开发库处理范围,不代表允许建立多根架构。
3. 页面与保存交互
- 树表支持单位名称、组织类型、状态筛选,提供展开/折叠、导入及导出。
- 台账表格精简字段,集中展示单位名称、组织类型、单位简称、组织架构编码、排序、创建时间、单位状态与操作列;统一社会信用代码、负责人、联系电话、邮箱等次要及联系信息收敛至新增/修改弹窗表单中编辑,确保在 1920×911 基准视口下平铺舒展且不产生横向滚动条。
- 顶部“新增”选择上级;行内“新增”添加该节点的合法下级。部门不能作为新节点父级。
- 表单维护组织类型、上级组织、单位名称、简称、组织架构编码、信用代码、排序、负责人、联系电话、邮箱和状态。上下级关系由结构派生:部门为
internal,公司/分公司/合资公司为affiliated。 - 2026-10-08 起新增表单不再提供「预置通用岗位」勾选,新建组织不再自动复制模板岗位(「预置岗位」能力整条链路移除,见岗位管理)。
- 首次编辑并发加载详情、父级及负责人候选,全部就绪后再回填,避免父级联动将已有组织类型清空。编辑对象切换或弹窗关闭后,迟到响应及校验/保存回调不能覆盖新表单;保存失败保留当前输入。2026-10-02 已复验“公司”类型回显和资料保存。
- 组织联系电话沿用现有手机校验;参建单位支持座机/分机的规则只适用于单位管理页,不能据此推定业主表单也已改动。
4. 持久化与关键机制
本页持久化主体为 SYS_DEPT;既有表全量结构见系统设置数据库设计,本轮受影响列的实际类型见工程基础数据库设计。
| 字段 | 当前用途 |
|---|---|
DEPT_ID/PARENT_ID/ANCESTORS | 组织 ID、父级和祖级路径,大 ID 保留原值 |
DEPT_TYPE | 管理入口固定业主 1,不提供跨域转换 |
ORG_TYPE | 业主结构唯一权威类型 |
DEPT_NAME/DEPT_SHORT_NAME/ORG_CODE/CREDIT_CODE | 名称、简称、组织架构编码和信用代码 |
RELATION_TYPE | 服务端按结构推导,页面不编辑 |
LEADER | 平台用户负责人 ID |
PHONE/EMAIL/ORDER_NUM/STATUS | 联系资料、排序和状态 |
DEPT_CATEGORY | 既有兼容列,业主页不录入或筛选业务类别 |
ADDRESS/LINK_MAN/MAILING_ADDRESS | 共表历史/参建侧字段;本页不维护项目部资料 |
DEL_FLAG 与审计五列 | 平台逻辑删除及操作审计 |
服务端规则:
- 同一父级下名称唯一,组织架构编码全局唯一,空白编码按未设置处理。
- 新增或变更父级时校验真实业主父级、状态与结构矩阵,拒绝自身或子孙作为父级;移动节点更新受影响下级祖级路径。
- 停用沿用已有用户、下级保护,不自动封禁账号或回收业务权限。
- 删除存在下级、用户或正式业务引用的节点被拒绝。可删除节点在同一事务内锁定相关岗位,清理岗位与用户关联,最后逻辑删除组织。
- 业主结构写入先锁固定集团根,再锁实际节点与所需父级;业务引用统计通过
DeptReferenceService,不反向锁项目或联合体。锁和校验位于 Service,Controller/前端不能形成旁路。 - 简单列表按当前用户、体系、状态缓存(
sys_dept_list#2m#0#2000);额外筛选不进入该缓存。组织写入失效列表、详情及受影响下级/Excel 映射;2 分钟为缓存兜底,不保证未回归的场景都即时刷新。
已被业务引用的组织原则上禁止改变上级或类型;唯一类型纠正例外是原节点为业主 company/branch、目标为 joint_venture,且 DEPT_ID、PARENT_ID、DEPT_TYPE=1 保持不变。例外不跳过根保护、下级结构、名称/编码唯一性与权限校验;反向转换、移动和跨体系转换继续拒绝。普通编辑与 Excel 覆盖导入共用服务端判定,不能由导入绕过保护。
4.1 单位引用保护统计范围
DeptReferenceService.isReferenced 经 DeptReferenceMapper.countReferences 统计五类真实 ID 引用之和:全局联合体成员(biz_consortium_member.dept_id)、联合体牵头(biz_consortium.lead_unit_id)、项目单位字段(biz_project 的 build/design/supervise/construct_unit 与 build/design/supervise/construct_unit_ids 两组 CSV 逗号完整 token 匹配,及 build/design/supervise/construct/belong_company_id 五个 ID 列)、项目参建主体(biz_project_participant 中 subject_type='UNIT'、关联项目未删除的 subject_id,按项目去重计数)、标段参建单位(biz_bid_section 的 general_contract/supervise/design/construct_unit_id)。统计只触达真实存在的表与列;修复记录:2026-10-13 曾因统计 SQL 引用 biz_line 不存在的 build_unit_id/operating_company_id 列导致达梦预编译报错(-2207 无法解析的成员访问表达式),使所有单位与组织删除均返回「发生未知异常」,已移除该子查询并补齐标段设计/施工单位 ID 统计;同轮补充项目四类 *_unit_ids 集合列与 biz_project_participant 参建主体引用统计,保证参建主体引用不因新增载体而漏计。
5. 业主 Excel 导入导出
模板维护单位 ID、上级组织 ID/名称/路径、组织资料、组织类型、邮箱、排序和状态等业主字段,不携带参建类别、联系人、邮寄地址或项目部子表。
- 指定已存在业主 ID 时覆盖;跨域 ID、集团根覆盖、新建根或非法结构均拒绝。
- 父级优先按明确 ID 解析,也可按完整路径或唯一名称解析;同名多匹配时要求填写 ID,不猜测父级。
- 每行使用
TransactionTemplate + PROPAGATION_REQUIRES_NEW独立提交/回滚,不使用保存点模拟行隔离。成功提交后更新成功/新增/覆盖计数,下一行刷新映射。 - 本轮真实混合导入已核对成功计数与实际新增一致;移动分公司后,后续按名称导入部门及现有下级的祖级路径均指向新公司。完整导出内容本轮未实测,见系统测试与验收。
6. 接口与权限
| 方法/路径 | 用途 | 后端权限 |
|---|---|---|
GET /system/dept/list | 固定业主域树数据 | system:dept:list |
GET /system/dept/{deptId} | 业主对象详情 | system:dept:query |
POST / PUT /system/dept | 合法新增 / 编辑 | system:dept:add/edit,分别匹配动作 |
DELETE /system/dept/{deptId} | 引用保护后删除 | system:dept:remove |
POST /system/dept/importData、importTemplate | 导入及模板 | system:dept:import |
POST /system/dept/export | 业主导出 | system:dept:export |
公共业务候选由登录只读 /system/option/deptTree 提供,支持体系、结构类型和单位子树条件;按已选 ID 回显由 /system/option/depts 提供最小字段。它们不要求组织维护权限,不开放联系人、电话或完整档案。隐藏参建根只作导航,不是业务单位/部门或用户/岗位归属候选。
7. 复核状态
本轮已取得合法业主层级、非法结构、集团身份保护、双向跨域拒绝、混合导入及祖级更新的真实接口证据,并取得组织首次编辑类型与资料保存的页面证据。集团普通资料改名未实际操作,最小业务角色账号缺项,岗位完整级联/流程角色旅程未全量复验;不能将本页部分证据写成全模块验收通过。最新测试数量、页面截图与证据边界统一见系统设置测试与验收。
岗位管理
所属模块:系统设置 | 路由
/system/post| 2026-10-08 起「预置岗位」能力整条链路移除(前端入口、/system/postTemplate接口、部门/单位预置复制逻辑与SYS_POST_TEMPLATE表)
1. 功能定位
岗位管理用于维护部门下的岗位:按部门树查看、新增、编辑、删除与导出岗位。
- 岗位台账:按部门树筛选,维护岗位编码、类别编码、名称、归属部门、排序与状态;
- 不再提供预置岗位:原「预置岗位」能力(业主/参建两套模板岗位 + 新建部门时勾选「预置通用岗位」自动复制)已于 2026-10-08 移除,岗位改为逐个维护。
2. 页面与交互
2.1 岗位管理页(左右双栏)
- 左栏 · 部门树:按部门筛选岗位(选中部门后右侧只显示该部门岗位,选中上级部门时显示其含下级部门的所有岗位);面板支持折叠/展开,树内为虚拟滚动列表,与用户管理页共用同一部门树面板组件;
- 右栏 · 岗位台账:查询(岗位编码/类别/名称/部门/状态)、新增、编辑、删除、导出;行内操作"修改/删除";
- 工具栏为 新增/修改/删除/导出 与列显隐按钮,不含「预置岗位」按钮。
2.2 岗位名称展示与提交
- 岗位选择下拉、用户详情和个人中心只对
postName做展示层归一化:兼容历史遗留的\\XXXX及字面量\\uXXXX十六进制转义文本,普通岗位名称保持原样; - 岗位选择提交值始终使用原始
postId,不使用展示名称,也不在展示归一化函数中转换 ID、权限关系或岗位主数据; - 新建或修改岗位时应直接保存正常 UTF-8 岗位名称。历史存量数据不因页面加载自动回写,避免隐式修改主数据。
3. 数据模型
3.1 岗位表 sys_post
| 字段 | 说明 |
|---|---|
post_id | 岗位ID(雪花) |
dept_id | 归属部门ID |
post_code | 岗位编码,同一部门内唯一 |
post_category | 岗位类别编码(可空) |
post_name | 岗位名称,同一部门内唯一 |
post_sort | 显示顺序 |
status | 状态(0正常 1停用) |
remark | 备注 |
del_flag | 逻辑删除(0 正常,@TableLogic) |
| 审计字段 | create_dept/create_by/create_time/update_by/update_time |
3.2 历史预置岗位表
该表已删除,历史核验和字段记录见数据库设计。
4. 岗位维护规则
- 岗位编码唯一性为"同一部门内唯一":原实现岗位编码全局唯一,无法支持同一编码在不同部门复用;现改为
dept_id + post_code维度校验(数据库无全局唯一索引,应用层按部门校验),不同部门允许相同编码; - 删除部门级联清理岗位:删除部门时先删除该部门岗位的
sys_user_post用户关联 → 再删除sys_post岗位记录 → 最后删除部门(同一事务),避免残留岗位与悬挂引用; - 权限复用岗位管理权限点:
system:post:list/add/edit/remove/export,无独立菜单。
2026-10-02 组织/单位分入口后,岗位只能新归属真实业主 group/company/branch/joint_venture/dept 或参建 company;隐藏参建根与项目部子记录不能承接岗位。2026-10-13 起组织类型新增合资公司 joint_venture,岗位归属候选同步纳入该类型单位(与用户归属单位取同一 OrgType.UNIT_TYPES 范围)。单位/组织删除先通过引用及用户保护,再锁岗位并清理附属关联。业务基线与本轮验证边界见工程基础管理需求及系统设置测试与验收。
5. 接口与权限点
接口前缀:/system/post
| 方法 | 路径 | 用途 | 权限点 |
|---|---|---|---|
| GET | /system/post/list | 岗位分页列表 | system:post:list |
| GET | /system/post/{postId} | 岗位详情 | system:post:query |
| POST | /system/post | 新增岗位 | system:post:add |
| PUT | /system/post | 修改岗位 | system:post:edit |
| DELETE | /system/post/{postIds} | 删除岗位 | system:post:remove |
| POST | /system/post/export | 导出岗位 | system:post:export |
原
/system/postTemplate/list、POST/PUT /system/postTemplate、DELETE /system/postTemplate/{templateIds}四个接口已随「预置岗位」能力移除,调用返回 404。
6. 验收要点
- 岗位台账可按部门树筛选,新增/修改/删除/导出正常,部门树面板可折叠并支持滚动;
- 同一部门内岗位编码唯一校验生效,不同部门可用相同编码;
- 删除部门 → 该部门岗位及岗位-用户关联被级联清理;
- 岗位管理页、部门新增弹窗与单位新增弹窗均不再出现「预置岗位」相关入口;
/system/postTemplate接口不再注册;新建部门/单位不再自动生成模板岗位;SYS_POST_TEMPLATE表已从开发库删除(2026-10-08,项目 MCP 回读确认)。
系统参数配置
所属模块:系统设置 | 前端页面:
digital-construction-ui/src/views/system/config/index.vue| 接口前缀:/system/config| 文档版本:v1.1 | 最近核对:2026-09-04
1. 功能范围
系统参数配置用于维护平台运行所需的参数名称、参数键名、参数键值、内置标识和备注。页面提供参数查询、分类查看、行内修改参数值、新增、编辑、删除、导出和刷新参数缓存。
参数配置不属于业务审批流程,不进入“我的任务”,也不复用固定表单流程工作台。
2. 页面结构
- 上方为“筛选条件”查询卡,支持按参数名称、参数键名查询,提供搜索和重置。
- 下方为“参数列表”卡片,左侧按“全部 / 系统内置 / 自定义配置”切换,右侧展示参数列表和分页。
- 列表字段为参数名称、参数键名、参数键值、备注和操作;参数键值支持失焦或回车后确认保存。
- 工具栏提供新增、导出、刷新缓存和列表刷新;编辑、删除位于行内操作列并受按钮权限控制。
- 新增和编辑使用弹窗填写参数名称、参数键名、参数键值、系统内置标识和备注。
3. 接口与权限
| 能力 | 接口 | 权限 |
|---|---|---|
| 分页查询 | GET /system/config/list | system:config:list |
| 查询详情 | GET /system/config/{configId} | system:config:query |
| 新增 | POST /system/config | system:config:add |
| 修改 | PUT /system/config | system:config:edit |
| 按键修改值 | PUT /system/config/updateByKey | system:config:edit |
| 删除 | DELETE /system/config/{configId} | system:config:remove |
| 导出 | POST /system/config/export | system:config:export |
| 刷新缓存 | DELETE /system/config/refreshCache | system:config:remove |
前端按钮隐藏只改善操作体验,接口仍必须执行服务端权限校验。参数名称、参数键名和参数键值为必填项;修改参数值或删除参数前需要确认,刷新缓存成功后提示结果。
4. UI 规范
页面遵循标准台账布局:查询卡、列表卡、工具栏、表格和分页保持单一纵向工作区;表格内容和操作列不换行,参数键名和备注超出宽度时提供悬停查看完整内容。新增/编辑弹窗采用标准单列表单宽度,窄屏按视口收缩,不能出现横向裁切。
当前页面是系统设置 CRUD 页面,与综合管理中的公文页面和安全质量环保固定表单流程的页面规范相互独立;三者的附件、流程和业务状态规则不能互相套用。
5. 核对状态
页面组件、API 客户端和字段类型已按当前代码核对;真实菜单权限、生产参数数据和服务端接口需要在对应环境继续回归。
活跃度统计
所属模块:系统设置(监控) | 页面路由
/system/log/activity| 后端接口前缀/monitor/activity| 后端ActivityController/IActivityStatsService/ActivityStatsDailyTask
1. 功能定位
活跃度统计是平台使用情况分析入口,承担:
- 用户登录情况统计(成功/失败次数),并支持自动统计计算;
- 采集用户操作日志与流程审批数据,分析单位 / 用户的登录次数、操作量、审批发起与处理量;
- 形成分析报告(概览指标 + 趋势图 + 单位/用户双维度排行 + Excel 导出),查询由菜单权限约束,不按角色数据范围过滤。
2. 页面结构
单屏自适应布局(按视口自适应,内容区域内部滚动,不以固定浏览器高度作为验收条件),自上而下:
- 查询工具栏:日期范围(默认近 7 天)、用户账号搜索、单位筛选、查询 / 立即统计 / 导出;
- 概览指标:登录成功、登录失败、活跃用户、操作次数、审批发起、审批处理 6 张指标卡;
- 活跃度趋势:ECharts 折线图(登录 / 活跃用户 / 操作 / 审批按天变化);
- 单位维度排行:按部门汇总活跃用户、登录次数、操作次数、审批发起/处理;
- 用户维度排行:按账号汇总登录/操作/审批,支持按单位筛选、账号搜索。
3. 核心设计
3.1 指标口径与数据来源
| 指标 | 来源 | 口径 |
|---|---|---|
| 登录成功 / 失败次数 | sys_login_info | 当日 status='0' / '1',按 user_name 计数;Mapper 已与 DM8 实际表名一致 |
| 操作次数 | sys_oper_log | 当日按 oper_name 计数 |
| 审批发起数 | flow_instance | 当日 create_by(用户ID)计数 |
| 审批处理数 | flow_his_task | 当日 approver 计数,flow_status in ('pass','reject') |
| 活跃用户数 | 汇总表 | 有登录/操作/审批记录的用户去重 |
3.2 汇总表 biz_user_activity_daily
- 字段:
id、stat_date(统计日期)、user_id、user_name、dept_id、dept_name(冗余,供单位维度与数据权限)、login_count、login_fail_count、oper_count、approval_start_count、approval_handle_count,含审计列create_dept / create_by / create_time / update_by / update_time; - 唯一索引:
(user_id, user_name, stat_date);其中user_id为空时按日志账号user_name区分未匹配用户,避免同一天多个未知账号互相冲突; - 当前运行库为 DM8;表结构、菜单和任务配置只以交付数据库及项目 MCP 实际结构为准,不假设存在 MySQL 第二套运行库。未来切换人大金仓或 openGauss 时按兼容清单复核。
3.3 自动统计
- SnailJob 定时任务
activityStatsDailyTask:每日 00:30 汇总 T-1; - 汇总逻辑幂等:
generateDaily先删当日数据再插入;用户/部门通过sys_user/sys_dept关联冗余; - 页面「立即统计」按钮手动补数(默认近 7 天,可指定区间),不依赖定时任务。
3.4 数据权限
- 汇总表查询原有的
@DataPermission(dept_id, user_id)角色数据范围过滤已于 2026-09-29 随机制整体移除:具备monitor:activity:list菜单权限的用户查看全量汇总数据,不再按部门/本人过滤。 - 单位 / 用户维度均基于全量数据聚合,不做部门或本人裁剪。
3.5 页面布局
- 页面使用共享
.app-page-immersive视口模式,列式布局 + 内部表格滚动;不以固定浏览器高度或页面专属calc(100vh - Npx)作为验收条件; - 视觉遵循
handbook/08-ui-guidelines.md:统一的外边距、卡间距、圆角、字体层级与色彩规范。
4. 操作说明
查询、统计和导出步骤见操作手册。
5. 模块约束
| 规则 | 说明 |
|---|---|
| 汇总幂等 | generateDaily 先删当日再插入,可重复执行不产生重复数据 |
| 审批处理口径 | flow_his_task 中 flow_status in ('pass','reject') 的节点处理记录 |
| 数据权限 | 角色数据范围机制已于 2026-09-29 移除;汇总查询由菜单权限(monitor:activity:list)约束,不再按部门过滤 |
| 使用时长 | 本期不统计(未采集退出/最后活跃时间,待后续埋点支持) |
| 数据库基线 | 当前仅核对 DM8;切换人大金仓或 openGauss 时需重新核对 DDL、时间类型、索引与任务配置 |
6. 接口与权限点
- 接口:
/monitor/activity(overview/trend/deptRank/userRank/generate/export); - 权限点:
monitor:activity:list。