diff --git a/关心人功能-API接口文档.html b/关心人功能-API接口文档.html deleted file mode 100644 index e5554c3..0000000 --- a/关心人功能-API接口文档.html +++ /dev/null @@ -1,1144 +0,0 @@ - - - - - 关心人功能 — API 接口文档 - - - -
-
-

关心人功能 — API 接口文档

-

面向前端开发 · 后端已就绪 · 编写日期 2026-05-14

-
- -
-
一句话总结
- 在产品 / 项目创建向导第 2 步增加"关心人"多选输入框,前端把选中的 - userId - 列表通过 - watcherUserIds - 字段一并提交到现有的 - create-with-team - 接口即可。后端自动给这些用户授予 - 产品/项目关心人 - 角色,让他们后续能在列表 / 详情看到这个对象(菜单按 watcher 角色权限渲染)。 -
- -
- 目录 -
    -
  1. 设计意图
  2. -
  3. 用户旅程 / 前端交互
  4. -
  5. 接口列表速览
  6. -
  7. 主接口 — 创建产品(含团队 + 关心人)
  8. -
  9. 主接口 — 创建项目(含团队 + 关心人)
  10. -
  11. 辅助接口 — 用户精简列表(用于选关心人)
  12. -
  13. 业务规则 / 边界 / FAQ
  14. -
-
- - - -

1. 设计意图

- -

1.1 关心人是什么

- -

- "关心人"(watcher)是 - 对产品 / 项目本身长期感兴趣,但不参与交付 - 的人。典型场景: -

- - - -

1.2 为什么不直接加成员?

- - - - - - - - - - - - - - - - - - - - - - - - - - -
身份角色 code能看什么能做什么
产品经理 / 项目负责人 - product_manager - / - project_manager - 对象内全部 tab所有操作(分配任务、改预算、删对象等)
团队成员(开发 / 测试 / 协办等)各业务角色对象内执行细节(任务、代码、文档等)跟自己角色 / 任务挂钩的写操作
关心人 watcher - - product_watcher - / - project_watcher - - 对象主要 tab(概览 / 进度 / 需求)只读 — 不参与交付
- -
-
为什么单独做 watcher,不复用现有 member?
- 数据权限设计里有 - 三条互不重叠的边界 - : - - 少量人盯几个对象就是 watcher 的位置 —— 比逐条加成员省事,比配 visibility_config 颗粒细。 -
- -

1.3 关心人的数据权限路径

- -

- 关心人记录最终落到 - rdms_user_object_role - 表(与 member 同表,只是 - role_id - 指向 watcher 角色)。系统按这个角色让用户进入"数据权限通道 1(自己参与)",跟普通成员路径一致 —— 区别只在 - 菜单 / 按钮粒度 - 由 watcher 角色绑定的权限决定。 -

- - - -

2. 用户旅程 / 前端交互

- -

2.1 当前两步向导(产品 / 项目都一样)

- -
    -
  1. - 第 1 步 - :填基础资料 —— 名称 / 编码 / 方向 / 负责人等 -
  2. -
  3. - 第 2 步 - :维护初始团队 —— 必须含负责人本人 + 其他成员(每人一个业务角色) -
  4. -
- -

2.2 本次新增 — 第 2 步追加"关心人"区块

- -

- 建议 UI:第 2 步页面里在"团队成员"列表下方加一个独立区块" - 关心人(选填) - ",含一个用户多选控件。 -

- -
┌─────────────────────────────────────────────────────────┐
-│  第 2 步:维护初始团队                                     │
-├─────────────────────────────────────────────────────────┤
-│                                                         │
-│  团队成员 *                                              │
-│  ┌────────────────────────────────────────────────────┐ │
-│  │ [+] 添加成员                                       │ │
-│  │  · 张三   产品经理      操作 ▾                     │ │
-│  │  · 李四   开发          操作 ▾                     │ │
-│  └────────────────────────────────────────────────────┘ │
-│                                                         │
-│  关心人(选填)                                           │
-│  ┌────────────────────────────────────────────────────┐ │
-│  │ [多选用户] 王五 ╳  赵六 ╳                          │ │
-│  └────────────────────────────────────────────────────┘ │
-│  提示:关心人将获得"产品/项目关心人"角色,能在列表和概览看到此对象,  │
-│       但不开放代码 / 任务 / 文档等执行细节。可与团队成员重叠。      │
-│                                                         │
-│  [取消]                                  [上一步] [完成] │
-└─────────────────────────────────────────────────────────┘
- -

