| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- <template>
- <div class="store-page">
- <Breadcrumb />
- <a-card title="AI 对话详情" :loading="loading">
- <a-descriptions :column="{ xs: 1, sm: 2 }" bordered>
- <a-descriptions-item label="会话编号">{{ data.conversation_no || '-' }}</a-descriptions-item>
- <a-descriptions-item label="内部ID">{{ data.id || '-' }}</a-descriptions-item>
- <a-descriptions-item label="标题">{{ data.title || '-' }}</a-descriptions-item>
- <a-descriptions-item label="用户">{{ data.username || '-' }}</a-descriptions-item>
- <a-descriptions-item label="用户UUID">{{ data.create_user || '-' }}</a-descriptions-item>
- <a-descriptions-item label="状态">{{ data.state === 1 ? '正常' : '已删除' }}</a-descriptions-item>
- <a-descriptions-item label="更新时间">{{ formatTime(data.update_time) }}</a-descriptions-item>
- </a-descriptions>
- </a-card>
- <a-card title="消息记录" class="message-card">
- <div v-if="!data.messages?.length" class="empty">暂无消息</div>
- <div v-for="message in data.messages" :key="message.id" class="message">
- <div class="message__head">
- <a-avatar :size="34">
- <img v-if="message.role === 'assistant'" src="@/assets/img/ai.png" alt="小妍助理" />
- <icon-user v-else-if="message.role === 'user'" />
- <icon-info-circle v-else />
- </a-avatar>
- <div>
- <div class="message__name">
- {{ roleLabel(message.role) }}
- <a-tag v-if="message.status === 'error'" color="red" size="small">异常</a-tag>
- </div>
- <div class="message__time">{{ formatTime(message.create_time) }}</div>
- </div>
- </div>
- <div v-if="message.content" class="message__content">{{ message.content }}</div>
- <div v-if="message.images?.length" class="message__images">
- <a-image v-for="url in message.images" :key="url" :src="url" width="120" height="120" fit="cover" />
- </div>
- <div v-if="message.error_msg" class="message__error">{{ message.error_msg }}</div>
- </div>
- </a-card>
- </div>
- </template>
- <script setup>
- import { onMounted, ref } from 'vue'
- import { useRoute } from 'vue-router'
- import { Notification } from '@arco-design/web-vue'
- import { adminGetAIChatConversationDetail } from '@/api/aiChat'
- const route = useRoute()
- const loading = ref(false)
- const data = ref({})
- const roleLabel = (role) => ({ user: '用户', assistant: '小妍助理', system: '系统' }[role] || role)
- const formatTime = (time) => time ? new Date(Number(time)).toLocaleString('zh-CN', { hour12: false }) : '-'
- const fetchDetail = async () => {
- loading.value = true
- try {
- const res = await adminGetAIChatConversationDetail({ id: route.params.id })
- if (!res || res.code !== 0) return Notification.error({ title: '获取 AI 对话详情失败', content: res?.msg || '请稍后再试' })
- data.value = res.data || {}
- } finally {
- loading.value = false
- }
- }
- onMounted(fetchDetail)
- </script>
- <style scoped lang="less">
- @import '@/styles/store-theme.less';
- .message-card {
- margin-top: 15px;
- }
- .empty {
- padding: 24px;
- text-align: center;
- color: @store-text-muted;
- }
- .message {
- padding: 14px 0;
- border-bottom: 1px solid var(--color-border-2);
- &:last-child {
- border-bottom: 0;
- }
- &__head {
- display: flex;
- align-items: flex-start;
- gap: 10px;
- }
- &__name {
- display: flex;
- align-items: center;
- gap: 8px;
- font-weight: 650;
- color: @store-primary;
- }
- &__time {
- margin-top: 2px;
- font-size: 12px;
- color: @store-text-muted;
- }
- &__content {
- margin: 10px 0 0 44px;
- max-width: 900px;
- white-space: pre-wrap;
- word-break: break-word;
- line-height: 1.7;
- }
- &__images {
- display: flex;
- flex-wrap: wrap;
- gap: 8px;
- margin: 10px 0 0 44px;
- }
- &__error {
- margin: 8px 0 0 44px;
- color: rgb(var(--red-6));
- }
- }
- </style>
|