Files
frontend-app/uni_modules/hashmall-customer-service/js_sdk/api.js
T
2026-09-09 11:46:36 +08:00

224 lines
7.1 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import request from '@/utils/request.js'
import { BASE_URL, KEFU_BASE_URL, Authorization } from '@/utils/config.js'
import { getStorageFun, TOKEN_NAME } from '@/utils/auth.js'
export const CONTENT_TYPE = Object.freeze({
TEXT: 1,
IMAGE: 2,
FILE: 3,
AUDIO: 4,
PRODUCT: 10,
ORDER: 11,
QUOTE: 12,
RECALLED: 99
})
function kefuRequest({ url, method = 'GET', data = {} }) {
const token = getStorageFun(TOKEN_NAME)
return new Promise((resolve, reject) => {
uni.request({
url: `${KEFU_BASE_URL}${url}`,
method,
data,
header: {
Authorization,
'HSM-AUTH': token || '',
'content-type': 'application/json'
},
success: response => {
const body = response.data || {}
if (response.statusCode >= 200 && response.statusCode < 300 && body.bizcode === 100) {
resolve(body)
return
}
const error = new Error(body.msg || `客服接口请求失败(${response.statusCode})`)
error.statusCode = response.statusCode
error.response = body
reject(error)
},
fail: error => reject(new Error(error.errMsg || '客服接口连接失败'))
})
})
}
export function getCurrentMember() {
return request({ url: '/user/getUserInfo', method: 'get', isShowLoading: false }).then(result => result.data)
}
export function getMessages({ userId, conversationId, page = 1, pageSize = 20 }) {
const data = conversationId ? { userId, conversationId, page, pageSize } : { userId, page, pageSize }
return kefuRequest({
url: '/kefu/user/messages',
method: 'get',
data: data
}).then(result => result.data || {})
}
export function sendMessage(data) {
return kefuRequest({
url: '/kefu/user/send',
method: 'post',
data
}).then(result => result.data)
}
export function transferToHuman({ userId, conversationId, reason = '用户点击转人工' }) {
return kefuRequest({
url: '/kefu/user/transfer-human',
method: 'post',
data: { userId, conversationId, reason }
}).then(result => result.data)
}
export function recallMessage({ userId, messageId }) {
const data = { userId, messageId }
return kefuRequest({
url: '/kefu/user/message/recall',
method: 'post',
data
}).catch(error => {
if (!error || error.statusCode !== 404) throw error
return kefuRequest({ url: '/kefu/user/recall', method: 'post', data })
})
.then(result => result.data)
}
export function deleteMessageForMember({ userId, messageId }) {
return kefuRequest({
url: '/kefu/user/message/delete',
method: 'post',
data: { userId, messageId }
}).then(result => result.data)
}
export function transcribeMessage({ userId, messageId }) {
return kefuRequest({
url: '/kefu/user/message/transcribe',
method: 'post',
data: { userId, messageId }
}).then(result => result.data)
}
export function getUnreadCount(userId) {
return kefuRequest({
url: '/kefu/user/unread-count',
method: 'get',
data: { userId }
}).then(result => Number(result.data || 0))
}
export function markMemberMessagesRead({ userId, conversationId }) {
return kefuRequest({
url: '/kefu/user/read',
method: 'post',
data: { userId, conversationId }
}).then(result => result.data)
}
export function getBrowseHistory({ userId, page = 1, pageSize = 10 }) {
return kefuRequest({
url: '/kefu/user/browse-history',
method: 'get',
data: { userId, page, pageSize }
}).then(result => result.data)
}
export function getOrders({ userId, page = 1, pageSize = 10 }) {
return kefuRequest({
url: '/kefu/user/orders',
method: 'get',
data: { userId, page, pageSize }
}).then(result => result.data)
}
export function uploadMessageImage(filePath) {
const token = getStorageFun(TOKEN_NAME)
return new Promise((resolve, reject) => {
uni.uploadFile({
url: `${BASE_URL}/common/upload/image`,
filePath,
name: 'file',
formData: { type: 'COMMON' },
header: {
Authorization,
'HSM-AUTH': token || ''
},
success: response => {
try {
const body = typeof response.data === 'string' ? JSON.parse(response.data) : response.data
if (!body || body.bizcode !== 100) throw new Error((body && body.msg) || '图片上传失败')
const data = body.data || {}
const url = data.accessUrl || data.dbUrl || data.url || data.fileUrl || data.path
if (!url) throw new Error('图片上传后未返回访问地址')
resolve(url)
} catch (error) {
reject(error)
}
},
fail: error => reject(new Error(error.errMsg || '图片上传失败'))
})
})
}
function resolveUploadResult(response, fallbackMessage) {
const body = typeof response.data === 'string' ? JSON.parse(response.data) : response.data
if (!body || body.bizcode !== 100) throw new Error((body && body.msg) || fallbackMessage)
const data = body.data || {}
const url = data.accessUrl || data.dbUrl || data.url || data.fileUrl || data.path
if (!url) throw new Error('上传成功但未返回访问地址')
return url
}
export function uploadMessageAsset(source, kind = 'file') {
const token = getStorageFun(TOKEN_NAME)
const endpoints = [...new Set([
`${String(KEFU_BASE_URL).replace(/\/$/, '')}/kefu/user/upload/${kind}`,
`${String(BASE_URL).replace(/\/$/, '')}/common/upload/${kind}`
])]
// #ifdef H5
if (typeof Blob !== 'undefined' && source instanceof Blob) {
const formData = new FormData()
formData.append('file', source, source.name || `${kind}-${Date.now()}`)
return (async () => {
let lastError = null
for (const endpoint of endpoints) {
const response = await fetch(endpoint, {
method: 'POST',
headers: { Authorization, 'HSM-AUTH': token || '' },
body: formData
})
if (response.status === 404) {
lastError = new Error(`${kind === 'audio' ? '语音' : '文件'}上传接口不存在`)
continue
}
return resolveUploadResult({ data: await response.text() }, `${kind === 'audio' ? '语音' : '文件'}上传失败`)
}
throw lastError || new Error(`${kind === 'audio' ? '语音' : '文件'}上传失败`)
})()
}
// #endif
const filePath = typeof source === 'string' ? source : (source.tempFilePath || source.path)
return new Promise((resolve, reject) => {
const uploadAt = index => {
uni.uploadFile({
url: endpoints[index],
filePath,
name: 'file',
header: { Authorization, 'HSM-AUTH': token || '' },
success: response => {
if (Number(response.statusCode) === 404 && index + 1 < endpoints.length) {
uploadAt(index + 1)
return
}
try { resolve(resolveUploadResult(response, `${kind === 'audio' ? '语音' : '文件'}上传失败`)) } catch (error) { reject(error) }
},
fail: error => reject(new Error(error.errMsg || `${kind === 'audio' ? '语音' : '文件'}上传失败`))
})
}
uploadAt(0)
})
}
export const uploadMessageFile = source => uploadMessageAsset(source, 'file')
export const uploadMessageAudio = source => uploadMessageAsset(source, 'audio')