/** * 后端 API 响应类型定义 * * 与 docs/miniprogram-dev/API-contract.md 保持同步 * 命名规则:Api + 模块 + 用途,如 ApiTaskItem / ApiNoteItem */ // ============================================ // 通用 // ============================================ /** 分页响应包装 */ interface ApiPaginated { items: T[] total: number page: number pageSize: number } // ============================================ // 认证模块 // ============================================ /** AUTH-1/2: 登录响应 */ interface ApiLoginResponse { access_token: string refresh_token: string user: ApiUserInfo } /** AUTH-3: /api/xcx/me 响应 */ interface ApiUserInfo { user_id: number status: 'new' | 'pending' | 'approved' | 'rejected' | 'disabled' nickname: string role?: string store_name?: string coach_level?: string avatar?: string } /** AUTH-4: 刷新 token 响应 */ interface ApiRefreshResponse { access_token: string refresh_token: string } // ============================================ // 任务模块 // ============================================ /** TASK-1: 任务列表项 */ interface ApiTaskItem { id: string customer_name: string customer_avatar: string task_type: 'callback' | 'priority_recall' | 'relationship' | 'high_priority' task_type_label: string deadline: string heart_score: number hobbies: string[] is_pinned: boolean has_note: boolean status: 'pending' | 'completed' | 'abandoned' } /** TASK-1: 任务列表响应(含绩效概览) */ interface ApiTaskListResponse extends ApiPaginated { performance: { total_hours: number total_income: number total_customers: number month_label: string } } /** 维客线索 */ interface ApiRetentionClue { tag: string tag_color: 'primary' | 'success' | 'purple' | 'error' emoji: string text: string source: string desc?: string } /** 服务记录 */ interface ApiServiceRecord { table: string type: string type_class: 'basic' | 'vip' | 'tip' | 'recharge' | 'incentive' record_type?: 'course' | 'recharge' duration: number duration_raw?: number income: number is_estimate?: boolean drinks: string date: string } /** TASK-2: 任务详情响应 */ interface ApiTaskDetail extends ApiTaskItem { last_visit_date?: string last_spend_amount?: number days_absent?: number spend_trend?: 'up' | 'down' | 'flat' churn_risk?: 'high' | 'medium' | 'low' callback_reason?: string preferences?: string[] consumption_habits?: string social_preference?: string retention_clues: ApiRetentionClue[] talking_points: string[] service_summary: { total_hours: number; total_income: number; avg_income: number } service_records: ApiServiceRecord[] ai_analysis: { summary: string; suggestions: string[] } notes: ApiNoteItem[] } // ============================================ // 备注模块 // ============================================ /** NOTE-1: 备注项 */ interface ApiNoteItem { id: string content: string tag_type: 'customer' | 'coach' | 'system' tag_label: string created_at: string /** AI 应用 6 评分(1-10),星数 = ai_score ÷ 2 */ ai_score?: number /** 再次服务意愿(1-5) */ rating_service_willingness?: number /** 再来店可能性(1-5) */ rating_revisit_likelihood?: number } // ============================================ // 绩效模块 // ============================================ /** PERF-2: 绩效明细记录 */ interface ApiPerfRecord { id: string customer_name: string time_range: string hours: number hours_raw?: number course_type: string course_type_class: string location: string income: number } /** PERF-2: 绩效明细按日期分组 */ interface ApiPerfDateGroup { date: string total_hours: number total_income: number records: ApiPerfRecord[] } /** PERF-2: 绩效明细响应 */ interface ApiPerfRecordsResponse { summary: { total_count: number total_hours: number total_hours_raw: number total_income: number } date_groups: ApiPerfDateGroup[] has_more: boolean } /** PERF-1: 绩效概览响应 */ interface ApiPerfOverview { total_hours: number total_income: number total_customers: number income_items: Array<{ label: string; amount: number; icon: string }> this_month_records: Array<{ customer_name: string; hours: number; income: number; date: string }> new_customers: Array<{ name: string; avatar_char: string }> regular_customers: Array<{ name: string; avatar_char: string; visits: number }> } // ============================================ // 客户模块 // ============================================ /** CUST-1: 客户详情响应 */ interface ApiCustomerDetail { id: string name: string phone: string phone_full: string avatar: string member_level: string relation_index: string tags: string[] retention_clues: ApiRetentionClue[] consumption_records: Array<{ id: string date: string type: string type_class: string amount: number table: string duration: number }> } /** CUST-2: 客户服务记录响应 */ interface ApiCustomerRecordsResponse { customer_name: string customer_phone: string relation_index: string tables: Array<{ id: string; name: string }> records: ApiServiceRecord[] has_more: boolean } // ============================================ // 看板模块 // ============================================ /** BOARD-1: 助教看板项 */ interface ApiBoardCoachItem { id: string name: string avatar: string level: string level_class: string skills: string[] total_hours: number total_income: number customer_count: number satisfaction: number } /** BOARD-2: 客户看板项 */ interface ApiBoardCustomerItem { id: string name: string avatar: string tags: string[] total_spend: number visit_count: number last_visit: string relation_index: string } /** BOARD-3: 财务看板指标 */ interface ApiBoardFinanceMetric { key: string label: string value: number unit: string trend?: 'up' | 'down' | 'flat' sub_items?: Array<{ label: string; value: number }> } // ============================================ // 对话模块 // ============================================ /** CHAT-1: 对话历史项 */ interface ApiChatHistoryItem { id: string customer_name: string last_message: string last_time: string unread_count: number } /** CHAT-2: 对话消息 */ interface ApiChatMessage { id: string role: 'user' | 'assistant' content: string created_at: string } /** CHAT-3: 发送消息响应 */ interface ApiChatSendResponse { user_message: { id: string; content: string; created_at: string } ai_reply: { id: string; content: string; created_at: string } } // ============================================ // 配置模块 // ============================================ /** CONFIG-1: 技能类型 */ interface ApiSkillType { value: string text: string icon?: string }