2.3 提交时数据组装

- -

- 点击"完成"时,按 - §4 - / - §5 - 的 ReqVO 结构组装: -

- - - - - -

3. 接口列表速览

- - - - - - - - - - - - - - - - - - - - - - - - - - -
方法路径用途本次是否新接口
POST/project/product/create-with-team创建产品(含初始团队 + 关心人) - 已有接口;本次只是 ReqVO 多了 - watcherUserIds - 字段 -
POST/project/project/create-with-team创建项目(含初始团队 + 关心人) - 已有接口;本次只是 ReqVO 多了 - watcherUserIds - 字段 -
GET - /system/user/list-all-simple -
- (别名 - /system/user/simple-list - ) -
获取启用用户精简列表(前端选关心人下拉用)已有接口,无需任何改动
- - - -

4. 主接口 — 创建产品(含团队 + 关心人)

- -
-
- POST - /project/product/create-with-team -
-

- 事务性原子接口:产品基础资料 + 初始团队 + 关心人在同一事务内完成,任一步失败整体回滚。 -

- -

权限

-

- @PreAuthorize("@ss.hasPermission('project:product:create')") - — 创建产品权限码 -

- -

- 请求体( - ProductCreateWithTeamReqVO - ) -

- -
{
-  "product": {
-    "code": "CNPD2026001",
-    "directionCode": "system",
-    "name": "RDMS 产品平台",
-    "managerUserId": 1024,
-    "description": "面向研发管理的一体化产品"
-  },
-  "members": [
-    { "userId": 1024, "roleId": 3100000002001, "remark": "产品经理本人" },
-    { "userId": 1025, "roleId": 3100000002002, "remark": "开发" }
-  ],
-  "watcherUserIds": [2001, 2002]
-}
- -

字段说明

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
路径类型必填说明
productobject必填产品基础资料,结构见下
product.codestring ≤ 64选填产品编码;为空时由后端按规则生成
product.directionCodestring ≤ 32必填 - 产品方向字典值(字典类型 - object_direction - ) -
product.namestring ≤ 128必填产品名称
product.managerUserIdLong必填 - 产品经理 user_id;必须在 - members - 列表里有对应的产品经理角色记录 -
product.descriptionstring选填产品描述
membersarray<object>必填 - 初始团队, - - 必须包含 userId == product.managerUserId 且 roleId 是 - product_manager - 的记录 - - ;后端不会自动追加经理 -
members[].userIdLong必填成员 user_id
members[].roleIdLong必填 - 对象域角色 ID( - scope_type='object' - , - object_type='product' - );前端用 role code 反查得到(如 - product_manager - ) -
members[].remarkstring ≤ 500选填成员备注
- watcherUserIds - array<Long>选填 - 关心人 user_id 数组 - 。允许为空 / 省略字段 / 与 members 重叠;后端按 (user, object, role) 三元组写入,重复跳过 / INACTIVE - 复活;后端会自动去 null 去重 -
- -

响应

- -
{
-  "code": 0,
-  "data": 30001,   // 新创建的 productId
-  "msg": ""
-}
- -

典型错误

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
错误码 / 信息触发条件
产品基础资料不能为空 - product - 字段缺失 -
初始团队成员不能为空 - members - 空数组或缺失 -
产品经理不能为空 - product.managerUserId - 缺失 -
产品方向不能为空 - product.directionCode - 缺失 -
PRODUCT_MEMBER_ALREADY_EXISTS - members - 里同 user 同 role 重复(multi-role 唯一索引拦截) -
PRODUCT_INTERNAL_ROLE_NOT_CONFIGURED - 后端启动校验通过但运行时找不到 - product_watcher - 角色(理论上不会发生 — 启动校验会拦) -
-
- - - -

5. 主接口 — 创建项目(含团队 + 关心人)

- -
-
- POST - /project/project/create-with-team -
-

