191 lines
4.3 KiB
Vue
191 lines
4.3 KiB
Vue
<template>
|
||
<view v-if="shouldRender">
|
||
<pass-rx-card v-if="payload && payload.data === 'AUDIPASS'" :extension="payload.extension" />
|
||
<view
|
||
v-else-if="isVideoConsult && videoConsultDisplayText"
|
||
class="chat-row"
|
||
:class="[messageFlow === 'out' ? 'chat-row--end' : '']"
|
||
>
|
||
<image
|
||
:src="avatarSrc"
|
||
class="chat-avatar chat-avatar--square"
|
||
:class="[messageFlow === 'out' ? 'chat-avatar--right' : '']"
|
||
/>
|
||
<view class="chat-row-content">
|
||
<view
|
||
class="video-record-bubble"
|
||
:class="[messageFlow === 'out' ? 'my-message' : '']"
|
||
>
|
||
<image class="video-record-icon" :src="videoIconSrc" mode="aspectFit" />
|
||
<text class="video-record-text">{{ videoConsultDisplayText }}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view
|
||
v-else-if="showSystemTip"
|
||
class="message-item"
|
||
>
|
||
【系统提示】{{ payload.extension }}
|
||
</view>
|
||
</view>
|
||
</template>
|
||
<script setup>
|
||
import { computed } from "vue";
|
||
import PassRxCard from "./rx-pass-card.vue";
|
||
|
||
// messageItem.payload data: 消息类型 startChat 会话开始 , endChat 会话结束 ,
|
||
const props = defineProps({
|
||
messageItem: {
|
||
type: Object,
|
||
default: () => ({}),
|
||
},
|
||
partnerAvatar: {
|
||
type: String,
|
||
default: "",
|
||
},
|
||
});
|
||
|
||
const payload = computed(() => {
|
||
return props.messageItem.payload;
|
||
});
|
||
|
||
const messageFlow = computed(() => {
|
||
return props.messageItem && typeof props.messageItem.flow === "string"
|
||
? props.messageItem.flow
|
||
: "";
|
||
});
|
||
|
||
const isVideoConsult = computed(() => {
|
||
return !!(payload.value && payload.value.description === "VIDEO_CONSULT");
|
||
});
|
||
|
||
function parseVideoRecordExtension(ext) {
|
||
if (!ext || typeof ext !== "string") return null;
|
||
try {
|
||
const obj = JSON.parse(ext);
|
||
if (!obj || typeof obj !== "object") return null;
|
||
if (!obj.doctorText || !obj.patientText) return null;
|
||
return obj;
|
||
} catch (e) {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
const videoConsultDisplayText = computed(() => {
|
||
const pl = payload.value || {};
|
||
const ext = typeof pl.extension === "string" ? pl.extension.trim() : "";
|
||
if (!ext) return "";
|
||
const record = parseVideoRecordExtension(ext);
|
||
if (!record) {
|
||
// 兼容历史:extension 直接是文案
|
||
return ext;
|
||
}
|
||
// 同一条消息在医生端/患者端展示不同文案:发送方(out)=doctorText,接收方(in)=patientText
|
||
return messageFlow.value === "in" ? record.patientText : record.doctorText;
|
||
});
|
||
|
||
const showSystemTip = computed(() => {
|
||
const pl = payload.value || {};
|
||
return !!(
|
||
pl.extension &&
|
||
pl.data !== "ACCEPTCONSULT" &&
|
||
pl.data !== "REPEATMEDICALADVICE"
|
||
);
|
||
});
|
||
|
||
const shouldRender = computed(() => {
|
||
const pl = payload.value || {};
|
||
return (
|
||
(pl && pl.data === "AUDIPASS") ||
|
||
(isVideoConsult.value && !!videoConsultDisplayText.value) ||
|
||
showSystemTip.value
|
||
);
|
||
});
|
||
|
||
const avatarSrc = computed(() => {
|
||
const msg = props.messageItem || {};
|
||
if (messageFlow.value === "in" && props.partnerAvatar) return props.partnerAvatar;
|
||
return (
|
||
msg.avatar ||
|
||
(msg.payload && msg.payload.avatar) ||
|
||
"https://web.sdk.qcloud.com/component/TUIKit/assets/avatar_21.png"
|
||
);
|
||
});
|
||
|
||
const videoIconSrc = "/static/icons/video-consult.svg";
|
||
</script>
|
||
|
||
<style scoped lang="scss">
|
||
//灰色 字体颜色
|
||
.message-item {
|
||
padding: 10px;
|
||
color: #666;
|
||
// border-radius: 10px;
|
||
margin: 0px 0 10px 0;
|
||
text-align: center;
|
||
font-size: 14px;
|
||
}
|
||
|
||
/* Align with existing chat bubble layout (see pages/chat/chat-message.vue) */
|
||
.chat-row {
|
||
display: flex;
|
||
padding-bottom: 10px;
|
||
width: 100%;
|
||
}
|
||
|
||
.chat-row--end {
|
||
justify-content: flex-end;
|
||
}
|
||
|
||
.chat-row-content {
|
||
max-width: 80%;
|
||
margin: 0 10px;
|
||
overflow: hidden;
|
||
order: 2;
|
||
}
|
||
|
||
.chat-avatar {
|
||
flex-shrink: 0;
|
||
width: 36px;
|
||
height: 36px;
|
||
order: 1;
|
||
}
|
||
|
||
.chat-avatar--right {
|
||
order: 3;
|
||
}
|
||
|
||
.chat-avatar--square {
|
||
border-radius: 4px;
|
||
}
|
||
|
||
.video-record-bubble {
|
||
display: inline-flex;
|
||
align-items: center;
|
||
max-width: 100%;
|
||
padding: 10px 12px;
|
||
background: #f2f2f2;
|
||
color: #333;
|
||
border-radius: 6px;
|
||
font-size: 14px;
|
||
line-height: 1.2;
|
||
}
|
||
|
||
.video-record-bubble.my-message {
|
||
background: #dceafd;
|
||
}
|
||
|
||
.video-record-icon {
|
||
width: 16px;
|
||
height: 16px;
|
||
flex: 0 0 auto;
|
||
}
|
||
|
||
.video-record-text {
|
||
margin-left: 6px;
|
||
white-space: normal;
|
||
word-break: break-word;
|
||
overflow: visible;
|
||
}
|
||
</style>
|