外包风险评估系统:领域引擎+前端+服务端持久化与生产部署
- 确定性领域引擎(分类/评分/分级/红线/费用/裁决)+LLM(通义千问)语言理解 - 6步评估向导、服务端草稿持久化(跨设备/编辑草稿保护) - 工作流(草稿→风控→管理层)、RBAC、报告导出、校准、客户/费率/红线/最低工资管理 - 专业图标体系替换全部emoji、看板美化 - 生产化:API_BASE可配置(同源反代)、auth密钥惰性读取修复RBAC - 444单测+204前端测试+51 e2e
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* 评估向导草稿持久化(服务端,跨设备)。
|
||||
* - source_assessment_id 为空:全新建评估的草稿
|
||||
* - source_assessment_id 非空:编辑某既有评估时的草稿
|
||||
* form 存完整向导快照(任意 JSON)。
|
||||
*/
|
||||
import type pg from 'pg';
|
||||
|
||||
export interface DraftRecord {
|
||||
id: string;
|
||||
assessorId: string | null;
|
||||
sourceAssessmentId: string | null;
|
||||
projectName: string | null;
|
||||
form: unknown;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
/** 列表项(不含 form 大字段,仅元信息)。 */
|
||||
export interface DraftSummary {
|
||||
id: string;
|
||||
assessorId: string | null;
|
||||
sourceAssessmentId: string | null;
|
||||
projectName: string | null;
|
||||
updatedAt: string;
|
||||
}
|
||||
|
||||
function isoOf(v: unknown): string {
|
||||
return v instanceof Date ? v.toISOString() : String(v);
|
||||
}
|
||||
|
||||
/** 列出草稿(可按 assessorId 过滤),不返回 form 大字段。 */
|
||||
export async function listDrafts(pool: pg.Pool, assessorId?: string): Promise<DraftSummary[]> {
|
||||
const where = assessorId ? 'WHERE assessor_id = $1' : '';
|
||||
const params = assessorId ? [assessorId] : [];
|
||||
const res = await pool.query(
|
||||
`SELECT id, assessor_id, source_assessment_id, project_name, updated_at
|
||||
FROM wizard_drafts ${where} ORDER BY updated_at DESC`,
|
||||
params,
|
||||
);
|
||||
return (res.rows as Array<Record<string, unknown>>).map((r) => ({
|
||||
id: String(r.id),
|
||||
assessorId: r.assessor_id != null ? String(r.assessor_id) : null,
|
||||
sourceAssessmentId: r.source_assessment_id != null ? String(r.source_assessment_id) : null,
|
||||
projectName: r.project_name != null ? String(r.project_name) : null,
|
||||
updatedAt: isoOf(r.updated_at),
|
||||
}));
|
||||
}
|
||||
|
||||
/** 取单个草稿(含 form)。 */
|
||||
export async function getDraft(pool: pg.Pool, id: string): Promise<DraftRecord | null> {
|
||||
const res = await pool.query(
|
||||
`SELECT id, assessor_id, source_assessment_id, project_name, form, updated_at
|
||||
FROM wizard_drafts WHERE id = $1`,
|
||||
[id],
|
||||
);
|
||||
const r = (res.rows as Array<Record<string, unknown>>)[0];
|
||||
if (!r) return null;
|
||||
return {
|
||||
id: String(r.id),
|
||||
assessorId: r.assessor_id != null ? String(r.assessor_id) : null,
|
||||
sourceAssessmentId: r.source_assessment_id != null ? String(r.source_assessment_id) : null,
|
||||
projectName: r.project_name != null ? String(r.project_name) : null,
|
||||
form: r.form,
|
||||
updatedAt: isoOf(r.updated_at),
|
||||
};
|
||||
}
|
||||
|
||||
export interface UpsertDraftInput {
|
||||
id: string;
|
||||
assessorId?: string | null;
|
||||
sourceAssessmentId?: string | null;
|
||||
projectName?: string | null;
|
||||
form: unknown;
|
||||
}
|
||||
|
||||
/** 新增或更新草稿(按 id)。 */
|
||||
export async function upsertDraft(pool: pg.Pool, input: UpsertDraftInput): Promise<DraftRecord> {
|
||||
const res = await pool.query(
|
||||
`INSERT INTO wizard_drafts(id, assessor_id, source_assessment_id, project_name, form, updated_at)
|
||||
VALUES($1,$2,$3,$4,$5,now())
|
||||
ON CONFLICT(id) DO UPDATE SET
|
||||
assessor_id = EXCLUDED.assessor_id,
|
||||
source_assessment_id = EXCLUDED.source_assessment_id,
|
||||
project_name = EXCLUDED.project_name,
|
||||
form = EXCLUDED.form,
|
||||
updated_at = now()
|
||||
RETURNING id, assessor_id, source_assessment_id, project_name, form, updated_at`,
|
||||
[
|
||||
input.id,
|
||||
input.assessorId ?? null,
|
||||
input.sourceAssessmentId ?? null,
|
||||
input.projectName ?? null,
|
||||
JSON.stringify(input.form ?? null),
|
||||
],
|
||||
);
|
||||
const r = (res.rows as Array<Record<string, unknown>>)[0]!;
|
||||
return {
|
||||
id: String(r.id),
|
||||
assessorId: r.assessor_id != null ? String(r.assessor_id) : null,
|
||||
sourceAssessmentId: r.source_assessment_id != null ? String(r.source_assessment_id) : null,
|
||||
projectName: r.project_name != null ? String(r.project_name) : null,
|
||||
form: r.form,
|
||||
updatedAt: isoOf(r.updated_at),
|
||||
};
|
||||
}
|
||||
|
||||
/** 删除草稿。 */
|
||||
export async function deleteDraft(pool: pg.Pool, id: string): Promise<void> {
|
||||
await pool.query('DELETE FROM wizard_drafts WHERE id = $1', [id]);
|
||||
}
|
||||
Reference in New Issue
Block a user