- 事务性原子接口:项目基础资料 + 初始团队 + 关心人在同一事务内完成,任一步失败整体回滚。 -

- -

权限

-

- @PreAuthorize("@ss.hasPermission('project:project:create')") - — 创建项目权限码 -

- -

- 请求体( - ProjectCreateWithTeamReqVO - ) -

- -
{
-  "project": {
-    "projectCode": "CNPJ2026001",
-    "projectName": "客户交付项目 A",
-    "projectType": "delivery",
-    "directionCode": "system",
-    "productId": 30001,
-    "managerUserId": 1024,
-    "plannedStartDate": "2026-06-01",
-    "plannedEndDate":   "2026-09-30",
-    "projectDesc": "为客户 XX 定制交付"
-  },
-  "members": [
-    { "userId": 1024, "roleId": 3100000003001, "remark": "项目负责人本人" },
-    { "userId": 1030, "roleId": 3100000003002, "remark": "前端开发" }
-  ],
-  "watcherUserIds": [2001, 2002]
-}
- -

字段说明

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
路径类型必填说明
projectobject必填 - 项目基础资料;新建场景不传 - actualStartDate - / - actualEndDate - (实际日期由执行阶段才有值) -
project.projectCodestring ≤ 64选填项目编码;为空时由后端按规则生成
project.projectNamestring ≤ 200必填项目名称
project.projectTypestring ≤ 32必填项目类型字典值
project.directionCodestring条件必填 - 项目方向; - 未选产品时必填;选了产品则后端按产品方向覆盖 - ,前端可不传 -
project.productIdLong选填所属产品 ID;不选表示无产品归属
project.managerUserIdLong必填 - 项目负责人 user_id;同产品规则,必须在 - members - 里出现且对应负责人角色 -
- project.plannedStartDate - / - plannedEndDate - - date - YYYY-MM-DD - 选填计划日期
project.projectDescstring ≤ 4000选填项目说明
membersarray<object>必填 - 结构同 - ProjectMemberSaveReqVO - ,与产品对称。必须包含 userId == project.managerUserId 且 roleId 为 - project_manager - 的记录 -
members[].userIdLong必填成员 user_id
members[].roleIdLong必填 - 对象域角色 ID( - scope_type='object' - , - object_type='project' - ) -
members[].remarkstring ≤ 500选填成员备注
- watcherUserIds - array<Long>选填 - 关心人 user_id 数组 - 。规则与产品端一致:允许空 / 省略 / 与 members 重叠;后端去 null 去重,按三元组幂等写入 -
- -

响应

- -
{
-  "code": 0,
-  "data": 40001,   // 新创建的 projectId
-  "msg": ""
-}
- -

典型错误

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
错误码 / 信息触发条件
项目基础资料不能为空 - project - 字段缺失 -
项目名称不能为空 - project.projectName - 缺失 -
项目负责人不能为空 - project.managerUserId - 缺失 -
初始团队成员不能为空 - members - 空 -
PROJECT_MEMBER_ALREADY_EXISTS - members - 里同 user 同 role 重复 -
PROJECT_INTERNAL_ROLE_NOT_CONFIGURED - 后端运行时找不到 - project_watcher - 角色(理论上不会发生) -
-
- - - -

6. 辅助接口 — 用户精简列表

- -
-
- GET - /system/user/list-all-simple -
-

- 获取所有 - 已启用 - 用户的精简信息,用于前端下拉 / 多选控件。也可访问别名 - /system/user/simple-list - 。 -

- -

权限

-

登录态即可(无显式权限码限制)。

- -

请求

-

无参数。

- -

- 响应( - List<UserSimpleRespVO> - ) -

- -
{
-  "code": 0,
-  "data": [
-    { "id": 1024, "nickname": "张三" },
-    { "id": 1025, "nickname": "李四" },
-    { "id": 2001, "nickname": "王五" }
-  ],
-  "msg": ""
-}
- -
-
前端使用建议
- 这个接口返回的字段比较精简(一般是 id + 昵称)。如果需要按部门 / 工号 / 状态筛选,可以叠加用 - GET /system/user/page - 走分页查询;或者拉一次全量后在前端做 search filter。 -
-
- - - -

7. 业务规则 / 边界 / FAQ

- -

7.1 watcher 与 member 可不可以是同一人?

