@@ -1,273 +1,585 @@
< template >
< div class = "app-container" >
< div class = "search-form" >
< el-form :inline = "true" :model = "queryParams" ref = "queryForm" label -width= " 68px " >
< el-form-item label = "用户ID" prop = "user " >
< el-input v-model = "queryParams.user" placeholder="请输入用户ID" clearable size="small" / >
< / el-form-item >
< el-form-item label = "会话ID" prop = "conversation_id" >
< el-input v-model = "queryParams.conversation_id" placeholder="请输入会话ID" clearable size="small" / >
< / el-form-item >
< el-form-item label = "消息内容" prop = "content " >
< el-input v-model = "queryParams.content" placeholder="请输入消息内容" clearable size="small" / >
< / el-form-item >
< el-form-item label = "时间段" >
< el-date-picker
v-model = "dateRange"
type = "daterange"
range -separato r =" 至 "
start -placeholder = " 开始日期 "
end -placeholder = " 结束日期 "
size = "small"
/ >
< / el-form-i tem >
< el-form-item >
< el-button type = "primary" icon = "el-icon-search" size = "small" @click ="handleQuery" > 搜索 < / el -button >
< el-button type = "success" icon = "el-icon-menu" size = "small" @click ="getConversationsByUser" > 查询会话 < / el-button >
< el-button icon = "el-icon-refresh" size = "small" @click ="resetQuery" > 重置 < / el -button >
< / el-form-item >
< / el-form >
< / div >
< div class = "app-container" >
< div class = "search-form-container " >
< el-form :model = "queryParams" ref = "queryForm" size = "small" v-show = "showSearch" label-width="80px" class="search-form" >
< el-row :gutter = "20 " >
< el-col :xs = "24" :sm = "12" :md = "8" :lg = "6" :xl = "6" >
< el-form-item label = "学号" prop = "stuNo" >
< el-input v-model = "queryParams.stuNo" placeholder="请输入学号" clearable @keyup.enter.native="handleQuery" / >
< / el-form-item >
< / el-col >
< el-col :xs = "24" :sm = "12" :md = "8" :lg = "6" :xl = "6 " >
< el-form-item label = "姓名" prop = "name" >
< el-input v-model = "queryParams.name" placeholder="请输入姓名" clearable @keyup.enter.native="handleQuery" / >
< / el-form-item >
< / el-col >
< el-col :xs = "24" :sm = "12" :md = "8" :lg = "6" :xl = "6" >
< el-form-item label = "所属班级" prop = "classId" >
< el-cascader placeholde r ="请选择班级" v-model = "classVlue1" :show-all-levels="false "
:options = "ClassNameList" @change ="handleChange1" clearable filterable style = "width: 100%" >
< template slot -scope = " { node , data } " >
< span > { { data . label } } < / span >
< span v-if = "!node.isLeaf" > ( {{ data.children.length }} ) < / span >
< / templa te>
< / el -cascader >
< / el-form-item >
< / el-col >
< el-col :xs = "24" :sm = "12" :md = "8" :lg = "6" :xl = "6" >
< el-form-item label = "学院" prop = "deptId" >
< el-select v-model = "queryParams.deptId" filterable clearable placeholder="请选择学院" style="width: 100%" >
< el -option v-for = "item in dept_list" :key="item.value" :label="item.label" :value="item.value" >
< / el -option >
< / el-select >
< / el-form-item >
< / el-col >
< el-col :xs = "24" :sm = "12" :md = "8" :lg = "6" :xl = "6" >
< el-form-item label = "辅导员" prop = "cphName" >
< el-input v-model = "queryParams.cphName" placeholder="请输入辅导员" clearable @keyup.enter.native="handleQuery" / >
< / el-form-item >
< / el-col >
< el-col :xs = "24" :sm = "12" :md = "8" :lg = "6" :xl = "6" >
< el-form-item label = "年级" prop = "gradeId" >
< el-select v-model = "queryParams.gradeId" filterable clearable placeholder="请选择年级" style="width: 100%" >
< el -option v-for = "item in grade_list" :key="item.gradeId" :label="item.gradeName" :value="item.gradeId" >
< / el -option >
< / el-select >
< / el-form-item >
< / el-col >
< el-col :xs = "24" :sm = "24" :md = "24" :lg = "24" :xl = "24" >
< el-form-item class = "search-buttons" >
< el-button type = "primary" icon = "el-icon-search" size = "mini" @click ="handleQuery" > 搜索 < / el -button >
< el-button icon = "el-icon-refresh" size = "mini" @click ="resetQuery" > 重置 < / el -button >
< / el-form-item >
< / el-col >
< / el-row >
< / el-form >
< / div >
< el-table v-loading = "loading" :data="historyList" border fit highlight-current-row style="width: 100%" >
< el -table -column label = "序号" type = "index" width = "50" align = "center" / >
< el-table-column prop = "user" label = "用户ID" width = "100" align = "center" / >
< el-table-column prop = "conversation_id" label = "会话ID" width = "180" align = "center" / >
< el-table-column prop = "message_id" label = "消息ID" width = "180" align = "center" / >
< el-table-column prop = "type" label = "消息类型" width = "80" align = "center" >
< template slot -scope = " scope " >
< el-tag : type = "scope.row.type === 'user' ? 'primary' : 'success'" size = "small" >
{ { scope . row . type === 'user' ? '用户' : 'AI' } }
< / el-tag >
< / template >
< / el-table-column >
< el-table-column prop = "content" label = "消息内容" min -width = " 300 " >
< template slot -scope = " scope " >
< div v-html = "scope.row.content" > < / div >
< / template >
< /el -table -column >
< el-table-column prop = "feedback" label = "反馈状态" width = "100" align = "center" >
< template slot -scope = " scope " >
< div v-if = "scope.row.feedback === 'like'"><i class="el-icon-thumb text-primary" > < / i > 点赞 < / div >
< div v-else-if = "scope.row.feedback === 'dislike'"><i class="el-icon-minus text-danger" > < / i > 点踩 < / div >
< div v-else > 无反馈 < / div >
< / template >
< / el -table -column>
< el-table-column prop = "created_at" label = "创建时间" width = "180" align = "center" / >
< el-table-column label = "操作" width = "150" align = "center" fixed = "right ">
< template slot -scope = " scope " >
< el-button type = "primary" icon = "el-icon-view" size = "mini" @click ="viewMessage(scope.row)" > 查看详情 < /el -button >
< / template >
< / el-table-column >
< / el-table >
< el-row :gutter = "10" class = "mb8" >
< right-toolbar :showSearch.sync = "showSearch" @queryTable ="getList" > < / right -toolbar >
< / el-row >
< el-table v-loading = "loading" :data="studentList" style="width: 100%" >
< el -table -column label = "学号" align = "center" prop = "stuNo" min -width = " 120 " / >
< el-table-column label = "姓名" align = "center" prop = "name" min -width = " 100 " / >
< el-table-column label = "性别" align = "center" prop = "gender" min -width = " 80 " / >
< el-table-column label = "学院名称" align = "center" prop = "deptId" min -width = " 120 " >
< template slot -scope = " scope " >
< span > { { scope . row . dept . deptName } } < / span >
< / template >
< / el-table-column >
< el-table-column label = "专业名称" align = "center" prop = "majorId" min -width = " 200 " >
< template slot -scope = " scope " >
< span > { { scope . row . srsMajors . majorName } } < / span >
< /template >
< / el-table-column >
< el-table-column label = "班级名称" align = "center" prop = "classId" min -width = " 200 " >
< template slot -scope = " scope " >
< span > { { scope . row . srsClass . className } } < / span >
< / template >
< / el-table-column >
< el -table-column label = "辅导员" align = "center" prop = "cphName" min -width = " 100 " / >
< el-table-column label = "学生状态" align = "center" prop = "status" min -width = " 100 " >
< template slot -scope = " scope " >
< dict-tag :options = "dict.type.srs_stu_status" :value = "scope.row.status" / >
< /template >
< / el-table-column >
< el-table-column label = "操作" align = "center" class -name = " small -padding fixed -width " min -width = " 120 " >
< template slot -scope = " scope " >
< el-button size = "mini" type = "text" icon = "el-icon-chat-dot-round" @click ="viewConversations(scope.row)" > 查看会话列表 < / el -button >
< / template >
< / el-table-column >
< / el-table >
< div class = "pagination-container" >
< el-pagination
v-show = "total > 0"
:current-page = "queryParams.pageNum"
:page-size = "queryParams.pageSize"
:total = "total "
: page -sizes = " [ 10 , 20 , 50 , 100 ] "
layout = "total, sizes, prev, pager, next, jumper "
@ size -chang e =" handleSizeChange "
@ current -change = " handleCurrentChange "
/ >
< pagination v-show = "total > 0" :total="total" :page.sync="queryParams.pageNum"
:limit.sync = "queryParams.pageSize" @pagination ="getList" / >
<!-- AI对话记录弹出对话框 -- >
< el-dialog
title = "AI对话记录 "
:visible.sync = "dialogVisible "
width = "80% "
:before-clos e ="closeChatHistory "
class = "chat-dialog "
>
< div class = "dialog-header" v-if = "currentStudent" >
< span class = "student-info" > 学生 : { { currentStudent . name } } ( { { currentStudent . stuNo } } ) < / span >
< / div >
< div v-loading = "chatLoading" class="chat-content" >
< div v-if = "chatMessages.length === 0 && !chatLoading" class="no-chat" >
< el -empty description = "暂无对话记录" > < / el-empty >
< / div >
< div v-for = "message in chatMessages" :key="message.id" class="message-item" >
< div class = "message-header" >
< span class = "message-time" > { { parseTime ( message . created _at * 1000 , '{y}-{m}-{d} {h}:{i}:{s}' ) } } < / span >
< div class = "feedback-status" v-if = "message.feedback" >
< el -tag v-if = "message.feedback && message.feedback.rating === 'like'" type="success" size="mini" >
< i class = "el-icon-thumb-up" > < / i > 点赞
< / el-tag >
< el-tag v-else-if = "message.feedback && message.feedback.rating === 'dislike'" type="danger" size="mini" >
< i class = "el-icon-thumb-down" > < / i > 点踩
< / el-tag >
< / div >
< / div >
< div class = "message-content" >
< div class = "user-message" >
< div class = "message-label" > 学生提问 : < / div >
< div class = "message-text user-text" > { { message . query } } < / div >
< / div >
< div class = "ai-message" >
< div class = "message-label" > AI回答 : < / div >
< div class = "message-text ai-text" : class = "{
'feedback-like': message.feedback && message.feedback.rating === 'like',
'feedback-dislike': message.feedback && message.feedback.rating === 'dislike'
}" > { { message . answer } } < / div >
< / div >
< / div >
< / div >
< / div >
< / el-dialog >
< / div >
< / div >
< / template >
< script >
import { getHistoryMessages , getFeedbacks , getConversationList } from "@/api/aitutor/cha t";
import { getTokenKeySessionStorage } from "@/utils/auth " ;
import { listStudent , getClassName } from "@/api/stuCQS/basedata/studen t";
import { getMessagesToAdmin } from "@/api/aitutor/chat " ;
import { listGrade } from "@/api/stuCQS/basedata/grade" ;
import { getDeptName } from "@/api/system/dept" ;
export default {
name : "ChatHistory" ,
data ( ) {
return {
loading : false ,
historyList : [ ] ,
conversationList : [ ] , // 存储会话列表
total : 0 ,
queryParams : {
pageNum : 1 ,
pageSize : 1 0,
user : undefined ,
conversation _id : undefined ,
content : undefined
} ,
dateRange : [ ] ,
userToken : getTokenKeySessionStorage ( )
} ;
} ,
created ( ) {
this . getList ( ) ;
} ,
methods : {
/** 根据用户ID查询会话列表 */
getConversationsByUser ( ) {
if ( ! this . queryParams . user ) {
this . $message . error ( '请输入用户ID' ) ;
return ;
}
this . loading = true ;
const params = {
user : this . queryParams . user
} ;
getConversationList ( params ) . then ( response => {
if ( response . code === 200 ) {
let conversationData = response . data ;
// 如果返回的是字符串形式的JSON, 尝试解析
if ( typeof conversationData === 'string' ) {
name : "ChatHistory" ,
dicts : [ 'srs_stu_status' ] ,
data ( ) {
return {
// 遮罩层
loading : true ,
// 显示搜索条件
showSearch : true ,
// 总条数
total : 0 ,
// 学生信息表格数据
studentList : [ ] ,
// 查询参数
queryParams : {
pageNum : 1 ,
pageSize : 10 ,
name : null ,
stuNo : null ,
deptId : null ,
classId : null ,
cphName : null ,
gradeId : null
} ,
// 班级名称列表
ClassNameList : [ ] ,
// 班级搜索选择
classVlue1 : [ ] ,
// 学院列表
dept _list : [ ] ,
// 年级列表
grade _list : [ ] ,
// AI对话记录相关
dialogVisible : false ,
chatMessages : [ ] ,
chatLoading : false ,
currentStudent : null
} ;
} ,
created ( ) {
this . getList ( ) ;
this . getClassNameList ( ) ;
this . listDept ( ) ;
this . listGrade ( ) ;
} ,
methods : {
/** 查询学生信息列表 */
getList ( ) {
this . loading = true ;
listStudent ( this . queryParams ) . then ( response => {
console . log ( '学生列表API响应:' , response ) ;
// 根据实际API响应结构调整数据获取方式
if ( response . data ) {
this . studentList = response . data . rows || response . data || [ ] ;
this . total = response . data . total || response . total || 0 ;
} else {
this . studentList = response . rows || [ ] ;
this . total = response . total || 0 ;
}
this . loading = false ;
} ) . catch ( error => {
console . error ( '获取学生列表失败:' , error ) ;
this . $message . error ( '获取学生列表失败' ) ;
this . loading = false ;
} ) ;
} ,
/** 获取班级名称列表 */
getClassNameList ( ) {
getClassName ( ) . then ( res => {
this . ClassNameList = res . data ;
} ) ;
} ,
/** 获取学院列表 */
async listDept ( ) {
try {
conversationData = JSON . parse ( conversationData ) ;
} catch ( e ) {
console . error ( '解析会话列表数据失败:' , e ) ;
let res = await getDeptName ( ) ;
this . dept _list = [ ... res . data ] ;
} catch ( error ) {
console . error ( '获取学院列表失败:' , error ) ;
}
}
// 格式化数据
if ( Array . isArray ( conversationData ) ) {
this . conversationList = conversationData ;
if ( conversationData . length > 0 ) {
this . $message . success ( ` 成功获取到 ${ conversationData . length } 条会话记录 ` ) ;
// 如果只有一条会话, 可以自动填充到会话ID输入框
if ( conversationData . length === 1 ) {
this . queryParams . conversation _id = conversationData [ 0 ] . conversation _id ;
}
} else {
this . $message . info ( '未找到该用户的会话记录' ) ;
}
} else if ( conversationData && Array . isArray ( conversationData . list ) ) {
this . conversationList = conversationData . list ;
this . $message . success ( ` 成功获取到 ${ conversationData . list . length } 条会话记录 ` ) ;
} else {
this . conversationList = [ ] ;
this . $message . info ( '未找到该用户的会话记录' ) ;
}
} else {
this . $message . error ( "获取会话列表失败:" + ( response . msg || response . message ) ) ;
}
this . loading = false ;
} ) . catch ( error => {
console . error ( '获取会话列表失败:' , error ) ;
this . $message . error ( "网络错误:" + error . message ) ;
this . loading = false ;
} ) ;
} ,
/** 查询历史消息列表 */
getList ( ) {
this . loading = true ;
// 处理日期范围
if ( this . dateRange && this . dateRange . length > 0 ) {
this . queryParams . start _time = this . dateRange [ 0 ] ;
this . queryParams . end _time = this . dateRange [ 1 ] ;
} else {
this . queryParams . start _time = undefined ;
this . queryParams . end _time = undefined ;
}
// 检查user参数是否存在
if ( ! this . queryParams . user ) {
this . $message . error ( '请输入用户ID' ) ;
this . loading = false ;
return ;
}
// 添加user参数以匹配API要求
const params = {
... this . queryParams ,
user : this . queryParams . user
} ;
getHistoryMessages ( params ) . then ( response => {
// 假设接口返回格式为 { code: 200, data: { list: [], total: 0 } }
// 根据实际接口调整
if ( response . code === 200 ) {
let historyData = response . data ;
// 如果返回的是字符串形式的JSON, 尝试解析
if ( typeof historyData === 'string' ) {
} ,
/** 获取年级列表 */
async listGrade ( ) {
try {
historyData = JSON . parse ( historyData ) ;
} catch ( e ) {
console . error ( '解析历史消息数据失败:' , e ) ;
let res = await listGrade ( ) ;
if ( res . code == 200 ) {
this . grade _list = [ ... res . rows ] ;
}
} catch ( error ) {
console . error ( '获取年级列表失败:' , error ) ;
}
}
// 格式化数据
if ( Array . isArray ( historyData ) ) {
this . historyList = historyData ;
this . total = historyData . length ;
} else if ( historyData && Array . isArray ( historyData . list ) ) {
this . historyList = historyData . list ;
this . total = historyData . total ;
} else {
this . historyList = [ ] ;
this . total = 0 ;
}
} else {
this . $message . error ( "获取历史消息失败:" + ( response . msg || response . message ) ) ;
} ,
/** 搜索班级选择 */
handleChange1 ( value ) {
this . queryParams . classId = value [ 2 ] ;
} ,
/** 搜索按钮操作 */
handleQuery ( ) {
this . queryParams . pageNum = 1 ;
this . getList ( ) ;
} ,
/** 重置按钮操作 */
resetQuery ( ) {
this . resetForm ( "queryForm" ) ;
this . classVlue1 = [ ] ;
this . handleQuery ( ) ;
} ,
/** 查看AI对话记录 */
viewConversations ( row ) {
this . currentStudent = row ;
this . dialogVisible = true ;
this . chatLoading = true ;
this . chatMessages = [ ] ;
getMessagesToAdmin ( {
user : row . stuNo
} ) . then ( response => {
console . log ( '对话记录API响应:' , response ) ;
if ( response . code === 200 && response . data && response . data . data ) {
this . chatMessages = response . data . data ;
} else {
this . $modal . msgWarning ( response . msg || '该学生暂无对话记录' ) ;
}
this . chatLoading = false ;
} ) . catch ( error => {
console . error ( '获取对话记录失败:' , error ) ;
this . $modal . msgError ( '获取对话记录失败' ) ;
this . chatLoading = false ;
} ) ;
} ,
/** 关闭对话记录 */
closeChatHistory ( ) {
this . dialogVisible = false ;
this . currentStudent = null ;
this . chatMessages = [ ] ;
}
this . loading = false ;
} ) . catch ( error => {
console . error ( '获取历史消息失败:' , error ) ;
this . $message . error ( "网络错误:" + error . message ) ;
this . loading = false ;
} ) ;
} ,
/** 搜索按钮操作 */
handleQuery ( ) {
this . queryParams . pageNum = 1 ;
this . getList ( ) ;
} ,
/** 重置按钮操作 */
resetQuery ( ) {
this . dateRange = [ ] ;
this . $refs . queryForm . resetFields ( ) ;
this . handleQuery ( ) ;
} ,
/** 查看消息详情 */
viewMessage ( row ) {
// 这里可以实现查看消息详情的逻辑
this . $modal . msgDetail ( '消息详情' , {
user : row . user ,
conversation _id : row . conversation _id ,
message _id : row . message _id ,
type : row . type ,
content : row . content ,
feedback : row . feedback ,
created _at : row . created _at
} ) ;
// 如果需要更复杂的详情展示,可以打开一个新的弹窗组件
// this.$refs.detailDialog.open(row);
} ,
/** 分页大小改变 */
handleSizeChange ( val ) {
this . queryParams . pageSize = val ;
this . getList ( ) ;
} ,
/** 当前页码改变 */
handleCurrentChange ( val ) {
this . queryParams . pageNum = val ;
this . getList ( ) ;
}
}
} ;
< / script >
< style scoped >
. search - form {
margin - bottom : 20 px ;
. app - container {
padding : 20 px ;
}
. pagination - container {
margin - top : 20 px ;
text - align : right ;
. mb8 {
margin - bot tom : 8 px ;
}
. el - table . cell {
word - break : break - word ;
}
/* 搜索表单容器样式 */
. search - form - container {
background : # f8f9fa ;
border : 1 px solid # e9ecef ;
border - radius : 0.5 rem ;
padding : 1.25 rem ;
margin - bottom : 1.25 rem ;
box - shadow : 0 0.125 rem 0.25 rem rgba ( 0 , 0 , 0 , 0.05 ) ;
box - sizing : border - box ;
}
. search - form {
margin : 0 ;
width : 100 % ;
box - sizing : border - box ;
}
. search - form . el - row {
display : flex ;
flex - wrap : wrap ;
margin : 0 - 0.625 rem ;
}
. search - form . el - col {
padding : 0 0.625 rem ;
box - sizing : border - box ;
min - width : 0 ;
flex - shrink : 0 ;
}
. search - form . el - form - item {
margin - bottom : 1 rem ;
width : 100 % ;
box - sizing : border - box ;
}
. search - form . el - form - item _ _label {
font - weight : 500 ;
color : # 606266 ;
white - space : nowrap ;
min - width : 5 rem ;
box - sizing : border - box ;
}
. search - form . el - form - item _ _content {
flex : 1 ;
min - width : 0 ;
box - sizing : border - box ;
}
. search - form . el - input ,
. search - form . el - select ,
. search - form . el - cascader {
width : 100 % ;
min - width : 8 rem ;
box - sizing : border - box ;
}
. search - form . el - input _ _inner ,
. search - form . el - select . el - input _ _inner {
box - sizing : border - box ;
transition : all 0.3 s ease ;
}
/* 搜索按钮样式 */
. search - buttons {
text - align : center ;
margin - top : 0.625 rem ;
width : 100 % ;
box - sizing : border - box ;
}
. search - buttons . el - button {
margin : 0 0.5 rem ;
padding : 0.5 rem 1.25 rem ;
border - radius : 0.25 rem ;
font - weight : 500 ;
box - sizing : border - box ;
min - width : 4 rem ;
}
. search - buttons . el - button -- primary {
background : linear - gradient ( 135 deg , # 409 eff 0 % , # 1890 ff 100 % ) ;
border : none ;
box - shadow : 0 0.125 rem 0.25 rem rgba ( 64 , 158 , 255 , 0.3 ) ;
}
. search - buttons . el - button -- primary : hover {
background : linear - gradient ( 135 deg , # 66 b1ff 0 % , # 40 a9ff 100 % ) ;
box - shadow : 0 0.25 rem 0.5 rem rgba ( 64 , 158 , 255 , 0.4 ) ;
}
/* 缩放适配 - 针对110%等非标准缩放 */
@ media screen and ( min - resolution : 1.1 dppx ) and ( max - resolution : 1.3 dppx ) {
. search - form - container {
padding : 1 rem ;
}
. search - form . el - form - item {
margin - bottom : 0.875 rem ;
}
. search - form . el - form - item _ _label {
min - width : 4.5 rem ;
font - size : 0.875 rem ;
}
. search - form . el - input ,
. search - form . el - select ,
. search - form . el - cascader {
min - width : 7 rem ;
}
}
/* 响应式调整 */
@ media ( max - width : 768 px ) {
. search - form - container {
padding : 0.9375 rem ;
}
. search - form . el - form - item {
margin - bottom : 0.75 rem ;
}
. search - form . el - form - item _ _label {
min - width : auto ;
margin - bottom : 0.25 rem ;
}
. search - buttons {
text - align : left ;
}
. search - buttons . el - button {
margin : 0.25 rem 0.5 rem 0.25 rem 0 ;
}
}
/* 超小屏幕适配 */
@ media ( max - width : 480 px ) {
. search - form . el - col {
flex : 0 0 100 % ;
max - width : 100 % ;
}
. search - form . el - form - item _ _label {
width : 100 % ;
text - align : left ;
}
}
/* 对话框样式 */
. chat - dialog . el - dialog _ _body {
padding : 0 ;
}
. dialog - header {
background : # f8f9fa ;
padding : 16 px 20 px ;
border - bottom : 1 px solid # e9ecef ;
margin - bottom : 0 ;
}
. student - info {
color : # 606266 ;
font - size : 14 px ;
font - weight : 500 ;
}
. chat - content {
max - height : 500 px ;
overflow - y : auto ;
padding : 20 px ;
}
. no - chat {
text - align : center ;
padding : 40 px 0 ;
}
. message - item {
margin - bottom : 24 px ;
border : 1 px solid # e4e7ed ;
border - radius : 8 px ;
overflow : hidden ;
}
. message - header {
background : # f5f7fa ;
padding : 12 px 16 px ;
display : flex ;
justify - content : space - between ;
align - items : center ;
border - bottom : 1 px solid # e4e7ed ;
}
. message - time {
color : # 909399 ;
font - size : 12 px ;
}
. feedback - status {
display : flex ;
align - items : center ;
}
. message - content {
padding : 16 px ;
}
. user - message ,
. ai - message {
margin - bottom : 16 px ;
}
. user - message : last - child ,
. ai - message : last - child {
margin - bottom : 0 ;
}
. message - label {
font - weight : 600 ;
color : # 303133 ;
margin - bottom : 8 px ;
font - size : 14 px ;
}
. message - text {
padding : 12 px 16 px ;
border - radius : 6 px ;
line - height : 1.6 ;
font - size : 14 px ;
word - wrap : break - word ;
}
. user - text {
background : # f0f9ff ;
border : 1 px solid # e1f5fe ;
color : # 0277 bd ;
}
. ai - text {
background : # f8f9fa ;
border : 1 px solid # e9ecef ;
color : # 495057 ;
}
. ai - text . feedback - like {
background : # f0f9ff ;
border - color : # 4 caf50 ;
box - shadow : 0 0 0 2 px rgba ( 76 , 175 , 80 , 0.1 ) ;
}
. ai - text . feedback - dislike {
background : # fff5f5 ;
border - color : # f56565 ;
box - shadow : 0 0 0 2 px rgba ( 245 , 101 , 101 , 0.1 ) ;
}
/* 滚动条样式 */
. chat - content : : - webkit - scrollbar {
width : 6 px ;
}
. chat - content : : - webkit - scrollbar - track {
background : # f1f1f1 ;
border - radius : 3 px ;
}
. chat - content : : - webkit - scrollbar - thumb {
background : # c1c1c1 ;
border - radius : 3 px ;
}
. chat - content : : - webkit - scrollbar - thumb : hover {
background : # a8a8a8 ;
}
< / style >