docs(api): 删除关心人功能和成员列表接口文档
- 移除关心人功能API接口文档文件 - 移除成员列表接口变更前端对接说明文档 - 清理相关HTML格式的API文档文件
This commit is contained in:
1144
关心人功能-API接口文档.html
1144
关心人功能-API接口文档.html
File diff suppressed because it is too large
Load Diff
@@ -1,754 +0,0 @@
|
||||
<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>成员列表接口变更 — 前端对接说明</title>
|
||||
<style>
|
||||
:root {
|
||||
--fg: #1f2328;
|
||||
--fg-muted: #57606a;
|
||||
--bg: #ffffff;
|
||||
--bg-soft: #f6f8fa;
|
||||
--border: #d0d7de;
|
||||
--border-soft: #e7ecf2;
|
||||
--accent: #0969da;
|
||||
--accent-soft: #ddf4ff;
|
||||
--warn: #9a6700;
|
||||
--warn-soft: #fff8c5;
|
||||
--danger: #cf222e;
|
||||
--danger-soft: #ffebe9;
|
||||
--ok: #1a7f37;
|
||||
--ok-soft: #dafbe1;
|
||||
--code-bg: #f6f8fa;
|
||||
}
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
background: var(--bg);
|
||||
color: var(--fg);
|
||||
font-family:
|
||||
-apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', 'Hiragino Sans GB',
|
||||
'Source Han Sans CN', 'Noto Sans CJK SC', Helvetica, Arial, sans-serif;
|
||||
font-size: 15px;
|
||||
line-height: 1.75;
|
||||
}
|
||||
.wrap {
|
||||
max-width: 1000px;
|
||||
margin: 0 auto;
|
||||
padding: 48px 32px 96px;
|
||||
}
|
||||
header.doc-header {
|
||||
border-bottom: 1px solid var(--border);
|
||||
padding-bottom: 16px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
header.doc-header h1 {
|
||||
margin: 0 0 8px;
|
||||
font-size: 28px;
|
||||
}
|
||||
header.doc-header .meta {
|
||||
color: var(--fg-muted);
|
||||
font-size: 13px;
|
||||
margin: 0;
|
||||
}
|
||||
h2 {
|
||||
margin: 40px 0 12px;
|
||||
padding-bottom: 6px;
|
||||
border-bottom: 1px solid var(--border-soft);
|
||||
font-size: 22px;
|
||||
}
|
||||
h3 {
|
||||
margin: 28px 0 8px;
|
||||
font-size: 17px;
|
||||
}
|
||||
h4 {
|
||||
margin: 20px 0 6px;
|
||||
font-size: 15px;
|
||||
}
|
||||
p {
|
||||
margin: 8px 0;
|
||||
}
|
||||
ul,
|
||||
ol {
|
||||
margin: 8px 0;
|
||||
padding-left: 24px;
|
||||
}
|
||||
ul li,
|
||||
ol li {
|
||||
margin: 3px 0;
|
||||
}
|
||||
code,
|
||||
pre {
|
||||
font-family: 'JetBrains Mono', Menlo, Consolas, 'Courier New', monospace;
|
||||
font-size: 13px;
|
||||
}
|
||||
code {
|
||||
background: var(--code-bg);
|
||||
padding: 1px 6px;
|
||||
border-radius: 4px;
|
||||
border: 1px solid var(--border-soft);
|
||||
}
|
||||
pre {
|
||||
background: var(--code-bg);
|
||||
border: 1px solid var(--border-soft);
|
||||
border-radius: 6px;
|
||||
padding: 14px 16px;
|
||||
overflow-x: auto;
|
||||
line-height: 1.55;
|
||||
}
|
||||
pre code {
|
||||
background: transparent;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
}
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
margin: 12px 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
th,
|
||||
td {
|
||||
border: 1px solid var(--border);
|
||||
padding: 7px 10px;
|
||||
text-align: left;
|
||||
vertical-align: top;
|
||||
}
|
||||
th {
|
||||
background: var(--bg-soft);
|
||||
font-weight: 600;
|
||||
}
|
||||
tr:nth-child(2n) td {
|
||||
background: #fafbfc;
|
||||
}
|
||||
|
||||
.callout {
|
||||
border-left: 4px solid var(--accent);
|
||||
background: var(--accent-soft);
|
||||
padding: 10px 14px;
|
||||
border-radius: 4px;
|
||||
margin: 12px 0;
|
||||
}
|
||||
.callout.warn {
|
||||
border-left-color: var(--warn);
|
||||
background: var(--warn-soft);
|
||||
}
|
||||
.callout.danger {
|
||||
border-left-color: var(--danger);
|
||||
background: var(--danger-soft);
|
||||
}
|
||||
.callout.ok {
|
||||
border-left-color: var(--ok);
|
||||
background: var(--ok-soft);
|
||||
}
|
||||
.callout .title {
|
||||
font-weight: 600;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.endpoint {
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 8px;
|
||||
padding: 16px 20px;
|
||||
margin: 14px 0;
|
||||
background: var(--bg);
|
||||
}
|
||||
.method {
|
||||
display: inline-block;
|
||||
padding: 3px 12px;
|
||||
border-radius: 4px;
|
||||
font-family: 'JetBrains Mono', Menlo, Consolas, monospace;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.method.get {
|
||||
background: #0969da;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.badge {
|
||||
display: inline-block;
|
||||
padding: 1px 8px;
|
||||
border-radius: 999px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
border: 1px solid var(--border);
|
||||
}
|
||||
.badge.new {
|
||||
background: var(--ok-soft);
|
||||
color: var(--ok);
|
||||
border-color: #aceeb6;
|
||||
}
|
||||
.badge.keep {
|
||||
background: var(--bg-soft);
|
||||
color: var(--fg-muted);
|
||||
}
|
||||
|
||||
.compare {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 12px;
|
||||
margin: 12px 0;
|
||||
}
|
||||
.compare > div {
|
||||
border: 1px solid var(--border);
|
||||
border-radius: 6px;
|
||||
padding: 12px 14px;
|
||||
}
|
||||
.compare .before {
|
||||
border-top: 3px solid var(--warn);
|
||||
}
|
||||
.compare .after {
|
||||
border-top: 3px solid var(--ok);
|
||||
}
|
||||
.compare h4 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: 0;
|
||||
border-top: 1px solid var(--border-soft);
|
||||
margin: 32px 0;
|
||||
}
|
||||
|
||||
.toc {
|
||||
background: var(--bg-soft);
|
||||
border: 1px solid var(--border-soft);
|
||||
border-radius: 6px;
|
||||
padding: 14px 20px;
|
||||
margin: 16px 0 24px;
|
||||
}
|
||||
.toc ol {
|
||||
margin: 4px 0;
|
||||
}
|
||||
.toc a {
|
||||
color: var(--accent);
|
||||
text-decoration: none;
|
||||
}
|
||||
.toc a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="wrap">
|
||||
<header class="doc-header">
|
||||
<h1>成员列表接口变更 — 前端对接说明</h1>
|
||||
<p class="meta">变更日期 2026-05-14 · 后端已就绪 · 前端需要配合调整渲染逻辑</p>
|
||||
</header>
|
||||
|
||||
<div class="callout">
|
||||
<div class="title">一句话总结</div>
|
||||
<strong>产品 / 项目成员列表接口</strong>
|
||||
现在按"
|
||||
<strong>一人一行</strong>
|
||||
"返回,同一用户的多个角色合并到主角色行,其他角色名通过新增的
|
||||
<code>additionalRoleNames: string[]</code>
|
||||
字段返回。前端只需要把这个数组拼到角色名旁边显示即可。
|
||||
</div>
|
||||
|
||||
<div class="toc">
|
||||
<strong>目录</strong>
|
||||
<ol>
|
||||
<li><a href="#sec-1">背景:为什么改</a></li>
|
||||
<li><a href="#sec-2">受影响的接口(仅 2 个)</a></li>
|
||||
<li><a href="#sec-3">改动前后对比</a></li>
|
||||
<li><a href="#sec-4">新增字段 additionalRoleNames</a></li>
|
||||
<li><a href="#sec-5">前端渲染建议</a></li>
|
||||
<li><a href="#sec-6">边界场景</a></li>
|
||||
<li><a href="#sec-7">不受影响的接口</a></li>
|
||||
<li><a href="#sec-8">前端落地 checklist</a></li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<!-- ====== 1 ====== -->
|
||||
|
||||
<h2 id="sec-1">1. 背景:为什么改</h2>
|
||||
|
||||
<p>
|
||||
多角色改造后,
|
||||
<strong>
|
||||
产品/项目的"创建者"角色会自动落一条
|
||||
<code>rdms_user_object_role</code>
|
||||
行
|
||||
</strong>
|
||||
。当
|
||||
<strong>创建者本人就是负责人</strong>
|
||||
时,同一用户在同一对象内会出现两条 ACTIVE 记录:
|
||||
</p>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
一条
|
||||
<code>product_manager</code>
|
||||
/
|
||||
<code>project_manager</code>
|
||||
</li>
|
||||
<li>
|
||||
一条
|
||||
<code>product_creator</code>
|
||||
/
|
||||
<code>project_creator</code>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<p>
|
||||
如果后端原样返回,前端列表会出现"同一个人重复两行"。讨论后约定:后端在
|
||||
<strong>列表接口</strong>
|
||||
层做合并展示,
|
||||
<strong>不影响</strong>
|
||||
底层数据(每个角色行仍独立存在,便于后续可能的"按角色单独操作")。
|
||||
</p>
|
||||
|
||||
<div class="callout warn">
|
||||
<div class="title">业务边界(重要)</div>
|
||||
当前业务上
|
||||
<strong>
|
||||
只有
|
||||
<code>creator + manager</code>
|
||||
这一种组合
|
||||
</strong>
|
||||
会让同人多角色出现。其他角色(产品专员、开发等)仍是一人一角色。所以前端可以放心按"主角色 + 附加角色名"
|
||||
的方式渲染,附加列表通常是 0 或 1 个元素。
|
||||
</div>
|
||||
|
||||
<!-- ====== 2 ====== -->
|
||||
|
||||
<h2 id="sec-2">2. 受影响的接口(仅 2 个)</h2>
|
||||
|
||||
<div class="endpoint">
|
||||
<span class="method get">GET</span>
|
||||
<code>/admin-api/project/product/{productId}/members</code>
|
||||
<p style="color: var(--fg-muted); font-size: 13px; margin: 6px 0 0">产品团队成员列表</p>
|
||||
</div>
|
||||
|
||||
<div class="endpoint">
|
||||
<span class="method get">GET</span>
|
||||
<code>/admin-api/project/project/{projectId}/members</code>
|
||||
<p style="color: var(--fg-muted); font-size: 13px; margin: 6px 0 0">项目团队成员列表</p>
|
||||
</div>
|
||||
|
||||
<p>
|
||||
响应结构两个接口对称,本文档下文统一用
|
||||
<code>RespVO</code>
|
||||
表示,字段路径一致。
|
||||
</p>
|
||||
|
||||
<!-- ====== 3 ====== -->
|
||||
|
||||
<h2 id="sec-3">3. 改动前后对比</h2>
|
||||
|
||||
<p>
|
||||
假设:产品 P 里
|
||||
<code>用户A</code>
|
||||
是产品经理(同时创建了该产品,所以也有
|
||||
<code>product_creator</code>
|
||||
角色),
|
||||
<code>用户B</code>
|
||||
是产品专员,
|
||||
<code>用户C</code>
|
||||
是已退场的历史成员。
|
||||
</p>
|
||||
|
||||
<div class="compare">
|
||||
<div class="before">
|
||||
<h4>改之前(数据原样返回,4 行)</h4>
|
||||
<pre><code>[
|
||||
{ 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: "..." }
|
||||
]</code></pre>
|
||||
<p style="color: var(--fg-muted); font-size: 12px">用户 A 出现 2 次 — 前端要么重复显示,要么自己去重。</p>
|
||||
</div>
|
||||
|
||||
<div class="after">
|
||||
<h4>改之后(合并后,3 行)</h4>
|
||||
<pre><code>[
|
||||
{ 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: "..." }
|
||||
]</code></pre>
|
||||
<p style="color: var(--fg-muted); font-size: 12px">
|
||||
用户 A 1 行 — 主行 manager,creator 名字进
|
||||
<code>additionalRoleNames</code>
|
||||
。
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h3>合并规则</h3>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>规则</th>
|
||||
<th>说明</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>仅合并 ACTIVE 行</td>
|
||||
<td>
|
||||
<code>status = 0</code>
|
||||
的多角色行才聚合;
|
||||
<code>status = 1</code>
|
||||
的历史 INACTIVE 行
|
||||
<strong>保持每条独立成行</strong>
|
||||
(历史角色留痕,便于审计)
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>主角色选择</td>
|
||||
<td>
|
||||
同人多角色时,
|
||||
<code>product_manager</code>
|
||||
/
|
||||
<code>project_manager</code>
|
||||
角色行优先做主;不在则按
|
||||
<code>roleId</code>
|
||||
升序选第一条(理论不该走到这条兜底)
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>主行字段</td>
|
||||
<td>
|
||||
<code>id</code>
|
||||
/
|
||||
<code>roleId</code>
|
||||
/
|
||||
<code>roleCode</code>
|
||||
/
|
||||
<code>roleName</code>
|
||||
/
|
||||
<code>joinedTime</code>
|
||||
/
|
||||
<code>leftTime</code>
|
||||
/
|
||||
<code>remark</code>
|
||||
等都按主角色行的值返回
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>非主角色名顺序</td>
|
||||
<td>
|
||||
<code>additionalRoleNames</code>
|
||||
按角色中文名字典序升序,前端可以直接顺序渲染
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- ====== 4 ====== -->
|
||||
|
||||
<h2 id="sec-4">
|
||||
4. 新增字段
|
||||
<code>additionalRoleNames</code>
|
||||
</h2>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>字段名</th>
|
||||
<th>类型</th>
|
||||
<th>状态</th>
|
||||
<th>说明</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>additionalRoleNames</code></td>
|
||||
<td><code>string[]</code></td>
|
||||
<td><span class="badge new">本次新增</span></td>
|
||||
<td>
|
||||
非主角色的中文名列表,多角色场景使用;
|
||||
<strong>
|
||||
单角色时为空数组
|
||||
<code>[]</code>
|
||||
</strong>
|
||||
,前端可以放心
|
||||
<code>length</code>
|
||||
判空
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<p>
|
||||
所有
|
||||
<strong>原有字段保持不变</strong>
|
||||
(
|
||||
<code>id</code>
|
||||
、
|
||||
<code>userId</code>
|
||||
、
|
||||
<code>userNickname</code>
|
||||
、
|
||||
<code>roleId</code>
|
||||
、
|
||||
<code>roleName</code>
|
||||
、
|
||||
<code>roleCode</code>
|
||||
、
|
||||
<code>managerFlag</code>
|
||||
、
|
||||
<code>status</code>
|
||||
、
|
||||
<code>joinedTime</code>
|
||||
、
|
||||
<code>leftTime</code>
|
||||
、
|
||||
<code>remark</code>
|
||||
),前端原有代码不会因为字段消失而报错。
|
||||
</p>
|
||||
|
||||
<!-- ====== 5 ====== -->
|
||||
|
||||
<h2 id="sec-5">5. 前端渲染建议</h2>
|
||||
|
||||
<h3>5.1 最简单的展示方式 — 拼成一个字符串</h3>
|
||||
|
||||
<pre><code>const displayRoleName = additionalRoleNames?.length
|
||||
? `${roleName} + ${additionalRoleNames.join(', ')}`
|
||||
: roleName;
|
||||
//
|
||||
// 例:roleName="产品经理", additionalRoleNames=["产品创建者"]
|
||||
// → "产品经理 + 产品创建者"
|
||||
//
|
||||
// 例:roleName="产品专员", additionalRoleNames=[]
|
||||
// → "产品专员"</code></pre>
|
||||
|
||||
<h3>5.2 更友好的展示 — 主角色 + 浅色 chip 标签</h3>
|
||||
|
||||
<pre><code><span class="role-main">{{ roleName }}</span>
|
||||
<span v-for="extra in additionalRoleNames" :key="extra" class="role-tag">
|
||||
{{ extra }}
|
||||
</span>
|
||||
//
|
||||
// CSS:role-tag 设计成浅色 background + 小圆角,跟主角色拉开视觉层级</code></pre>
|
||||
|
||||
<h3>5.3 表格单元格示意</h3>
|
||||
|
||||
<pre><code>| 用户 | 角色 | 状态 |
|
||||
|-----------|---------------------------|------|
|
||||
| 灿能管理 | 产品经理 [产品创建者] | 有效 |
|
||||
| 洪圣文 | 产品专员 | 有效 |
|
||||
| 李凡 | 游客 | 历史 |</code></pre>
|
||||
|
||||
<!-- ====== 6 ====== -->
|
||||
|
||||
<h2 id="sec-6">6. 边界场景</h2>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>场景</th>
|
||||
<th>预期返回</th>
|
||||
<th>前端展示</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>用户 A 仅是产品经理(不是创建者)</td>
|
||||
<td>
|
||||
1 行,
|
||||
<code>additionalRoleNames=[]</code>
|
||||
</td>
|
||||
<td>"产品经理"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>用户 A 同时是产品经理 + 创建者</td>
|
||||
<td>
|
||||
1 行(主行 manager),
|
||||
<code>additionalRoleNames=["产品创建者"]</code>
|
||||
</td>
|
||||
<td>"产品经理 + 产品创建者"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>用户 A 仅是创建者(罕见,理论上创建后立即把 manager 转给别人才会出现)</td>
|
||||
<td>
|
||||
1 行,主行就是 creator,
|
||||
<code>additionalRoleNames=[]</code>
|
||||
</td>
|
||||
<td>"产品创建者"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>用户 A 是产品专员(单角色非 manager)</td>
|
||||
<td>
|
||||
1 行,
|
||||
<code>additionalRoleNames=[]</code>
|
||||
</td>
|
||||
<td>"产品专员"</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>用户 A 退场(status=1 INACTIVE 历史行)</td>
|
||||
<td>
|
||||
每条 INACTIVE 行独立 1 行,
|
||||
<code>additionalRoleNames=[]</code>
|
||||
</td>
|
||||
<td>"产品专员(已退场)"等灰显</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
用户 A 同时有
|
||||
<strong>历史失效</strong>
|
||||
的角色行 +
|
||||
<strong>当前生效</strong>
|
||||
的角色行
|
||||
</td>
|
||||
<td>ACTIVE 行合并 1 行 + 每条 INACTIVE 行各占 1 行;同用户在列表里会出现多次(不同 status)</td>
|
||||
<td>分别用"有效 / 历史"区分;不要再二次合并</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- ====== 7 ====== -->
|
||||
|
||||
<h2 id="sec-7">7. 不受影响的接口</h2>
|
||||
|
||||
<p>
|
||||
以下接口
|
||||
<strong>不变</strong>
|
||||
,前端原有调用方式保持:
|
||||
</p>
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th>接口</th>
|
||||
<th>说明</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>POST /admin-api/project/product/{productId}/members</code>
|
||||
<br />
|
||||
<code>POST /admin-api/project/project/{projectId}/members</code>
|
||||
</td>
|
||||
<td>
|
||||
新增成员 — 仍按"一个角色一条记录"操作,传
|
||||
<code>userId + roleId</code>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>PUT /admin-api/project/.../members/{memberId}</code></td>
|
||||
<td>
|
||||
更新成员 — 按
|
||||
<code>memberId</code>
|
||||
(即
|
||||
<code>rdms_user_object_role.id</code>
|
||||
)定位具体角色行操作
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>PUT /admin-api/project/.../members/{memberId}/inactive</code></td>
|
||||
<td>
|
||||
失效成员 — 同上,按
|
||||
<code>memberId</code>
|
||||
操作
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<code>GET /admin-api/project/product/{productId}/context</code>
|
||||
<br />
|
||||
<code>GET /admin-api/project/project/{projectId}/context</code>
|
||||
</td>
|
||||
<td>
|
||||
对象上下文 —
|
||||
<code>currentRole.additionalRoleNames</code>
|
||||
字段早已存在,
|
||||
<strong>不在本次变更范围</strong>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<div class="callout warn">
|
||||
<div class="title">特别提醒 — 编辑 / 失效操作</div>
|
||||
当用户 A 同时是 manager + creator(合并展示成 1 行)时,前端如果允许"编辑这一行的角色"或"踢出",传的
|
||||
<code>memberId</code>
|
||||
是
|
||||
<strong>
|
||||
主角色行的
|
||||
<code>id</code>
|
||||
</strong>
|
||||
(也就是 manager 那条)。
|
||||
<strong>不会影响</strong>
|
||||
同人的 creator 角色行 — creator 角色仍保留。
|
||||
<br />
|
||||
<br />
|
||||
这是符合设计的行为:creator 是"留痕"角色,原则上不应该被踢出。如果业务上要踢出整个人,需要前端先调一次 list
|
||||
接口拿到该用户的所有 active 角色行(注意 — 合并后的 list 里看不到 creator 那条的
|
||||
<code>id</code>
|
||||
),后续
|
||||
<strong>是否要单独提供"列出某 user 所有角色行"接口</strong>
|
||||
取决于业务实际诉求,目前没有这个接口。
|
||||
</div>
|
||||
|
||||
<!-- ====== 8 ====== -->
|
||||
|
||||
<h2 id="sec-8">8. 前端落地 checklist</h2>
|
||||
|
||||
<div class="callout ok">
|
||||
<ul style="margin: 6px 0">
|
||||
<li>
|
||||
✅ 把
|
||||
<code>additionalRoleNames</code>
|
||||
数组加到 TypeScript 类型定义(ProductMemberRespVO / ProjectMemberRespVO 两处)
|
||||
</li>
|
||||
<li>
|
||||
✅ 列表渲染逻辑:把
|
||||
<code>additionalRoleNames</code>
|
||||
拼到
|
||||
<code>roleName</code>
|
||||
旁边显示(字符串或 chip 标签均可)
|
||||
</li>
|
||||
<li>
|
||||
✅ 验证:找一个"创建者 = 经理"的产品/项目,确认列表里这个人只出现
|
||||
<strong>1 行</strong>
|
||||
,且能看到"产品经理 + 产品创建者"字样
|
||||
</li>
|
||||
<li>
|
||||
✅ 验证:找一个普通成员(产品专员等),
|
||||
<code>additionalRoleNames</code>
|
||||
应该是
|
||||
<code>[]</code>
|
||||
,不影响展示
|
||||
</li>
|
||||
<li>
|
||||
✅ 验证:历史退场成员(
|
||||
<code>status=1</code>
|
||||
),仍按原方式各占一行
|
||||
</li>
|
||||
<li>
|
||||
⏸ 编辑/失效操作 — 当前不动,仍按
|
||||
<code>memberId</code>
|
||||
操作主角色行;若业务需要"踢人整体",后端再补接口
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<hr />
|
||||
|
||||
<h3>变更影响最小范围说明</h3>
|
||||
|
||||
<p style="color: var(--fg-muted); font-size: 13px">
|
||||
本次后端改动仅在
|
||||
<code>ProductMemberServiceImpl.getProductMemberList</code>
|
||||
和
|
||||
<code>ProjectMemberServiceImpl.getProjectMemberList</code>
|
||||
两个方法中实现,
|
||||
<strong>不修改底层数据</strong>
|
||||
(
|
||||
<code>rdms_user_object_role</code>
|
||||
仍按一行一角色存储)。即使前端暂时不读
|
||||
<code>additionalRoleNames</code>
|
||||
字段,也只是看不到"+ 产品创建者"字样,不会出现数据错误或重复行问题。
|
||||
</p>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user