-

- 可以。多角色合法,会落两条 - rdms_user_object_role - 记录(一条 member 角色 + 一条 watcher 角色),数据权限 - 取并集 - 。这种情况通常不会出现 —— 已经在团队里的人不需要再设为 watcher —— 但允许重叠不报错,前端不需要做"过滤已在 - members 里的 user"的校验,让后端兜底。 -

- -

7.2 创建之后能不能再加 / 删关心人?

-

- 当前 - create-with-team 是唯一的批量入口 - 。创建后维护 watcher 的接口暂未单独提供 —— 如果业务后续需要"在产品 / - 项目编辑页面再加关心人",需要再拉一条接口(沿用现有的 - add member - / - remove member - 模式即可,roleId 传 watcher 角色 ID)。 -

- -

7.3 watcher 进入对象后能看到什么、能做什么?

-

- 取决于业务侧给 - product_watcher - / - project_watcher - 角色在权限管理界面绑了哪些菜单(对象域菜单 - system_menu.scope_type='object' - )。建议粒度: -

- - -
-
前端可能用到的角色 code 常量
- -
- -

7.4 watcher 字段不传会怎样?

-

- 完全等价于传空数组。 - watcherUserIds - 是可选字段 —— 不写 / 写 null / 写 - [] - 都不会落任何 watcher 记录,接口正常完成。 -

- -

7.5 watcher 列表能放多少人?

-

- 当前没有上限校验。从产品语义看,关心人本来就是"少量长期看的人",前端可以加个软性提示(如超过 20 - 人时提示考虑用方向级 visibility_config 配置),但不阻塞提交。 -

- -

7.6 关心人能看到对象里的"工时"吗?

-

- 看不到。工时是敏感数据,按对象内身份控制:协办人只看自己填报的工时;任务/项目负责人可看团队成员工时。 - watcher 既不是协办人也不是负责人,工时列表对其不可见 - 。 -

- -

7.7 watcher 和"用户可见性配置(visibility_config)"什么区别?

- - - - - - - - - - - - - - - - - - - - - - - - - - -
维度关心人 watcher用户可见性配置 visibility_config
粒度单个产品 / 项目整个方向 or 全局(all / directions)
谁来加产品 / 项目创建人在新建表单里加系统管理员在用户管理 / 可见性配置页加
典型场景外部顾问盯几个产品 / 长期评审人跨方向工程师看一片方向的所有产品 / 技术支持组协调全部
底层存储 - rdms_user_object_role - (一条对象成员记录) - - system_user_visibility_config - (一条用户级配置) -
- -
-
前端落地 checklist
- -
-
- - diff --git a/成员列表接口变更-前端对接说明.html b/成员列表接口变更-前端对接说明.html deleted file mode 100644 index c174d9b..0000000 --- a/成员列表接口变更-前端对接说明.html +++ /dev/null @@ -1,754 +0,0 @@ - - - - - 成员列表接口变更 — 前端对接说明 - - - -
-
-

成员列表接口变更 — 前端对接说明

-

变更日期 2026-05-14 · 后端已就绪 · 前端需要配合调整渲染逻辑

-
- -
-
一句话总结
- 产品 / 项目成员列表接口 - 现在按" - 一人一行 - "返回,同一用户的多个角色合并到主角色行,其他角色名通过新增的 - additionalRoleNames: string[] - 字段返回。前端只需要把这个数组拼到角色名旁边显示即可。 -
- -
- 目录 -
    -
  1. 背景:为什么改
  2. -
  3. 受影响的接口(仅 2 个)
  4. -
  5. 改动前后对比
  6. -
  7. 新增字段 additionalRoleNames
  8. -
  9. 前端渲染建议
  10. -
  11. 边界场景
  12. -
  13. 不受影响的接口
  14. -
  15. 前端落地 checklist
  16. -
-
- - - -

1. 背景:为什么改

- -

- 多角色改造后, - - 产品/项目的"创建者"角色会自动落一条 - rdms_user_object_role - 行 - - 。当 - 创建者本人就是负责人 - 时,同一用户在同一对象内会出现两条 ACTIVE 记录: -

- - - -

