创建评查点分组的API文件
This commit is contained in:
+18
-9
@@ -58,17 +58,26 @@ export class ApiError extends Error {
|
||||
* 构建请求URL
|
||||
*/
|
||||
export function buildUrl(path: string, params?: Record<string, any>): string {
|
||||
const url = new URL(`${API_BASE_URL}${path}`);
|
||||
// 确保API_BASE_URL末尾没有斜杠,而path开头有斜杠
|
||||
const baseUrl = API_BASE_URL.endsWith('/') ? API_BASE_URL.slice(0, -1) : API_BASE_URL;
|
||||
const normalizedPath = path.startsWith('/') ? path : `/${path}`;
|
||||
|
||||
if (params) {
|
||||
Object.entries(params).forEach(([key, value]) => {
|
||||
if (value !== undefined && value !== null) {
|
||||
url.searchParams.append(key, String(value));
|
||||
}
|
||||
});
|
||||
try {
|
||||
const url = new URL(`${baseUrl}${normalizedPath}`);
|
||||
|
||||
if (params) {
|
||||
Object.entries(params).forEach(([key, value]) => {
|
||||
if (value !== undefined && value !== null) {
|
||||
url.searchParams.append(key, String(value));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return url.toString();
|
||||
} catch (error) {
|
||||
console.error('URL构建错误:', error);
|
||||
throw new Error(`无法构建URL: ${baseUrl}${normalizedPath}, 错误: ${error}`);
|
||||
}
|
||||
|
||||
return url.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+37
-14
@@ -14,8 +14,9 @@ export type ApiResponse<T> = {
|
||||
export type QueryParams = Record<string, string | number | boolean | undefined>;
|
||||
|
||||
// 获取 API 基础 URL
|
||||
const API_BASE_URL = '172.18.0.100:3000';
|
||||
// const API_BASE_URL = '172.18.0.100:3000';
|
||||
// const API_BASE_URL = '172.16.0.119:9000/admin';
|
||||
const API_BASE_URL = 'http://nas.7bm.co:3000';
|
||||
|
||||
// 是否使用模拟数据(开发环境使用)
|
||||
const USE_MOCK_DATA = false; // 设置为true使用模拟数据,避免API连接问题
|
||||
@@ -24,22 +25,36 @@ const USE_MOCK_DATA = false; // 设置为true使用模拟数据,避免API连
|
||||
* 构建完整的 API URL
|
||||
*/
|
||||
function buildUrl(endpoint: string, params?: QueryParams): string {
|
||||
// 创建 URL 字符串
|
||||
const url = new URL(
|
||||
endpoint.startsWith('http') ? endpoint : `http://${API_BASE_URL}${endpoint.startsWith('/') ? endpoint : `/${endpoint}`}`,
|
||||
typeof window !== 'undefined' ? window.location.origin : 'http://localhost:3000'
|
||||
);
|
||||
let fullUrl;
|
||||
|
||||
// 添加查询参数
|
||||
if (params) {
|
||||
Object.entries(params).forEach(([key, value]) => {
|
||||
if (value !== undefined) {
|
||||
url.searchParams.append(key, String(value));
|
||||
}
|
||||
});
|
||||
// 检查endpoint是否已经是完整URL
|
||||
if (endpoint.startsWith('http')) {
|
||||
fullUrl = endpoint;
|
||||
} else {
|
||||
// 确保API_BASE_URL格式正确
|
||||
const baseUrl = API_BASE_URL.endsWith('/') ? API_BASE_URL.slice(0, -1) : API_BASE_URL;
|
||||
const path = endpoint.startsWith('/') ? endpoint : `/${endpoint}`;
|
||||
fullUrl = `${baseUrl}${path}`;
|
||||
}
|
||||
|
||||
return url.toString();
|
||||
try {
|
||||
// 创建URL对象
|
||||
const url = new URL(fullUrl);
|
||||
|
||||
// 添加查询参数
|
||||
if (params) {
|
||||
Object.entries(params).forEach(([key, value]) => {
|
||||
if (value !== undefined) {
|
||||
url.searchParams.append(key, String(value));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return url.toString();
|
||||
} catch (error) {
|
||||
console.error('URL构建错误:', fullUrl, error);
|
||||
throw new Error(`无法构建URL: ${fullUrl}, 错误: ${error}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 超时控制
|
||||
@@ -48,6 +63,7 @@ const fetchWithTimeout = async (url: string, options: RequestInit, timeout = 500
|
||||
const id = setTimeout(() => controller.abort(), timeout);
|
||||
|
||||
try {
|
||||
console.log(`📦 API 端点: ${url}`);
|
||||
const response = await fetch(url, {
|
||||
...options,
|
||||
signal: controller.signal
|
||||
@@ -56,6 +72,13 @@ const fetchWithTimeout = async (url: string, options: RequestInit, timeout = 500
|
||||
return response;
|
||||
} catch (error) {
|
||||
clearTimeout(id);
|
||||
console.error(`📦 API请求失败: ${error}`);
|
||||
|
||||
// 检查是否是网络连接问题
|
||||
if (error instanceof TypeError && error.message.includes('fetch failed')) {
|
||||
console.error('网络连接错误,请检查API_BASE_URL配置是否正确');
|
||||
}
|
||||
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,249 @@
|
||||
import { postgrestGet, type PostgrestParams } from '../postgrest-client';
|
||||
|
||||
/**
|
||||
* 评查点分组接口
|
||||
*/
|
||||
export interface RuleGroup {
|
||||
id: string;
|
||||
pid: string;
|
||||
name: string;
|
||||
status: boolean;
|
||||
ruleCount?: number; // 评查点数量
|
||||
children?: RuleGroup[]; // 子分组
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取评查点分组列表
|
||||
* @returns 评查点分组列表
|
||||
*/
|
||||
export async function getRuleGroups(): Promise<{data: RuleGroup[]; error?: never} | {data?: never; error: string; status?: number}> {
|
||||
try {
|
||||
// 1. 获取所有一级分组(pid=0)
|
||||
const parentGroupsParams: PostgrestParams = {
|
||||
select: `
|
||||
id,
|
||||
pid,
|
||||
name,
|
||||
status
|
||||
`,
|
||||
filter: {
|
||||
'pid': 'eq.0'
|
||||
}
|
||||
};
|
||||
|
||||
const parentGroupsResponse = await postgrestGet<{code: number; msg: string; data: Array<{
|
||||
id: number;
|
||||
pid: number;
|
||||
name: string;
|
||||
status: boolean;
|
||||
}>}>('evaluation_point_groups', parentGroupsParams);
|
||||
|
||||
if (parentGroupsResponse.error) {
|
||||
return { error: parentGroupsResponse.error, status: parentGroupsResponse.status };
|
||||
}
|
||||
|
||||
// 处理响应数据
|
||||
let parentGroups: RuleGroup[] = [];
|
||||
if (parentGroupsResponse.data && 'code' in parentGroupsResponse.data && parentGroupsResponse.data.data) {
|
||||
parentGroups = parentGroupsResponse.data.data.map(group => ({
|
||||
id: group.id.toString(),
|
||||
pid: group.pid.toString(),
|
||||
name: group.name,
|
||||
status: group.status,
|
||||
children: [] // 初始化子分组数组
|
||||
}));
|
||||
} else if (Array.isArray(parentGroupsResponse.data)) {
|
||||
parentGroups = parentGroupsResponse.data.map(group => ({
|
||||
id: group.id.toString(),
|
||||
pid: group.pid.toString(),
|
||||
name: group.name,
|
||||
status: group.status,
|
||||
children: [] // 初始化子分组数组
|
||||
}));
|
||||
}
|
||||
|
||||
return { data: parentGroups };
|
||||
} catch (error) {
|
||||
console.error('获取评查点分组列表出错:', error);
|
||||
return {
|
||||
error: error instanceof Error ? error.message : '获取评查点分组列表失败',
|
||||
status: 500
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定分组的子分组
|
||||
* @param parentId 父分组ID
|
||||
* @returns 子分组列表
|
||||
*/
|
||||
export async function getChildGroups(parentId: string): Promise<{data: RuleGroup[]; error?: never} | {data?: never; error: string; status?: number}> {
|
||||
try {
|
||||
// 1. 获取子分组
|
||||
const childGroupsParams: PostgrestParams = {
|
||||
select: `
|
||||
id,
|
||||
pid,
|
||||
name,
|
||||
status
|
||||
`,
|
||||
filter: {
|
||||
'pid': `eq.${parentId}`
|
||||
}
|
||||
};
|
||||
|
||||
const childGroupsResponse = await postgrestGet<{code: number; msg: string; data: Array<{
|
||||
id: number;
|
||||
pid: number;
|
||||
name: string;
|
||||
status: boolean;
|
||||
}>}>('evaluation_point_groups', childGroupsParams);
|
||||
|
||||
if (childGroupsResponse.error) {
|
||||
return { error: childGroupsResponse.error, status: childGroupsResponse.status };
|
||||
}
|
||||
|
||||
// 2. 获取每个子分组的评查点数量
|
||||
let childGroups: RuleGroup[] = [];
|
||||
if (childGroupsResponse.data && 'code' in childGroupsResponse.data && childGroupsResponse.data.data) {
|
||||
childGroups = await Promise.all(childGroupsResponse.data.data.map(async group => {
|
||||
// 获取该分组的评查点数量
|
||||
const ruleCountParams: PostgrestParams = {
|
||||
select: 'id',
|
||||
filter: {
|
||||
'evaluation_point_groups_id': `eq.${group.id}`
|
||||
}
|
||||
};
|
||||
|
||||
const ruleCountResponse = await postgrestGet<{code: number; msg: string; data: Array<{id: number}>}>('evaluation_points', ruleCountParams);
|
||||
|
||||
return {
|
||||
id: group.id.toString(),
|
||||
pid: group.pid.toString(),
|
||||
name: group.name,
|
||||
status: group.status,
|
||||
ruleCount: ruleCountResponse.data && 'code' in ruleCountResponse.data
|
||||
? ruleCountResponse.data.data?.length || 0
|
||||
: Array.isArray(ruleCountResponse.data)
|
||||
? ruleCountResponse.data.length
|
||||
: 0
|
||||
};
|
||||
}));
|
||||
} else if (Array.isArray(childGroupsResponse.data)) {
|
||||
childGroups = await Promise.all(childGroupsResponse.data.map(async group => {
|
||||
// 获取该分组的评查点数量
|
||||
const ruleCountParams: PostgrestParams = {
|
||||
select: 'id',
|
||||
filter: {
|
||||
'evaluation_point_groups_id': `eq.${group.id}`
|
||||
}
|
||||
};
|
||||
|
||||
const ruleCountResponse = await postgrestGet<{code: number; msg: string; data: Array<{id: number}>}>('evaluation_points', ruleCountParams);
|
||||
|
||||
return {
|
||||
id: group.id.toString(),
|
||||
pid: group.pid.toString(),
|
||||
name: group.name,
|
||||
status: group.status,
|
||||
ruleCount: ruleCountResponse.data && 'code' in ruleCountResponse.data
|
||||
? ruleCountResponse.data.data?.length || 0
|
||||
: Array.isArray(ruleCountResponse.data)
|
||||
? ruleCountResponse.data.length
|
||||
: 0
|
||||
};
|
||||
}));
|
||||
}
|
||||
|
||||
return { data: childGroups };
|
||||
} catch (error) {
|
||||
console.error('获取子分组列表出错:', error);
|
||||
return {
|
||||
error: error instanceof Error ? error.message : '获取子分组列表失败',
|
||||
status: 500
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有评查点分组(包括一级和二级)
|
||||
* @returns 完整的评查点分组列表
|
||||
*/
|
||||
export async function getAllRuleGroups(): Promise<{data: RuleGroup[]; error?: never} | {data?: never; error: string; status?: number}> {
|
||||
try {
|
||||
// 1. 获取所有分组
|
||||
const allGroupsParams: PostgrestParams = {
|
||||
select: `
|
||||
id,
|
||||
pid,
|
||||
name,
|
||||
status
|
||||
`
|
||||
};
|
||||
|
||||
const allGroupsResponse = await postgrestGet<{code: number; msg: string; data: Array<{
|
||||
id: number;
|
||||
pid: number;
|
||||
name: string;
|
||||
status: boolean;
|
||||
}>}>('evaluation_point_groups', allGroupsParams);
|
||||
|
||||
if (allGroupsResponse.error) {
|
||||
return { error: allGroupsResponse.error, status: allGroupsResponse.status };
|
||||
}
|
||||
|
||||
// 2. 处理响应数据
|
||||
let allGroups: RuleGroup[] = [];
|
||||
if (allGroupsResponse.data && 'code' in allGroupsResponse.data && allGroupsResponse.data.data) {
|
||||
allGroups = allGroupsResponse.data.data.map(group => ({
|
||||
id: group.id.toString(),
|
||||
pid: group.pid.toString(),
|
||||
name: group.name,
|
||||
status: group.status,
|
||||
children: []
|
||||
}));
|
||||
} else if (Array.isArray(allGroupsResponse.data)) {
|
||||
allGroups = allGroupsResponse.data.map(group => ({
|
||||
id: group.id.toString(),
|
||||
pid: group.pid.toString(),
|
||||
name: group.name,
|
||||
status: group.status,
|
||||
children: []
|
||||
}));
|
||||
}
|
||||
|
||||
// 3. 构建树形结构
|
||||
const parentGroups = allGroups.filter(group => group.pid === '0');
|
||||
|
||||
// 4. 为每个父分组添加子分组
|
||||
for (const parent of parentGroups) {
|
||||
parent.children = allGroups.filter(group => group.pid === parent.id);
|
||||
|
||||
// 5. 获取每个子分组的评查点数量
|
||||
for (const child of parent.children) {
|
||||
const ruleCountParams: PostgrestParams = {
|
||||
select: 'id',
|
||||
filter: {
|
||||
'evaluation_point_groups_id': `eq.${child.id}`
|
||||
}
|
||||
};
|
||||
|
||||
const ruleCountResponse = await postgrestGet<{code: number; msg: string; data: Array<{id: number}>}>('evaluation_points', ruleCountParams);
|
||||
|
||||
child.ruleCount = ruleCountResponse.data && 'code' in ruleCountResponse.data
|
||||
? ruleCountResponse.data.data?.length || 0
|
||||
: Array.isArray(ruleCountResponse.data)
|
||||
? ruleCountResponse.data.length
|
||||
: 0;
|
||||
}
|
||||
}
|
||||
|
||||
return { data: parentGroups };
|
||||
} catch (error) {
|
||||
console.error('获取所有评查点分组出错:', error);
|
||||
return {
|
||||
error: error instanceof Error ? error.message : '获取所有评查点分组失败',
|
||||
status: 500
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -25,10 +25,14 @@ export interface PostgrestParams {
|
||||
function logPostgrestQuery(endpoint: string, params?: QueryParams): void {
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
// const baseUrl = 'http://172.16.0.119:9000/admin';
|
||||
const baseUrl = 'http://172.18.0.100:3000';
|
||||
// const baseUrl = 'http://172.18.0.100:3000';
|
||||
const baseUrl = 'http://nas.7bm.co:3000';
|
||||
|
||||
// 确保 endpoint 格式正确
|
||||
const normalizedEndpoint = endpoint.startsWith('/') ? endpoint.substring(1) : endpoint;
|
||||
|
||||
console.log('\n📦 PostgREST 查询日志 ========================');
|
||||
console.log(`📦 API 端点: ${baseUrl}/${endpoint}`);
|
||||
console.log(`📦 API 端点: ${baseUrl}/${normalizedEndpoint}`);
|
||||
|
||||
if (params && Object.keys(params).length > 0) {
|
||||
console.log('📦 查询参数:');
|
||||
@@ -67,7 +71,7 @@ function logPostgrestQuery(endpoint: string, params?: QueryParams): void {
|
||||
})
|
||||
.join('&');
|
||||
|
||||
console.log(`\n📦 可读URL: ${baseUrl}/${endpoint}${readableQueryString ? '?' + readableQueryString : ''}`);
|
||||
console.log(`\n📦 可读URL: ${baseUrl}/${normalizedEndpoint}${readableQueryString ? '?' + readableQueryString : ''}`);
|
||||
|
||||
// 格式化查询为 PostgreSQL 风格的查询
|
||||
let postgrestQuery = `SELECT `;
|
||||
@@ -78,7 +82,7 @@ function logPostgrestQuery(endpoint: string, params?: QueryParams): void {
|
||||
postgrestQuery += '*';
|
||||
}
|
||||
|
||||
postgrestQuery += ` FROM ${endpoint}`;
|
||||
postgrestQuery += ` FROM ${normalizedEndpoint}`;
|
||||
|
||||
const conditions: string[] = [];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user