180 lines
5.3 KiB
TypeScript
180 lines
5.3 KiB
TypeScript
/**
|
|
* 人群包服务
|
|
* 负责人群包管理相关的API调用
|
|
*/
|
|
|
|
import apiClient from '@/infrastructure/api/client';
|
|
import { API_ENDPOINTS } from '@/infrastructure/api/endpoints';
|
|
|
|
// =====================
|
|
// 类型定义
|
|
// =====================
|
|
|
|
/** 条件操作符 */
|
|
export type ConditionOperator =
|
|
| 'EQUALS'
|
|
| 'NOT_EQUALS'
|
|
| 'CONTAINS'
|
|
| 'NOT_CONTAINS'
|
|
| 'GREATER_THAN'
|
|
| 'LESS_THAN'
|
|
| 'BETWEEN'
|
|
| 'IN'
|
|
| 'NOT_IN'
|
|
| 'IS_NULL'
|
|
| 'IS_NOT_NULL'
|
|
| 'HAS_TAG'
|
|
| 'NOT_HAS_TAG';
|
|
|
|
/** 逻辑操作符 */
|
|
export type LogicOperator = 'AND' | 'OR';
|
|
|
|
/** 人群包状态 */
|
|
export type SegmentStatus = 'DRAFT' | 'ACTIVE' | 'ARCHIVED';
|
|
|
|
/** 条件项 */
|
|
export interface SegmentCondition {
|
|
field: string;
|
|
operator: ConditionOperator;
|
|
value?: string | number | boolean | string[];
|
|
}
|
|
|
|
/** 条件组 */
|
|
export interface SegmentConditionGroup {
|
|
logic: LogicOperator;
|
|
conditions: SegmentCondition[];
|
|
}
|
|
|
|
/** 人群包 */
|
|
export interface AudienceSegment {
|
|
id: string;
|
|
name: string;
|
|
description: string | null;
|
|
conditionGroups: SegmentConditionGroup[];
|
|
groupsLogic: LogicOperator;
|
|
status: SegmentStatus;
|
|
estimatedUsers: number | null;
|
|
lastRefreshedAt: string | null;
|
|
isEnabled: boolean;
|
|
createdAt: string;
|
|
updatedAt: string;
|
|
createdBy: string;
|
|
}
|
|
|
|
/** 创建人群包请求 */
|
|
export interface CreateSegmentRequest {
|
|
name: string;
|
|
description?: string;
|
|
conditionGroups: SegmentConditionGroup[];
|
|
groupsLogic?: LogicOperator;
|
|
}
|
|
|
|
/** 更新人群包请求 */
|
|
export interface UpdateSegmentRequest {
|
|
name?: string;
|
|
description?: string;
|
|
conditionGroups?: SegmentConditionGroup[];
|
|
groupsLogic?: LogicOperator;
|
|
status?: SegmentStatus;
|
|
isEnabled?: boolean;
|
|
}
|
|
|
|
/** 人群包列表查询参数 */
|
|
export interface ListSegmentsParams {
|
|
status?: SegmentStatus;
|
|
isEnabled?: boolean;
|
|
limit?: number;
|
|
offset?: number;
|
|
}
|
|
|
|
/** 分页响应 */
|
|
export interface PaginatedResponse<T> {
|
|
items: T[];
|
|
total: number;
|
|
}
|
|
|
|
// =====================
|
|
// 选项常量
|
|
// =====================
|
|
|
|
/** 人群包状态选项 */
|
|
export const SEGMENT_STATUS_OPTIONS = [
|
|
{ value: 'DRAFT', label: '草稿', color: 'gray' },
|
|
{ value: 'ACTIVE', label: '已激活', color: 'green' },
|
|
{ value: 'ARCHIVED', label: '已归档', color: 'yellow' },
|
|
] as const;
|
|
|
|
/** 条件操作符选项 */
|
|
export const CONDITION_OPERATOR_OPTIONS = [
|
|
{ value: 'EQUALS', label: '等于', group: 'comparison' },
|
|
{ value: 'NOT_EQUALS', label: '不等于', group: 'comparison' },
|
|
{ value: 'CONTAINS', label: '包含', group: 'string' },
|
|
{ value: 'NOT_CONTAINS', label: '不包含', group: 'string' },
|
|
{ value: 'GREATER_THAN', label: '大于', group: 'number' },
|
|
{ value: 'LESS_THAN', label: '小于', group: 'number' },
|
|
{ value: 'BETWEEN', label: '在...之间', group: 'number' },
|
|
{ value: 'IN', label: '在列表中', group: 'list' },
|
|
{ value: 'NOT_IN', label: '不在列表中', group: 'list' },
|
|
{ value: 'IS_NULL', label: '为空', group: 'null' },
|
|
{ value: 'IS_NOT_NULL', label: '不为空', group: 'null' },
|
|
{ value: 'HAS_TAG', label: '有标签', group: 'tag' },
|
|
{ value: 'NOT_HAS_TAG', label: '无标签', group: 'tag' },
|
|
] as const;
|
|
|
|
/** 可用字段选项 */
|
|
export const SEGMENT_FIELD_OPTIONS = [
|
|
// 用户基础属性
|
|
{ value: 'registrationDays', label: '注册天数', type: 'number' },
|
|
{ value: 'lastLoginDays', label: '最后登录距今天数', type: 'number' },
|
|
{ value: 'province', label: '省份', type: 'string' },
|
|
{ value: 'city', label: '城市', type: 'string' },
|
|
// 消费行为
|
|
{ value: 'totalPurchaseAmount', label: '累计消费金额', type: 'number' },
|
|
{ value: 'purchaseCount', label: '购买次数', type: 'number' },
|
|
{ value: 'lastPurchaseDays', label: '最后购买距今天数', type: 'number' },
|
|
{ value: 'averageOrderAmount', label: '平均订单金额', type: 'number' },
|
|
// 邀请数据
|
|
{ value: 'totalInvites', label: '累计邀请人数', type: 'number' },
|
|
{ value: 'directInvites', label: '直接邀请人数', type: 'number' },
|
|
// 标签
|
|
{ value: 'tag', label: '用户标签', type: 'tag' },
|
|
] as const;
|
|
|
|
// =====================
|
|
// 服务方法
|
|
// =====================
|
|
|
|
export const audienceSegmentService = {
|
|
/** 获取人群包列表 */
|
|
async getSegments(params: ListSegmentsParams = {}): Promise<PaginatedResponse<AudienceSegment>> {
|
|
return apiClient.get(API_ENDPOINTS.AUDIENCE_SEGMENTS.LIST, { params });
|
|
},
|
|
|
|
/** 获取人群包详情 */
|
|
async getSegment(id: string): Promise<AudienceSegment> {
|
|
return apiClient.get(API_ENDPOINTS.AUDIENCE_SEGMENTS.DETAIL(id));
|
|
},
|
|
|
|
/** 创建人群包 */
|
|
async createSegment(data: CreateSegmentRequest): Promise<AudienceSegment> {
|
|
return apiClient.post(API_ENDPOINTS.AUDIENCE_SEGMENTS.CREATE, data);
|
|
},
|
|
|
|
/** 更新人群包 */
|
|
async updateSegment(id: string, data: UpdateSegmentRequest): Promise<AudienceSegment> {
|
|
return apiClient.put(API_ENDPOINTS.AUDIENCE_SEGMENTS.UPDATE(id), data);
|
|
},
|
|
|
|
/** 删除人群包 */
|
|
async deleteSegment(id: string): Promise<void> {
|
|
return apiClient.delete(API_ENDPOINTS.AUDIENCE_SEGMENTS.DELETE(id));
|
|
},
|
|
|
|
/** 刷新人群包 (重新计算用户数) */
|
|
async refreshSegment(id: string): Promise<AudienceSegment> {
|
|
return apiClient.post(API_ENDPOINTS.AUDIENCE_SEGMENTS.REFRESH(id));
|
|
},
|
|
};
|
|
|
|
export default audienceSegmentService;
|