- 如果后端原样返回,前端列表会出现"同一个人重复两行"。讨论后约定:后端在 - 列表接口 - 层做合并展示, - 不影响 - 底层数据(每个角色行仍独立存在,便于后续可能的"按角色单独操作")。 -

- -
-
业务边界(重要)
- 当前业务上 - - 只有 - creator + manager - 这一种组合 - - 会让同人多角色出现。其他角色(产品专员、开发等)仍是一人一角色。所以前端可以放心按"主角色 + 附加角色名" - 的方式渲染,附加列表通常是 0 或 1 个元素。 -
- - - -

2. 受影响的接口(仅 2 个)

- -
- GET - /admin-api/project/product/{productId}/members -

产品团队成员列表

-
- -
- GET - /admin-api/project/project/{projectId}/members -

项目团队成员列表

-
- -

- 响应结构两个接口对称,本文档下文统一用 - RespVO - 表示,字段路径一致。 -

- - - -

3. 改动前后对比

- -

- 假设:产品 P 里 - 用户A - 是产品经理(同时创建了该产品,所以也有 - product_creator - 角色), - 用户B - 是产品专员, - 用户C - 是已退场的历史成员。 -

- -
-
-

改之前(数据原样返回,4 行)

-
[
-  { id: "100", userId: "A", roleCode: "product_manager",
-    roleName: "产品经理", status: 0, ... },
-  { id: "101", userId: "A", roleCode: "product_creator",
-    roleName: "产品创建者", status: 0, ... },
-  { id: "102", userId: "B", roleCode: "product_specialist",
-    roleName: "产品专员", status: 0, ... },
-  { id: "103", userId: "C", roleCode: "product_specialist",
-    roleName: "产品专员", status: 1, leftTime: "..." }
-]
-

用户 A 出现 2 次 — 前端要么重复显示,要么自己去重。

-
- -
-

改之后(合并后,3 行)

-
[
-  { id: "100", userId: "A", roleCode: "product_manager",
-    roleName: "产品经理",
-    additionalRoleNames: ["产品创建者"],  // ← 新增字段
-    status: 0, ... },
-  { id: "102", userId: "B", roleCode: "product_specialist",
-    roleName: "产品专员",
-    additionalRoleNames: [],
-    status: 0, ... },
-  { id: "103", userId: "C", roleCode: "product_specialist",
-    roleName: "产品专员",
-    additionalRoleNames: [],
-    status: 1, leftTime: "..." }
-]
-

- 用户 A 1 行 — 主行 manager,creator 名字进 - additionalRoleNames - 。 -

-
-
- -

合并规则

- - - - - - - - - - - - - - - - - - - - - - -
规则说明
仅合并 ACTIVE 行 - status = 0 - 的多角色行才聚合; - status = 1 - 的历史 INACTIVE 行 - 保持每条独立成行 - (历史角色留痕,便于审计) -
主角色选择 - 同人多角色时, - product_manager - / - project_manager - 角色行优先做主;不在则按 - roleId - 升序选第一条(理论不该走到这条兜底) -
主行字段 - id - / - roleId - / - roleCode - / - roleName - / - joinedTime - / - leftTime - / - remark - 等都按主角色行的值返回 -
非主角色名顺序 - additionalRoleNames - 按角色中文名字典序升序,前端可以直接顺序渲染 -
- - - -

- 4. 新增字段 - additionalRoleNames -

- - - - - - - - - - - - - - -
字段名类型状态说明
additionalRoleNamesstring[]本次新增 - 非主角色的中文名列表,多角色场景使用; - - 单角色时为空数组 - [] - - ,前端可以放心 - length - 判空 -
- -

- 所有 - 原有字段保持不变 - ( - id - 、 - userId - 、 - userNickname - 、 - roleId - 、 - roleName - 、 - roleCode - 、 - managerFlag - 、 - status - 、 - joinedTime - 、 - leftTime - 、 - remark - ),前端原有代码不会因为字段消失而报错。 -

- - - -

5. 前端渲染建议

- -

5.1 最简单的展示方式 — 拼成一个字符串

