4848 </a-tag >
4949 </div >
5050
51- <!-- 卡片内容:消息内容和对话信息 -->
51+ <!-- 卡片内容:对话信息、消息内容和反馈原因 -->
5252 <div class =" card-content" >
53- <div class =" message-section" >
54- <div class =" message-content" >{{ feedback.message_content }}</div >
55- </div >
56-
57- <div class =" conversation-section" >
53+ <!-- 对话标题 -->
54+ <div class =" conversation-section" v-if =" feedback.conversation_title" >
5855 <div class =" conversation-info" >
5956 <div class =" info-item" >
57+ <span
58+ class =" conversation-title"
59+ :class =" { 'collapsed': !expandedStates.get(`${feedback.id}-conversation`) }"
60+ >
61+ 标题:{{ feedback.conversation_title }}
62+ </span >
63+ <a-button
64+ v-if =" shouldShowConversationExpandButton(feedback.conversation_title)"
65+ type =" link"
66+ size =" small"
67+ @click =" toggleConversationExpand(feedback.id)"
68+ class =" expand-button-inline"
69+ >
70+ {{ expandedStates.get(`${feedback.id}-conversation`) ? '收起' : '展开' }}
71+ </a-button >
72+ </div >
73+ <div class =" info-item" v-if =" !props.agentId" >
6074 <span class =" label" >智能体:</span >
6175 <span class =" value" >{{ feedback.agent_id }}</span >
6276 </div >
63- <div class =" info-item" v-if =" feedback.conversation_title" >
64- <span class =" label" >对话:</span >
65- <span class =" value" >{{ feedback.conversation_title }}</span >
66- </div >
6777 </div >
6878 </div >
6979
80+ <!-- 消息内容 -->
81+ <div class =" message-section" >
82+ <div
83+ class =" message-content"
84+ :class =" { 'collapsed': !expandedStates.get(`${feedback.id}-message`) }"
85+ >
86+ {{ feedback.message_content }}
87+ </div >
88+ <a-button
89+ v-if =" shouldShowExpandButton(feedback.message_content)"
90+ type =" link"
91+ size =" small"
92+ @click =" toggleExpand(feedback.id)"
93+ class =" expand-button"
94+ >
95+ {{ expandedStates.get(`${feedback.id}-message`) ? '收起' : '展开全部' }}
96+ </a-button >
97+ </div >
98+
7099 <!-- 反馈原因 -->
71100 <div v-if =" feedback.reason" class =" reason-section" >
72101 <div class =" reason-content" >{{ feedback.reason }}</div >
@@ -98,6 +127,14 @@ import { LikeOutlined, DislikeOutlined, ClockCircleOutlined } from '@ant-design/
98127import { dashboardApi } from ' @/apis/dashboard_api'
99128import { formatFullDateTime } from ' @/utils/time'
100129
130+ // 常量配置
131+ const CONFIG = {
132+ MESSAGE_MAX_LINES : 8 , // 消息最大显示行数
133+ CONVERSATION_MAX_LINES : 2 , // 对话标题最大显示行数
134+ CONVERSATION_MAX_CHARS : 60 , // 对话标题字符数阈值
135+ AVG_CHARS_PER_LINE : 30 // 每行平均字符数(中英文混合)
136+ }
137+
101138// Props
102139const props = defineProps ({
103140 agentId: {
@@ -119,6 +156,9 @@ const feedbackOptions = [
119156 { label: ' 点踩' , value: ' dislike' }
120157]
121158
159+ // 展开状态映射(使用 Map 避免直接修改对象)
160+ const expandedStates = ref (new Map ())
161+
122162// 显示模态框
123163const show = () => {
124164 modalVisible .value = true
@@ -128,6 +168,37 @@ const show = () => {
128168// 暴露方法给父组件
129169defineExpose ({ show })
130170
171+ // 计算文本行数的辅助函数(估算)
172+ const estimateLines = (text ) => {
173+ if (! text) return 0
174+ return Math .ceil (text .length / CONFIG .AVG_CHARS_PER_LINE )
175+ }
176+
177+ // 判断是否显示展开按钮
178+ const shouldShowExpandButton = (content ) => {
179+ return estimateLines (content) > CONFIG .MESSAGE_MAX_LINES
180+ }
181+
182+ // 判断对话标题是否需要展开按钮
183+ const shouldShowConversationExpandButton = (title ) => {
184+ if (! title) return false
185+ return title .length > CONFIG .CONVERSATION_MAX_CHARS
186+ }
187+
188+ // 切换展开/收起状态
189+ const toggleExpand = (feedbackId ) => {
190+ const key = ` ${ feedbackId} -message`
191+ const currentState = expandedStates .value .get (key) ?? false
192+ expandedStates .value .set (key, ! currentState)
193+ }
194+
195+ // 切换对话标题展开/收起状态
196+ const toggleConversationExpand = (feedbackId ) => {
197+ const key = ` ${ feedbackId} -conversation`
198+ const currentState = expandedStates .value .get (key) ?? false
199+ expandedStates .value .set (key, ! currentState)
200+ }
201+
131202// 加载反馈列表
132203const loadFeedbacks = async () => {
133204 loadingFeedbacks .value = true
@@ -139,9 +210,12 @@ const loadFeedbacks = async () => {
139210
140211 const response = await dashboardApi .getFeedbacks (params)
141212 feedbacks .value = response
213+ // 重置展开状态
214+ expandedStates .value .clear ()
142215 } catch (error) {
143216 console .error (' 加载反馈列表失败:' , error)
144- message .error (' 加载反馈列表失败' )
217+ message .error (' 加载反馈列表失败,请稍后重试' )
218+ feedbacks .value = []
145219 } finally {
146220 loadingFeedbacks .value = false
147221 }
@@ -268,6 +342,25 @@ watch(() => props.agentId, () => {
268342 line- height: 1.4 ;
269343 color: var (-- gray- 800 );
270344 word- break: break - word;
345+ overflow: hidden;
346+ transition: max- height 0 .3s ease;
347+ }
348+
349+ .message - content .collapsed {
350+ display: - webkit- box;
351+ - webkit- box- orient: vertical;
352+ - webkit- line- clamp: 8 ;
353+ line- clamp: 8 ;
354+ overflow: hidden;
355+ text- overflow: ellipsis;
356+ }
357+
358+ .expand - button {
359+ padding: 0 ;
360+ height: auto;
361+ font- size: 12px ;
362+ margin- top: 8px ;
363+ color: var (-- main- color);
271364}
272365
273366.conversation - section {
@@ -277,7 +370,7 @@ watch(() => props.agentId, () => {
277370.conversation - info {
278371 display: flex;
279372 flex- direction: column;
280- gap : 4 px ;
373+ gap: 8px ;
281374}
282375
283376.info - item {
@@ -297,6 +390,41 @@ watch(() => props.agentId, () => {
297390 font- weight: 400 ;
298391 word- break: break - all;
299392 }
393+
394+ // 对话标题样式(独立显示)
395+ .conversation - title {
396+ display: block;
397+ color: var (-- gray- 700 );
398+ font- size: 13px ;
399+ font- weight: 500 ;
400+ line- height: 1.4 ;
401+ word- break: break - word;
402+ transition: all 0 .3s ease;
403+
404+ & .collapsed {
405+ display: - webkit- box;
406+ - webkit- box- orient: vertical;
407+ - webkit- line- clamp: 2 ;
408+ line- clamp: 2 ;
409+ overflow: hidden;
410+ text- overflow: ellipsis;
411+ }
412+ }
413+
414+ // 包含对话标题的 info-item 改为垂直布局
415+ & : has (.conversation - title ) {
416+ flex- direction: column;
417+ align- items: flex- start;
418+ gap: 4px ;
419+ }
420+ }
421+
422+ .expand - button- inline {
423+ padding: 0 ;
424+ height: auto;
425+ font- size: 11px ;
426+ color: var (-- main- color);
427+ align- self : flex- start;
300428}
301429
302430.reason - section {
@@ -346,14 +474,8 @@ watch(() => props.agentId, () => {
346474 gap: 12px ;
347475 }
348476
349- .feedback-card {
350- margin-bottom : 0 ;
351- }
352-
353477 .card - header {
354478 padding: 10px 12px ;
355- flex-direction : column ;
356- align-items : flex-start ;
357479 gap: 8px ;
358480 }
359481
@@ -362,19 +484,6 @@ watch(() => props.agentId, () => {
362484 gap: 10px ;
363485 }
364486
365- .conversation-info {
366- .info-item {
367- flex-direction : column ;
368- align-items : flex-start ;
369- gap : 2px ;
370-
371- .label {
372- min-width : auto ;
373- margin-right : 0 ;
374- }
375- }
376- }
377-
378487 .card - footer {
379488 padding: 6px 12px ;
380489 }
0 commit comments