refactor(agent): 重构智能体页面布局和样式

-调整了智能体卡片的布局结构,优化了标题和描述的显示方式
- 改进了历史对话的展示样式,增加了滚动指示器
- 统一了标签和图标的样式,提升了视觉一致性
- 优化了搜索框和卡片列表的样式,提高了用户体验
This commit is contained in:
林志军
2025-07-28 13:47:40 +08:00
parent 7cdc7c1e44
commit 8ed40110ae
8 changed files with 294 additions and 226 deletions

View File

@ -22,19 +22,11 @@ const COMPONENTS: AppRouteRecordRaw[] = [
name: 'AgentIndex', name: 'AgentIndex',
component: () => import('@/views/agent/index'), component: () => import('@/views/agent/index'),
meta: { meta: {
locale:'ai应用',
requiresAuth: false, requiresAuth: false,
requireLogin: true, requireLogin: true,
}, },
}, }
{
path: 'index',
name: 'AgentIndex',
component: () => import('@/views/agent/index'),
meta: {
requiresAuth: false,
requireLogin: true,
},
},
], ],
}, },
]; ];

View File

@ -22,14 +22,16 @@
.image-container { .image-container {
height: 400px; height: 400px;
overflow: hidden; overflow: hidden;
border-radius: 8px; border-radius: 10px;
} }
.image-container img { .image-container img {
width: 100%; width: 100%;
height: auto; height: auto;
padding: 24px;
aspect-ratio: 1 / 1; aspect-ratio: 1 / 1;
object-fit: cover; object-fit: cover;
border-radius: 10px;
} }
} }
@ -94,12 +96,12 @@
.usage-info { .usage-info {
width: 79px; width: 79px;
height: 24px; height: 34px;
position: relative; position: relative;
.count { .count {
left: 0px; left: 0px;
top: 0px; top: 10px;
position: absolute; position: absolute;
color: var(--Text-2, #3C4043); color: var(--Text-2, #3C4043);
font-size: 16px; font-size: 16px;
@ -110,7 +112,7 @@
.label { .label {
left: 43px; left: 43px;
top: 3px; top: 10px;
position: absolute; position: absolute;
color: var(--Text-3, #737478); color: var(--Text-3, #737478);
font-size: 12px; font-size: 12px;

View File

@ -83,12 +83,12 @@ const initChat = async () => {
Object.assign(cozeInfo, data.info); Object.assign(cozeInfo, data.info);
await loadScript('https://lf-cdn.coze.cn/obj/unpkg/flow-platform/chat-app-sdk/1.2.0-beta.10/libs/cn/index.js'); await loadScript('https://lf-cdn.coze.cn/obj/unpkg/flow-platform/chat-app-sdk/1.2.0-beta.10/libs/cn/index.js');
let cozeConfig = await cozeWebSdkConfig(data.info.bot_id, data.info.name, data.info.auth); let cozeConfig = await cozeWebSdkConfig(data.info.bot_id, data.info.name, data.info.auth, data.info.user_info);
cozeWebSDK = cozeWebSDK = new CozeWebSDK.WebChatClient(cozeConfig); cozeWebSDK = cozeWebSDK = new CozeWebSDK.WebChatClient(cozeConfig);
showChatPage(); showChatPage();
}; };
const cozeWebSdkConfig = (botId, name, auth) => { const cozeWebSdkConfig = (botId, name, auth, userInfo) => {
auth.onRefreshToken = function () { auth.onRefreshToken = function () {
return ''; return '';
}; };
@ -108,11 +108,12 @@ const cozeWebSdkConfig = (botId, name, auth) => {
icon: '', icon: '',
zIndex: 1000, zIndex: 1000,
}, },
footer:{ footer: {
expressionText:"内容由AI生成无法确保真实准确仅供参考。", expressionText: '内容由AI生成无法确保真实准确仅供参考。',
}, },
}, },
auth: auth, auth: auth,
userInfo: userInfo,
header: { header: {
isShow: true, isShow: true,
isNeedClose: false, isNeedClose: false,

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="agent-wrap"> <div class="agent-wrap">
<a-input <a-input
style="float: right; width: 300px" style="float: right; width: 400px"
v-model="query.name" v-model="query.name"
@blur="getData()" @blur="getData()"
placeholder="搜索智能体" placeholder="搜索智能体"
@ -32,7 +32,7 @@
<div class="card-footer"> <div class="card-footer">
<div <div
:class="['status-tag', product.type === 1 ? 'blue-tag' : 'red-tag']" :class="['status-tag', product.type === 1 ? 'blue-tag' : 'red-tag']"
:style="{ background: product.type === 1 ? 'var(--Functional-Blue-1, #E6F3FF)' : 'var(--Functional-Red-1, #FFE9E7)' }" :style="{ background: product.type === 1 ? 'var(--Functional-Blue-1, #F0EDFF)' : 'var(--Functional-Red-1, #FFE9E7)' }"
data-size="mini-20px" data-size="mini-20px"
> >
<img <img

View File

@ -34,29 +34,42 @@
} }
.card-image-container { .card-image-container {
width: 99%; // 设置宽度 width: 99%;
height: 200px; // 设置高度,与宽度一致,保持正方形比例 height: 150px;
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
overflow: hidden; // 防止图片超出容器 overflow: hidden;
} }
.card-image { .card-image {
width: 100%; width: 100%;
height: 100%; height: 100%;
border-radius: 7px; border-radius: 7px;
object-fit: cover; // 确保图片按比例缩放并裁剪 object-fit: cover;
} }
.card-content { .card-content {
align-self: stretch; flex: 1;
display: flex; overflow: hidden;
flex-direction: column;
justify-content: flex-start; .card-title {
align-items: flex-start; white-space: nowrap;
gap: 4px; overflow: hidden;
text-overflow: ellipsis;
} }
.card-description {
height: 40px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
}
.card-title { .card-title {
color: var(--Text-1, #211f24); color: var(--Text-1, #211f24);
font-size: 16px; font-size: 16px;
@ -124,7 +137,7 @@
.blue-tag { .blue-tag {
.status-text { .status-text {
color: var(--Functional-Blue-6, #007BFF); color: var(--Functional-Blue-6, #6D4CFE);
} }
} }

View File

@ -1,12 +1,13 @@
<template> <template>
<div class="container"> <div class="agent-card">
<div class="header-image-container"> <div class="header-section">
<div class="header-image"> <div class="image-container">
<img :src="cozeInfo?.icon_url" alt="Header Image" /> <img :src="cozeInfo.icon_url" alt="" />
</div> </div>
</div> </div>
<div class="title-container"> <div class="info-section">
<div class="title">{{cozeInfo?.name}}</div> <div class="title-group">
<div class="title">{{cozeInfo.name}}</div>
<div class="tag"> <div class="tag">
<div class=""> <div class="">
<img <img
@ -14,21 +15,37 @@
:src="workflow" :src="workflow"
/> />
</div> </div>
<div class="tag-text">工作流</div> <div class="text">工作流</div>
</div>
<div class="usage-stats">
<div class="usage-count">{{cozeInfo?.views}}</div>
<div class="usage-label">次使用</div>
</div> </div>
</div> </div>
<div class="usage-info">
<div class="count">{{cozeInfo.views}}</div>
<div class="label">次使用</div>
</div>
</div>
<div class="description-section">
<div class="description"> <div class="description">
{{cozeInfo?.description}} {{cozeInfo.description}}
</div> </div>
</div>
<div class="divider"></div>
<!-- <div class="history-section">-->
<!-- <div class="history-title">-->
<!-- <div class="text">历史对话</div>-->
<!-- </div>-->
<!-- <div class="history-list">-->
<!-- <div class="history-item">-->
<!-- <div class="item-text">梳理这次舆情的时间线和关键节点</div>-->
<!-- </div>-->
<!-- </div>-->
<!-- </div>-->
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { defineProps } from 'vue'; import { defineProps } from 'vue';
import { delAgentMessage, getHistoryChat } from '@/api/all/agent';
import workflow from '@/assets/svg/workflow.svg'; import workflow from '@/assets/svg/workflow.svg';
const props = defineProps({ const props = defineProps({
@ -36,16 +53,32 @@ const props = defineProps({
type: Object as () => any, type: Object as () => any,
default: () => ({}), default: () => ({}),
}, },
botId: {
type: String,
default: '',
},
}); });
const delMessage = async (chatId, conversationId) => {
const { code, data } = await delAgentMessage({ chat_id: chatId, conversation_id: conversationId });
if (code === 200) {
console.log(data, 'data');
}
};
const conversations = ref([]);
const getHistoryChatData = async (botId) => {
const { code, data } = await getHistoryChat({ bot_id: botId });
if (code === 200) {
conversations.value = data.list;
}
};
const truncateText = (text: string, maxLength = 30) => {
if (text.length <= maxLength) return text;
return text.slice(0, maxLength) + '...';
};
onMounted(() => { onMounted(() => {
}); });
</script> </script>
<style scoped> <style scoped>
@import "./history.scss"; @import './history.scss';
</style> </style>

View File

@ -1,198 +1,225 @@
.container {
.agent-card {
width: 100%; width: 100%;
height: 100%; height: 100%;
background: var(--BG-100, #F7F8FA); background: var(--BG-100, #F7F8FA);
overflow: hidden; overflow: hidden;
border-radius: 8px; border-radius: 8px;
display: flex;
flex-direction: column; flex-direction: column;
justify-content: flex-start; justify-content: flex-start;
align-items: flex-start; align-items: flex-start;
display: inline-flex;
}
.header-image-container { .header-section {
align-self: stretch; align-self: stretch;
height: 160px; height: 300px;
display: flex;
flex-direction: column; flex-direction: column;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
gap: 10px; gap: 10px;
display: flex;
}
.header-image { .image-container {
align-self: stretch; height: 400px;
flex: 1 1 0;
position: relative;
background: #FFEDED;
overflow: hidden; overflow: hidden;
border-radius: 8px; border-radius: 8px;
} }
.header-image img { .image-container img {
width: 408.90px; width: 100%;
height: 218px; height: auto;
left: -24.45px; aspect-ratio: 1 / 1;
top: -29px; object-fit: cover;
position: absolute; }
} }
.title-container { .info-section {
align-self: stretch; align-self: stretch;
padding-top: 15px; padding-top: 15px;
padding-bottom: 15px; padding-bottom: 15px;
display: flex;
justify-content: space-between; justify-content: space-between;
align-items: flex-start; align-items: flex-start;
display: inline-flex;
}
.title { .title-group {
justify-content: center;
display: flex; display: flex;
flex-direction: column;
color: var(--Text-1, #211F24);
font-size: 18px;
padding: 5px;
font-family: Alibaba PuHuiTi;
font-weight: 400;
line-height: 26px;
word-wrap: break-word;
}
.tag {
height: 20px;
padding-left: 8px;
padding-right: 8px;
background: var(--Functional-Red-1, #FFE9E7);
overflow: hidden;
border-radius: 2px;
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
gap: 4px; gap: 4px;
display: flex;
}
.tag-icon { .title {
color: var(--Text-1, #211F24);
font-size: 18px;
font-family: 'Alibaba PuHuiTi', sans-serif;
font-weight: 400;
line-height: 26px;
padding: 10px;
}
.tag {
height: 20px;
padding: 0 8px;
background: var(--Functional-Red-1, #FFE9E7);
border-radius: 2px;
display: flex;
justify-content: flex-start;
align-items: center;
gap: 4px;
.icon {
width: 12px; width: 12px;
height: 12px; height: 12px;
position: relative; position: relative;
}
.tag-icon-inner { &::before {
width: 11.50px; content: '';
height: 10.75px; width: 10.74px;
left: 0.25px; height: 10.50px;
top: 0.63px; left: 0.63px;
top: 0.75px;
position: absolute; position: absolute;
background: var(--Functional-Red-6, #F64B31); background: var(--Brand-6, #6D4CFE);
} }
}
.tag-text { .text {
color: var(--Functional-Red-6, #F64B31); color: var(--Functional-Red-6, #F64B31);
font-size: 12px; font-size: 12px;
font-family: Alibaba PuHuiTi; font-family: 'Alibaba PuHuiTi', sans-serif;
font-weight: 400; font-weight: 400;
line-height: 20px; line-height: 20px;
word-wrap: break-word; }
} }
}
.usage-stats { .usage-info {
width: 79px; width: 79px;
height: 24px; height: 34px;
position: relative; position: relative;
}
.usage-count { .count {
left: 0px; left: 0px;
top: 0px; top: 10px;
position: absolute; position: absolute;
color: var(--Text-2, #3C4043); color: var(--Text-2, #3C4043);
font-size: 16px; font-size: 16px;
font-family: Alibaba PuHuiTi; font-family: 'Alibaba PuHuiTi', sans-serif;
font-weight: 400; font-weight: 400;
line-height: 24px; line-height: 24px;
word-wrap: break-word; }
}
.usage-label { .label {
left: 43px; left: 43px;
top: 3px; top: 10px;
position: absolute; position: absolute;
color: var(--Text-3, #737478); color: var(--Text-3, #737478);
font-size: 12px; font-size: 12px;
font-family: Alibaba PuHuiTi; font-family: 'Alibaba PuHuiTi', sans-serif;
font-weight: 400; font-weight: 400;
line-height: 20px; line-height: 20px;
word-wrap: break-word; }
} }
}
.description { .description-section {
align-self: stretch;
overflow: hidden;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
gap: 10px;
.description {
align-self: stretch; align-self: stretch;
color: var(--Text-2, #3C4043); color: var(--Text-2, #3C4043);
font-size: 14px; font-size: 14px;
font-family: Alibaba PuHuiTi; font-family: 'Alibaba PuHuiTi', sans-serif;
font-weight: 400; font-weight: 400;
line-height: 22px; line-height: 22px;
word-wrap: break-word; padding: 10px;
padding-inline: 5px; }
} }
.divider { .divider {
align-self: stretch; align-self: stretch;
height: 0px; height: 0px;
outline: 1px var(--Border-2, #E6E6E8) solid; outline: 1px var(--Border-2, #E6E6E8) solid;
outline-offset: -0.50px; outline-offset: -0.50px;
} }
.history-title { .history-section {
color: var(--Text-3, #737478); align-self: stretch;
flex: 1 1 0;
position: relative;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
.history-title {
align-self: stretch;
height: 40px;
display: flex;
justify-content: flex-start;
align-items: center;
gap: 10px;
.text {
color: var(--Functional-Red-6, #F64B31);
font-size: 14px; font-size: 14px;
font-family: Alibaba PuHuiTi; font-family: 'Alibaba PuHuiTi', sans-serif;
font-weight: 400; font-weight: 400;
line-height: 22px; line-height: 22px;
word-wrap: break-word; }
} }
.history-item { .history-list {
align-self: stretch;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: flex-start;
.history-item {
align-self: stretch; align-self: stretch;
height: 40px; height: 40px;
padding: 8px; padding: 8px;
border-radius: 8px; border-radius: 8px;
display: flex;
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
gap: 10px; gap: 10px;
display: inline-flex;
}
.history-item-text { .item-text {
flex: 1 1 0; flex: 1 1 0;
color: var(--Text-1, #211F24); color: var(--Text-1, #211F24);
font-size: 14px; font-size: 14px;
font-family: Alibaba PuHuiTi; font-family: 'Alibaba PuHuiTi', sans-serif;
font-weight: 400; font-weight: 400;
line-height: 22px; line-height: 22px;
word-wrap: break-word; }
} }
}
.scroll-indicator { .scroll-indicator {
width: 8px; width: 8px;
height: 240px; height: 240px;
padding-left: 1px; padding: 8px 1px;
padding-right: 1px; position: absolute;
padding-top: 8px;
padding-bottom: 8px;
left: 362px; left: 362px;
top: 40px; top: 40px;
position: absolute; display: flex;
justify-content: flex-start; justify-content: flex-start;
align-items: flex-start; align-items: flex-start;
gap: 10px; gap: 10px;
display: inline-flex;
}
.scroll-indicator-bar { .indicator-bar {
flex: 1 1 0; flex: 1 1 0;
height: 80px; height: 80px;
background: var(--BG-600, #939499); background: var(--BG-600, #939499);
border-radius: 4px; border-radius: 4px;
}
}
}
} }