- -
const displayRoleName = additionalRoleNames?.length
-  ? `${roleName} + ${additionalRoleNames.join(', ')}`
-  : roleName;
-//
-// 例:roleName="产品经理", additionalRoleNames=["产品创建者"]
-// → "产品经理 + 产品创建者"
-//
-// 例:roleName="产品专员", additionalRoleNames=[]
-// → "产品专员"
- -

5.2 更友好的展示 — 主角色 + 浅色 chip 标签

- -
<span class="role-main">{{ roleName }}</span>
-<span v-for="extra in additionalRoleNames" :key="extra" class="role-tag">
-  {{ extra }}
-</span>
-//
-// CSS:role-tag 设计成浅色 background + 小圆角,跟主角色拉开视觉层级
- -

5.3 表格单元格示意

- -
| 用户       | 角色                       | 状态  |
-|-----------|---------------------------|------|
-| 灿能管理   | 产品经理 [产品创建者]       | 有效 |
-| 洪圣文     | 产品专员                   | 有效 |
-| 李凡       | 游客                       | 历史 |
- - - -

6. 边界场景

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
场景预期返回前端展示
用户 A 仅是产品经理(不是创建者) - 1 行, - additionalRoleNames=[] - "产品经理"
用户 A 同时是产品经理 + 创建者 - 1 行(主行 manager), - additionalRoleNames=["产品创建者"] - "产品经理 + 产品创建者"
用户 A 仅是创建者(罕见,理论上创建后立即把 manager 转给别人才会出现) - 1 行,主行就是 creator, - additionalRoleNames=[] - "产品创建者"
用户 A 是产品专员(单角色非 manager) - 1 行, - additionalRoleNames=[] - "产品专员"
用户 A 退场(status=1 INACTIVE 历史行) - 每条 INACTIVE 行独立 1 行, - additionalRoleNames=[] - "产品专员(已退场)"等灰显
- 用户 A 同时有 - 历史失效 - 的角色行 + - 当前生效 - 的角色行 - ACTIVE 行合并 1 行 + 每条 INACTIVE 行各占 1 行;同用户在列表里会出现多次(不同 status)分别用"有效 / 历史"区分;不要再二次合并
- - - -

7. 不受影响的接口

- -

- 以下接口 - 不变 - ,前端原有调用方式保持: -

- - - - - - - - - - - - - - - - - - - - - - -
接口说明
- POST /admin-api/project/product/{productId}/members -
- POST /admin-api/project/project/{projectId}/members -
- 新增成员 — 仍按"一个角色一条记录"操作,传 - userId + roleId -
PUT /admin-api/project/.../members/{memberId} - 更新成员 — 按 - memberId - (即 - rdms_user_object_role.id - )定位具体角色行操作 -
PUT /admin-api/project/.../members/{memberId}/inactive - 失效成员 — 同上,按 - memberId - 操作 -
- GET /admin-api/project/product/{productId}/context -
- GET /admin-api/project/project/{projectId}/context -
- 对象上下文 — - currentRole.additionalRoleNames - 字段早已存在, - 不在本次变更范围 -
- -
-
特别提醒 — 编辑 / 失效操作
- 当用户 A 同时是 manager + creator(合并展示成 1 行)时,前端如果允许"编辑这一行的角色"或"踢出",传的 - memberId - 是 - - 主角色行的 - id - - (也就是 manager 那条)。 - 不会影响 - 同人的 creator 角色行 — creator 角色仍保留。 -
-
- 这是符合设计的行为:creator 是"留痕"角色,原则上不应该被踢出。如果业务上要踢出整个人,需要前端先调一次 list - 接口拿到该用户的所有 active 角色行(注意 — 合并后的 list 里看不到 creator 那条的 - id - ),后续 - 是否要单独提供"列出某 user 所有角色行"接口 - 取决于业务实际诉求,目前没有这个接口。 -
- - - -

8. 前端落地 checklist

- -
- -
- -
- -

变更影响最小范围说明

- -

- 本次后端改动仅在 - ProductMemberServiceImpl.getProductMemberList - 和 - ProjectMemberServiceImpl.getProjectMemberList - 两个方法中实现, - 不修改底层数据 - ( - rdms_user_object_role - 仍按一行一角色存储)。即使前端暂时不读 - additionalRoleNames - 字段,也只是看不到"+ 产品创建者"字样,不会出现数据错误或重复行问题。 -

-
- -