大改动:全部人员用ID关联(JWT带uid + audit actor_id + assessorId改用户ID + 看板按ID匹配 + 历史回填)
- JWT 载荷增加 uid;登录返回 id;前端持久化 uid 并在变更请求中携带 userId - 操作人服务端解析(优先JWT.uid,回退body.userId),审计写入 actor_id + 当时显示名 - audit_logs 增加 actor_id 列;持久化与加载带 actorId - assessments.assessorId 改存用户ID,列表/详情按ID解析显示名(assessorName) - 看板待办「分给我的」改为按 userId 匹配;发起人显示真实姓名 - 审批线指派按 salesId(用户ID) 计算 - scripts/backfill-actor-ids.sql 回填历史(旧账号名→当前用户ID),本地+生产已执行
This commit is contained in:
@@ -159,7 +159,7 @@ export function Dashboard(): JSX.Element {
|
||||
fetch(`${API_BASE}/api/accuracy`).then((r) => r.json()).then(setAccuracy).catch(() => undefined);
|
||||
// 草稿箱(仅销售展示):列出当前用户的向导草稿。
|
||||
if (role === '商务/销售') {
|
||||
listDrafts(user?.username ?? undefined).then(setDrafts).catch(() => setDrafts([]));
|
||||
listDrafts(user?.id ?? undefined).then(setDrafts).catch(() => setDrafts([]));
|
||||
} else {
|
||||
setDrafts([]);
|
||||
}
|
||||
@@ -207,7 +207,7 @@ export function Dashboard(): JSX.Element {
|
||||
<span style={{ fontWeight: 700, color: colorVar('color.text.primary'), whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
|
||||
{display}
|
||||
</span>
|
||||
<span style={{ ...typographyStyle('caption'), color: colorVar('color.text.secondary'), whiteSpace: 'nowrap' }}>发起人:{r.assessorId}</span>
|
||||
<span style={{ ...typographyStyle('caption'), color: colorVar('color.text.secondary'), whiteSpace: 'nowrap' }}>发起人:{r.assessorName ?? r.assessorId}</span>
|
||||
</div>
|
||||
);
|
||||
},
|
||||
@@ -517,16 +517,16 @@ export function Dashboard(): JSX.Element {
|
||||
)}
|
||||
|
||||
{todoItems.length > 0 && (() => {
|
||||
const myName = user?.username;
|
||||
const myId = user?.id;
|
||||
const assignedToMe = (id: string): boolean => {
|
||||
const a = assignments[id];
|
||||
if (a === undefined) return false;
|
||||
return role === '风控' ? a.riskReviewerName === myName : role === '管理层' ? a.managerName === myName : false;
|
||||
return role === '风控' ? a.riskReviewerId === myId : role === '管理层' ? a.managerId === myId : false;
|
||||
};
|
||||
const isAssigned = (id: string): boolean => {
|
||||
const a = assignments[id];
|
||||
if (a === undefined) return false;
|
||||
return role === '风控' ? a.riskReviewerName !== null : role === '管理层' ? a.managerName !== null : false;
|
||||
return role === '风控' ? a.riskReviewerId !== null : role === '管理层' ? a.managerId !== null : false;
|
||||
};
|
||||
// 软约束:默认只看分给我的;未指派的也展示(避免遗漏)。
|
||||
const shown = onlyMine ? todoItems.filter((t) => assignedToMe(t.id) || !isAssigned(t.id)) : todoItems;
|
||||
@@ -536,8 +536,9 @@ export function Dashboard(): JSX.Element {
|
||||
render: (r) => {
|
||||
const a = assignments[r.id];
|
||||
const name = a !== undefined ? (role === '管理层' ? a.managerName : a.riskReviewerName) : null;
|
||||
const aid = a !== undefined ? (role === '管理层' ? a.managerId : a.riskReviewerId) : null;
|
||||
if (name === null || name === undefined) return <span style={{ color: colorVar('color.text.secondary') }}>未指派</span>;
|
||||
const mine = name === myName;
|
||||
const mine = aid === myId;
|
||||
return <span style={{ ...typographyStyle('caption'), fontWeight: 600, color: mine ? '#15803D' : colorVar('color.text.primary') }}>{name}{mine ? '(我)' : ''}</span>;
|
||||
},
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user