2 Commits

Author SHA1 Message Date
023d556977 feat: 消息页面的样式调整 2026-01-13 22:45:03 +08:00
b47565bdfc feat: 历史消息的列表样式及交互处理 2026-01-13 21:32:51 +08:00
2 changed files with 85 additions and 30 deletions

View File

@@ -6,26 +6,40 @@
<div ref="listRef" class="flex-1 overflow-y-auto px-6 py-6 space-y-6">
<div v-for="msg in messages" :key="msg.id" class="flex items-start gap-3"
:class="msg.role === 'user' ? 'justify-end' : 'justify-start'">
<!-- AI avatar -->
<div v-if="msg.role === 'ai'"
class="w-9 h-9 rounded-full bg-blue-500 flex items-center justify-center text-white font-bold shrink-0">
N
</div>
<img v-if="msg.role === 'ai'" class="w-9 h-9 rounded-full shrink-0" src="@assets/images/login/blue_logo.png" />
<!-- 气泡 -->
<!-- 消息气泡 -->
<div class="max-w-[70%]">
<div class="px-4 py-3 text-sm text-gray-700" :class="msg.role === 'user' ? 'bg-[#f7f9fc] rounded-md' : ''">
<div class="flex items-start gap-2 pt-0.5 mb-2" :class="msg.role === 'user' ? 'flex-row-reverse' : 'flex-row'">
<span class="text-xs text-[#4E5969]"> ZHINIAN</span>
<span class="text-xs text-[#86909C]"> 20:30</span>
</div>
<div class="text-sm text-gray-700" :class="msg.role === 'user' ? 'bg-[#f7f9fc] rounded-md px-2 py-2' : ''">
{{ msg.content }}
</div>
<!-- AI 标识 -->
<div v-if="msg.role === 'ai'" class="mt-1 text-xs text-gray-400 ">
<div v-if="msg.role === 'ai'" class="mt-2 text-xs text-gray-400 ">
本回答由 AI 生成
</div>
<!-- AI 操作按钮 -->
<div v-if="msg.role === 'ai'" class="mt-4 text-gray-500 flex items-center justify-between gap-4 ">
<RiFileCopyLine size="16px" @click="copyFileClick(msg)" />
<div class="flex items-center gap-4">
<RiShareForwardLine size="16px" @click="shareForwardClick(msg)"/>
<RiDownload2Line size="16px" @click="downloadClick(msg)" />
<RiThumbUpLine size="16px" @click="thumbUpClick(msg)" />
<RiThumbDownLine size="16px" @click="thumbDownClick(msg)" />
</div>
</div>
</div>
<!-- User avatar -->
<div v-if="msg.role === 'user'" class="w-9 h-9 rounded-full bg-blue-200 shrink-0"></div>
<img v-if="msg.role === 'user'" class="w-9 h-9 rounded-full shrink-0" src="@assets/images/login/user_icon.png" />
</div>
</div>
@@ -58,8 +72,7 @@
<script setup lang="ts">
import { ref } from 'vue'
import { RiLink, RiSendPlaneFill } from '@remixicon/vue'
import { RiLink, RiSendPlaneFill, RiFileCopyLine, RiShareForwardLine, RiDownload2Line, RiThumbUpLine, RiThumbDownLine } from '@remixicon/vue'
type Message = {
id: number
@@ -81,4 +94,23 @@ const messages = ref<Message[]>(
),
}))
)
/// actions 实现复制、分享、下载、点赞等功能
const copyFileClick = (msg: Message) => {
console.log('copy file', msg)
}
const shareForwardClick = (msg: Message) => {
console.log('share forward', msg)
}
const downloadClick = (msg: Message) => {
console.log('download', msg)
}
const thumbUpClick = (msg: Message) => {
console.log('thumb up', msg)
}
const thumbDownClick = (msg: Message) => {
console.log('thumb down', msg)
}
</script>

View File

