feat(chat): 为消息添加发送者名称显示并调整布局

- 在消息内容上方显示发送者名称(AI 或用户)
- 调整消息容器布局,使用 flex 列布局确保名称和内容正确对齐
- 将 AI 消息的默认头像替换为专用 AI 头像
- 移除消息容器的换行设置,保持整体左右布局
This commit is contained in:
yangzhe 2026-03-20 17:18:42 +08:00
parent 731989eaac
commit e73c2a9826
1 changed files with 72 additions and 41 deletions

View File

@ -153,60 +153,77 @@
:id="'msg-' + message.id" :id="'msg-' + message.id"
> >
<image <image
v-if="message.sendName === 'AI'"
class="ai-avatar"
src="/static/common/images/avatar_ai.png"
mode="scaleToFill"
/>
<image
v-else
class="ai-avatar" class="ai-avatar"
:src="receiverHeadSculptureUrl" :src="receiverHeadSculptureUrl"
mode="scaleToFill" mode="scaleToFill"
/> />
<view <view class="message-content-wrapper">
class="message-content" <view class="message-sender-name">{{
:class="{ message.sendName || vuex_msgUser.name
'message-content-structured': }}</view>
getStructuredMessageBlocks(message).length,
}"
>
<view <view
v-if="getStructuredMessageBlocks(message).length" class="message-content"
class="structured-message" :class="{
'message-content-structured':
getStructuredMessageBlocks(message).length,
}"
> >
<view <view
v-for="(block, blockIndex) in getStructuredMessageBlocks( v-if="getStructuredMessageBlocks(message).length"
message, class="structured-message"
)"
:key="`${message.id || index}-block-${blockIndex}`"
class="structured-item"
:class="`structured-item-${block.type}`"
> >
<text v-if="block.type === 'text'" class="structured-text">
{{ block.value }}
</text>
<image
v-else-if="block.type === 'image'"
class="structured-image"
:src="block.url"
mode="widthFix"
@click="previewMessageImage(block.url)"
></image>
<view <view
v-else-if="block.type === 'file'" v-for="(block, blockIndex) in getStructuredMessageBlocks(
class="structured-file" message,
@click="downloadMessageFile(block.url)" )"
:key="`${message.id || index}-block-${blockIndex}`"
class="structured-item"
:class="`structured-item-${block.type}`"
> >
<text
v-if="block.type === 'text'"
class="structured-text"
>
{{ block.value }}
</text>
<image <image
class="structured-file-icon" v-else-if="block.type === 'image'"
src="/static/common/images/icon-file.png" class="structured-image"
mode="scaleToFill" :src="block.url"
mode="widthFix"
@click="previewMessageImage(block.url)"
></image> ></image>
<text class="structured-file-name">{{ block.name }}</text> <view
<u-icon v-else-if="block.type === 'file'"
name="download" class="structured-file"
size="36" @click="downloadMessageFile(block.url)"
color="#666666" >
class="structured-file-download" <image
></u-icon> class="structured-file-icon"
src="/static/common/images/icon-file.png"
mode="scaleToFill"
></image>
<text class="structured-file-name">{{
block.name
}}</text>
<u-icon
name="download"
size="36"
color="#666666"
class="structured-file-download"
></u-icon>
</view>
</view> </view>
</view> </view>
<markdown-viewer v-else :content="message.message" />
</view> </view>
<markdown-viewer v-else :content="message.message" />
</view> </view>
</view> </view>
</view> </view>
@ -675,7 +692,7 @@ export default {
.message-left { .message-left {
justify-content: flex-start; justify-content: flex-start;
flex-wrap: wrap; /* 允许反馈区换行到消息下方 */ flex-wrap: nowrap; /* 不换行,整体左右排布 */
.ai-avatar { .ai-avatar {
width: 64rpx; width: 64rpx;
@ -686,13 +703,27 @@ export default {
flex-shrink: 0; flex-shrink: 0;
} }
.message-content-wrapper {
display: flex;
flex-direction: column;
align-items: flex-start;
max-width: 70%;
}
.message-sender-name {
font-size: 24rpx;
color: #999999;
margin-bottom: 8rpx;
}
.message-content { .message-content {
background-color: #ffffff; background-color: #ffffff;
max-width: 70%;
padding: 20rpx 24rpx; padding: 20rpx 24rpx;
border-radius: 0 16rpx 16rpx 16rpx; border-radius: 0 16rpx 16rpx 16rpx;
font-size: 28rpx; font-size: 28rpx;
line-height: 1.5; line-height: 1.5;
width: 100%;
box-sizing: border-box;
&.message-content-structured { &.message-content-structured {
background-color: transparent; background-color: transparent;