feat(ctrt): 完成 CTRT-01~03 响应契约统一 - 三端拦截器+portal_token清理+调用点适配
This commit is contained in:
@@ -0,0 +1,126 @@
|
||||
// =============================================================================
|
||||
// 企微IT智能服务台 — 阶段5 自动化闭环 API 调用模块(H5 员工端)
|
||||
// =============================================================================
|
||||
// 说明:封装员工侧自动化会话相关 HTTP 请求。
|
||||
// 约定:与坐席端一致,baseURL 已在 api/index.ts 配置为 /api,
|
||||
// 这里只写相对路径 /itportal/automation/...;响应拦截器已解包为 data。
|
||||
// 注意:本模块返回「内层 data」(与 h5 其它 api 模块一致),调用方直接使用。
|
||||
// =============================================================================
|
||||
|
||||
import apiClient from '@/api'
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// 类型定义(与后端 Schema / 坐席端保持一致)
|
||||
// --------------------------------------------------------------------------
|
||||
export interface AutomationAction {
|
||||
id: string
|
||||
session_id: string
|
||||
action_index: number
|
||||
action_type: string
|
||||
adapter: string
|
||||
risk_level: string
|
||||
title: string
|
||||
description: string
|
||||
status: string
|
||||
payload: Record<string, any> | null
|
||||
result: Record<string, any> | null
|
||||
error: string | null
|
||||
approved_by: string | null
|
||||
approved_at: string | null
|
||||
}
|
||||
|
||||
export interface ApprovalTicket {
|
||||
id: string
|
||||
action_id: string
|
||||
session_id: string
|
||||
approver_id: string | null
|
||||
channel: string
|
||||
status: string
|
||||
reason: string | null
|
||||
decision_note: string | null
|
||||
decided_at: string | null
|
||||
}
|
||||
|
||||
export interface AutomationSession {
|
||||
id: string
|
||||
conversation_id: string | null
|
||||
employee_id: string
|
||||
agent_id: string | null
|
||||
scenario_key: string | null
|
||||
status: string
|
||||
mode: string
|
||||
confidence: number
|
||||
title: string
|
||||
intent: Record<string, any> | null
|
||||
current_action_id: string | null
|
||||
auto_close_at: string | null
|
||||
resolved_at: string | null
|
||||
closed_by: string | null
|
||||
meta: Record<string, any> | null
|
||||
actions: AutomationAction[]
|
||||
approval: ApprovalTicket | null
|
||||
created_at: string | null
|
||||
updated_at: string | null
|
||||
}
|
||||
|
||||
/** 发起自动化会话请求体 */
|
||||
export interface StartSessionPayload {
|
||||
conversation_id?: string | null
|
||||
employee_id: string
|
||||
description: string
|
||||
scenario_key?: string
|
||||
}
|
||||
|
||||
/** 员工侧高危动作二次确认请求体 */
|
||||
export interface ConfirmPayload {
|
||||
confirmed: boolean
|
||||
note?: string
|
||||
}
|
||||
|
||||
/** 标记已解决 / 静默关单反馈请求体 */
|
||||
export interface ResolvePayload {
|
||||
satisfied?: boolean
|
||||
note?: string
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// 员工端接口(路径与后端契约 §15.3 一致)
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
/** 发起自动化会话(员工侧触发) */
|
||||
export async function startAutomationSession(
|
||||
payload: StartSessionPayload,
|
||||
): Promise<AutomationSession> {
|
||||
const res = await apiClient.post('/itportal/automation/sessions/start', payload)
|
||||
return res as AutomationSession
|
||||
}
|
||||
|
||||
/** 会话详情 */
|
||||
export async function getAutomationSession(sessionId: string): Promise<AutomationSession> {
|
||||
const res = await apiClient.get(`/itportal/automation/sessions/${sessionId}`)
|
||||
return res as AutomationSession
|
||||
}
|
||||
|
||||
/** 单个动作详情(用于二次确认弹窗展示) */
|
||||
export async function getAutomationAction(actionId: string): Promise<AutomationAction> {
|
||||
const res = await apiClient.get(`/itportal/automation/actions/${actionId}`)
|
||||
return res as AutomationAction
|
||||
}
|
||||
|
||||
/** 员工侧高危动作二次确认(P1:员工确认/取消执行) */
|
||||
export async function confirmAutomationAction(
|
||||
actionId: string,
|
||||
payload: ConfirmPayload,
|
||||
): Promise<AutomationAction> {
|
||||
const res = await apiClient.post(`/itportal/automation/actions/${actionId}/confirm`, payload)
|
||||
return res as AutomationAction
|
||||
}
|
||||
|
||||
/** 标记会话已解决 / 提交静默关单反馈 */
|
||||
export async function resolveAutomationSession(
|
||||
sessionId: string,
|
||||
payload: ResolvePayload,
|
||||
): Promise<AutomationSession> {
|
||||
const res = await apiClient.post(`/itportal/automation/sessions/${sessionId}/resolved`, payload)
|
||||
return res as AutomationSession
|
||||
}
|
||||
@@ -40,8 +40,8 @@ export interface ConversationInfo {
|
||||
employee_id: string
|
||||
/** 员工姓名(会话发起人) */
|
||||
employee_name: string
|
||||
/** 会话状态:waiting(排队中) / serving(服务中) / closed(已结单) */
|
||||
status: 'waiting' | 'serving' | 'closed'
|
||||
/** 会话状态:waiting(排队中) / serving(服务中) / resolved(已结单) */
|
||||
status: 'waiting' | 'serving' | 'resolved'
|
||||
/** 坐席 ID(未接入时为空) */
|
||||
agent_id: string
|
||||
/** 坐席名称(未接入时为空) */
|
||||
@@ -131,6 +131,10 @@ export interface ShakeResponse {
|
||||
/** 会话状态:queued(排队中) / serving(服务中) / closed(已结单) */
|
||||
status: string
|
||||
}
|
||||
/** 分配结果:assigned(已分配坐席) / queued(排队中) / assign_failed(分配失败) */
|
||||
assign_result?: string
|
||||
/** 已分配的坐席ID(当 assign_result 为 assigned 时) */
|
||||
assigned_agent_id?: string
|
||||
}
|
||||
|
||||
/** 审批流程链接 */
|
||||
@@ -243,8 +247,8 @@ function mapMessages(rawList: any[]): Message[] {
|
||||
// -------------------------------------------------------------------------
|
||||
// API 方法
|
||||
// -------------------------------------------------------------------------
|
||||
// 注意:响应拦截器返回 response.data(即 {code, data, message} 包装对象)
|
||||
// API 函数通过 await + response.data 取出业务数据(与原始工作代码一致)
|
||||
// 注意:响应拦截器返回 response(即 {code, data, message} 包装对象)
|
||||
// API 函数通过 await + response 取出业务数据(与原始工作代码一致)
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
@@ -255,7 +259,7 @@ function mapMessages(rawList: any[]): Message[] {
|
||||
*/
|
||||
export async function getUser(): Promise<UserInfo> {
|
||||
const response: any = await apiClient.get('/h5/user')
|
||||
return response.data
|
||||
return response
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -265,7 +269,7 @@ export async function getUser(): Promise<UserInfo> {
|
||||
*/
|
||||
export async function getCurrentConversation(): Promise<ConversationInfo | null> {
|
||||
const response: any = await apiClient.get('/h5/conversations/current')
|
||||
return response.data
|
||||
return response
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -281,14 +285,14 @@ export async function sendMessage(data: SendMessageRequest): Promise<SendMessage
|
||||
timeout: 30000,
|
||||
})
|
||||
// 注意:apiClient 拦截器返回的是 {code: 0, data: {...}, message: "success"} 包装对象,
|
||||
// 需要通过 response.data 获取实际业务数据
|
||||
// 需要通过 response 获取实际业务数据
|
||||
// 修复字段映射:后端返回 id/sender_type,H5前端期望 message_id/message_type
|
||||
return {
|
||||
user_message: mapMessage(response.data.user_message),
|
||||
ai_reply: response.data.ai_reply ? mapMessage(response.data.ai_reply) : response.data.ai_reply,
|
||||
is_guidance: response.data.is_guidance,
|
||||
ai_reply_count: response.data.ai_reply_count,
|
||||
can_call_agent: response.data.can_call_agent,
|
||||
user_message: mapMessage(response.user_message),
|
||||
ai_reply: response.ai_reply ? mapMessage(response.ai_reply) : response.ai_reply,
|
||||
is_guidance: response.is_guidance,
|
||||
ai_reply_count: response.ai_reply_count,
|
||||
can_call_agent: response.can_call_agent,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -300,13 +304,45 @@ export async function sendMessage(data: SendMessageRequest): Promise<SendMessage
|
||||
*/
|
||||
export async function pollMessages(params?: PollMessagesParams): Promise<Message[]> {
|
||||
const response: any = await apiClient.get('/h5/conversations/current/messages/poll', { params })
|
||||
// response.data = { items: [...], has_more: bool }
|
||||
const data = response.data
|
||||
// response = { items: [...], has_more: bool }
|
||||
const data = response
|
||||
const rawItems = data?.items || data || []
|
||||
// 修复字段映射:后端返回 id/sender_type,H5前端期望 message_id/message_type
|
||||
return mapMessages(rawItems)
|
||||
}
|
||||
|
||||
/** 获取消息列表请求参数 */
|
||||
export interface GetMessagesParams {
|
||||
/** 每页消息数量(默认50) */
|
||||
limit?: number
|
||||
/** 获取此消息ID之前的消息(向上翻页) */
|
||||
before?: string
|
||||
}
|
||||
|
||||
/** 消息列表响应 */
|
||||
export interface MessageListData {
|
||||
items: Message[]
|
||||
has_more: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取消息列表(历史消息)
|
||||
* 获取当前会话的消息历史记录,支持分页向上翻页
|
||||
* @param params 查询参数(limit 和 before)
|
||||
* @returns 消息列表数据
|
||||
*/
|
||||
export async function getMessages(params?: GetMessagesParams): Promise<MessageListData> {
|
||||
const response: any = await apiClient.get('/h5/conversations/current/messages', { params })
|
||||
// response = { items: [...], has_more: bool }
|
||||
const data = response
|
||||
const rawItems = data?.items || []
|
||||
// 修复字段映射:后端返回 id/sender_type,H5前端期望 message_id/message_type
|
||||
return {
|
||||
items: mapMessages(rawItems),
|
||||
has_more: data?.has_more || false,
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 摇人 — 一键呼叫 IT 坐席
|
||||
* 触发转人工流程,返回趣味话术和会话状态
|
||||
@@ -315,7 +351,7 @@ export async function pollMessages(params?: PollMessagesParams): Promise<Message
|
||||
*/
|
||||
export async function shake(data: ShakeRequest): Promise<ShakeResponse> {
|
||||
const response: any = await apiClient.post('/h5/conversations/current/shake', data)
|
||||
return response.data
|
||||
return response
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -325,8 +361,8 @@ export async function shake(data: ShakeRequest): Promise<ShakeResponse> {
|
||||
*/
|
||||
export async function getApprovalLinks(): Promise<ApprovalLink[]> {
|
||||
const response: any = await apiClient.get('/h5/approval-links')
|
||||
// response.data = { items: [...] } 或 [...]
|
||||
const data = response.data
|
||||
// response = { items: [...] } 或 [...]
|
||||
const data = response
|
||||
return (data?.items || data || []) as ApprovalLink[]
|
||||
}
|
||||
|
||||
@@ -349,7 +385,7 @@ export interface ApprovalKeyword {
|
||||
*/
|
||||
export async function getApprovalKeywords(): Promise<ApprovalKeyword[]> {
|
||||
const response: any = await apiClient.get('/approval/keywords')
|
||||
return response.data || []
|
||||
return response || []
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -359,7 +395,7 @@ export async function getApprovalKeywords(): Promise<ApprovalKeyword[]> {
|
||||
*/
|
||||
export async function createApprovalJump(templateId: string): Promise<{ url: string; template_name: string }> {
|
||||
const response: any = await apiClient.post('/approval/jump', { template_id: templateId })
|
||||
return response.data
|
||||
return response
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -369,8 +405,8 @@ export async function createApprovalJump(templateId: string): Promise<{ url: str
|
||||
*/
|
||||
export async function getSoftwareDownloads(): Promise<SoftwareDownload[]> {
|
||||
const response: any = await apiClient.get('/h5/software-downloads')
|
||||
// response.data = { items: [...] } 或 [...]
|
||||
const data = response.data
|
||||
// response = { items: [...] } 或 [...]
|
||||
const data = response
|
||||
return (data?.items || data || []) as SoftwareDownload[]
|
||||
}
|
||||
|
||||
@@ -394,7 +430,7 @@ export async function joinConversation(
|
||||
const response: any = await apiClient.post(
|
||||
`/h5/conversations/${conversationId}/join`
|
||||
)
|
||||
return response.data
|
||||
return response
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -410,7 +446,7 @@ export async function leaveAsParticipant(
|
||||
const response: any = await apiClient.post(
|
||||
`/h5/conversations/${conversationId}/leave-participant`
|
||||
)
|
||||
return response.data
|
||||
return response
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -426,6 +462,95 @@ export async function getParticipants(
|
||||
const response: any = await apiClient.get(
|
||||
`/h5/conversations/${conversationId}/participants`
|
||||
)
|
||||
const data = response.data
|
||||
const data = response
|
||||
return data?.participants || []
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// 摇人按钮 - 呼叫坐席
|
||||
// -------------------------------------------------------------------------
|
||||
export interface CallAgentResponse {
|
||||
code: number
|
||||
message: string
|
||||
data?: {
|
||||
conversation_id: string
|
||||
status: 'waiting' | 'serving'
|
||||
queue_position?: number
|
||||
estimated_wait_seconds?: number
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 呼叫坐席(摇人按钮)
|
||||
* 用户点击摇人按钮后,触发转人工流程
|
||||
*/
|
||||
export async function callAgent(): Promise<CallAgentResponse> {
|
||||
const response: any = await apiClient.post('/h5/conversations/current/call-agent', {})
|
||||
return response || { code: -1, message: '网络错误' }
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// 满意度评价 API (P1-25)
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/** 评价提交请求 */
|
||||
export interface EvaluationSubmitRequest {
|
||||
/** 星级评分(1-5) */
|
||||
star_rating: number
|
||||
/** 表情评价(satisfied/neutral/dissatisfied) */
|
||||
emoji: string
|
||||
/** 文字反馈(可选) */
|
||||
feedback_text?: string
|
||||
}
|
||||
|
||||
/** 评价记录 */
|
||||
export interface EvaluationRecord {
|
||||
/** 评价ID */
|
||||
id: string
|
||||
/** 会话ID */
|
||||
conversation_id: string
|
||||
/** 员工ID */
|
||||
employee_id: string
|
||||
/** 员工姓名 */
|
||||
employee_name: string
|
||||
/** 星级评分 */
|
||||
star_rating: number
|
||||
/** 表情评价 */
|
||||
emoji: string
|
||||
/** 文字反馈 */
|
||||
feedback_text?: string
|
||||
/** 评价时间 */
|
||||
created_at: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交满意度评价
|
||||
* 员工对已结束的会话进行满意度评价
|
||||
* @param conversationId - 会话ID
|
||||
* @param data - 评价内容
|
||||
* @returns 评价记录
|
||||
*/
|
||||
export async function submitEvaluation(
|
||||
conversationId: string,
|
||||
data: EvaluationSubmitRequest
|
||||
): Promise<EvaluationRecord> {
|
||||
const response: any = await apiClient.post(
|
||||
`/conversation/${conversationId}/evaluate`,
|
||||
data
|
||||
)
|
||||
return response
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取会话的评价记录
|
||||
* @param conversationId - 会话ID
|
||||
* @returns 评价记录(如果已评价)
|
||||
*/
|
||||
export async function getEvaluation(
|
||||
conversationId: string
|
||||
): Promise<EvaluationRecord | null> {
|
||||
const response: any = await apiClient.get(
|
||||
`/conversation/${conversationId}/evaluation`
|
||||
)
|
||||
return response
|
||||
}
|
||||
|
||||
@@ -67,8 +67,8 @@ export interface OAuthAuthorizeResponse {
|
||||
// -------------------------------------------------------------------------
|
||||
// API 方法
|
||||
// -------------------------------------------------------------------------
|
||||
// 注意:响应拦截器返回 response.data(即 {code, data, message} 包装对象)
|
||||
// API 函数通过 await + response.data 取出业务数据(与原始工作代码一致)
|
||||
// 注意:响应拦截器返回 response(即 {code, data, message} 包装对象)
|
||||
// API 函数通过 await + response 取出业务数据(与原始工作代码一致)
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
@@ -83,8 +83,8 @@ export interface OAuthAuthorizeResponse {
|
||||
export async function oauthCallback(data: OAuthCallbackRequest): Promise<OAuthCallbackResponse> {
|
||||
const response: any = await apiClient.post('/h5/oauth/callback', data)
|
||||
// response = {code:0, data: {token:"...", ...}, message:"success"}(拦截器返回值)
|
||||
// response.data = 业务数据 {token:"...", employee_id:"...", ...}
|
||||
return response.data
|
||||
// response = 业务数据 {token:"...", employee_id:"...", ...}
|
||||
return response
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -98,7 +98,7 @@ export async function oauthCallback(data: OAuthCallbackRequest): Promise<OAuthCa
|
||||
*/
|
||||
export async function mockLogin(data: { employee_id: string; employee_name?: string }): Promise<OAuthCallbackResponse> {
|
||||
const response: any = await apiClient.post('/h5/mock-login', data)
|
||||
return response.data
|
||||
return response
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,7 +109,7 @@ export async function mockLogin(data: { employee_id: string; employee_name?: str
|
||||
*/
|
||||
export async function getEmployeeInfo(): Promise<EmployeeInfo> {
|
||||
const response: any = await apiClient.get('/h5/me')
|
||||
return response.data
|
||||
return response
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,5 +123,45 @@ export async function getOAuthAuthorizeUrl(): Promise<OAuthAuthorizeResponse> {
|
||||
const response: any = await apiClient.get('/h5/oauth/authorize', {
|
||||
params: { redirect_uri: redirectUri },
|
||||
})
|
||||
return response.data
|
||||
return response
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------------------
|
||||
// 密码管理
|
||||
// -------------------------------------------------------------------------
|
||||
|
||||
/** 修改密码请求参数 */
|
||||
export interface ChangePasswordRequest {
|
||||
/** 旧密码 */
|
||||
old_password: string
|
||||
/** 新密码 */
|
||||
new_password: string
|
||||
}
|
||||
|
||||
/** 重置密码请求参数 */
|
||||
export interface ResetPasswordRequest {
|
||||
/** 新密码 */
|
||||
new_password: string
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改当前坐席密码
|
||||
* 需要验证旧密码
|
||||
* @param data 包含旧密码和新密码的请求参数
|
||||
* @returns 修改结果
|
||||
*/
|
||||
export async function changePassword(data: ChangePasswordRequest): Promise<{ message: string }> {
|
||||
const response: any = await apiClient.post('/agents/password', data)
|
||||
return response
|
||||
}
|
||||
|
||||
/**
|
||||
* 管理员重置坐席密码
|
||||
* @param userId 坐席用户ID
|
||||
* @param newPassword 新密码
|
||||
* @returns 重置结果
|
||||
*/
|
||||
export async function adminResetPassword(userId: string, newPassword: string): Promise<{ message: string }> {
|
||||
const response: any = await apiClient.post(`/admin/agents/${userId}/reset-password`, { new_password: newPassword })
|
||||
return response
|
||||
}
|
||||
|
||||
@@ -44,15 +44,6 @@ apiClient.interceptors.request.use(
|
||||
config.headers['Authorization'] = `Bearer ${token}`
|
||||
}
|
||||
|
||||
// 兼容过渡:如果同时存在 employee_id 且无 token,则仍然发送 X-Employee-Id
|
||||
// 这确保了在 token 过期但 localStorage 中仍有旧数据的降级场景
|
||||
if (!token) {
|
||||
const employeeId = localStorage.getItem('employee_id')
|
||||
if (employeeId) {
|
||||
config.headers['X-Employee-Id'] = employeeId
|
||||
}
|
||||
}
|
||||
|
||||
return config
|
||||
},
|
||||
(error) => {
|
||||
@@ -77,23 +68,24 @@ apiClient.interceptors.response.use(
|
||||
// 后端 _get_current_employee 在 Redis 查不到 token 时返回此码
|
||||
if (res.code === 1002) {
|
||||
handleAuthExpired('biz1002')
|
||||
return Promise.reject(new Error(res.message || '未授权'))
|
||||
return Promise.reject({ code: 1002, message: res.message || '未授权' })
|
||||
}
|
||||
|
||||
// 普通业务错误:显示轻提示
|
||||
showToast(res.message || '请求失败')
|
||||
return Promise.reject(new Error(res.message || '请求失败'))
|
||||
return Promise.reject({ code: res.code, message: res.message || '请求失败' })
|
||||
}
|
||||
|
||||
// 业务成功:返回 response.data(即 {code, data, message} 包装对象)
|
||||
// API 函数通过 response.data 取出业务数据(与原始工作代码一致)
|
||||
return response.data
|
||||
// 业务成功:Scheme A — 直接返回 inner data(三端统一契约)
|
||||
return res.data
|
||||
},
|
||||
async (error) => {
|
||||
// 网络错误或服务器错误
|
||||
// 网络错误或服务器错误:统一 reject {code, message}(CTRT-03)
|
||||
let message = '网络异常,请稍后重试'
|
||||
let code = -1
|
||||
|
||||
if (error.response) {
|
||||
code = error.response.status
|
||||
switch (error.response.status) {
|
||||
case 401:
|
||||
// HTTP 401:Token 过期或无效(FastAPI 直接返回的 HTTP 状态码)
|
||||
@@ -116,11 +108,11 @@ apiClient.interceptors.response.use(
|
||||
}
|
||||
|
||||
// 显示轻提示(401 时不显示通用提示,因为会自动跳转授权)
|
||||
if (!error.response || error.response.status !== 401) {
|
||||
if (code !== 401) {
|
||||
showToast(message)
|
||||
}
|
||||
|
||||
return Promise.reject(error)
|
||||
return Promise.reject({ code, message })
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ export async function recallMessage(messageId: string): Promise<any> {
|
||||
const response: AxiosResponse = await apiClient.post(
|
||||
`/messages/${messageId}/recall`
|
||||
)
|
||||
return response.data
|
||||
return response
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -46,7 +46,7 @@ export async function deleteMessage(messageId: string): Promise<any> {
|
||||
const response: AxiosResponse = await apiClient.delete(
|
||||
`/messages/${messageId}`
|
||||
)
|
||||
return response.data
|
||||
return response
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -59,7 +59,7 @@ export async function markConversationRead(conversationId: string): Promise<any>
|
||||
const response: AxiosResponse = await apiClient.post(
|
||||
`/conversations/${conversationId}/mark-read`
|
||||
)
|
||||
return response.data
|
||||
return response
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,7 +77,7 @@ export async function pollMessages(afterMessageId?: string): Promise<Message[]>
|
||||
'/h5/conversations/current/messages/poll',
|
||||
{ params }
|
||||
)
|
||||
const data = response.data.data
|
||||
const data = response
|
||||
const items = data?.items || []
|
||||
// 映射后端字段到前端字段
|
||||
return items.map((item: any) => ({
|
||||
@@ -121,7 +121,7 @@ export async function uploadImage(file: File): Promise<{
|
||||
},
|
||||
}
|
||||
)
|
||||
return response.data.data
|
||||
return response
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -148,5 +148,5 @@ export async function uploadMessageFile(file: File): Promise<{
|
||||
},
|
||||
}
|
||||
)
|
||||
return response.data.data
|
||||
return response
|
||||
}
|
||||
@@ -103,7 +103,7 @@ export async function getTroubleshootingTemplates(
|
||||
page_size: params?.page_size || 20,
|
||||
},
|
||||
})
|
||||
return response.data.data
|
||||
return response
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -116,5 +116,5 @@ export async function getTroubleshootingTemplate(
|
||||
id: string,
|
||||
): Promise<TroubleshootingTemplate> {
|
||||
const response: AxiosResponse = await apiClient.get(`/troubleshooting-templates/${id}`)
|
||||
return response.data.data
|
||||
return response
|
||||
}
|
||||
|
||||
@@ -77,8 +77,8 @@ async function uploadWithRetry(formData: FormData, maxRetries: number = 3): Prom
|
||||
})
|
||||
// 响应拦截器已确保 code === 0
|
||||
// response = {code:0, data: {url:"...",...}, message:"success"}(拦截器返回值)
|
||||
// response.data = 业务数据 {url:"...", filename:"...", ...}
|
||||
return response.data as UploadResponse
|
||||
// response = 业务数据 {url:"...", filename:"...", ...}
|
||||
return response as UploadResponse
|
||||
} catch (err) {
|
||||
if (attempt === maxRetries) throw err
|
||||
// 指数退避:1s, 2s, 4s
|
||||
|
||||
Reference in New Issue
Block a user