events filter
This commit is contained in:
@@ -9,8 +9,8 @@ export enum TimeGranularity {
|
||||
MONTH = 'month'
|
||||
}
|
||||
|
||||
// 获取事件列表
|
||||
export async function getEvents(params: {
|
||||
// 事件查询参数类型
|
||||
export interface EventsQueryParams {
|
||||
startTime?: string;
|
||||
endTime?: string;
|
||||
eventType?: string;
|
||||
@@ -19,11 +19,17 @@ export async function getEvents(params: {
|
||||
userId?: string;
|
||||
teamId?: string;
|
||||
projectId?: string;
|
||||
teamIds?: string[];
|
||||
projectIds?: string[];
|
||||
tagIds?: string[];
|
||||
page?: number;
|
||||
pageSize?: number;
|
||||
sortBy?: string;
|
||||
sortOrder?: 'asc' | 'desc';
|
||||
}): Promise<{ events: Event[]; total: number }> {
|
||||
}
|
||||
|
||||
// 获取事件列表
|
||||
export async function getEvents(params: EventsQueryParams): Promise<{ events: Event[]; total: number }> {
|
||||
const filter = buildFilter(params);
|
||||
const pagination = buildPagination(params.page, params.pageSize);
|
||||
const orderBy = buildOrderBy(params.sortBy, params.sortOrder);
|
||||
|
||||
@@ -28,95 +28,108 @@ function buildDateFilter(startTime?: string, endTime?: string): string {
|
||||
export function buildFilter(params: Partial<EventsQueryParams>): string {
|
||||
const filters = [];
|
||||
|
||||
// 时间范围过滤
|
||||
// 添加日期过滤条件
|
||||
if (params.startTime || params.endTime) {
|
||||
const dateFilter = buildDateFilter(params.startTime, params.endTime).replace('WHERE ', '');
|
||||
const dateFilter = buildDateFilter(params.startTime, params.endTime);
|
||||
if (dateFilter) {
|
||||
filters.push(dateFilter);
|
||||
filters.push(dateFilter.replace('WHERE ', ''));
|
||||
}
|
||||
}
|
||||
|
||||
// 事件类型过滤
|
||||
// 添加事件类型过滤条件
|
||||
if (params.eventType) {
|
||||
filters.push(`event_type = '${params.eventType}'`);
|
||||
}
|
||||
|
||||
// 链接ID过滤
|
||||
// 添加链接ID过滤条件
|
||||
if (params.linkId) {
|
||||
filters.push(`link_id = '${params.linkId}'`);
|
||||
}
|
||||
|
||||
// 链接短码过滤
|
||||
// 添加链接Slug过滤条件
|
||||
if (params.linkSlug) {
|
||||
filters.push(`link_slug = '${params.linkSlug}'`);
|
||||
}
|
||||
|
||||
// 用户ID过滤
|
||||
// 添加用户ID过滤条件
|
||||
if (params.userId) {
|
||||
filters.push(`user_id = '${params.userId}'`);
|
||||
}
|
||||
|
||||
// 团队ID过滤 - 支持多选
|
||||
if (params.teamIds && params.teamIds.length > 0) {
|
||||
const teamValues = params.teamIds.map(id => `'${id}'`).join(', ');
|
||||
filters.push(`team_id IN (${teamValues})`);
|
||||
} else if (params.teamId) {
|
||||
// 添加团队ID过滤条件
|
||||
if (params.teamId) {
|
||||
filters.push(`team_id = '${params.teamId}'`);
|
||||
}
|
||||
|
||||
// 项目ID过滤 - 支持多选
|
||||
if (params.projectIds && params.projectIds.length > 0) {
|
||||
const projectValues = params.projectIds.map(id => `'${id}'`).join(', ');
|
||||
filters.push(`project_id IN (${projectValues})`);
|
||||
} else if (params.projectId) {
|
||||
// 处理多个团队ID
|
||||
if (params.teamIds && params.teamIds.length > 0) {
|
||||
filters.push(`team_id IN (${params.teamIds.map(id => `'${id}'`).join(', ')})`);
|
||||
}
|
||||
|
||||
// 添加项目ID过滤条件
|
||||
if (params.projectId) {
|
||||
filters.push(`project_id = '${params.projectId}'`);
|
||||
}
|
||||
|
||||
// 标签ID过滤 - 支持多选
|
||||
// 处理多个项目ID
|
||||
if (params.projectIds && params.projectIds.length > 0) {
|
||||
filters.push(`project_id IN (${params.projectIds.map(id => `'${id}'`).join(', ')})`);
|
||||
}
|
||||
|
||||
// 处理标签过滤 - 使用LIKE来匹配标签字符串
|
||||
if (params.tagIds && params.tagIds.length > 0) {
|
||||
// 假设我们在link_tags字段存储标签ID的JSON数组
|
||||
const tagConditions = params.tagIds.map(id => `arrayExists(x -> x = '${id}', JSONExtractArrayRaw(link_tags))`);
|
||||
const tagConditions = params.tagIds.map(tag =>
|
||||
`link_tags LIKE '%${tag}%'`
|
||||
);
|
||||
filters.push(`(${tagConditions.join(' OR ')})`);
|
||||
}
|
||||
|
||||
return filters.length > 0 ? `WHERE ${filters.join(' AND ')}` : '';
|
||||
}
|
||||
|
||||
// 构建分页
|
||||
export function buildPagination(page?: number, pageSize?: number): string {
|
||||
const limit = pageSize || 20;
|
||||
const offset = ((page || 1) - 1) * limit;
|
||||
return `LIMIT ${limit} OFFSET ${offset}`;
|
||||
// 构建分页条件
|
||||
export function buildPagination(page: number = 1, pageSize: number = 20): string {
|
||||
const offset = (page - 1) * pageSize;
|
||||
return `LIMIT ${pageSize} OFFSET ${offset}`;
|
||||
}
|
||||
|
||||
// 构建排序
|
||||
export function buildOrderBy(sortBy?: string, sortOrder?: 'asc' | 'desc'): string {
|
||||
if (!sortBy) {
|
||||
return 'ORDER BY event_time DESC';
|
||||
}
|
||||
return `ORDER BY ${sortBy} ${sortOrder || 'desc'}`;
|
||||
// 构建排序条件
|
||||
export function buildOrderBy(sortBy: string = 'event_time', sortOrder: string = 'desc'): string {
|
||||
return `ORDER BY ${sortBy} ${sortOrder}`;
|
||||
}
|
||||
|
||||
// 执行查询并处理错误
|
||||
export async function executeQuery<T>(query: string): Promise<T[]> {
|
||||
// 执行查询
|
||||
export async function executeQuery(query: string) {
|
||||
console.log('执行查询:', query); // 查询日志
|
||||
try {
|
||||
const resultSet = await clickhouse.query({
|
||||
query,
|
||||
format: 'JSONEachRow'
|
||||
format: 'JSONEachRow',
|
||||
});
|
||||
|
||||
const rows = await resultSet.json<T>();
|
||||
return Array.isArray(rows) ? rows : [rows];
|
||||
const rows = await resultSet.json();
|
||||
return rows;
|
||||
} catch (error) {
|
||||
console.error('ClickHouse query error:', error);
|
||||
console.error('查询执行错误:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
// 执行查询并返回单个结果
|
||||
export async function executeQuerySingle<T>(query: string): Promise<T | null> {
|
||||
const results = await executeQuery<T>(query);
|
||||
return results.length > 0 ? results[0] : null;
|
||||
// 执行返回单一结果的查询
|
||||
export async function executeQuerySingle(query: string) {
|
||||
console.log('执行单一结果查询:', query); // 查询日志
|
||||
try {
|
||||
const resultSet = await clickhouse.query({
|
||||
query,
|
||||
format: 'JSONEachRow',
|
||||
});
|
||||
|
||||
const rows = await resultSet.json();
|
||||
return rows.length > 0 ? rows[0] : null;
|
||||
} catch (error) {
|
||||
console.error('单一结果查询执行错误:', error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export default clickhouse;
|
||||
10
lib/types.ts
10
lib/types.ts
@@ -24,6 +24,16 @@ export enum DeviceType {
|
||||
OTHER = 'other'
|
||||
}
|
||||
|
||||
// 标签类型
|
||||
export interface Tag {
|
||||
id: string;
|
||||
name: string;
|
||||
color?: string;
|
||||
type?: string;
|
||||
attributes?: Record<string, any>;
|
||||
team_id?: string;
|
||||
}
|
||||
|
||||
// API 响应基础接口
|
||||
export interface ApiResponse<T> {
|
||||
success: boolean;
|
||||
|
||||
Reference in New Issue
Block a user