import { API_BASE_URL } from '~/config/api-config'; import { getUserSession } from '~/api/login/auth.server'; import { buildRuleYamlPack, EMPTY_RULE_YAML, type RuleSummary, type RuleYamlPack, } from './rules-yaml-mock.server'; type RuleConfigPackApi = { packId: number; groupId: number; rootGroupId?: number | null; bindingId?: number | null; ruleSetId?: number | null; ruleType?: string | null; ruleName?: string | null; currentVersionId?: number | null; fallbackVersionId?: number | null; resolvedVersionId?: number | null; hasUsableVersion?: boolean; usableRuleCount?: number; documentTypeId?: number | null; documentType?: string; moduleType?: string; mainType?: string; subtype?: string; yamlText?: string; sourceStatus?: 'ready' | 'empty' | 'missing'; }; export type RuleConfigPackSummary = { id: string; documentType: string; moduleType: string; mainType: string; subtype: string; businessType: string; ruleTypeCode: string; currentVersionId?: number | null; fallbackVersionId?: number | null; resolvedVersionId?: number | null; yamlName: string; sourceStatus: 'ready' | 'empty' | 'missing'; rules: RuleSummary[]; }; type ApiEnvelope = { code?: number; message?: string; msg?: string; data?: T; }; export type RuleVersionItem = { id: number; ruleSetId: number; versionNo: string; status: string; ossUrl: string; changeNote?: string | null; publishedAt?: string | null; }; function getMessage(payload: unknown, fallback: string): string { if (!payload || typeof payload !== 'object') { return fallback; } return String((payload as ApiEnvelope).message || (payload as ApiEnvelope).msg || fallback); } function mapApiPackSummary(item: RuleConfigPackApi & { yamlName?: string; rules?: RuleSummary[] }): RuleConfigPackSummary { const ruleTypeCode = String(item.ruleType || '').trim(); const businessType = item.mainType || item.documentType || ''; return { id: String(item.packId), documentType: item.documentType || '', moduleType: item.moduleType || (item.documentType ? `${item.documentType}评查` : '规则配置'), mainType: item.mainType || item.documentType || '', subtype: item.subtype || '通用', businessType, ruleTypeCode, currentVersionId: item.currentVersionId ?? null, fallbackVersionId: item.fallbackVersionId ?? null, resolvedVersionId: item.resolvedVersionId ?? null, yamlName: String(item.yamlName || item.ruleName || ''), sourceStatus: item.sourceStatus || 'empty', rules: Array.isArray(item.rules) ? item.rules : [], }; } function mapApiPackToRuleYamlPack(item: RuleConfigPackApi): RuleYamlPack { const ruleTypeCode = String(item.ruleType || '').trim(); // 业务类型必须以后端 pack 聚合返回的 mainType 为准。 // 不能再从 ruleType 第二段硬拆;例如 contract.entrust 会被错误显示成 entrust。 const businessType = item.mainType || item.documentType || ''; const yamlSource = (item.yamlText || '').trim() ? String(item.yamlText) : EMPTY_RULE_YAML; const sourceStatus = item.sourceStatus || ((item.yamlText || '').trim() ? 'ready' : 'empty'); return buildRuleYamlPack( { id: String(item.packId), yamlPath: null, documentType: item.documentType || '', moduleType: item.moduleType || (item.documentType ? `${item.documentType}评查` : '规则配置'), mainType: item.mainType || item.documentType || '', subtype: item.subtype || '通用', businessType, ruleTypeCode, currentVersionId: item.currentVersionId ?? null, fallbackVersionId: item.fallbackVersionId ?? null, resolvedVersionId: item.resolvedVersionId ?? null, }, yamlSource, sourceStatus, ); } async function fetchRuleConfigPayload(request: Request, path: string): Promise { const { frontendJWT } = await getUserSession(request); if (!frontendJWT) { throw new Response('未登录或会话已失效', { status: 401 }); } const response = await fetch(`${API_BASE_URL}${path}`, { method: 'GET', headers: { Authorization: `Bearer ${frontendJWT}`, Accept: 'application/json', }, }); const payload = (await response.json()) as ApiEnvelope; if (!response.ok || typeof payload.data === 'undefined' || payload.data === null) { throw new Response(getMessage(payload, '规则配置加载失败'), { status: response.status || 500 }); } return payload.data; } export async function loadRuleConfigPackSummaries(request: Request): Promise { const items = await fetchRuleConfigPayload>(request, '/api/v3/rule-config-packs?summaryOnly=true'); return items.map(mapApiPackSummary); } export async function loadRuleConfigPacks(request: Request): Promise { const items = await fetchRuleConfigPayload(request, '/api/v3/rule-config-packs'); return items.map(mapApiPackToRuleYamlPack); } export async function loadRuleConfigPack(request: Request, packId: string): Promise { if (!packId) { const packs = await loadRuleConfigPacks(request); return packs[0]; } const item = await fetchRuleConfigPayload(request, `/api/v3/rule-config-packs/${encodeURIComponent(packId)}`); return mapApiPackToRuleYamlPack(item); } export async function loadRuleConfigVersions(request: Request, ruleType: string): Promise { if (!ruleType) { return []; } return fetchRuleConfigPayload(request, `/api/rule-sets/${encodeURIComponent(ruleType)}/versions`); }