feat: 1. 完善全局路由的访问权限的验证。 2. 完善接口返回的树形路由结构 3.优化评查点列表的查询,改用表连接的方式,废弃使用数据库的rpc函数,同时进行地区隔离和权限隔离。
4. 删除冗余的评查文件列表。 5.完善上传文档 页面初始化查询数据的时候 查询文件类型(改成动态指定) 6. 添加获取入口模块的查询接口。 7.完善服务端中判断token的有效性,失效则跳转到登录页。 8. 重构layout和sidebar的页面,改成由动态权限路由来渲染对应的菜单栏。 9.重构入口页面,通过动态查询根据不同地区的人返回不同的入口。
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
import { postgrestPut, postgrestPost } from '../postgrest-client';
|
||||
import { formatDate } from '../../utils';
|
||||
import { postgrestPut } from '../postgrest-client';
|
||||
|
||||
// 文档数据库表接口
|
||||
export interface Document {
|
||||
@@ -62,32 +61,6 @@ export interface ReviewFileUI {
|
||||
manualCount: number;
|
||||
}
|
||||
|
||||
// 数据库函数返回的评查文件结构
|
||||
interface ReviewFileFromSQL {
|
||||
id: number;
|
||||
status: string;
|
||||
path: string;
|
||||
file_name: string;
|
||||
file_code: string;
|
||||
file_type_name: string;
|
||||
file_type_id: number;
|
||||
file_size: number;
|
||||
upload_time: string;
|
||||
created_at: string;
|
||||
evaluations_status: number;
|
||||
audit_status: number | null;
|
||||
created_by_user_id: number | null;
|
||||
issue_count: number;
|
||||
total_score: number;
|
||||
pass_count: number;
|
||||
warning_count: number;
|
||||
fail_count: number;
|
||||
manual_count: number;
|
||||
issues: Array<{
|
||||
severity: 'info' | 'warning' | 'error' | 'critical';
|
||||
message: string;
|
||||
}> | null;
|
||||
}
|
||||
|
||||
// 文件列表搜索参数
|
||||
export interface DocumentSearchParams {
|
||||
@@ -133,183 +106,7 @@ export function mapUIToReviewStatus(status: string): number {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取文件扩展名
|
||||
* @param fileName 文件名
|
||||
* @returns 文件扩展名
|
||||
*/
|
||||
export function getFileExtension(fileName: string): string {
|
||||
return fileName.split('.').pop()?.toLowerCase() || '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取评查文件列表
|
||||
* @param searchParams 搜索参数
|
||||
* @param documentIds 文档ID数组(可选)
|
||||
* @param userId 用户ID
|
||||
* @returns 评查文件列表和总数
|
||||
*/
|
||||
export async function getReviewFiles(searchParams: DocumentSearchParams = {}, documentIds: number[] | null = null, userId?: string): Promise<{
|
||||
data?: { files: ReviewFileUI[], total: number };
|
||||
error?: string;
|
||||
status?: number;
|
||||
}> {
|
||||
try {
|
||||
// 确保userId必须存在,如果不存在则抛出错误
|
||||
if (!userId) {
|
||||
return { error: '用户身份验证失败,无法获取评查文件列表', status: 401 };
|
||||
}
|
||||
|
||||
const {
|
||||
page = 1,
|
||||
pageSize = 10,
|
||||
keyword,
|
||||
fileType, // sessionStorage.getItem('reviewType')
|
||||
reviewStatus,
|
||||
dateFrom,
|
||||
dateTo,
|
||||
sortOrder = 'upload_time_desc'
|
||||
} = searchParams;
|
||||
|
||||
let p_typeid: number[] | null = null;
|
||||
if (fileType) {
|
||||
if (fileType === 'record') {
|
||||
p_typeid = [2, 3, 155];
|
||||
} else if (fileType === 'contract') {
|
||||
p_typeid = [1];
|
||||
} else {
|
||||
const typeId = parseInt(fileType, 10);
|
||||
if (!isNaN(typeId)) {
|
||||
p_typeid = [typeId];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const rpcParams = {
|
||||
p_keyword: keyword || null,
|
||||
p_typeid: p_typeid,
|
||||
p_evaluations_status: reviewStatus ? mapUIToReviewStatus(reviewStatus) : null,
|
||||
p_date_from: dateFrom || null,
|
||||
p_date_to: dateTo || null,
|
||||
p_document_ids: documentIds || null,
|
||||
p_user_id: parseInt(userId, 10), // 强制要求传递用户ID
|
||||
};
|
||||
|
||||
const listParams = {
|
||||
...rpcParams,
|
||||
p_page: page,
|
||||
p_page_size: pageSize,
|
||||
p_sort_order: sortOrder
|
||||
};
|
||||
|
||||
// 并行执行获取数据和获取总数的请求
|
||||
const [filesResponse, countResponse] = await Promise.all([
|
||||
postgrestPost<ReviewFileFromSQL[]>('rpc/get_review_files_with_details', listParams),
|
||||
postgrestPost<number>('rpc/count_review_files', rpcParams)
|
||||
]);
|
||||
|
||||
// 处理获取文档列表的错误
|
||||
if (filesResponse.error || !filesResponse.data) {
|
||||
return { error: filesResponse.error || '获取文档数据失败', status: filesResponse.status || 500 };
|
||||
}
|
||||
|
||||
// 处理获取总数的错误
|
||||
if (countResponse.error || typeof countResponse.data !== 'number') {
|
||||
console.error('获取文档总数失败:', countResponse.error);
|
||||
}
|
||||
|
||||
const totalCount = typeof countResponse.data === 'number' ? countResponse.data : 0;
|
||||
|
||||
// 将SQL返回的数据转换为UI格式
|
||||
const reviewFiles: ReviewFileUI[] = filesResponse.data.map((file: ReviewFileFromSQL) => ({
|
||||
id: file.id.toString(),
|
||||
status: file.status,
|
||||
path: file.path,
|
||||
fileName: file.file_name,
|
||||
fileCode: file.file_code,
|
||||
fileType: file.file_type_name,
|
||||
fileTypeId: file.file_type_id,
|
||||
fileSize: file.file_size,
|
||||
uploadTime: formatDate(file.created_at),
|
||||
reviewStatus: mapReviewStatusToUI(file.evaluations_status),
|
||||
reviewStatusCode: file.evaluations_status,
|
||||
issueCount: file.issue_count,
|
||||
score: file.total_score,
|
||||
auditStatus: file.audit_status,
|
||||
issues: file.issues || [],
|
||||
createdBy: file.created_by_user_id?.toString() || '系统',
|
||||
passCount: file.pass_count,
|
||||
warningCount: file.warning_count,
|
||||
failCount: file.fail_count,
|
||||
manualCount: file.manual_count,
|
||||
}));
|
||||
|
||||
return {
|
||||
data: {
|
||||
files: reviewFiles,
|
||||
total: totalCount
|
||||
}
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('获取评查文件列表失败:', error);
|
||||
return {
|
||||
error: error instanceof Error ? error.message : '获取评查文件列表失败',
|
||||
status: 500
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新文件的评查状态
|
||||
* @param id 文件ID
|
||||
* @param status 评查状态
|
||||
* @returns 更新后的文件信息
|
||||
*/
|
||||
// export async function updateReviewStatus(id: string, status: string): Promise<{
|
||||
// data?: ReviewFileUI;
|
||||
// error?: string;
|
||||
// status?: number;
|
||||
// }> {
|
||||
// try {
|
||||
// if (!id) {
|
||||
// return { error: '文件ID不能为空', status: 400 };
|
||||
// }
|
||||
|
||||
// const statusValue = mapUIToReviewStatus(status);
|
||||
|
||||
// const response = await postgrestPut<Document, Partial<Document>>(
|
||||
// 'documents',
|
||||
// { evaluations_status: statusValue },
|
||||
// { id: parseInt(id) }
|
||||
// );
|
||||
|
||||
// if (response.error) {
|
||||
// return { error: response.error, status: response.status };
|
||||
// }
|
||||
|
||||
// const extractedData = extractApiData<Document>(response.data);
|
||||
|
||||
// if (!extractedData) {
|
||||
// return { error: '更新评查状态失败', status: 500 };
|
||||
// }
|
||||
|
||||
// // 获取文档类型,用于查找文档类型名称
|
||||
// const documentTypesResponse = await getDocumentTypes({pageSize: 500});
|
||||
// const documentTypes = documentTypesResponse.data?.types || [];
|
||||
|
||||
// // 查找文档类型名称
|
||||
// const docType = documentTypes.find((type: DocumentTypeUI) => type.id === extractedData.type_id);
|
||||
// const typeName = docType ? docType.name : '未知类型';
|
||||
|
||||
// return { data: convertToReviewFileUI(extractedData, typeName) };
|
||||
// } catch (error) {
|
||||
// console.error('更新评查状态失败:', error);
|
||||
// return {
|
||||
// error: error instanceof Error ? error.message : '更新评查状态失败',
|
||||
// status: 500
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
/**
|
||||
* 更新文件的审核状态
|
||||
|
||||
+212
-201
@@ -32,9 +32,10 @@ export interface RulesQueryParams {
|
||||
groupId?: string; // 规则组ID
|
||||
isActive?: boolean;
|
||||
keyword?: string;
|
||||
area?: string; // 地区过滤
|
||||
orderBy?: string;
|
||||
orderDirection?: 'asc' | 'desc';
|
||||
reviewType?: string; // 添加 reviewType 参数,值为 contract 或 record
|
||||
userRole?: string; // 用户角色
|
||||
token?: string; // JWT token
|
||||
}
|
||||
|
||||
@@ -53,6 +54,7 @@ export interface ApiRule {
|
||||
id: number;
|
||||
code: string;
|
||||
name: string;
|
||||
area?: string; // 地区
|
||||
evaluation_point_groups_id: number | null;
|
||||
risk: string;
|
||||
description: string;
|
||||
@@ -61,6 +63,15 @@ export interface ApiRule {
|
||||
first_name: string;
|
||||
second_name: string;
|
||||
};
|
||||
// 🆕 PostgREST 双连接查询返回的字段
|
||||
child_group?: {
|
||||
id: number;
|
||||
name: string;
|
||||
} | null;
|
||||
parent_group?: {
|
||||
id: number;
|
||||
name: string;
|
||||
} | null;
|
||||
references_laws: Record<string, unknown>;
|
||||
extraction_config: {
|
||||
type: string;
|
||||
@@ -118,27 +129,42 @@ function mapApiRuleToFrontendModel(apiRule: ApiRule): Rule {
|
||||
'低': 'low'
|
||||
};
|
||||
|
||||
//评查点类型映射
|
||||
// 🆕 优先使用 PostgREST 双连接查询返回的数据
|
||||
let ruleType = '';
|
||||
let groupName = '';
|
||||
let groupId = '';
|
||||
|
||||
// 规则类型映射(这里根据实际业务逻辑设置一个默认值)
|
||||
// const ruleType = 'essential'; // 实际应用中可能需要从其他字段推断
|
||||
// console.log("apiRule.evaluation_point_groups",apiRule);
|
||||
|
||||
// 如果evaluation_point_groups_id为null或空,则不显示ruleType和groupName
|
||||
const isGroupIdEmpty = !apiRule.evaluation_point_groups_id;
|
||||
|
||||
// 规则类型只在有分组ID时才显示
|
||||
const ruleType = isGroupIdEmpty ? '' : (apiRule.evaluation_point_groups?.first_name || '');
|
||||
if (apiRule.child_group || apiRule.parent_group) {
|
||||
// 有 PostgREST 双连接查询数据(外键约束方式)
|
||||
groupId = apiRule.child_group?.id.toString() || '';
|
||||
groupName = apiRule.child_group?.name || '';
|
||||
ruleType = apiRule.parent_group?.name || '';
|
||||
} else if (apiRule.evaluation_point_groups) {
|
||||
// 兼容旧的查询方式(RPC 函数或手动拼接)
|
||||
const isGroupIdEmpty = !apiRule.evaluation_point_groups_id;
|
||||
ruleType = isGroupIdEmpty ? '' : (apiRule.evaluation_point_groups.first_name || '');
|
||||
groupName = isGroupIdEmpty ? '' : (apiRule.evaluation_point_groups.second_name || `${apiRule.evaluation_point_groups_id}`);
|
||||
groupId = isGroupIdEmpty ? '' : apiRule.evaluation_point_groups_id?.toString() || '';
|
||||
} else {
|
||||
// 没有任何分组信息
|
||||
const isGroupIdEmpty = !apiRule.evaluation_point_groups_id;
|
||||
groupId = isGroupIdEmpty ? '' : apiRule.evaluation_point_groups_id?.toString() || '';
|
||||
}
|
||||
|
||||
// 🔑 清洗评查点编码:移除最后一个 '--' 及其后面的字符
|
||||
// 例如:'code-mis--mz' --> 'code-mis', 'code-mbs--alsi--gz' --> 'code-mbs--alsi'
|
||||
let cleanedCode = apiRule.code || '';
|
||||
const lastDoubleHyphenIndex = cleanedCode.lastIndexOf('--');
|
||||
if (lastDoubleHyphenIndex !== -1) {
|
||||
cleanedCode = cleanedCode.substring(0, lastDoubleHyphenIndex);
|
||||
}
|
||||
|
||||
// 规则组名称只在有分组ID时才显示
|
||||
const groupName = isGroupIdEmpty ? '' : (apiRule.evaluation_point_groups?.second_name || `${apiRule.evaluation_point_groups_id}`);
|
||||
|
||||
return {
|
||||
id: apiRule.id ? apiRule.id.toString() : '', // 添加空值检查
|
||||
code: apiRule.code || '',
|
||||
id: apiRule.id ? apiRule.id.toString() : '',
|
||||
code: cleanedCode,
|
||||
name: apiRule.name || '',
|
||||
ruleType: ruleType,
|
||||
groupId: isGroupIdEmpty ? '' : apiRule.evaluation_point_groups_id?.toString() || '',
|
||||
groupId: groupId,
|
||||
groupName: groupName,
|
||||
priority: priorityMap[apiRule.risk] || 'medium',
|
||||
description: apiRule.description || '',
|
||||
@@ -156,40 +182,63 @@ function mapApiRuleToFrontendModel(apiRule: ApiRule): Rule {
|
||||
export async function getRulesList(params: RulesQueryParams): Promise<{data: RulesListResponse; error?: never} | {data?: never; error: string; status?: number}> {
|
||||
try {
|
||||
// 解构并设置默认值
|
||||
const {
|
||||
page = 1,
|
||||
pageSize = 10,
|
||||
ruleType,
|
||||
groupId,
|
||||
isActive,
|
||||
const {
|
||||
page = 1,
|
||||
pageSize = 10,
|
||||
ruleType,
|
||||
groupId,
|
||||
isActive,
|
||||
keyword,
|
||||
area,
|
||||
orderBy = 'created_at',
|
||||
orderDirection = 'desc',
|
||||
reviewType,
|
||||
userRole,
|
||||
token
|
||||
} = params;
|
||||
|
||||
// 🔑 如果没有传递 userRole,尝试从 localStorage 中获取
|
||||
let user_role = ''
|
||||
if (!userRole && typeof window !== 'undefined' && window.localStorage) {
|
||||
try {
|
||||
const userInfoStr = localStorage.getItem('user_info');
|
||||
if (userInfoStr) {
|
||||
const userInfo = JSON.parse(userInfoStr);
|
||||
user_role = userInfo.user_role || userInfo.userRole;
|
||||
// console.log('📋 [getRulesList] 从 localStorage 获取用户角色:', userRole);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('❌ [getRulesList] 解析 localStorage 用户信息失败:', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 构建PostgrestParams参数
|
||||
const postgrestParams: PostgrestParams = {
|
||||
// 修改select语句,不使用嵌入查询语法
|
||||
// 🆕 使用 PostgREST 双连接查询(直接连接父子分组)
|
||||
// child_group: 通过 evaluation_point_groups_id 获取子分组(所属规则组)
|
||||
// parent_group: 通过 evaluation_point_groups_pid 直接获取父分组(评查点类型)
|
||||
// ⚠️ 重要:使用 .replace() 移除换行符,PostgREST 的 select 参数不支持多行字符串
|
||||
select: `
|
||||
id,
|
||||
code,
|
||||
name,
|
||||
area,
|
||||
evaluation_point_groups_id,
|
||||
evaluation_point_groups_pid,
|
||||
risk,
|
||||
description,
|
||||
is_enabled,
|
||||
created_at,
|
||||
updated_at
|
||||
`,
|
||||
updated_at,
|
||||
child_group:evaluation_point_groups!fk_evaluation_points_group(id,name),
|
||||
parent_group:evaluation_point_groups!fk_evaluation_points_parent_group(id,name)
|
||||
`.replace(/\s+/g, ' ').trim(),
|
||||
// 设置分页
|
||||
limit: pageSize,
|
||||
offset: (page - 1) * pageSize,
|
||||
|
||||
|
||||
// 设置排序
|
||||
order: `${orderBy}.${orderDirection}`,
|
||||
|
||||
|
||||
// 构建过滤条件
|
||||
filter: {},
|
||||
|
||||
@@ -204,62 +253,30 @@ export async function getRulesList(params: RulesQueryParams): Promise<{data: Rul
|
||||
if (groupId) {
|
||||
postgrestParams.filter!['evaluation_point_groups_id'] = `eq.${groupId}`;
|
||||
}
|
||||
|
||||
|
||||
if (isActive !== undefined) {
|
||||
postgrestParams.filter!['is_enabled'] = `eq.${isActive}`;
|
||||
}
|
||||
|
||||
// 根据reviewType添加过滤条件
|
||||
if (reviewType) {
|
||||
try {
|
||||
// 先获取所有评查点组数据,用于找到对应的pid
|
||||
const groupsAllResponse = await postgrestGet<{code: number; msg: string; data: Array<{id: number; pid: number; m_type: number}>}>('evaluation_point_groups', {
|
||||
select: 'id,pid,m_type',
|
||||
token
|
||||
});
|
||||
|
||||
let groups: Array<{id: number; pid: number; m_type: number}> = [];
|
||||
|
||||
if (!groupsAllResponse.error) {
|
||||
if (groupsAllResponse.data && 'code' in groupsAllResponse.data && groupsAllResponse.data.data) {
|
||||
groups = groupsAllResponse.data.data;
|
||||
} else if (Array.isArray(groupsAllResponse.data)) {
|
||||
groups = groupsAllResponse.data;
|
||||
}
|
||||
}
|
||||
|
||||
// 根据reviewType过滤pid
|
||||
let pidList: number[] = [];
|
||||
|
||||
if (reviewType === 'contract') {
|
||||
// 合同类型,找到所有pid=3的评查点组 2025/10/29: 修改为通过m_type = 0 去查找评查点组
|
||||
// const contractGroups = groups.filter(g => g.pid === 3).map(g => g.id);
|
||||
const contractGroups = groups.filter(g => g.m_type === 0).map(g => g.id);
|
||||
pidList = contractGroups;
|
||||
} else if (reviewType === 'record') {
|
||||
// 卷宗类型,找到所有pid=1或pid=2的评查点组 2025/10/29: 修改为通过m_type = 1 去查找评查点组
|
||||
// const recordGroups = groups.filter(g => g.pid === 1 || g.pid === 2).map(g => g.id);
|
||||
const recordGroups = groups.filter(g => g.m_type === 1).map(g => g.id);
|
||||
pidList = recordGroups;
|
||||
}
|
||||
|
||||
// 如果有过滤的组id,则添加到查询条件中
|
||||
if (pidList.length > 0) {
|
||||
postgrestParams.filter!['evaluation_point_groups_id'] = `in.(${pidList.join(',')})`;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取评查点组数据出错:', error);
|
||||
}
|
||||
|
||||
// 🔑 添加地区过滤
|
||||
if (user_role == 'provincial_admin') {
|
||||
postgrestParams.filter!['area'] = `eq.省级`;
|
||||
}else{
|
||||
postgrestParams.filter!['area'] = `eq.${area}`;
|
||||
}
|
||||
|
||||
|
||||
// 如果指定了评查点类型ID,需要先查询该类型下的所有规则组ID
|
||||
if (ruleType) {
|
||||
try {
|
||||
// 先获取该类型下的所有规则组
|
||||
// 🔑 检查是否为多个类型(逗号分隔)
|
||||
const isMultipleTypes = ruleType.includes(',');
|
||||
|
||||
// 先获取该类型(或多个类型)下的所有规则组
|
||||
const groupsParams: PostgrestParams = {
|
||||
select: 'id',
|
||||
filter: {
|
||||
'pid': `eq.${ruleType}`
|
||||
// 如果是多个类型,使用 in.(type1,type2),否则使用 eq.type
|
||||
'pid': isMultipleTypes ? `in.(${ruleType})` : `eq.${ruleType}`
|
||||
},
|
||||
token
|
||||
};
|
||||
@@ -311,7 +328,7 @@ export async function getRulesList(params: RulesQueryParams): Promise<{data: Rul
|
||||
if (response.error) {
|
||||
return { error: response.error, status: response.status };
|
||||
}
|
||||
|
||||
|
||||
// 处理不同的API响应格式
|
||||
let apiRules: ApiRule[] = [];
|
||||
let totalCount = 0;
|
||||
@@ -352,87 +369,18 @@ export async function getRulesList(params: RulesQueryParams): Promise<{data: Rul
|
||||
totalCount = apiRules.length;
|
||||
}
|
||||
|
||||
// 打印第一个数据项来查看结构(仅用于调试)
|
||||
// if (apiRules.length > 0) {
|
||||
// console.log('评查点数据示例:', JSON.stringify(apiRules[0], null, 2));
|
||||
// }
|
||||
|
||||
// 🆕 使用嵌套查询后,不再需要手动查询分组信息
|
||||
// PostgREST 的嵌套 select 已经自动关联了分组数据
|
||||
console.log('📋 [getRulesList] 使用 PostgREST 嵌套查询获取评查点数据');
|
||||
|
||||
// 收集所有规则分组ID(实际上是二级分组) (多进行一步查找表的操作)
|
||||
const groupIds = [...new Set(apiRules.map(rule => rule.evaluation_point_groups_id))];
|
||||
// 如果有分组ID,查询分组信息 - 更新类型定义
|
||||
const groupsMap: Record<string, {first_name: string; second_name: string}> = {};
|
||||
if (groupIds.length > 0) {
|
||||
try {
|
||||
// 过滤null和空值
|
||||
const validGroupIds = groupIds.filter(id => id != null && id.toString().trim() !== '');
|
||||
|
||||
if (validGroupIds.length > 0) {
|
||||
// 使用Promise.all并行查询所有分组信息 - 使用正确的函数名
|
||||
const groupPromises = validGroupIds.map(id =>
|
||||
postgrestGet<{code: number; msg: string; data: {id: number; pid: number; name: string; first_name: string; second_name: string}[]}>(
|
||||
`rpc/get_evaluation_point_group_with_pid?input_id=${id}`,
|
||||
{ token }
|
||||
)
|
||||
);
|
||||
|
||||
const groupResponses = await Promise.all(groupPromises);
|
||||
// console.log("groupResponsesdddddddddddddddddd",groupResponses);
|
||||
// 处理响应,填充groupsMap
|
||||
groupResponses.forEach((response) => {
|
||||
if (!response.error && response.data) {
|
||||
// 处理不同API响应格式
|
||||
if (Array.isArray(response.data.data) && response.data.data.length > 0) {
|
||||
const groupid = response.data.data[1]?.id || "";
|
||||
groupsMap[groupid] = {
|
||||
first_name: response.data.data[0]?.name || "",
|
||||
second_name: response.data.data[1]?.name || ""
|
||||
};
|
||||
}else if(Array.isArray(response.data) && response.data.length > 0){
|
||||
const groupid = response.data[1]?.id || "";
|
||||
groupsMap[groupid] = {
|
||||
first_name: response.data[0]?.name || "",
|
||||
second_name: response.data[1]?.name || ""
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取分组数据失败:', error);
|
||||
// 失败不阻止主流程,使用默认分组名
|
||||
}
|
||||
}
|
||||
|
||||
// 将API返回的数据映射到前端模型
|
||||
const mappedRules = apiRules.map(apiRule => {
|
||||
const rule = mapApiRuleToFrontendModel(apiRule);
|
||||
|
||||
// 应用本地过滤 - 只在API不支持的情况下使用
|
||||
const filteredRules = [...apiRules];
|
||||
// 不再需要本地过滤,因为已经在API层面添加了评查点类型过滤
|
||||
// 如果进行了本地过滤,则需要调整总记录数
|
||||
// if (ruleType) {
|
||||
// totalCount = filteredRules.length;
|
||||
// }
|
||||
|
||||
|
||||
// 将API返回的数据映射到前端模型,并附加分组名称
|
||||
// console.log("groupsMap",groupsMap);
|
||||
const mappedRules = filteredRules.map(apiRule => {
|
||||
// 创建修改版的apiRule,添加从分组映射获取的名称
|
||||
const enhancedApiRule = {
|
||||
...apiRule,
|
||||
// 从映射中获取分组名称,如果不存在则使用默认值
|
||||
evaluation_point_groups: {
|
||||
first_name: groupsMap[apiRule.evaluation_point_groups_id?.toString() || '']?.first_name || `${apiRule.evaluation_point_groups_id}`,
|
||||
second_name: groupsMap[apiRule.evaluation_point_groups_id?.toString() || '']?.second_name || `${apiRule.evaluation_point_groups_id}`
|
||||
}
|
||||
};
|
||||
|
||||
const rule = mapApiRuleToFrontendModel(enhancedApiRule);
|
||||
|
||||
// 格式化日期字段
|
||||
rule.createdAt = formatDate(rule.createdAt);
|
||||
rule.updatedAt = formatDate(rule.updatedAt);
|
||||
|
||||
|
||||
return rule;
|
||||
});
|
||||
|
||||
@@ -848,72 +796,134 @@ export interface RuleGroup {
|
||||
|
||||
/**
|
||||
* 获取评查点类型列表
|
||||
* @param reviewType 评查类型,contract表示合同,record表示卷宗
|
||||
* @param documentTypeIds 文档类型 ID 列表
|
||||
* @param token JWT token (可选)
|
||||
* @returns 评查点类型列表
|
||||
*/
|
||||
export async function getRuleTypes(reviewType?: string, token?: string): Promise<{data: RuleType[]; error?: never} | {data?: never; error: string; status?: number}> {
|
||||
export async function getRuleTypes(documentTypeIds?: number[], token?: string): Promise<{data: RuleType[]; error?: never} | {data?: never; error: string; status?: number}> {
|
||||
try {
|
||||
// 构建PostgrestParams参数
|
||||
const postgrestParams: PostgrestParams = {
|
||||
// 如果没有传入 documentTypeIds,返回空数组
|
||||
if (!documentTypeIds || documentTypeIds.length === 0) {
|
||||
console.warn('getRuleTypes: 未提供 documentTypeIds');
|
||||
return { data: [] };
|
||||
}
|
||||
|
||||
// 1️⃣ 根据 documentTypeIds 查询 document_types 表
|
||||
const typeIdsStr = documentTypeIds.join(',');
|
||||
const documentTypesParams: PostgrestParams = {
|
||||
select: 'id, name, evaluation_point_groups_ids',
|
||||
filter: {
|
||||
'id': `in.(${typeIdsStr})`
|
||||
},
|
||||
token
|
||||
};
|
||||
|
||||
const documentTypesResponse = await postgrestGet<{
|
||||
code: number;
|
||||
msg: string;
|
||||
data: Array<{
|
||||
id: number;
|
||||
name: string;
|
||||
evaluation_point_groups_ids: number[];
|
||||
}>
|
||||
}>('document_types', documentTypesParams);
|
||||
|
||||
if (documentTypesResponse.error) {
|
||||
return { error: documentTypesResponse.error, status: documentTypesResponse.status };
|
||||
}
|
||||
|
||||
// 提取 document_types 数据
|
||||
let documentTypesData: Array<{
|
||||
id: number;
|
||||
name: string;
|
||||
evaluation_point_groups_ids: number[];
|
||||
}> = [];
|
||||
|
||||
if (documentTypesResponse.data && 'code' in documentTypesResponse.data && documentTypesResponse.data.data) {
|
||||
if (Array.isArray(documentTypesResponse.data.data)) {
|
||||
documentTypesData = documentTypesResponse.data.data;
|
||||
}
|
||||
} else if (Array.isArray(documentTypesResponse.data)) {
|
||||
documentTypesData = documentTypesResponse.data as Array<{
|
||||
id: number;
|
||||
name: string;
|
||||
evaluation_point_groups_ids: number[];
|
||||
}>;
|
||||
}
|
||||
|
||||
if (documentTypesData.length === 0) {
|
||||
console.warn('getRuleTypes: 未找到对应的文档类型数据');
|
||||
return { data: [] };
|
||||
}
|
||||
|
||||
// 2️⃣ 提取并组合所有的 evaluation_point_groups_ids
|
||||
const allGroupIds = new Set<number>();
|
||||
documentTypesData.forEach(docType => {
|
||||
if (Array.isArray(docType.evaluation_point_groups_ids)) {
|
||||
docType.evaluation_point_groups_ids.forEach(id => allGroupIds.add(id));
|
||||
}
|
||||
});
|
||||
|
||||
if (allGroupIds.size === 0) {
|
||||
console.warn('getRuleTypes: 未找到评查点组 ID');
|
||||
return { data: [] };
|
||||
}
|
||||
|
||||
// console.log('📋 [getRuleTypes] 提取的评查点组 IDs:', Array.from(allGroupIds));
|
||||
|
||||
// 3️⃣ 根据组合后的 ID 查询 evaluation_point_groups 表
|
||||
const groupIdsStr = Array.from(allGroupIds).join(',');
|
||||
const groupsParams: PostgrestParams = {
|
||||
select: `
|
||||
id,
|
||||
pid,
|
||||
code,
|
||||
name,
|
||||
description,
|
||||
is_enabled,
|
||||
m_type
|
||||
is_enabled
|
||||
`,
|
||||
// 查询父ID为0的类型(顶级类型)
|
||||
filter: {
|
||||
'pid': 'eq.0'
|
||||
'id': `in.(${groupIdsStr})`,
|
||||
'pid': 'eq.0'
|
||||
},
|
||||
token
|
||||
};
|
||||
|
||||
// 根据 reviewType 添加过滤条件
|
||||
if (reviewType === 'contract') {
|
||||
// 如果是合同类型,只加载id=3的评查点类型 2025/10/29: 修改为通过m_type = 0 去查找评查点组
|
||||
postgrestParams.filter!['m_type'] = 'eq.0';
|
||||
} else if (reviewType === 'record') {
|
||||
// 如果是卷宗类型,只加载id=1和id=2的评查点类型 2025/10/29: 修改为通过m_type = 1 去查找评查点组
|
||||
postgrestParams.filter!['m_type'] = 'eq.1';
|
||||
}
|
||||
|
||||
// 发送请求获取评查点类型列表
|
||||
const response = await postgrestGet<{code: number; msg: string; data: Array<{
|
||||
id: number;
|
||||
pid: number;
|
||||
code: string;
|
||||
name: string;
|
||||
description: string;
|
||||
is_enabled: boolean;
|
||||
}>;
|
||||
}>('evaluation_point_groups', postgrestParams);
|
||||
|
||||
|
||||
const response = await postgrestGet<{
|
||||
code: number;
|
||||
msg: string;
|
||||
data: Array<{
|
||||
id: number;
|
||||
pid: number;
|
||||
code: string;
|
||||
name: string;
|
||||
description: string;
|
||||
is_enabled: boolean;
|
||||
}>
|
||||
}>('evaluation_point_groups', groupsParams);
|
||||
|
||||
// 检查是否有错误响应
|
||||
if (response.error) {
|
||||
return { error: response.error, status: response.status };
|
||||
}
|
||||
|
||||
if(response.data && 'code' in response.data && response.data.data){
|
||||
if(Array.isArray(response.data.data) && response.data.data.length > 0){
|
||||
// 将API返回的数据映射到前端模型
|
||||
const ruleTypes = response.data.data.map(item => ({
|
||||
id: item.id.toString(),
|
||||
pid: item.pid.toString(),
|
||||
code: item.code,
|
||||
name: item.name,
|
||||
description: item.description,
|
||||
isEnabled: item.is_enabled
|
||||
}));
|
||||
return { data: ruleTypes };
|
||||
}else{
|
||||
return { error: '9000接口返回数据格式不正确', status: 500 };
|
||||
|
||||
// 处理响应数据
|
||||
if (response.data && 'code' in response.data && response.data.data) {
|
||||
if (Array.isArray(response.data.data)) {
|
||||
const ruleTypes = response.data.data.map(item => ({
|
||||
id: item.id.toString(),
|
||||
pid: item.pid.toString(),
|
||||
code: item.code,
|
||||
name: item.name,
|
||||
description: item.description,
|
||||
isEnabled: item.is_enabled
|
||||
}));
|
||||
// console.log('📋 [getRuleTypes] 返回评查点类型:', ruleTypes);
|
||||
return { data: ruleTypes };
|
||||
} else {
|
||||
return { data: [] };
|
||||
}
|
||||
}else if(Array.isArray(response.data) && response.data.length > 0){
|
||||
// console.log("评查点类型列表",response.data);
|
||||
} else if (Array.isArray(response.data)) {
|
||||
const ruleTypes = response.data.map(item => ({
|
||||
id: item.id.toString(),
|
||||
pid: item.pid.toString(),
|
||||
@@ -922,13 +932,14 @@ export async function getRuleTypes(reviewType?: string, token?: string): Promise
|
||||
description: item.description,
|
||||
isEnabled: item.is_enabled
|
||||
}));
|
||||
// console.log('📋 [getRuleTypes] 返回评查点类型:', ruleTypes);
|
||||
return { data: ruleTypes };
|
||||
}else{
|
||||
return { error: '3000接口返回数据格式不正确', status: 500 };
|
||||
} else {
|
||||
return { data: [] };
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取评查点类型出错:', error);
|
||||
return {
|
||||
return {
|
||||
error: error instanceof Error ? error.message : '获取评查点类型失败',
|
||||
status: 500
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user