|
|
|
|
@ -382,16 +382,20 @@ export const useAppStore = defineStore('app', () => { |
|
|
|
|
if (!payload || typeof payload !== 'object') return '' |
|
|
|
|
|
|
|
|
|
const options = payload.message?.[0]?.options || {} |
|
|
|
|
const reqAndResType = String(payload.reqAndResType || '') |
|
|
|
|
const msgType = String(payload.msgType || '') |
|
|
|
|
const fromFlag = String(payload.fromFlag || '') |
|
|
|
|
const reqAndResType = String(payload.reqAndResType || '').trim() |
|
|
|
|
const msgType = String(payload.msgType || '').trim() |
|
|
|
|
const fromFlag = String(payload.fromFlag || '').trim() |
|
|
|
|
const isProtocolImage = |
|
|
|
|
(reqAndResType === '2' && fromFlag === '1' && msgType !== '01') || |
|
|
|
|
(reqAndResType === '08' && msgType === '02') |
|
|
|
|
const isTextAnswer = Boolean(payload.msgText) && (msgType === '01' || fromFlag !== '1') && !isProtocolImage |
|
|
|
|
// msgType=01 text answers must not be treated as images even with leftover imageUrl.
|
|
|
|
|
const hasTextBody = Boolean( |
|
|
|
|
payload.msgText || payload.answer || payload.answerText || payload.content || payload.text, |
|
|
|
|
) |
|
|
|
|
const isTextAnswer = hasTextBody && (msgType === '01' || msgType === '1' || fromFlag !== '1') && !isProtocolImage |
|
|
|
|
const hasExplicitImageField = !isTextAnswer && Boolean( |
|
|
|
|
payload.imgUrl || payload.imgKey || payload.fileKey || |
|
|
|
|
(payload.imageUrl && !payload.msgText), |
|
|
|
|
(payload.imageUrl && !hasTextBody), |
|
|
|
|
) |
|
|
|
|
const isImageMessage = |
|
|
|
|
!isTextAnswer && ( |
|
|
|
|
@ -401,7 +405,7 @@ export const useAppStore = defineStore('app', () => { |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
if (!isImageMessage) { |
|
|
|
|
return payload.imageUrl || options.imageUrl || '' |
|
|
|
|
return '' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// liics may return an image URL/key in any of these fields. For a
|
|
|
|
|
@ -421,13 +425,16 @@ export const useAppStore = defineStore('app', () => { |
|
|
|
|
function isConversationImage(payload, imageUrl) { |
|
|
|
|
if (!payload || typeof payload !== 'object') return false |
|
|
|
|
|
|
|
|
|
const reqAndResType = String(payload.reqAndResType || '') |
|
|
|
|
const msgType = String(payload.msgType || '') |
|
|
|
|
const fromFlag = String(payload.fromFlag || '') |
|
|
|
|
const reqAndResType = String(payload.reqAndResType || '').trim() |
|
|
|
|
const msgType = String(payload.msgType || '').trim() |
|
|
|
|
const fromFlag = String(payload.fromFlag || '').trim() |
|
|
|
|
const isProtocolImage = |
|
|
|
|
(reqAndResType === '2' && fromFlag === '1' && msgType !== '01') || |
|
|
|
|
(reqAndResType === '08' && msgType === '02') |
|
|
|
|
const isTextAnswer = Boolean(payload.msgText) && (msgType === '01' || fromFlag !== '1') && !isProtocolImage |
|
|
|
|
const hasTextBody = Boolean( |
|
|
|
|
payload.msgText || payload.answer || payload.answerText || payload.content || payload.text, |
|
|
|
|
) |
|
|
|
|
const isTextAnswer = hasTextBody && (msgType === '01' || msgType === '1' || fromFlag !== '1') && !isProtocolImage |
|
|
|
|
return Boolean( |
|
|
|
|
!isTextAnswer && imageUrl && ( |
|
|
|
|
payload.message?.[0]?.type === 'image' || |
|
|
|
|
@ -435,26 +442,22 @@ export const useAppStore = defineStore('app', () => { |
|
|
|
|
payload.imgUrl || |
|
|
|
|
payload.imgKey || |
|
|
|
|
payload.fileKey || |
|
|
|
|
(payload.imageUrl && !payload.msgText) |
|
|
|
|
(payload.imageUrl && !hasTextBody) |
|
|
|
|
), |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// liics 的 qaChat 使用 msgText/fromFlag,chat-new 使用 message/type。
|
|
|
|
|
// 在 store 边界统一转换,旧聊天组件继续读取 chatList,新页面读取 chatArr。
|
|
|
|
|
function pushConversationMessage(payload, fallbackType = 'bot') { |
|
|
|
|
const payloadList = Array.isArray(payload) ? payload : [payload] |
|
|
|
|
let lastMessage = null |
|
|
|
|
|
|
|
|
|
payloadList.forEach((item) => { |
|
|
|
|
if (item == null) return |
|
|
|
|
// liics qaChat uses msgText/fromFlag; chat-new uses message/type.
|
|
|
|
|
// Normalize at the store boundary so chat-content can keep reading chatArr.
|
|
|
|
|
function formatConversationMessage(item, fallbackType = 'bot') { |
|
|
|
|
if (item == null) return null |
|
|
|
|
|
|
|
|
|
const content = getConversationMessageText(item) |
|
|
|
|
const imageUrl = getConversationImageSource(item) |
|
|
|
|
const isImage = isConversationImage(item, imageUrl) |
|
|
|
|
if (!content && !imageUrl) return |
|
|
|
|
if (!content && !imageUrl) return null |
|
|
|
|
|
|
|
|
|
const fromFlag = typeof item === 'object' ? String(item.fromFlag || '') : '' |
|
|
|
|
const fromFlag = typeof item === 'object' ? String(item.fromFlag ?? '').trim() : '' |
|
|
|
|
const messageType = fromFlag === '1' ? 'user' : fromFlag === '2' ? 'bot' : fallbackType |
|
|
|
|
const resolvedFromFlag = |
|
|
|
|
fromFlag || (messageType === 'user' ? '1' : messageType === 'bot' ? '2' : '') |
|
|
|
|
@ -464,37 +467,45 @@ export const useAppStore = defineStore('app', () => { |
|
|
|
|
typeof item === 'object' && item.reqAndResType !== undefined && item.reqAndResType !== null && item.reqAndResType !== '' |
|
|
|
|
const hasMsgType = |
|
|
|
|
typeof item === 'object' && item.msgType !== undefined && item.msgType !== null && item.msgType !== '' |
|
|
|
|
// chat-content 机器人文本分支依赖 reqAndResType=='01' && msgType=='01'
|
|
|
|
|
const resolvedReqAndResType = hasReqType |
|
|
|
|
? item.reqAndResType |
|
|
|
|
: imageUrl |
|
|
|
|
? (messageType === 'user' ? '2' : '2') |
|
|
|
|
// chat-content bot text branch depends on reqAndResType=='01' && msgType=='01'
|
|
|
|
|
let resolvedReqAndResType = hasReqType |
|
|
|
|
? String(item.reqAndResType).trim() |
|
|
|
|
: isImage |
|
|
|
|
? '2' |
|
|
|
|
: messageType === 'bot' |
|
|
|
|
? '01' |
|
|
|
|
: '1' |
|
|
|
|
const resolvedMsgType = hasMsgType |
|
|
|
|
? item.msgType |
|
|
|
|
: imageUrl |
|
|
|
|
let resolvedMsgType = hasMsgType |
|
|
|
|
? String(item.msgType).trim() |
|
|
|
|
: isImage |
|
|
|
|
? '02' |
|
|
|
|
: '01' |
|
|
|
|
const message = { |
|
|
|
|
|
|
|
|
|
// Bot plain text: normalize backend '1'/1 into chat-content '01'
|
|
|
|
|
if (messageType === 'bot' && !isImage) { |
|
|
|
|
if (resolvedReqAndResType === '1') resolvedReqAndResType = '01' |
|
|
|
|
if (resolvedMsgType === '1') resolvedMsgType = '01' |
|
|
|
|
if (!hasMsgType) resolvedMsgType = '01' |
|
|
|
|
if (!hasReqType) resolvedReqAndResType = '01' |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return { |
|
|
|
|
...(typeof item === 'object' ? item : {}), |
|
|
|
|
type: messageType, |
|
|
|
|
system: (typeof item === 'object' && item.system) || 'LIICS', |
|
|
|
|
isSendSuccess: typeof item === 'object' ? item.isSendSuccess !== false : true, |
|
|
|
|
imageUrl, |
|
|
|
|
system: item?.system || 'LIICS', |
|
|
|
|
isSendSuccess: item?.isSendSuccess !== false, |
|
|
|
|
imageUrl: isImage ? imageUrl : '', |
|
|
|
|
imageKey: isImage ? imageUrl : '', |
|
|
|
|
raw: item, |
|
|
|
|
// 兼容 chat-content:保留/补齐 liics 字段
|
|
|
|
|
// keep/fill liics fields for chat-content
|
|
|
|
|
msgText: content || (typeof item === 'object' ? item.msgText : '') || '', |
|
|
|
|
fromFlag: resolvedFromFlag, |
|
|
|
|
reqAndResType: resolvedReqAndResType, |
|
|
|
|
msgType: resolvedMsgType, |
|
|
|
|
timestamp: resolvedTimestamp, |
|
|
|
|
imgUrl: (typeof item === 'object' && (item.imgUrl || item.imageUrl)) || imageUrl || '', |
|
|
|
|
imgUrl: isImage |
|
|
|
|
? ((typeof item === 'object' && (item.imgUrl || item.imageUrl)) || imageUrl || '') |
|
|
|
|
: '', |
|
|
|
|
VIEW_ID: |
|
|
|
|
(typeof item === 'object' && item.VIEW_ID) || ('msg' + resolvedTimestamp), |
|
|
|
|
message: [ |
|
|
|
|
@ -512,9 +523,26 @@ export const useAppStore = defineStore('app', () => { |
|
|
|
|
}, |
|
|
|
|
], |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function normalizeHistoryMessages(list = []) { |
|
|
|
|
return (Array.isArray(list) ? list : []).map((item) => { |
|
|
|
|
const fallbackType = |
|
|
|
|
String(item?.fromFlag ?? '') === '1' || item?.fromFlag === 1 ? 'user' : 'bot' |
|
|
|
|
return formatConversationMessage(item, fallbackType) || item |
|
|
|
|
}) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function pushConversationMessage(payload, fallbackType = 'bot') { |
|
|
|
|
const payloadList = Array.isArray(payload) ? payload : [payload] |
|
|
|
|
let lastMessage = null |
|
|
|
|
|
|
|
|
|
payloadList.forEach((item) => { |
|
|
|
|
const message = formatConversationMessage(item, fallbackType) |
|
|
|
|
if (!message) return |
|
|
|
|
|
|
|
|
|
chatArr.value.push(message) |
|
|
|
|
isChatLoading.value = messageType === 'user' |
|
|
|
|
isChatLoading.value = message.type === 'user' |
|
|
|
|
lastMessage = message |
|
|
|
|
}) |
|
|
|
|
|
|
|
|
|
@ -916,7 +944,25 @@ export const useAppStore = defineStore('app', () => { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function isMessageLike(value) { |
|
|
|
|
if (!value || typeof value !== 'object' || Array.isArray(value)) return false |
|
|
|
|
return ( |
|
|
|
|
value.msgText != null || |
|
|
|
|
value.answer != null || |
|
|
|
|
value.answerText != null || |
|
|
|
|
value.msgType != null || |
|
|
|
|
value.reqAndResType != null || |
|
|
|
|
value.fromFlag != null || |
|
|
|
|
value.cmd != null |
|
|
|
|
) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function getResponsePayload(response) { |
|
|
|
|
if (response == null) return response |
|
|
|
|
if (Array.isArray(response)) return response |
|
|
|
|
if (Array.isArray(response.data)) return response.data |
|
|
|
|
if (isMessageLike(response.data)) return response.data |
|
|
|
|
if (isMessageLike(response)) return response |
|
|
|
|
return response?.data ?? response |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@ -1406,6 +1452,9 @@ export const useAppStore = defineStore('app', () => { |
|
|
|
|
setSysConfig, |
|
|
|
|
setHeaderAvatar, |
|
|
|
|
pushUserMessage, |
|
|
|
|
formatConversationMessage, |
|
|
|
|
normalizeHistoryMessages, |
|
|
|
|
pushConversationMessage, |
|
|
|
|
pushImageMessage, |
|
|
|
|
updateImageMessage, |
|
|
|
|
setSendLoading, |
|
|
|
|
|