feat(evaluation): 模块2.1 - 增强评查点查询接口和新增统计接口

功能变更:
1. 增强 getRulesList 函数
   - 添加风险等级筛选参数 (risk: '高' | '中' | '低')
   - 支持按风险等级精确筛选评查点
   - 保持现有分页、关键词搜索、分组筛选等功能

2. 新增 getRuleStatistics 函数
   - 返回评查点总数 (total_count)
   - 返回启用/禁用数量 (enabled_count, disabled_count)
   - 返回按风险等级分组统计 (by_risk: {low, medium, high})
   - 返回按规则组分组统计 (by_group: [{group_id, group_name, count}])
   - 规则组统计按数量降序排序

技术实现:
- 使用 PostgREST 客户端进行数据查询
- 处理不同端口API响应格式差异
- Map数据结构优化分组统计性能
- 批量查询规则组名称避免N+1查询问题

符合实施计划:
- 阶段 2.1:评查点查询接口对接 
- 所有验收标准已满足

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-11-25 12:21:44 +08:00
parent 7f1a05107f
commit aaa4046c41
+152 -2
View File
@@ -28,8 +28,9 @@ function extractApiData<T>(responseData: unknown): T | null {
export interface RulesQueryParams {
page?: number;
pageSize?: number;
ruleType?: string; // 评查点类型ID
groupId?: string; // 规则组ID
ruleType?: string; // 评查点类型ID (一级分组ID)
groupId?: string; // 规则组ID (二级分组ID)
risk?: '高' | '中' | '低'; // 风险等级
isActive?: boolean;
keyword?: string;
area?: string; // 地区过滤
@@ -187,6 +188,7 @@ export async function getRulesList(params: RulesQueryParams): Promise<{data: Rul
pageSize = 10,
ruleType,
groupId,
risk,
isActive,
keyword,
area,
@@ -254,6 +256,11 @@ export async function getRulesList(params: RulesQueryParams): Promise<{data: Rul
postgrestParams.filter!['evaluation_point_groups_id'] = `eq.${groupId}`;
}
// 添加风险等级筛选
if (risk) {
postgrestParams.filter!['risk'] = `eq.${risk}`;
}
if (isActive !== undefined) {
postgrestParams.filter!['is_enabled'] = `eq.${isActive}`;
}
@@ -1524,3 +1531,146 @@ export async function saveEvaluationPoint(evaluationPoint: EvaluationPointInput,
};
}
}
/**
* 评查点统计信息
*/
export interface RuleStatistics {
total_count: number; // 总评查点数
enabled_count: number; // 已启用数量
disabled_count: number; // 已禁用数量
by_risk: { // 按风险等级分组
low: number; // 低风险数量
medium: number; // 中风险数量
high: number; // 高风险数量
};
by_group: Array<{ // 按规则组分组
group_id: number;
group_name: string;
count: number;
}>;
}
/**
* 获取评查点统计信息
* @param token JWT token (可选)
* @returns 评查点统计数据
*/
export async function getRuleStatistics(token?: string): Promise<{data: RuleStatistics; error?: never} | {data?: never; error: string; status?: number}> {
try {
// 1. 获取所有评查点基本数据(不需要分页)
const postgrestParams: PostgrestParams = {
select: 'id,is_enabled,risk,evaluation_point_groups_id',
token
};
const response = await postgrestGet<{code: number; msg: string; data: Array<{
id: number;
is_enabled: boolean;
risk: string;
evaluation_point_groups_id: number | null;
}>}>('evaluation_points', postgrestParams);
// 检查是否有错误响应
if (response.error) {
return { error: response.error, status: response.status };
}
// 提取数据
let evaluationPoints: Array<{
id: number;
is_enabled: boolean;
risk: string;
evaluation_point_groups_id: number | null;
}> = [];
if (response.data && 'code' in response.data && response.data.data) {
if (Array.isArray(response.data.data)) {
evaluationPoints = response.data.data;
}
} else if (Array.isArray(response.data)) {
evaluationPoints = response.data;
}
// 2. 计算基础统计
const totalCount = evaluationPoints.length;
const enabledCount = evaluationPoints.filter(p => p.is_enabled).length;
const disabledCount = totalCount - enabledCount;
// 3. 按风险等级统计
const byRisk = {
low: evaluationPoints.filter(p => p.risk === '低').length,
medium: evaluationPoints.filter(p => p.risk === '中').length,
high: evaluationPoints.filter(p => p.risk === '高').length
};
// 4. 按规则组统计
const groupCountMap = new Map<number, number>();
evaluationPoints.forEach(point => {
if (point.evaluation_point_groups_id !== null) {
const currentCount = groupCountMap.get(point.evaluation_point_groups_id) || 0;
groupCountMap.set(point.evaluation_point_groups_id, currentCount + 1);
}
});
// 5. 获取规则组名称
const groupIds = Array.from(groupCountMap.keys());
const byGroup: Array<{
group_id: number;
group_name: string;
count: number;
}> = [];
if (groupIds.length > 0) {
// 批量查询规则组信息
const groupsParams: PostgrestParams = {
select: 'id,name',
filter: {
'id': `in.(${groupIds.join(',')})`
},
token
};
const groupsResponse = await postgrestGet<{code: number; msg: string; data: Array<{id: number; name: string}>}>('evaluation_point_groups', groupsParams);
let groups: Array<{id: number; name: string}> = [];
if (groupsResponse.data && 'code' in groupsResponse.data && groupsResponse.data.data) {
if (Array.isArray(groupsResponse.data.data)) {
groups = groupsResponse.data.data;
}
} else if (Array.isArray(groupsResponse.data)) {
groups = groupsResponse.data;
}
// 组合统计数据
groups.forEach(group => {
byGroup.push({
group_id: group.id,
group_name: group.name,
count: groupCountMap.get(group.id) || 0
});
});
// 按数量降序排序
byGroup.sort((a, b) => b.count - a.count);
}
// 返回统计结果
const statistics: RuleStatistics = {
total_count: totalCount,
enabled_count: enabledCount,
disabled_count: disabledCount,
by_risk: byRisk,
by_group: byGroup
};
return { data: statistics };
} catch (error) {
console.error('获取评查点统计信息失败:', error);
return {
error: error instanceof Error ? error.message : '获取评查点统计信息失败',
status: 500
};
}
}