存客宝 React
This commit is contained in:
29
Cunkebao/types/acquisition.ts
Normal file
29
Cunkebao/types/acquisition.ts
Normal file
@@ -0,0 +1,29 @@
|
||||
export interface AcquisitionPlan {
|
||||
id: string
|
||||
name: string
|
||||
type: string
|
||||
reward: {
|
||||
type: "disabled" | "onSubmit" | "onApprove"
|
||||
amount: number
|
||||
}
|
||||
workers: Worker[]
|
||||
webUrl?: string
|
||||
miniappUrl?: string
|
||||
}
|
||||
|
||||
export interface Worker {
|
||||
id: string
|
||||
name: string
|
||||
avatar?: string
|
||||
}
|
||||
|
||||
export interface OrderFormData {
|
||||
customerName: string
|
||||
phone: string
|
||||
wechatId: string
|
||||
source: string
|
||||
amount?: number
|
||||
orderDate: string
|
||||
remark: string
|
||||
}
|
||||
|
||||
41
Cunkebao/types/auto-group.ts
Normal file
41
Cunkebao/types/auto-group.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
export interface AutoGroupPlan {
|
||||
id: string
|
||||
name: string
|
||||
customerType: string
|
||||
startDate: string
|
||||
endDate: string
|
||||
groupSize: number
|
||||
welcomeMessage: string
|
||||
deviceId: string
|
||||
operatorId: string
|
||||
status: "running" | "stopped" | "completed"
|
||||
createdGroups: number
|
||||
totalFriends: number
|
||||
tags: string[]
|
||||
specificWechatIds: string[]
|
||||
keywords: string[]
|
||||
}
|
||||
|
||||
export interface GroupMember {
|
||||
id: string
|
||||
wechatId: string
|
||||
nickname: string
|
||||
avatar: string
|
||||
tags: string[]
|
||||
}
|
||||
|
||||
export interface Device {
|
||||
id: string
|
||||
name: string
|
||||
status: "online" | "offline"
|
||||
currentOperator: string
|
||||
}
|
||||
|
||||
export interface WechatAccount {
|
||||
id: string
|
||||
wechatId: string
|
||||
nickname: string
|
||||
avatar: string
|
||||
status: "online" | "offline"
|
||||
}
|
||||
|
||||
44
Cunkebao/types/common.ts
Normal file
44
Cunkebao/types/common.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
// API响应格式
|
||||
export interface ApiResponse<T> {
|
||||
code: number
|
||||
message: string
|
||||
data: T | null
|
||||
}
|
||||
|
||||
// 分页响应格式
|
||||
export interface PaginatedResponse<T> {
|
||||
items: T[]
|
||||
total: number
|
||||
page: number
|
||||
pageSize: number
|
||||
totalPages: number
|
||||
}
|
||||
|
||||
// 通用查询参数
|
||||
export interface QueryParams {
|
||||
page?: number
|
||||
pageSize?: number
|
||||
keyword?: string
|
||||
dateRange?: {
|
||||
start: string
|
||||
end: string
|
||||
}
|
||||
}
|
||||
|
||||
// 通用状态枚举
|
||||
export enum Status {
|
||||
ACTIVE = "active",
|
||||
INACTIVE = "inactive",
|
||||
PENDING = "pending",
|
||||
COMPLETED = "completed",
|
||||
FAILED = "failed",
|
||||
DRAFT = "draft",
|
||||
}
|
||||
|
||||
// 通用基础实体
|
||||
export interface BaseEntity {
|
||||
id: string
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
}
|
||||
|
||||
30
Cunkebao/types/content-library.ts
Normal file
30
Cunkebao/types/content-library.ts
Normal file
@@ -0,0 +1,30 @@
|
||||
export interface ContentLibrary {
|
||||
id: string
|
||||
name: string
|
||||
type: "moments" | "group"
|
||||
source: string
|
||||
creator: string
|
||||
contentCount: number
|
||||
lastUpdated: string
|
||||
status: "active" | "inactive"
|
||||
}
|
||||
|
||||
export interface ContentLibraryResponse {
|
||||
code: number
|
||||
message: string
|
||||
data: {
|
||||
libraries: ContentLibrary[]
|
||||
total: number
|
||||
}
|
||||
}
|
||||
|
||||
export interface ContentLibrarySelectResponse {
|
||||
code: number
|
||||
message: string
|
||||
data: {
|
||||
success: boolean
|
||||
libraryId: string
|
||||
name: string
|
||||
}
|
||||
}
|
||||
|
||||
42
Cunkebao/types/content.ts
Normal file
42
Cunkebao/types/content.ts
Normal file
@@ -0,0 +1,42 @@
|
||||
export interface ContentLibrary {
|
||||
id: string
|
||||
name: string
|
||||
source: string
|
||||
creator: string
|
||||
contentCount: number
|
||||
lastUpdated: string
|
||||
type: "moments" | "chat" | "group"
|
||||
status: "active" | "inactive"
|
||||
items: ContentItem[]
|
||||
}
|
||||
|
||||
export interface ContentItem {
|
||||
id: string
|
||||
title: string
|
||||
content: string
|
||||
type: "text" | "image" | "video"
|
||||
images?: string[]
|
||||
video?: string
|
||||
createTime: string
|
||||
publishTime?: string
|
||||
status: "pending" | "published" | "failed"
|
||||
}
|
||||
|
||||
export interface Tag {
|
||||
id: string
|
||||
name: string
|
||||
description?: string
|
||||
contentCount: number
|
||||
lastSync: string
|
||||
settings: {
|
||||
syncInterval: number
|
||||
timeRange: {
|
||||
start: string
|
||||
end: string
|
||||
}
|
||||
dailyLimit: number
|
||||
accountType: "business" | "personal"
|
||||
enabled: boolean
|
||||
}
|
||||
}
|
||||
|
||||
118
Cunkebao/types/device.ts
Normal file
118
Cunkebao/types/device.ts
Normal file
@@ -0,0 +1,118 @@
|
||||
// 设备状态枚举
|
||||
export enum DeviceStatus {
|
||||
ONLINE = "online",
|
||||
OFFLINE = "offline",
|
||||
BUSY = "busy",
|
||||
ERROR = "error",
|
||||
}
|
||||
|
||||
// 设备类型枚举
|
||||
export enum DeviceType {
|
||||
ANDROID = "android",
|
||||
IOS = "ios",
|
||||
}
|
||||
|
||||
// 设备基础信息
|
||||
export interface Device {
|
||||
id: string
|
||||
name: string
|
||||
imei: string
|
||||
type: DeviceType
|
||||
status: DeviceStatus
|
||||
wechatId: string
|
||||
friendCount: number
|
||||
battery: number
|
||||
lastActive: string
|
||||
addFriendStatus: "normal" | "abnormal"
|
||||
remark?: string
|
||||
}
|
||||
|
||||
// 设备统计信息
|
||||
export interface DeviceStats {
|
||||
totalTasks: number
|
||||
completedTasks: number
|
||||
failedTasks: number
|
||||
todayNewFriends: number
|
||||
totalNewFriends: number
|
||||
onlineTime: number // 在线时长(分钟)
|
||||
}
|
||||
|
||||
// 设备任务记录
|
||||
export interface DeviceTaskRecord {
|
||||
id: string
|
||||
deviceId: string
|
||||
taskType: string
|
||||
status: "pending" | "running" | "completed" | "failed"
|
||||
startTime: string
|
||||
endTime?: string
|
||||
result?: string
|
||||
error?: string
|
||||
}
|
||||
|
||||
// API响应格式
|
||||
export interface ApiResponse<T> {
|
||||
code: number
|
||||
message: string
|
||||
data: T | null
|
||||
}
|
||||
|
||||
// 分页响应格式
|
||||
export interface PaginatedResponse<T> {
|
||||
items: T[]
|
||||
total: number
|
||||
page: number
|
||||
pageSize: number
|
||||
totalPages: number
|
||||
}
|
||||
|
||||
// 设备查询参数
|
||||
export interface QueryDeviceParams {
|
||||
keyword?: string
|
||||
status?: DeviceStatus
|
||||
type?: DeviceType
|
||||
tags?: string[]
|
||||
page?: number
|
||||
pageSize?: number
|
||||
dateRange?: {
|
||||
start: string
|
||||
end: string
|
||||
}
|
||||
}
|
||||
|
||||
// 创建设备参数
|
||||
export interface CreateDeviceParams {
|
||||
name: string
|
||||
imei: string
|
||||
type: DeviceType
|
||||
wechatId?: string
|
||||
remark?: string
|
||||
tags?: string[]
|
||||
}
|
||||
|
||||
// 更新设备参数
|
||||
export interface UpdateDeviceParams {
|
||||
id: string
|
||||
name?: string
|
||||
wechatId?: string
|
||||
remark?: string
|
||||
tags?: string[]
|
||||
}
|
||||
|
||||
export interface DeviceResponse {
|
||||
code: number
|
||||
message: string
|
||||
data: {
|
||||
devices: Device[]
|
||||
total: number
|
||||
}
|
||||
}
|
||||
|
||||
export interface DeviceSelectResponse {
|
||||
code: number
|
||||
message: string
|
||||
data: {
|
||||
success: boolean
|
||||
deviceIds: string[]
|
||||
}
|
||||
}
|
||||
|
||||
40
Cunkebao/types/group-push.ts
Normal file
40
Cunkebao/types/group-push.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
export interface ServiceAccount {
|
||||
id: string
|
||||
name: string
|
||||
avatar: string
|
||||
}
|
||||
|
||||
export interface WechatGroup {
|
||||
id: string
|
||||
name: string
|
||||
avatar: string
|
||||
serviceAccount: ServiceAccount
|
||||
}
|
||||
|
||||
export interface ContentTarget {
|
||||
id: string
|
||||
avatar: string
|
||||
}
|
||||
|
||||
export interface ContentLibrary {
|
||||
id: string
|
||||
name: string
|
||||
targets: ContentTarget[]
|
||||
}
|
||||
|
||||
export interface GroupPushTask {
|
||||
id: string
|
||||
name: string
|
||||
pushTimeStart: string
|
||||
pushTimeEnd: string
|
||||
dailyPushCount: number
|
||||
pushOrder: "earliest" | "latest"
|
||||
isLoopPush: boolean
|
||||
isImmediatePush: boolean
|
||||
isEnabled: boolean
|
||||
groups: WechatGroup[]
|
||||
contentLibraries: ContentLibrary[]
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
}
|
||||
|
||||
36
Cunkebao/types/group-sync.ts
Normal file
36
Cunkebao/types/group-sync.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
export interface GroupSyncTask {
|
||||
id: string
|
||||
name: string
|
||||
pushTimeStart: string
|
||||
pushTimeEnd: string
|
||||
dailyPushCount: number
|
||||
pushOrder: "earliest" | "latest"
|
||||
isLoopPush: boolean
|
||||
isImmediatePush: boolean
|
||||
isEnabled: boolean
|
||||
groups: WechatGroup[]
|
||||
contentLibraries: ContentLibrary[]
|
||||
createdAt: string
|
||||
updatedAt: string
|
||||
}
|
||||
|
||||
export interface WechatGroup {
|
||||
id: string
|
||||
name: string
|
||||
avatar?: string
|
||||
serviceAccount: {
|
||||
id: string
|
||||
name: string
|
||||
avatar?: string
|
||||
}
|
||||
}
|
||||
|
||||
export interface ContentLibrary {
|
||||
id: string
|
||||
name: string
|
||||
targets: {
|
||||
id: string
|
||||
avatar?: string
|
||||
}[]
|
||||
}
|
||||
|
||||
112
Cunkebao/types/scenario.ts
Normal file
112
Cunkebao/types/scenario.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
import type {
|
||||
ApiResponse,
|
||||
CreateScenarioParams,
|
||||
UpdateScenarioParams,
|
||||
QueryScenarioParams,
|
||||
ScenarioBase,
|
||||
ScenarioStats,
|
||||
AcquisitionRecord,
|
||||
PaginatedResponse,
|
||||
} from "@/types/scenario"
|
||||
|
||||
const API_BASE = "/api/scenarios"
|
||||
|
||||
// 获客场景API
|
||||
export const scenarioApi = {
|
||||
// 创建场景
|
||||
async create(params: CreateScenarioParams): Promise<ApiResponse<ScenarioBase>> {
|
||||
const response = await fetch(`${API_BASE}`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(params),
|
||||
})
|
||||
return response.json()
|
||||
},
|
||||
|
||||
// 更新场景
|
||||
async update(params: UpdateScenarioParams): Promise<ApiResponse<ScenarioBase>> {
|
||||
const response = await fetch(`${API_BASE}/${params.id}`, {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(params),
|
||||
})
|
||||
return response.json()
|
||||
},
|
||||
|
||||
// 获取场景详情
|
||||
async getById(id: string): Promise<ApiResponse<ScenarioBase>> {
|
||||
const response = await fetch(`${API_BASE}/${id}`)
|
||||
return response.json()
|
||||
},
|
||||
|
||||
// 查询场景列表
|
||||
async query(params: QueryScenarioParams): Promise<ApiResponse<PaginatedResponse<ScenarioBase>>> {
|
||||
const queryString = new URLSearchParams({
|
||||
...params,
|
||||
dateRange: params.dateRange ? JSON.stringify(params.dateRange) : "",
|
||||
}).toString()
|
||||
|
||||
const response = await fetch(`${API_BASE}?${queryString}`)
|
||||
return response.json()
|
||||
},
|
||||
|
||||
// 删除场景
|
||||
async delete(id: string): Promise<ApiResponse<void>> {
|
||||
const response = await fetch(`${API_BASE}/${id}`, {
|
||||
method: "DELETE",
|
||||
})
|
||||
return response.json()
|
||||
},
|
||||
|
||||
// 启动场景
|
||||
async start(id: string): Promise<ApiResponse<void>> {
|
||||
const response = await fetch(`${API_BASE}/${id}/start`, {
|
||||
method: "POST",
|
||||
})
|
||||
return response.json()
|
||||
},
|
||||
|
||||
// 暂停场景
|
||||
async pause(id: string): Promise<ApiResponse<void>> {
|
||||
const response = await fetch(`${API_BASE}/${id}/pause`, {
|
||||
method: "POST",
|
||||
})
|
||||
return response.json()
|
||||
},
|
||||
|
||||
// 获取场景统计数据
|
||||
async getStats(id: string): Promise<ApiResponse<ScenarioStats>> {
|
||||
const response = await fetch(`${API_BASE}/${id}/stats`)
|
||||
return response.json()
|
||||
},
|
||||
|
||||
// 获取获客记录
|
||||
async getRecords(id: string, page = 1, pageSize = 20): Promise<ApiResponse<PaginatedResponse<AcquisitionRecord>>> {
|
||||
const response = await fetch(`${API_BASE}/${id}/records?page=${page}&pageSize=${pageSize}`)
|
||||
return response.json()
|
||||
},
|
||||
|
||||
// 导出获客记录
|
||||
async exportRecords(id: string, dateRange?: { start: string; end: string }): Promise<Blob> {
|
||||
const queryString = dateRange ? `?start=${dateRange.start}&end=${dateRange.end}` : ""
|
||||
const response = await fetch(`${API_BASE}/${id}/records/export${queryString}`)
|
||||
return response.blob()
|
||||
},
|
||||
|
||||
// 批量更新标签
|
||||
async updateTags(id: string, customerIds: string[], tags: string[]): Promise<ApiResponse<void>> {
|
||||
const response = await fetch(`${API_BASE}/${id}/tags`, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify({ customerIds, tags }),
|
||||
})
|
||||
return response.json()
|
||||
},
|
||||
}
|
||||
|
||||
15
Cunkebao/types/traffic.ts
Normal file
15
Cunkebao/types/traffic.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
export interface TrafficUser {
|
||||
id: string
|
||||
avatar: string
|
||||
nickname: string
|
||||
wechatId: string
|
||||
phone: string
|
||||
region: string
|
||||
note: string
|
||||
status: "pending" | "added" | "failed"
|
||||
addTime: string
|
||||
source: string
|
||||
assignedTo: string
|
||||
category: "potential" | "customer" | "lost"
|
||||
}
|
||||
|
||||
13
Cunkebao/types/tutorial.ts
Normal file
13
Cunkebao/types/tutorial.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export interface TutorialVideo {
|
||||
id: string
|
||||
title: string
|
||||
description: string
|
||||
url: string
|
||||
thumbnailUrl: string
|
||||
}
|
||||
|
||||
export interface PageTutorial {
|
||||
pageId: string
|
||||
videos: TutorialVideo[]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user