新增功能

This commit is contained in:
Your Name
2026-04-01 09:46:25 +08:00
parent 099bc1dd22
commit a780356908
332 changed files with 7845 additions and 866 deletions
@@ -0,0 +1,106 @@
import dayjs from 'dayjs'
export type FriendlyParse = { main: string; sub?: string; tag?: string }
/** 业务时间:支持秒级时间戳或毫秒(字符串数字) */
export function formatBizTime(t: unknown): string | undefined {
if (t == null || t === '') return undefined
const n =
typeof t === 'string' && /^\d+$/.test(t.trim())
? parseInt(t.trim(), 10)
: Number(t)
if (!Number.isFinite(n) || n <= 0) return undefined
return n > 1e12
? dayjs(n).format('YYYY-MM-DD HH:mm:ss')
: dayjs.unix(n).format('YYYY-MM-DD HH:mm:ss')
}
export function parseRtcInner(inner: Record<string, unknown>): FriendlyParse {
const callType = inner.call_type
const callTypeLabel =
callType === 2 ? '视频通话' : callType === 1 ? '语音通话' : '通话'
const cmd = String(inner.cmd || '')
const cmdMap: Record<string, string> = {
hangup: '已结束',
invite: '发起通话',
linebusy: '对方忙线',
cancel: '已取消',
reject: '已拒绝',
accept: '已接听',
timeout: '无人接听'
}
const action = cmdMap[cmd] || (cmd ? `状态:${cmd}` : '')
const main = action ? `${callTypeLabel} · ${action}` : callTypeLabel
const parts: string[] = []
if (inner.inviter) parts.push(`发起方 ${inner.inviter}`)
if (inner.invitee) parts.push(`对方 ${inner.invitee}`)
if (inner.groupID) parts.push(`群组 ${inner.groupID}`)
return {
main,
sub: parts.length ? parts.join('') : undefined,
tag: '通话'
}
}
/**
* 将 IM 自定义 / 信令 JSON 解析为可读文案(医生进诊室、音视频通话等)。
* 与后台 IM 漫游、小程序 TUIKit 约定字段一致。
*/
export function parseImBusinessPayload(raw: string): FriendlyParse | null {
const s = raw.trim()
if (!s.startsWith('{')) return null
let o: Record<string, unknown>
try {
o = JSON.parse(s) as Record<string, unknown>
} catch {
return null
}
if (!('businessID' in o) && !('cmd' in o)) {
return null
}
if (o.businessID === 'doctor_entered_consult_room') {
const t = formatBizTime(o.time)
return { main: '医生已进入诊室', sub: t, tag: '诊室' }
}
if (o.businessID === 'patient_opened_chat') {
const parts: string[] = []
if (o.patientName) parts.push(`患者:${String(o.patientName)}`)
if (o.patientId != null && o.patientId !== '') parts.push(`患者 ID${String(o.patientId)}`)
if (o.doctorId != null && o.doctorId !== '') parts.push(`关联医生:${String(o.doctorId)}`)
const t = formatBizTime(o.time)
if (t) parts.push(t)
return { main: '患者进入聊天', sub: parts.length ? parts.join(' · ') : undefined, tag: '诊室' }
}
if (o.businessID === 'user_typing_status') {
return { main: '对方正在输入…', tag: '状态' }
}
if (o.businessID === 'consultation_complete') {
return { main: '问诊已完成', sub: formatBizTime(o.time), tag: '诊室' }
}
if (o.businessID === 1 || o.businessID === '1') {
let inner: unknown = o.data
if (typeof inner === 'string') {
try {
inner = JSON.parse(inner)
} catch {
return { main: '通话信令', sub: '内层数据解析失败', tag: '通话' }
}
}
if (inner && typeof inner === 'object') {
return parseRtcInner(inner as Record<string, unknown>)
}
return null
}
if (o.businessID === 'rtc_call' || o.cmd) {
return parseRtcInner(o as Record<string, unknown>)
}
return null
}