260720
This commit is contained in:
447
pages/assistant/chat-service.js
Normal file
447
pages/assistant/chat-service.js
Normal file
@@ -0,0 +1,447 @@
|
||||
import {
|
||||
API_BASE_URL,
|
||||
DEFAULT_TENANT_ID,
|
||||
TOKEN_HEADER_NAME,
|
||||
clearAuthStorage,
|
||||
getStoredUserInfo,
|
||||
getToken,
|
||||
redirectToLogin
|
||||
} from '../../utils/request'
|
||||
|
||||
export { API_BASE_URL, getToken }
|
||||
|
||||
const MODULES_API_URL = API_BASE_URL
|
||||
const APP_SECRET = 'ffd6eee985af45e4a75098422d1decbb'
|
||||
const AI_REQUEST_TIMEOUT = 10 * 60 * 1000
|
||||
|
||||
let realAtob
|
||||
const b64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='
|
||||
const b64re = /^(?:[A-Za-z\d+/]{4})*?(?:[A-Za-z\d+/]{2}(?:==)?|[A-Za-z\d+/]{3}=?)?$/
|
||||
|
||||
if (typeof atob !== 'function') {
|
||||
realAtob = function(str) {
|
||||
let input = String(str || '').replace(/[\t\n\f\r ]+/g, '')
|
||||
if (!b64re.test(input)) {
|
||||
throw new Error("Failed to execute 'atob': The string to be decoded is not correctly encoded.")
|
||||
}
|
||||
input += '=='.slice(2 - (input.length & 3))
|
||||
let bitmap
|
||||
let result = ''
|
||||
let r1
|
||||
let r2
|
||||
let index = 0
|
||||
for (; index < input.length;) {
|
||||
bitmap =
|
||||
(b64.indexOf(input.charAt(index++)) << 18) |
|
||||
(b64.indexOf(input.charAt(index++)) << 12) |
|
||||
((r1 = b64.indexOf(input.charAt(index++))) << 6) |
|
||||
(r2 = b64.indexOf(input.charAt(index++)))
|
||||
result +=
|
||||
r1 === 64
|
||||
? String.fromCharCode((bitmap >> 16) & 255)
|
||||
: r2 === 64
|
||||
? String.fromCharCode((bitmap >> 16) & 255, (bitmap >> 8) & 255)
|
||||
: String.fromCharCode((bitmap >> 16) & 255, (bitmap >> 8) & 255, bitmap & 255)
|
||||
}
|
||||
return result
|
||||
}
|
||||
} else {
|
||||
realAtob = atob
|
||||
}
|
||||
|
||||
function b64DecodeUnicode(str) {
|
||||
return decodeURIComponent(
|
||||
realAtob(str)
|
||||
.split('')
|
||||
.map((char) => `%${`00${char.charCodeAt(0).toString(16)}`.slice(-2)}`)
|
||||
.join('')
|
||||
)
|
||||
}
|
||||
|
||||
function parseTokenPayload(token) {
|
||||
const rawToken = String(token || '').replace(/^Bearer\s+/i, '')
|
||||
const parts = rawToken.split('.')
|
||||
if (!rawToken || parts.length !== 3) {
|
||||
return null
|
||||
}
|
||||
try {
|
||||
const normalized = parts[1].replace(/-/g, '+').replace(/_/g, '/')
|
||||
return JSON.parse(b64DecodeUnicode(normalized))
|
||||
} catch (error) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
function safeAdd(x, y) {
|
||||
const lsw = (x & 0xffff) + (y & 0xffff)
|
||||
const msw = (x >> 16) + (y >> 16) + (lsw >> 16)
|
||||
return (msw << 16) | (lsw & 0xffff)
|
||||
}
|
||||
|
||||
function bitRotateLeft(num, cnt) {
|
||||
return (num << cnt) | (num >>> (32 - cnt))
|
||||
}
|
||||
|
||||
function md5cmn(q, a, b, x, s, t) {
|
||||
return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b)
|
||||
}
|
||||
|
||||
function md5ff(a, b, c, d, x, s, t) {
|
||||
return md5cmn((b & c) | (~b & d), a, b, x, s, t)
|
||||
}
|
||||
|
||||
function md5gg(a, b, c, d, x, s, t) {
|
||||
return md5cmn((b & d) | (c & ~d), a, b, x, s, t)
|
||||
}
|
||||
|
||||
function md5hh(a, b, c, d, x, s, t) {
|
||||
return md5cmn(b ^ c ^ d, a, b, x, s, t)
|
||||
}
|
||||
|
||||
function md5ii(a, b, c, d, x, s, t) {
|
||||
return md5cmn(c ^ (b | ~d), a, b, x, s, t)
|
||||
}
|
||||
|
||||
function binlMD5(x, len) {
|
||||
x[len >> 5] |= 0x80 << len % 32
|
||||
x[(((len + 64) >>> 9) << 4) + 14] = len
|
||||
|
||||
let i
|
||||
let olda
|
||||
let oldb
|
||||
let oldc
|
||||
let oldd
|
||||
let a = 1732584193
|
||||
let b = -271733879
|
||||
let c = -1732584194
|
||||
let d = 271733878
|
||||
|
||||
for (i = 0; i < x.length; i += 16) {
|
||||
olda = a
|
||||
oldb = b
|
||||
oldc = c
|
||||
oldd = d
|
||||
|
||||
a = md5ff(a, b, c, d, x[i], 7, -680876936)
|
||||
d = md5ff(d, a, b, c, x[i + 1], 12, -389564586)
|
||||
c = md5ff(c, d, a, b, x[i + 2], 17, 606105819)
|
||||
b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330)
|
||||
a = md5ff(a, b, c, d, x[i + 4], 7, -176418897)
|
||||
d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426)
|
||||
c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341)
|
||||
b = md5ff(b, c, d, a, x[i + 7], 22, -45705983)
|
||||
a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416)
|
||||
d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417)
|
||||
c = md5ff(c, d, a, b, x[i + 10], 17, -42063)
|
||||
b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162)
|
||||
a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682)
|
||||
d = md5ff(d, a, b, c, x[i + 13], 12, -40341101)
|
||||
c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290)
|
||||
b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329)
|
||||
|
||||
a = md5gg(a, b, c, d, x[i + 1], 5, -165796510)
|
||||
d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632)
|
||||
c = md5gg(c, d, a, b, x[i + 11], 14, 643717713)
|
||||
b = md5gg(b, c, d, a, x[i], 20, -373897302)
|
||||
a = md5gg(a, b, c, d, x[i + 5], 5, -701558691)
|
||||
d = md5gg(d, a, b, c, x[i + 10], 9, 38016083)
|
||||
c = md5gg(c, d, a, b, x[i + 15], 14, -660478335)
|
||||
b = md5gg(b, c, d, a, x[i + 4], 20, -405537848)
|
||||
a = md5gg(a, b, c, d, x[i + 9], 5, 568446438)
|
||||
d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690)
|
||||
c = md5gg(c, d, a, b, x[i + 3], 14, -187363961)
|
||||
b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501)
|
||||
a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467)
|
||||
d = md5gg(d, a, b, c, x[i + 2], 9, -51403784)
|
||||
c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473)
|
||||
b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734)
|
||||
|
||||
a = md5hh(a, b, c, d, x[i + 5], 4, -378558)
|
||||
d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463)
|
||||
c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562)
|
||||
b = md5hh(b, c, d, a, x[i + 14], 23, -35309556)
|
||||
a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060)
|
||||
d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353)
|
||||
c = md5hh(c, d, a, b, x[i + 7], 16, -155497632)
|
||||
b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640)
|
||||
a = md5hh(a, b, c, d, x[i + 13], 4, 681279174)
|
||||
d = md5hh(d, a, b, c, x[i], 11, -358537222)
|
||||
c = md5hh(c, d, a, b, x[i + 3], 16, -722521979)
|
||||
b = md5hh(b, c, d, a, x[i + 6], 23, 76029189)
|
||||
a = md5hh(a, b, c, d, x[i + 9], 4, -640364487)
|
||||
d = md5hh(d, a, b, c, x[i + 12], 11, -421815835)
|
||||
c = md5hh(c, d, a, b, x[i + 15], 16, 530742520)
|
||||
b = md5hh(b, c, d, a, x[i + 2], 23, -995338651)
|
||||
|
||||
a = md5ii(a, b, c, d, x[i], 6, -198630844)
|
||||
d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415)
|
||||
c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905)
|
||||
b = md5ii(b, c, d, a, x[i + 5], 21, -57434055)
|
||||
a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571)
|
||||
d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606)
|
||||
c = md5ii(c, d, a, b, x[i + 10], 15, -1051523)
|
||||
b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799)
|
||||
a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359)
|
||||
d = md5ii(d, a, b, c, x[i + 15], 10, -30611744)
|
||||
c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380)
|
||||
b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649)
|
||||
a = md5ii(a, b, c, d, x[i + 4], 6, -145523070)
|
||||
d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379)
|
||||
c = md5ii(c, d, a, b, x[i + 2], 15, 718787259)
|
||||
b = md5ii(b, c, d, a, x[i + 9], 21, -343485551)
|
||||
|
||||
a = safeAdd(a, olda)
|
||||
b = safeAdd(b, oldb)
|
||||
c = safeAdd(c, oldc)
|
||||
d = safeAdd(d, oldd)
|
||||
}
|
||||
return [a, b, c, d]
|
||||
}
|
||||
|
||||
function binl2rstr(input) {
|
||||
let index
|
||||
let output = ''
|
||||
const length32 = input.length * 32
|
||||
for (index = 0; index < length32; index += 8) {
|
||||
output += String.fromCharCode((input[index >> 5] >>> index % 32) & 0xff)
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
function rstr2binl(input) {
|
||||
const output = Array(input.length >> 2)
|
||||
let index
|
||||
for (index = 0; index < output.length; index += 1) {
|
||||
output[index] = 0
|
||||
}
|
||||
const length8 = input.length * 8
|
||||
for (index = 0; index < length8; index += 8) {
|
||||
output[index >> 5] |= (input.charCodeAt(index / 8) & 0xff) << index % 32
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
function rstrMD5(value) {
|
||||
return binl2rstr(binlMD5(rstr2binl(value), value.length * 8))
|
||||
}
|
||||
|
||||
function rstr2hex(input) {
|
||||
const hexTab = '0123456789abcdef'
|
||||
let output = ''
|
||||
let index
|
||||
let value
|
||||
for (index = 0; index < input.length; index += 1) {
|
||||
value = input.charCodeAt(index)
|
||||
output += hexTab.charAt((value >>> 4) & 0x0f) + hexTab.charAt(value & 0x0f)
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
function str2rstrUTF8(input) {
|
||||
return unescape(encodeURIComponent(input))
|
||||
}
|
||||
|
||||
function md5(value) {
|
||||
return rstr2hex(rstrMD5(str2rstrUTF8(String(value || ''))))
|
||||
}
|
||||
|
||||
function objKeySort(obj) {
|
||||
const next = {}
|
||||
Object.keys(obj || {})
|
||||
.sort()
|
||||
.forEach((key) => {
|
||||
next[key] = obj[key]
|
||||
})
|
||||
return next
|
||||
}
|
||||
|
||||
function addSignature(payload) {
|
||||
const form = payload || {}
|
||||
form.timestamp = Date.now()
|
||||
form.version = 'v3'
|
||||
let sign = ''
|
||||
const sorted = objKeySort(form)
|
||||
Object.keys(sorted).forEach((key) => {
|
||||
const value = form[key]
|
||||
if (value !== null && value !== undefined && value !== '') {
|
||||
sign = `${sign}${value}-`
|
||||
}
|
||||
})
|
||||
form.sign = md5(`${sign}${APP_SECRET}`)
|
||||
return form
|
||||
}
|
||||
|
||||
function getStorageValue(keys) {
|
||||
for (let index = 0; index < keys.length; index += 1) {
|
||||
const value = uni.getStorageSync(keys[index])
|
||||
if (value) {
|
||||
return value
|
||||
}
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
export function getCurrentUser() {
|
||||
const primaryToken = getToken()
|
||||
const storedUser = getStoredUserInfo()
|
||||
const tokenList = [
|
||||
primaryToken,
|
||||
uni.getStorageSync('uni_id_token'),
|
||||
uni.getStorageSync('access_token')
|
||||
].filter(Boolean)
|
||||
let payload = null
|
||||
|
||||
for (let index = 0; index < tokenList.length; index += 1) {
|
||||
payload = parseTokenPayload(tokenList[index])
|
||||
if (payload) {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (!payload) {
|
||||
return {
|
||||
...storedUser,
|
||||
token: primaryToken || ''
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
...storedUser,
|
||||
userId: Number(payload.userId || payload.uid || payload.id || 0) || null,
|
||||
nickname: payload.nickname || payload.username || payload.nickName || '',
|
||||
realName: payload.realName || payload.realname || payload.name || '',
|
||||
token: primaryToken || ''
|
||||
}
|
||||
}
|
||||
|
||||
export function apiRequest({
|
||||
url,
|
||||
method = 'GET',
|
||||
data,
|
||||
withSignature = true,
|
||||
withTenant = false,
|
||||
timeout
|
||||
}) {
|
||||
const token = getToken()
|
||||
const requestData = data ? { ...data } : undefined
|
||||
const headers = {}
|
||||
|
||||
if (token) {
|
||||
headers[TOKEN_HEADER_NAME] = token
|
||||
}
|
||||
|
||||
if (requestData && withTenant) {
|
||||
requestData.tenantId = DEFAULT_TENANT_ID
|
||||
}
|
||||
|
||||
if (requestData && withSignature) {
|
||||
addSignature(requestData)
|
||||
}
|
||||
|
||||
return uni.request({
|
||||
url,
|
||||
method,
|
||||
data: requestData,
|
||||
header: headers,
|
||||
...(timeout !== undefined && { timeout })
|
||||
}).then((response) => {
|
||||
const responseHeader = (response && response.header) || {}
|
||||
const nextToken =
|
||||
responseHeader[TOKEN_HEADER_NAME] ||
|
||||
responseHeader[TOKEN_HEADER_NAME.toLowerCase()]
|
||||
if (nextToken) {
|
||||
uni.setStorageSync('access_token', nextToken)
|
||||
}
|
||||
|
||||
const { statusCode } = response || {}
|
||||
const body = (response && response.data) || {}
|
||||
if (statusCode && statusCode >= 400) {
|
||||
return Promise.reject(new Error(body.message || '请求失败'))
|
||||
}
|
||||
if (Number(body.code) === 401) {
|
||||
clearAuthStorage()
|
||||
redirectToLogin()
|
||||
return Promise.reject(new Error(body.message || '登录已失效'))
|
||||
}
|
||||
if (body.code === 0) {
|
||||
return body.data !== undefined ? body.data : body.message
|
||||
}
|
||||
return Promise.reject(new Error(body.message || '请求失败'))
|
||||
})
|
||||
}
|
||||
|
||||
export function listAiChatList(params) {
|
||||
return apiRequest({
|
||||
url: `${MODULES_API_URL}/ai/ai-chat-list`,
|
||||
method: 'GET',
|
||||
data: params
|
||||
})
|
||||
}
|
||||
|
||||
export function listAiChatHistory(params) {
|
||||
return apiRequest({
|
||||
url: `${MODULES_API_URL}/ai/ai-chat-history`,
|
||||
method: 'GET',
|
||||
data: params
|
||||
})
|
||||
}
|
||||
|
||||
export function removeAiChatList(id) {
|
||||
return apiRequest({
|
||||
url: `${MODULES_API_URL}/ai/ai-chat-list/${id}`,
|
||||
method: 'DELETE',
|
||||
withSignature: false
|
||||
})
|
||||
}
|
||||
|
||||
export function sendMessage(data) {
|
||||
return apiRequest({
|
||||
url: `${API_BASE_URL}/ai/chat/message`,
|
||||
method: 'POST',
|
||||
data,
|
||||
withTenant: true,
|
||||
timeout: AI_REQUEST_TIMEOUT
|
||||
})
|
||||
}
|
||||
|
||||
export function manuscriptGen(data) {
|
||||
return apiRequest({
|
||||
url: `${API_BASE_URL}/ai/manuscriptGen`,
|
||||
method: 'POST',
|
||||
data,
|
||||
withTenant: true,
|
||||
timeout: AI_REQUEST_TIMEOUT
|
||||
})
|
||||
}
|
||||
|
||||
export function creativeAssistant(data) {
|
||||
return apiRequest({
|
||||
url: `${API_BASE_URL}/ai/creativeAssistant`,
|
||||
method: 'POST',
|
||||
data,
|
||||
withTenant: true,
|
||||
timeout: AI_REQUEST_TIMEOUT
|
||||
})
|
||||
}
|
||||
|
||||
export function activityOutlineGen(data) {
|
||||
return apiRequest({
|
||||
url: `${API_BASE_URL}/ai/activityOutlineGen`,
|
||||
method: 'POST',
|
||||
data,
|
||||
withTenant: true,
|
||||
timeout: AI_REQUEST_TIMEOUT
|
||||
})
|
||||
}
|
||||
|
||||
export function buildWebSocketUrl(userId) {
|
||||
const url = String(API_BASE_URL || '')
|
||||
if (/^https?:\/\//.test(url)) {
|
||||
return `${url
|
||||
.replace(/^https:/, 'wss:')
|
||||
.replace(/^http:/, 'ws:')
|
||||
.replace(/\/api\/?$/, '')
|
||||
.replace(/\/$/, '')}/chat/${userId}`
|
||||
}
|
||||
return `${url.replace(/\/api\/?$/, '')}/chat/${userId}`
|
||||
}
|
||||
1725
pages/assistant/index.vue
Normal file
1725
pages/assistant/index.vue
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user