feat: add agent favorite functionality with UI and API implementation
- Add `addFavorite` and `removeFavorite` API functions in agent.js - Implement favorite button UI in Agents.vue with star icons - Add login check before favorite operations using token manager - Sort agents with favorites appearing at the top of the list - Include success/error messages for user feedback - Add backend API endpoints for creating/deleting agent favorites - Update agent list response to include favorite status - Style favorite button with hover and active states
This commit is contained in:
@@ -116,3 +116,27 @@ export function getMessages(params) {
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加智能体收藏
|
||||
* @param {number} agentId - 智能体ID
|
||||
*/
|
||||
export function addFavorite(agentId) {
|
||||
return request({
|
||||
url: `${BASE_URL}/agent/favorite/create`,
|
||||
method: 'post',
|
||||
params: { agentId }
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消智能体收藏
|
||||
* @param {number} agentId - 智能体ID
|
||||
*/
|
||||
export function removeFavorite(agentId) {
|
||||
return request({
|
||||
url: `${BASE_URL}/agent/favorite/delete`,
|
||||
method: 'delete',
|
||||
params: { agentId }
|
||||
})
|
||||
}
|
||||
|
||||
@@ -134,6 +134,15 @@
|
||||
|
||||
<!-- 底部操作栏 -->
|
||||
<div class="card-footer">
|
||||
<button
|
||||
class="favorite-btn"
|
||||
:class="{ 'favorite-btn--active': agent.isFavorite }"
|
||||
@click.stop="handleFavorite(agent)"
|
||||
>
|
||||
<StarFilled v-if="agent.isFavorite" />
|
||||
<StarOutlined v-else />
|
||||
<span>{{ agent.isFavorite ? '已收藏' : '收藏' }}</span>
|
||||
</button>
|
||||
<div class="footer-spacer"></div>
|
||||
<button class="chat-btn" @click.stop="handleChat(agent)">
|
||||
<MessageOutlined class="chat-btn-icon" />
|
||||
@@ -172,12 +181,15 @@ import {
|
||||
CloseOutlined,
|
||||
ArrowRightOutlined,
|
||||
MessageOutlined,
|
||||
AppstoreOutlined
|
||||
AppstoreOutlined,
|
||||
StarOutlined,
|
||||
StarFilled
|
||||
} from '@ant-design/icons-vue'
|
||||
import { message } from 'ant-design-vue'
|
||||
import FullWidthLayout from '@/layouts/components/FullWidthLayout.vue'
|
||||
import ChatDrawer from '@/components/agents/ChatDrawer.vue'
|
||||
import { getAgentList } from '@/api/agent'
|
||||
import { getAgentList, addFavorite, removeFavorite } from '@/api/agent'
|
||||
import tokenManager from '@gold/utils/token-manager'
|
||||
|
||||
// 状态管理
|
||||
const loading = ref(false)
|
||||
@@ -218,7 +230,7 @@ const categories = computed(() => {
|
||||
return cats
|
||||
})
|
||||
|
||||
// 过滤后的列表
|
||||
// 过滤后的列表(收藏置顶)
|
||||
const filteredAgentList = computed(() => {
|
||||
let list = agentList.value
|
||||
|
||||
@@ -234,7 +246,11 @@ const filteredAgentList = computed(() => {
|
||||
)
|
||||
}
|
||||
|
||||
return list
|
||||
// 收藏的智能体置顶
|
||||
return list.sort((a, b) => {
|
||||
if (a.isFavorite === b.isFavorite) return 0
|
||||
return a.isFavorite ? -1 : 1
|
||||
})
|
||||
})
|
||||
|
||||
// 获取智能体列表
|
||||
@@ -250,7 +266,8 @@ const fetchAgentList = async () => {
|
||||
description: item.description,
|
||||
avatar: item.icon,
|
||||
categoryName: item.categoryName || '其他',
|
||||
tagColor: getTagColor(item.categoryName)
|
||||
tagColor: getTagColor(item.categoryName),
|
||||
isFavorite: item.isFavorite || false
|
||||
}))
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -327,6 +344,30 @@ const handleSendMessage = (data) => {
|
||||
console.log('发送消息:', data)
|
||||
}
|
||||
|
||||
// 收藏切换
|
||||
const handleFavorite = async (agent) => {
|
||||
// 检查登录状态
|
||||
if (!tokenManager.isLoggedIn()) {
|
||||
message.warning('请先登录')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
if (agent.isFavorite) {
|
||||
await removeFavorite(agent.id)
|
||||
agent.isFavorite = false
|
||||
message.success('已取消收藏')
|
||||
} else {
|
||||
await addFavorite(agent.id)
|
||||
agent.isFavorite = true
|
||||
message.success('收藏成功')
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('收藏操作失败:', error)
|
||||
message.error('操作失败,请重试')
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化
|
||||
onMounted(() => {
|
||||
fetchAgentList()
|
||||
@@ -799,6 +840,38 @@ onMounted(() => {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
// 收藏按钮
|
||||
.favorite-btn {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 5px;
|
||||
padding: 6px 12px;
|
||||
background: transparent;
|
||||
border: 1px solid var(--color-gray-300);
|
||||
border-radius: 8px;
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: var(--color-gray-600);
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
border-color: #F59E0B;
|
||||
color: #F59E0B;
|
||||
background: #FFFBEB;
|
||||
}
|
||||
|
||||
&:active {
|
||||
transform: scale(0.95);
|
||||
}
|
||||
|
||||
&--active {
|
||||
border-color: #F59E0B;
|
||||
color: #F59E0B;
|
||||
background: #FFFBEB;
|
||||
}
|
||||
}
|
||||
|
||||
// ============================================
|
||||
// 空状态
|
||||
// ============================================
|
||||
|
||||
Reference in New Issue
Block a user