@@ -1,29 +1,28 @@
<template>
<aside class="w-64 h-screen box-border flex flex-col">
<header class="flex items-center justify-between mb-3">
<div class="flex items-center gap-2">
<img class="w-20 h-20 rounded-md object-cover" src="@assets/images/login/white_logo.png" />
<div class="font-bold text-gray-800">YINIAN</div>
</div>
</header>
<div class="mb-3 pl-4 pr-4">
<button class="bg-white rounded-lg px-3 py-2 border shadow-sm w-full text-center"> 新对话</button>
<aside class="w-50 h-screen box-border flex flex-col">
<div class="flex items-center m-2">
<img class="w-10 h-10 rounded-md" src="@assets/images/login/white_logo.png" />
<div class="font-bold text-gray-80">YINIAN</div>
</div>
<div class="overflow-y-auto p-4">
<section v-for="group in groups" :key="group.title" class="mb-3">
<div class="flex items-center justify-between text-sm text-gray-500 py-2">
<div class="flex justify-center m-2 bg-white rounded-lg p-2.5 border-[##E5E8EE] shadow-sm text-center" @click="addNewChat">
<RiAddLine /> 新对话
</div>
<div class="overflow-y-auto p-2 ">
<section v-for="(group, index) in groups" :key="group.title" class="mb-3">
<div class="flex items-center justify-between text-sm text-gray-500" @click="selectGroupKey(index)">
<span>{{ group.title }}</span>
<RiArrowDownSLine />
<RiArrowDownSLine v-show="group.selected" color="rgba(153,160,174,1)" />
<RiArrowRightSLine v-show="!group.selected" color="rgba(153,160,174,1)" />
</div>
<ul class="list-none p-1 mr-4">
<li v-for="item in group.items" :key="item.id" @click="select(item.id)" :class="[
<ul class="list-none mt-1.5" v-if="group.selected">
<li v-for="item in group.items" :key="item.id" @click="selectedHistoryMessage(item.id)" :class="[
'flex items-center gap-2 p-2 text-gray-600 rounded-lg cursor-pointer transition-colors',
item.id === selectedId ? 'bg-white shadow-md border border-gray-200' : 'hover:bg-gray-50'
item.id === selectedId ? 'bg-white shadow-sm border-[##E5E8EE]' : 'hover:bg-gray-50'
]">
<span class="w-2 h-2 rounded-full bg-sky-200 flex-none"></span>
<span class="w-2 h-2 rounded-full bg-[#BEDBFF] flex-none"></span>
<div class="flex-1 min-w-0">
<div class="truncate text-sm">{{ item.title }}</div>
</div>
@@ -38,13 +37,16 @@
<script setup lang="ts">
import { ref } from 'vue'
import { RiArrowDownSLine } from '@remixicon/vue'
import { RiAddLine, RiArrowRightSLine, RiArrowDownSLine } from '@remixicon/vue'
/// 记录选择的历史消息ID
const selectedId = ref<number | null>(2)
/// 历史消息分组数据
const groups = ref([
{
title: '近3天',
selected: false,
items: [
{ id: 1, title: '这是一段对话' },
{ id: 2, title: '这是一段对话' },
@@ -55,6 +57,7 @@ const groups = ref([
},
{
title: '近7天',
selected: false,
items: [
{ id: 6, title: '这是一段对话' },
{ id: 7, title: '这是一段对话' },
@@ -64,6 +67,7 @@ const groups = ref([
},
{
title: '近15天',
selected: false,
items: [
{ id: 10, title: '这是一段对话' },
{ id: 11, title: '这是一段对话' },
@@ -74,6 +78,7 @@ const groups = ref([
},
{
title: '近30天',
selected: false,
items: [
{ id: 15, title: '这是一段对话' },
{ id: 16, title: '这是一段对话' },
@@ -83,6 +88,7 @@ const groups = ref([
},
{
title: '近60天',
selected: false,
items: [
{ id: 19, title: '这是一段对话' },
{ id: 20, title: '这是一段对话' },
@@ -93,6 +99,7 @@ const groups = ref([
},
{
title: '近90天',
selected: false,
items: [
{ id: 24, title: '这是一段对话' },
{ id: 25, title: '这是一段对话' },
@@ -102,7 +109,23 @@ const groups = ref([
}
])
function select(id: number) {
/// 选择历史消息
const selectedHistoryMessage = (id: number) => {
selectedId.value = id
}
/// 选择分组展开/收起
const selectGroupKey = (index: number) => {
groups.value.forEach((group, i) => {
if (i === index) {
group.selected = !group.selected
}
})
}
/// TODO: 添加新对话
const addNewChat = () => {
console.log('add new chat')
}
</script>