大改动:全部人员用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:
+21
-4
@@ -24,6 +24,15 @@ function authHeader(): Record<string, string> {
|
||||
}
|
||||
}
|
||||
|
||||
/** 当前登录用户 ID(用于在记录中以 ID 关联操作人;演示模式下作为 body 兜底)。 */
|
||||
export function currentUserId(): string | undefined {
|
||||
try {
|
||||
return localStorage.getItem('risk-agent-uid') ?? undefined;
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/** API 调用错误。 */
|
||||
export class ApiError extends Error {
|
||||
constructor(
|
||||
@@ -118,6 +127,8 @@ export interface AssessmentListItem {
|
||||
readonly acceptability?: string;
|
||||
readonly createdAt: string;
|
||||
readonly assessorId: string;
|
||||
/** 发起人显示名(按 assessorId 解析)。 */
|
||||
readonly assessorName?: string;
|
||||
readonly status: WorkflowStatus;
|
||||
readonly auditLog: AuditLogEntry[];
|
||||
readonly archived?: boolean;
|
||||
@@ -439,6 +450,7 @@ export async function archiveAssessment(
|
||||
return request('POST', `/api/assessments/${id}/archive`, {
|
||||
archived,
|
||||
...(user !== undefined ? { user } : {}),
|
||||
...(currentUserId() !== undefined ? { userId: currentUserId() } : {}),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -473,6 +485,8 @@ export interface AssessmentDetailResponse {
|
||||
readonly expiresAt?: string | null;
|
||||
/** 审批人指派(按审批线,软约束)。 */
|
||||
readonly assignment?: { riskReviewerName: string | null; managerName: string | null } | null;
|
||||
/** 发起人显示名(按 assessorId 解析)。 */
|
||||
readonly assessorName?: string | null;
|
||||
}
|
||||
|
||||
/** 获取单条评估详情。 */
|
||||
@@ -510,6 +524,7 @@ export async function reviewAssessment(
|
||||
return request('POST', `/api/assessments/${id}/review`, {
|
||||
action,
|
||||
user,
|
||||
...(currentUserId() !== undefined ? { userId: currentUserId() } : {}),
|
||||
...(comment !== undefined && comment !== '' ? { comment } : {}),
|
||||
});
|
||||
}
|
||||
@@ -525,6 +540,7 @@ export async function approveAssessment(
|
||||
return request('POST', `/api/assessments/${id}/approve`, {
|
||||
action,
|
||||
user,
|
||||
...(currentUserId() !== undefined ? { userId: currentUserId() } : {}),
|
||||
...(comment !== undefined && comment !== '' ? { comment } : {}),
|
||||
...(rejectTo !== undefined ? { rejectTo } : {}),
|
||||
});
|
||||
@@ -532,12 +548,12 @@ export async function approveAssessment(
|
||||
|
||||
/** 重新提交评估。 */
|
||||
export async function resubmitAssessment(id: string, user: string): Promise<{ status: WorkflowStatus }> {
|
||||
return request('POST', `/api/assessments/${id}/resubmit`, { user });
|
||||
return request('POST', `/api/assessments/${id}/resubmit`, { user, ...(currentUserId() !== undefined ? { userId: currentUserId() } : {}) });
|
||||
}
|
||||
|
||||
/** 申报:将草稿评估报送风控审核。 */
|
||||
export async function submitAssessment(id: string, user: string): Promise<{ status: WorkflowStatus }> {
|
||||
return request('POST', `/api/assessments/${id}/submit`, { user });
|
||||
return request('POST', `/api/assessments/${id}/submit`, { user, ...(currentUserId() !== undefined ? { userId: currentUserId() } : {}) });
|
||||
}
|
||||
|
||||
/** 应用预测准确度校准(调整目标净利率基准,管理层)。 */
|
||||
@@ -550,7 +566,7 @@ export async function submitRedlineVerdict(
|
||||
id: string,
|
||||
params: { redlineId: string; status: '命中' | '未命中'; note?: string; user: string; role?: string; title?: string },
|
||||
): Promise<{ redlineId: string; status: string; acceptability: string }> {
|
||||
return request('POST', `/api/assessments/${id}/redline-verdict`, params);
|
||||
return request('POST', `/api/assessments/${id}/redline-verdict`, { ...params, ...(currentUserId() !== undefined ? { userId: currentUserId() } : {}) });
|
||||
}
|
||||
|
||||
/** 管理层对「已通过」或「已放弃」项目直接调整工作流状态(留痕)。 */
|
||||
@@ -563,6 +579,7 @@ export async function overrideAssessmentStatus(
|
||||
return request('POST', `/api/assessments/${id}/override`, {
|
||||
status,
|
||||
user,
|
||||
...(currentUserId() !== undefined ? { userId: currentUserId() } : {}),
|
||||
...(comment !== undefined && comment !== '' ? { comment } : {}),
|
||||
});
|
||||
}
|
||||
@@ -987,7 +1004,7 @@ export async function updateAssessment(
|
||||
const res = await fetch(`${API_BASE}/api/assessments/${id}`, {
|
||||
method: 'PUT',
|
||||
headers: { 'Content-Type': 'application/json', ...authHeader() },
|
||||
body: JSON.stringify(data),
|
||||
body: JSON.stringify({ ...data, ...(currentUserId() !== undefined ? { userId: currentUserId() } : {}) }),
|
||||
});
|
||||
if (!res.ok) {
|
||||
const err = await res.json().catch(() => ({})) as { error?: string };
|
||||
|
||||
Reference in New Issue
Block a user