hn-hlw-app/pages/chat/chat-message.vue
2026-07-27 11:26:39 +08:00

231 lines
5.4 KiB
Vue

<template>
<view class="chat-row" :class="[
message.flow === 'out' ? 'chat-row--end' : '',
{ 'chat-row--elder': elderMode }
]">
<image
src="https://web.sdk.qcloud.com/component/TUIKit/assets/avatar_21.png"
class="chat-avatar"
:class="[
message.flow === 'out' ? 'chat-avatar--right' : '',
{ 'chat-avatar--elder': elderMode }
]"
></image>
<view class="chat-row-content" :class="{ 'chat-row-content--elder': elderMode }">
<view
v-if="message.type === 'TIMTextElem'"
class="message-container"
:class="[
message.flow === 'out' ? 'my-message' : '',
{ 'message-container--elder': elderMode }
]"
>
{{ message.payload.text }}
</view> <image
v-else-if="message.type === 'TIMImageElem'"
:style="{ width: imageStyles.width, height: imageStyles.height }"
:src="getImageUrl(props.message)"
:class="{ 'chat-image--elder': elderMode }"
@tap="previewImage(message)"
@load="imageLoad"
/>
</view>
</view>
</template>
<script setup>
import { ref, watchEffect, onMounted, onUnmounted } from "vue";
// 长辈模式状态
const elderMode = ref(false);
// 处理长辈模式变化
const handleElderModeChange = () => {
try {
const storedElderMode = uni.getStorageSync('elderMode');
elderMode.value = storedElderMode === 'true' || storedElderMode === true;
// 同步到全局数据
const app = getApp();
if (app && app.globalData) {
app.globalData.elderMode = elderMode.value;
}
} catch (error) {
console.error('获取长辈模式状态失败:', error);
elderMode.value = false;
}
};
onMounted(() => {
handleElderModeChange();
// 监听长辈模式变化事件
uni.$on('elderModeChanged', handleElderModeChange);
});
onUnmounted(() => {
// 移除事件监听
uni.$off('elderModeChanged', handleElderModeChange);
});
const props = defineProps({
message: {
type: Object,
default: false,
},
text: {
type: String,
default: "",
},
});
const DEFAULT_MAX_SIZE = 155;
const imageStyles = ref({
width: "auto",
height: "auto",
});
// 获取图片URL
const getImageUrl = (message) => {
if (!message.payload || !message.payload.imageInfoArray) return "";
// 优先使用小图
const smallImage = message.payload.imageInfoArray.find(
(item) => item.type === 0
);
if (smallImage) return smallImage.url;
// 如果没有小图,使用原图
const originalImage = message.payload.imageInfoArray.find(
(item) => item.type === 1
);
if (originalImage) return originalImage.url;
return "";
};
// 预览图片
const previewImage = (message) => {
if (!message.payload || !message.payload.imageInfoArray) return;
// 获取原图URL
const originalImage = message.payload.imageInfoArray.find(
(item) => item.type === 1
);
if (originalImage) {
uni.previewImage({
urls: [originalImage.url],
});
}
};
function getImageText(item) {
return {
imageUrl: item.imageInfoArray[0].imageUrl,
imageHeight: item.imageInfoArray[0].height,
imageWidth: item.imageInfoArray[0].width,
};
}
const genImageStyles = () => {
const imageInfoArray = props.message?.payload?.imageInfoArray;
if (
imageInfoArray &&
Array.isArray(imageInfoArray) &&
imageInfoArray.length > 0
) {
const { width, height } = imageInfoArray[0];
if (width === 0 || height === 0) {
return;
}
let imageWidth = 0;
let imageHeight = 0;
if (width >= height) {
imageWidth = DEFAULT_MAX_SIZE;
imageHeight = (DEFAULT_MAX_SIZE * height) / width;
} else {
imageWidth = (DEFAULT_MAX_SIZE * width) / height;
imageHeight = DEFAULT_MAX_SIZE;
}
imageStyles.value.width = imageWidth + "px";
imageStyles.value.height = imageHeight + "px";
}
};
const imageLoad = (event) => {
genImageStyles(event.detail);
};
watchEffect(() => {
genImageStyles(props.message);
});
</script>
<style lang="scss" scoped>
.chat-row {
display: flex;
padding-bottom: 20rpx;
width: 100%;
@at-root &.chat-row--end {
justify-content: flex-end;
}
// 长辈模式样式
@at-root &.chat-row--elder {
padding-bottom: 28rpx; // 增加行间距
}
}
.message-container {
padding: 24rpx;
background: #fbfbfb;
font-size: 28rpx;
color: #000;
border-radius: 0rpx 20rpx 20rpx 20rpx;
@at-root &.my-message {
border-radius: 20rpx 0 20rpx 20rpx;
background: #dceafd;
}
// 长辈模式样式
@at-root &.message-container--elder {
padding: 32rpx; // 增加内边距
font-size: 36rpx; // 字体放大 1.3倍 (28rpx → 36rpx)
line-height: 1.5; // 增加行高
border-radius: 0rpx 26rpx 26rpx 26rpx; // 稍微增大圆角
&.my-message {
border-radius: 26rpx 0 26rpx 26rpx;
}
}
}
.chat-row-content {
max-width: 80%;
margin: 0 20rpx;
overflow: hidden;
order: 2;
// 长辈模式样式
@at-root &.chat-row-content--elder {
margin: 0 26rpx; // 稍微增加间距
}
}
.chat-avatar {
flex-shrink: 0;
width: 72rpx;
height: 72rpx;
order: 1;
@at-root &.chat-avatar--right {
order: 3;
}
// 长辈模式样式
@at-root &.chat-avatar--elder {
width: 90rpx; // 头像稍微放大 (72rpx → 90rpx)
height: 90rpx;
}
}
// 聊天图片长辈模式样式
.chat-image--elder {
border-radius: 8rpx; // 添加圆角
transform: scale(1.1); // 长辈模式下图片稍微放大
}
</style>