| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- import { resolveResourceUrl } from '@/utils/resourceUrl'
- /** 与后端 ConsultSessionRules 一致 */
- export const SENDER_ROLE_USER = 1
- export const SENDER_ROLE_VET = 2
- export const SENDER_ROLE_AI = 3
- export const MSG_TYPE_TEXT = 1
- export const MSG_TYPE_IMAGE = 2
- export const MSG_TYPE_VIDEO = 3
- export const MSG_TYPE_VOICE = 4
- export const DEFAULT_SESSION_TITLE = '新会话'
- export const MESSAGE_PAGE_SIZE = 50
- /** 移动端快捷分类:问诊 / 咨询 */
- export const AI_CATEGORY = {
- advise: 1,
- consult: 2,
- medicine: 3,
- device: 4
- }
- function resolveConsultIdFromIdFields(session) {
- if (!session) return null
- if (session.id != null && session.id !== '') {
- return String(session.id)
- }
- if (session.realSessionId != null && session.realSessionId !== '') {
- return String(session.realSessionId)
- }
- return null
- }
- /**
- * 若依问诊会话主键(listAiConsultMessages / sendAiConsultMessage 路径参数)。
- * 与改造前一致:id → 列表 sessionId → realSessionId。
- */
- export function resolveConsultSessionId(session) {
- if (!session) return null
- if (typeof session === 'string' || typeof session === 'number') {
- return String(session)
- }
- const fromId = resolveConsultIdFromIdFields(session)
- if (fromId) {
- return fromId
- }
- if (session.sessionId != null && session.sessionId !== '') {
- return String(session.sessionId)
- }
- return null
- }
- /** @deprecated 使用 resolveConsultSessionId */
- export function resolveSessionId(session) {
- return resolveConsultSessionId(session)
- }
- /** 列表 rows[].sessionId:与若依主键不同时,为大模型网关 sessionId */
- export function resolveLlmSessionIdFromRow(session) {
- if (!session) return null
- if (session.llmSessionId != null && session.llmSessionId !== '') {
- return String(session.llmSessionId)
- }
- const consultId = resolveConsultIdFromIdFields(session)
- if (session.sessionId != null && session.sessionId !== '') {
- const sid = String(session.sessionId)
- if (!consultId || sid !== consultId) {
- return sid
- }
- }
- return null
- }
- /** 解析当前会话的大模型 sessionId(行内字段 + 可选本地缓存) */
- export function resolveLlmSessionId(session, loadFromStorage) {
- if (!session) return null
- const consultId = resolveConsultSessionId(session)
- const fromRow =
- resolveLlmSessionIdFromRow(session) ||
- (session.llmSessionId != null && session.llmSessionId !== '' ? String(session.llmSessionId) : null)
- if (fromRow) return fromRow
- if (consultId && typeof loadFromStorage === 'function') {
- const stored = loadFromStorage(consultId)
- if (stored) return String(stored)
- }
- return null
- }
- /** 列表行标准化:realSessionId → id;sessionId(列表) → llmSessionId */
- export function normalizeSessionRow(row, llmByConsultId) {
- const consultId = resolveConsultSessionId(row)
- if (!consultId) {
- return row
- }
- const map = llmByConsultId && typeof llmByConsultId === 'object' ? llmByConsultId : {}
- const llm =
- resolveLlmSessionIdFromRow(row) ||
- (row.llmSessionId != null && row.llmSessionId !== '' ? String(row.llmSessionId) : null) ||
- map[consultId] ||
- null
- return {
- ...row,
- id: consultId,
- realSessionId: row.realSessionId != null && row.realSessionId !== '' ? String(row.realSessionId) : consultId,
- llmSessionId: llm
- }
- }
- export function mergeSessionsPreserveLlmId(rows, prevSessions, loadFromStorage) {
- const prevMap = {}
- ;(prevSessions || []).forEach((s) => {
- const id = resolveSessionId(s)
- const llm = resolveLlmSessionIdFromRow(s) || s.llmSessionId
- if (id && llm) {
- prevMap[id] = String(llm)
- }
- })
- return (rows || []).map((row) => {
- const consultId = resolveConsultSessionId(row)
- if (!consultId) {
- return row
- }
- const stored = typeof loadFromStorage === 'function' ? loadFromStorage(consultId) : null
- const llm =
- resolveLlmSessionIdFromRow(row) ||
- prevMap[consultId] ||
- stored ||
- null
- return normalizeSessionRow(row, llm ? { [consultId]: llm } : prevMap)
- })
- }
- export function isUserMessage(m) {
- return m && m.senderRole === SENDER_ROLE_USER
- }
- export function isAiMessage(m) {
- return m && m.senderRole === SENDER_ROLE_AI
- }
- export function isVetMessage(m) {
- return m && m.senderRole === SENDER_ROLE_VET
- }
- export function mediaUrl(url) {
- return resolveResourceUrl(url)
- }
- export function normalizeMessage(m) {
- return {
- id: m.id || m.messageId,
- sessionId: m.sessionId,
- senderRole: m.senderRole,
- senderName: m.senderName,
- msgType: m.msgType,
- content: m.content,
- mediaDuration: m.mediaDuration,
- sendTime: m.sendTime
- }
- }
- export function sessionTitle(s, fallback) {
- if (!s) return fallback || ''
- const t = s.sessionTitle
- if (!t || t === DEFAULT_SESSION_TITLE) {
- return fallback || t || ''
- }
- return t
- }
- export function formatListDate(time) {
- if (!time) return ''
- const d = new Date(time)
- if (isNaN(d.getTime())) return ''
- const now = new Date()
- const isToday =
- d.getFullYear() === now.getFullYear() &&
- d.getMonth() === now.getMonth() &&
- d.getDate() === now.getDate()
- if (isToday) {
- const h = String(d.getHours()).padStart(2, '0')
- const min = String(d.getMinutes()).padStart(2, '0')
- return `${h}:${min}`
- }
- return `${d.getMonth() + 1}/${d.getDate()}`
- }
- export function formatMsgTime(time) {
- if (!time) return ''
- const d = new Date(time)
- if (isNaN(d.getTime())) return ''
- const h = String(d.getHours()).padStart(2, '0')
- const min = String(d.getMinutes()).padStart(2, '0')
- return `${h}:${min}`
- }
- export function dateKey(time) {
- if (!time) return ''
- const d = new Date(time)
- if (isNaN(d.getTime())) return ''
- return `${d.getFullYear()}-${d.getMonth() + 1}-${d.getDate()}`
- }
- export function formatDateDivider(key, tFn) {
- if (!key) return ''
- const parts = key.split('-')
- if (parts.length >= 3) {
- const month = Number(parts[1])
- const day = Number(parts[2])
- if (tFn) {
- return tFn('aiOnlineConsult.dateDivider', { month, day })
- }
- return `${month}月${day}日`
- }
- return key
- }
- export function formatVoiceDuration(sec) {
- const s = Math.max(1, Math.round(Number(sec) || 1))
- return s + '"'
- }
- export function buildMessageGroups(messages, tFn) {
- const groups = []
- let currentKey = null
- let currentItems = []
- for (const m of messages) {
- const key = dateKey(m.sendTime)
- if (key !== currentKey) {
- if (currentItems.length) {
- groups.push({
- dateLabel: formatDateDivider(currentKey, tFn),
- items: currentItems
- })
- }
- currentKey = key
- currentItems = [m]
- } else {
- currentItems.push(m)
- }
- }
- if (currentItems.length) {
- groups.push({
- dateLabel: formatDateDivider(currentKey, tFn),
- items: currentItems
- })
- }
- return groups
- }
- export function previewText(msgType, content, tFn) {
- if (msgType === MSG_TYPE_IMAGE) return tFn ? tFn('aiOnlineConsult.msgImage') : '[图片]'
- if (msgType === MSG_TYPE_VIDEO) return tFn ? tFn('aiOnlineConsult.msgVideo') : '[视频]'
- if (msgType === MSG_TYPE_VOICE) return tFn ? tFn('aiOnlineConsult.msgVoice') : '[语音]'
- return content || ''
- }
|