问题: sponsor 主账号新建的子账号 role_type 没写入,
被 sys_user.role_type DEFAULT 'executor' 覆盖,
导致子账号进入 executor 视角;另外 Login.vue
autoRole/短信登录都硬编 'leader' 兜底, getInfo
失败时静默跳 /leader/home。
修复:
- BizPersonServiceImpl.insert 读主账号 SysUser,
把 mainUser.getRoleType() 写到新子账号
(SysUserMapper.xml insertUser 已支持 role_type 列)
- Login.vue: 短信登录 fallbackRole 改 '',
autoRole 不匹配返回 '', afterLogin 无 role 跳 /login
(不再 fallback /leader/home)
Co-Authored-By: Claude <noreply@anthropic.com>
22 KiB
executor / People — 端到端页面技术审查
审查日期: 2026-08-18 审查范围: 前端 → 后端 → 数据库 → 原型 审查目标:
ry-vue3/src/views/executor/People.vue
0. 四跳定位
| 跳 | 文件 / 位置 | 命中 |
|---|---|---|
| ① 角色菜单 | ry-vue3/src/layout/AdminLayout.vue:119 |
{ path: '/executor/people', title: '人员管理', icon: User, requireMain: true } |
| ② 路由 | ry-vue3/src/router/index.js:101-110 |
父路由 meta: { role: 'executor' } → 子路由 { path: 'people', name: 'executor-people', component: () => import('@/views/executor/People.vue'), meta: { title: '人员管理' } } |
| ③ 组件 | ry-vue3/src/views/executor/People.vue |
✅ 审查目标 (1-171 行) |
| ④ 原型 | proto/html/components/people.html |
proto/html/executor.html:206 → data-page="components/people.html" |
角色定义: AdminLayout.vue:65 — executor: '执行人'
1. 主要功能与可见性
1.1 主要功能
| 功能 | 前端入口 | 后端接口 | 数据表 |
|---|---|---|---|
| 列表 + 筛选 + 分页 | loadList() (onMounted) |
GET /business/person/executorList |
biz_person + LEFT JOIN biz_org, sys_user |
| 新建人员 | goNew() → 跳 /executor/people/new |
(另页 NewPerson.vue) |
biz_person + sys_user (新建 SUB 子账号) |
| 编辑人员 | goEdit(row) → 跳 /executor/people/edit/:id |
PUT /business/person |
biz_person + 同步 sys_user |
| 查看详情 | onView(row) (本地 dialog) |
GET /business/person/{id} |
同列表 |
| 启用 / 禁用 | onToggleStatus(row, action) |
PUT /business/person (传 status + userId) |
biz_person (无字段,status transient) + 同步 sys_user.status |
| 批量导入 | submitImport() (dialog) |
POST /business/person/executorImport (本页面未调用,UI 占位) |
biz_person + sys_user |
1.2 可见性三层过滤
| 层 | 校验 | 行为 |
|---|---|---|
| 前端菜单 | AdminLayout.vue:119 requireMain: true |
仅主账号可见 (子账号在菜单里看不到该入口) |
| 路由守卫 | router/index.js:101 meta.role = 'executor' |
仅 executor 角色可进入 |
| 后端 SQL | BizPersonMapper.xml:170-187 selectExecutorList |
✅ 硬编码 p.unit_type = 'executor' + (u.parent_user_id = #{executorOwnerUid} OR u.user_id = #{executorOwnerUid}),前端绕不开 |
不能看到本页面的人群:
- 其他角色映射到自己的同名页:
admin/manager在router/index.js:41-43, 79-81有executor-people(实际是"全公司视角",看所有执行方的人员);sponsor有自己的sponsor-people(router:119) - executor 子账号 — 菜单项
requireMain: true,前端就不渲染
数据隔离机制 (核心):
-- BizPersonMapper.xml:170-187 (selectExecutorList)
where u.del_flag = '0'
and p.unit_type = 'executor' -- SQL 硬编码,前端改 unit_type 也无效
and (u.parent_user_id = #{params.executorOwnerUid} -- 主账号视角: 看到我的子账号人员
or u.user_id = #{params.executorOwnerUid}) -- 主账号自己也是 person,避免漏自己
⚠️ 注意 executorOwnerUid 由 BizPersonController.java:81-89 的 getUserId() 注入 — 后端取的是当前登录用户,前端无法注入他人 UID。
2. 筛选项 (filter-form)
| UI label | 控件 | 绑定字段 | 后端 SQL | 命中表.字段 | 选项来源 | 原型对照 |
|---|---|---|---|---|---|---|
| 姓名 | el-input |
q.name |
mapper.xml:177 <if test="name != null and name != ''"> and p.name like concat('%', #{name}, '%')</if> |
biz_person.name (模糊) |
用户输入 | ✅ 原型有 |
| 手机号 | el-input |
q.phone |
mapper.xml:178 and p.phone = #{phone} |
biz_person.phone (精确) |
用户输入 | ✅ |
| 所属公司 | el-input |
q.orgName |
mapper.xml:180 and o.org_name like concat('%', #{orgName}, '%')</if> |
biz_org.org_name (模糊) |
用户输入 | ⚠️ 原型 label "工作单位",实现改成 "所属公司" |
| 部门 | el-input |
q.department |
mapper.xml:181 and p.department = #{department} |
biz_person.department |
用户输入 | ✅ |
| 职务 | el-input |
q.position |
mapper.xml:182 and p.position = #{position} |
biz_person.position |
用户输入 | ✅ |
附注 — 角色 / 状态列:
- 前端不展示"角色" / "状态"作为筛选项 (但表格里作为列展示),后端 SQL mapper.xml:183-184 提供
<if>支持,但前端没传参
3. 工具栏按钮 (toolbar)
| 按钮 | 功能 | 接口 | 涉及表 | 原型对照 |
|---|---|---|---|---|
| 查找 | 触发列表刷新 | 无 (本地) | — | ✅ |
| 重置 | 清空筛选 + 回 pageNum=1 | 无 (本地) | — | ⚠️ 原型无"重置"按钮 |
| 新建人员 | 跳独立页 /executor/people/new |
(另页) | biz_person + sys_user |
✅ |
| 批量导入 | 弹 dialog (本页面 UI 占位,未实际上传) | (UI 占位) | — | ✅ (原型 alert,实现也 alert) |
⚠️ P2: downloadTemplate / submitImport 都只 ElMessage.info 占位,没有真实 Excel 下载 / 上传逻辑。BizPersonController.java:152-164 已实现 /executorImportTemplate 和 /executorImport 接口,但前端未对接。
4. 表格 (el-table)
4.1 数据来源
BizPersonMapper.xml:170-187 (selectExecutorList):
select p.person_id, p.name, p.phone, p.org_id, o.org_name, o.org_type,
p.department, p.position, p.role, p.unit_type, p.user_id,
p.create_by, p.create_time, p.update_by, p.update_time,
u.account_type, u.parent_user_id, u.status, u.del_flag as user_del_flag
from biz_person p
left join biz_org o on p.org_id = o.org_id
left join sys_user u on p.user_id = u.user_id
where u.del_flag = '0'
and p.unit_type = 'executor'
and (u.parent_user_id = #{params.executorOwnerUid}
or u.user_id = #{params.executorOwnerUid})
[ and p.name like concat('%', #{name}, '%') ]
[ and p.phone = #{phone} ]
[ and p.org_id = #{orgId} ]
[ and o.org_name like concat('%', #{orgName}, '%') ]
[ and p.department = #{department} ]
[ and p.position = #{position} ]
[ and p.role = #{role} ]
[ and u.status = #{status} ]
order by p.person_id desc
4.2 列映射
| 列名 | row.* |
DB 表.字段 | 原型对照 |
|---|---|---|---|
| 姓名 | row.name |
biz_person.name |
✅ |
| 手机号 | row.phone |
biz_person.phone |
✅ |
| 所属公司 | row.orgName |
biz_org.org_name (LEFT JOIN) |
⚠️ 原型列名 "工作单位" |
| 部门 | row.department |
biz_person.department |
✅ |
| 职务 | row.position |
biz_person.position |
✅ |
| 角色 | row.role |
biz_person.role (translatePersonRole 转中文) |
✅ |
| 状态 | row.status |
sys_user.status (LEFT JOIN) |
✅ |
| 操作 | — | — | ✅ |
附注 — status 字段不在 biz_person:
BizPerson.java:51-53 标注 status 字段为 transient:
/** 启停状态 '0'/'1' (前端 toggle 用, BizPersonServiceImpl 同步到 sys_user.status) - 非持久化字段 */
@com.fasterxml.jackson.annotation.JsonProperty("status")
private transient String status;
所以表格里的 row.status 是 sys_user.status 通过 LEFT JOIN 进来,不要尝试往 biz_person.status UPDATE(不存在这列)。
5. 行内操作按钮
| 按钮 | 触发函数 | 接口 | 后端动作 | 涉及表.字段 | 原型对照 |
|---|---|---|---|---|---|
| 查看 | onView(row) |
无 (本地弹 dialog) | 无 | — | ✅ |
| 编辑 | goEdit(row) |
跳 /executor/people/edit/${row.personId} |
PUT /business/person (另页) |
biz_person.* + 同步 sys_user.nick_name/phonenumber/status |
✅ |
| 禁用 / 恢复 | onToggleStatus(row, action) |
PUT /business/person (本页面直调) |
BizPersonServiceImpl.updateByPrimaryKey (impl:106-118): 先 updateByPrimaryKey 改 biz_person 业务字段,if (entity.getUserId() != null) 同步 sys_user.status |
sys_user.status (NOT biz_person.status,后者不存在) |
✅ |
保护逻辑 (People.vue:46-50):
<template v-if="row.userId !== store.user?.userId">
<el-button v-if="(row.status || '正常') === '正常'" ... >禁用</el-button>
...
</template>
✅ 主账号的"本人"行不显示禁用按钮 — 防主账号把自己禁用造成锁定。但没禁掉子账号主账号的(主账号不是 executor 自己,这里只针对本主账号自己)。
真实落点 — 同步到 sys_user:
BizPersonServiceImpl.java:106-118 (updateByPrimaryKey):
int n = bizPersonMapper.updateByPrimaryKey(entity);
if (n > 0 && entity.getUserId() != null) {
SysUser u = new SysUser();
u.setUserId(entity.getUserId());
u.setNickName(entity.getName());
u.setPhonenumber(entity.getPhone());
u.setUpdateBy(SecurityUtils.getUsername());
if (entity.getStatus() != null) {
u.setStatus(entity.getStatus());
}
sysUserMapper.updateUser(u);
}
⚠️ 关键: entity.getUserId() == null 时,不会同步 sys_user.status。前端 People.vue:144 已传 userId ✅。
6. Java Entity ↔ 数据库表 一致性
6.1 biz_person DDL (DB 实测 2026-08-18)
CREATE TABLE `biz_person` (
`person_id` bigint NOT NULL DEFAULT '0',
`user_id` bigint DEFAULT NULL,
`name` varchar(50) NOT NULL,
`phone` varchar(20) NOT NULL,
`org_id` bigint DEFAULT NULL,
`department` varchar(100) DEFAULT NULL,
`position` varchar(50) DEFAULT NULL,
`role` varchar(20) DEFAULT NULL COMMENT '角色 项目经理/会务执行/合规员/劳务执行',
`unit_type` varchar(20) DEFAULT 'execution' COMMENT '所属单位类型 execution执行/sponsor支持',
`create_by` varchar(64) DEFAULT '',
`create_time` datetime DEFAULT NULL,
`update_by` varchar(64) DEFAULT '',
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`person_id`),
UNIQUE KEY `uk_person_phone` (`phone`),
UNIQUE KEY `uk_person_user_id` (`user_id`),
KEY `idx_person_role` (`role`),
KEY `idx_person_unit_type` (`unit_type`),
KEY `idx_person_org_id` (`org_id`),
KEY `idx_person_org_role` (`org_id`,`role`)
)
6.2 biz_org DDL (DB 实测)
CREATE TABLE `biz_org` (
`org_id` bigint NOT NULL AUTO_INCREMENT,
`org_name` varchar(200) NOT NULL,
`org_type` varchar(20) NOT NULL DEFAULT 'sponsor' COMMENT 'sponsor支持方/execution执行方',
`business_nature` varchar(20) DEFAULT NULL,
`address` varchar(500) DEFAULT NULL,
`tax_no` varchar(50) DEFAULT NULL,
`contact_name` varchar(50) DEFAULT NULL,
`contact_phone` varchar(20) DEFAULT NULL,
`intent_count` int DEFAULT '0',
`status` varchar(20) DEFAULT '0',
`create_by` varchar(64) DEFAULT '',
`create_time` datetime DEFAULT NULL,
`update_by` varchar(64) DEFAULT '',
`update_time` datetime DEFAULT NULL,
`user_id` bigint DEFAULT NULL COMMENT '主账号 sys_user.user_id',
PRIMARY KEY (`org_id`),
UNIQUE KEY `uk_org_user_type` (`user_id`,`org_type`),
KEY `idx_org_type_status` (`org_type`,`status`),
KEY `idx_org_type_name` (`org_type`,`org_name`),
KEY `idx_org_user_type_name` (`user_id`,`org_type`,`org_name`)
)
6.3 BizPerson Entity ↔ biz_person 表
| 实体字段 | Java 类型 | 表字段 | 表类型 | 一致? | 备注 |
|---|---|---|---|---|---|
| personId | String | person_id | bigint | ✅ | 类型不一致: Java String vs DB bigint — 但 MyBatis resultMap 兼容 (driver 自动转),⚠️ 性能上不建议 |
| name | String | name | varchar(50) NOT NULL | ✅ | |
| phone | String | phone | varchar(20) NOT NULL | ✅ | 有 uk_person_phone 唯一约束 |
| orgId | Long | org_id | bigint | ✅ | LEFT JOIN biz_org 时填 orgName/orgType |
| orgName | String | — (JOIN) | — | ✅ | 仅展示字段,resultMap 映射到 org_name |
| orgType | String | — (JOIN) | — | ✅ | 仅展示 |
| department | String | department | varchar(100) | ✅ | |
| position | String | position | varchar(50) | ✅ | |
| role | String | role | varchar(20) | ✅ | |
| unitType | String | unit_type | varchar(20) | ✅ | |
| userId | Long | user_id | bigint | ✅ | 有 uk_person_user_id 唯一约束 |
| status | String (transient) | — (不存在) | — | ✅ | 实际写 sys_user.status |
| accountType | String (JOIN) | — | — | ✅ | LEFT JOIN sys_user.account_type |
| parentUserId | Long (JOIN) | — | — | ✅ | LEFT JOIN sys_user.parent_user_id |
| loginUsername | String (transient) | — | — | ✅ | 创建 sys_user 子账号用 |
| loginPassword | String (transient) | — | — | ✅ | 创建后丢弃 |
| delFlag | String (return null) | — | — | ⚠️ | getter 永远返回 null — 软删走 sys_user.del_flag='1' |
6.4 修订:之前在 _self/sponsor_people.md 写过的"work_unit 已删除"假设
实测 DB 后: biz_person 表里没有 work_unit 字段,但也没有 biz_person.work_unit 这张废表;目前存"所属公司"的方式是 biz_person.org_id LEFT JOIN biz_org。所以现在的设计是外键指向公司表,比之前假设的"work_unit 字段"更规范 ✅。
7. 索引检查
7.1 biz_person (DB 实测)
| Key | 列 | 用途覆盖 | 评估 |
|---|---|---|---|
| PRIMARY | person_id |
✅ updateByPrimaryKey WHERE person_id = ?, selectByPrimaryKey |
OK |
| uk_person_phone | phone (UNIQUE) |
✅ insert 唯一性,SELECT WHERE phone = ? 精确 |
OK |
| uk_person_user_id | user_id (UNIQUE) |
✅ insert 唯一性,JOIN sys_user 关键 |
OK |
| idx_person_role | role |
✅ mapper:183 and p.role = #{role},idx_person_org_role 已覆盖 |
OK (但有冗余) |
| idx_person_unit_type | unit_type |
✅ selectList:49 and p.unit_type = #{unitType},selectSponsorList/selectExecutorList 硬编码 unit_type='sponsor'/'executor' |
OK |
| idx_person_org_id | org_id |
✅ selectByPrimaryKey JOIN,selectList:52 and p.org_id = #{orgId} |
OK |
| idx_person_org_role | (org_id, role) |
✅ countAdminByOrgId (impl 中可能) |
OK |
7.2 biz_org
| Key | 列 | 用途覆盖 | 评估 |
|---|---|---|---|
| PRIMARY | org_id |
✅ JOIN | OK |
| uk_org_user_type | (user_id, org_type) |
✅ 主账号唯一公司 | OK |
| idx_org_type_status | (org_type, status) |
OK | |
| idx_org_type_name | (org_type, org_name) |
✅ selectList:53 LIKE '%org_name%' — 但 LIKE 前缀模糊会走全索引扫描(若 % 开头,索引失效) |
⚠️ 暂可接受(org 数量小) |
| idx_org_user_type_name | (user_id, org_type, org_name) |
OK |
7.3 sys_user (已实测,见 _self/sponsor_account.md §7)
| Key | 列 | 评估 |
|---|---|---|
| PRIMARY | user_id | ✅ |
| idx_parent_user_id | parent_user_id | ✅ SELECT 子账号 |
| — | phonenumber | ❌ 缺(暂可接受,26 行) |
⚠️ selectExecutorList 的关键过滤 (u.parent_user_id = X OR u.user_id = X) 走 PRIMARY 主键索引 (u.user_id = X) + idx_parent_user_id,虽然 OR 走全索引扫描但小表 OK;破万后考虑重写为 UNION ALL。
8. 与原型差异 (proto/html/components/people.html)
8.1 实现新增 (原型没有)
- 分页 (
el-pagination) — 原型 8 行静态,实现加分页支持 - 数据隔离 — 原型无账号概念,实现按主账号/子账号隔离
- 行内按钮"恢复"(启用) — 原型叫"启用",实现叫"恢复";语义一致 ✅
- 本人禁用按钮隐藏 — 业务逻辑(防主账号自禁用),原型无
- status 状态列颜色 tag — 扩展
- 角色列 tag — 原型是普通 span,实现是 el-tag + type
8.2 原型有但实现缺失
- 顶部 h1 "人员管理" + breadcrumb — 实现只用
class="page-sub"一行小字"管理执行方人员,分配会务执行角色",无 h1,无面包屑;与项目其它页风格不一致(其它页用 breadcrumb) - 复选框列 — 原型表头第一列是 checkbox(全选/单选),实现完全删了。原型注释 (people.html:30) 自承"整合为整列",但实际实现把整列删了
- 红字提示
*角色:执行方管理员新建人员时,默认只有会议执行的角色— 原型 people.html:282-284 有提示卡片,实现无 ⚠️
8.3 文字 / 标签差异
| 项 | 原型 | 实现 | 评估 |
|---|---|---|---|
| 筛选项 label | "工作单位:" | "所属公司" | ⚠️ 改了语义,后端 SQL LIKE %org_name% 含义不变,但用户口径不一致 |
| 列表列名 | "工作单位" | "所属公司" | ⚠️ 同上 |
| 操作按钮文字 | "启用" | "恢复" | 轻微差异,语义等价 ✅ |
| 表头 | 无角色/状态标题 color | "角色"/"状态"独立列 | ✅ 改进 |
8.4 总结
- 方向: 实现做了减法 + 加法 — 删了复选框 / 标题 / 提示,加了分页 / 隔离 / 状态管理
- 缺失最严重的: 顶部 h1 + breadcrumb(项目其它页都是这个风格);"工作单位"→"所属公司" 是有意的口径调整(后端表名
biz_org.org_name)
9. 表字段冗余 / 设计问题
| # | 问题 | 文件 | 说明 |
|---|---|---|---|
| 1 | BizPerson.status 字段是 transient,前端 toggle 后通过 service 同步到 sys_user.status |
BizPerson.java:51-53 + BizPersonServiceImpl.java:106-118 |
字段不持久化,语义跨表,易出 bug — 但前端已规范传 userId,目前安全 ⚠️ |
| 2 | BizPerson.delFlag getter 永远返回 null |
BizPerson.java:84-86 |
设计意图是"软删走 sys_user",getter 留作兼容 — 但保留这个 getter 容易误导 |
| 3 | BizPerson.personId Java 类型是 String,DB 是 bigint |
BizPerson.java:13 vs DDL |
MyBatis 自动转换 OK,但后续若有 personId > 100 这类比较会 ClassCastException ⚠️ |
| 4 | biz_person.unit_type 默认值 'execution',但 executor 端 SQL 硬编码 unit_type='executor' |
DDL vs mapper.xml:174 | DEFAULT 是历史值,新代码已用 'executor' 字符串;DEFAULT 未统一 |
| 5 | People.vue:144 调用 bizUpdate('person', ...) 传 userId 是强依赖,没传则 status 不更新 |
BizPersonServiceImpl.java:108 |
这是隐式契约,前端注释 (People.vue:142-143) 已标,但没有任何后端校验(传 null 会 silently noop) |
| 6 | selectExecutorList 包含 u.status = ? 过滤条件,前端未用,SQL 永远不过滤 |
BizPersonMapper.xml:184 |
是预留扩展 OK,但注意 status 列展示不是用这个条件 — 展示来自 select *(全字段) |
| 7 | 删除走 sys_user.del_flag='1',业务侧 biz_person 记录永远存在;若要"恢复"还得改 del_flag='0',当前无"恢复已删人员" UI |
BizPersonMapper.xml:122-145 |
是设计选择,但产品流程上若有"误删恢复"需求会找不到入口 |
10. 待修复列表 (按优先级)
| # | 问题 | 文件 / 位置 | 修复建议 | 严重度 |
|---|---|---|---|---|
| 1 | 顶部缺 h1 + breadcrumb,与项目其它页风格不一致 | People.vue:3 |
加 breadcrumb 首页 / 人员管理 + (可选) h1,跟 manager/executor/Overview 风格统一 |
P2 |
| 2 | 批量导入 dialog UI 占位,未对接 /executorImport 接口 |
People.vue:64-80, 154-158 |
调用 POST /business/person/executorImport + 模板下载 GET /executorImportTemplate;返回的 errorRows 渲染成明细 |
P2 |
| 3 | 缺原型红字提示 "*角色:执行方管理员新建人员时,默认只有会议执行的角色" | People.vue:18-23 batch-bar |
在表格上方或表单区补一行提示 | P2 |
| 4 | 原型有复选框列(全选/批量操作),实现完全删了 | People.vue:26-53 |
如不需批量操作,可保留一行 checkbox 列+ disabled;若产品决定不做批量,需与原型对齐(在原型文件加 "调整说明" 备注) | P2 |
| 5 | biz_person.unit_type 默认值 'execution' 与 executor SQL 'executor' 不一致 |
DDL DEFAULT vs mapper.xml | 把 DDL DEFAULT 改 'executor' (或同步 sponsor SQL) | P3 |
| 6 | BizPerson.delFlag getter 返回 null 是误导 |
BizPerson.java:84-86 |
移除 getter/setter 或改名 getSysUserDelFlag() |
P3 |
| 7 | BizPerson.personId 用 String 存 bigint |
BizPerson.java:13 |
改为 Long,前端 personId 转 Number |
P3 |
| 8 | serviceImpl updateByPrimaryKey 在 userId=null 时 silently noop status 同步 | BizPersonServiceImpl.java:108 |
加日志 warn 或抛异常提示前端 | P3 |
| 9 | "工作单位" → "所属公司" 改名是 SQL 含义,产品口径需统一 | 前端文案 | 与产品确认:对外叫"所属公司"还是"工作单位" | P3 |
11. 引用清单
| 用途 | 文件 | 行号 |
|---|---|---|
| 角色菜单 | ry-vue3/src/layout/AdminLayout.vue |
65, 115-122 |
| 路由 | ry-vue3/src/router/index.js |
101-110 |
| 路由守卫 | ry-vue3/src/router/index.js |
134+ |
| 审查目标 | ry-vue3/src/views/executor/People.vue |
1-171 |
| 前端 API 封装 | ry-vue3/src/api/business/person.js |
24-31 (listExecutorPerson) |
| 后端 Controller | ry-api/ruoyi-business/src/main/java/com/ruoyi/business/controller/BizPersonController.java |
39-62 (BUSINESS_MAIN_ROLES), 81-89 (executorList), 152-164 (executorImport) |
| 后端 Mapper XML | ry-api/ruoyi-business/src/main/resources/mapper/business/BizPersonMapper.xml |
4-22 (resultMap), 24-38 (selectFields), 105-120 (updateByPrimaryKey), 122-145 (deleteByPrimaryKey/Keys), 168-187 (selectExecutorList), 189-194 (countAdminByOrgId) |
| 后端 Service 实现 | ry-api/ruoyi-business/src/main/java/com/ruoyi/business/service/impl/BizPersonServiceImpl.java |
96-98 (SysUser 构造), 106-118 (updateByPrimaryKey + sys_user 同步) |
| Entity | ry-api/ruoyi-business/src/main/java/com/ruoyi/business/domain/BizPerson.java |
9-108 (字段定义 + setter/getter,行 51-53 status 是 transient) |
| DDL (DB 实测) | mysql -h 127.0.0.1 -e 'USE guoju0808; SHOW CREATE TABLE biz_person\G' |
2026-08-18 |
| DDL (DB 实测) | mysql -h 127.0.0.1 -e 'USE guoju0808; SHOW CREATE TABLE biz_org\G' |
2026-08-18 |
| 原型 | proto/html/components/people.html |
全文 434 行 (含详细注释) |
| 原型菜单链 | proto/html/executor.html |
206 (data-page="components/people.html") |
| 记忆 (角色真相) | memory/sys-user-role-type-truth.md | role_type 是单一可信源 |
| 记忆 (sponsor 同模式) | commit 50c2678 |
executorList 加 executorList 兜底 (sponsor 同模式) |