(null)
+
+// 处理 PinnedProject 组件的 pin 状态改变事件
+const handlePinChanged = async (title: string) => {
+ // 更新对应推荐项目的 pin 状态
+ const rec = aiRecommendations.value.find(r => r.title === title)
+ if (rec) {
+ rec.pin = false
+ }
+}
+
// 切换 AI 推荐项目的 Pin 状态
const togglePin = async (item: AIRecommendation) => {
try {
@@ -335,6 +347,10 @@ const togglePin = async (item: AIRecommendation) => {
await axios.patch(`/api/bids/${encodeURIComponent(item.title)}/pin`, { pin: newPinStatus })
item.pin = newPinStatus
ElMessage.success(newPinStatus ? '已置顶' : '已取消置顶')
+ // 刷新 PinnedProject 组件的数据
+ if (pinnedProjectRef.value) {
+ pinnedProjectRef.value.loadPinnedBids()
+ }
} catch (error) {
ElMessage.error('操作失败')
}
diff --git a/frontend/src/components/Dashboard.vue b/frontend/src/components/Dashboard.vue
index 7f19648..982be19 100644
--- a/frontend/src/components/Dashboard.vue
+++ b/frontend/src/components/Dashboard.vue
@@ -7,7 +7,7 @@
立刻抓取
-
+
Today's Bids
@@ -48,6 +48,20 @@
+
+
+
+
+
+
+
{{ scope.row.title }}
@@ -65,7 +79,7 @@
import { ref, computed, watch } from 'vue'
import axios from 'axios'
import { ElMessage } from 'element-plus'
-import { Refresh, ArrowDown } from '@element-plus/icons-vue'
+import { Refresh, ArrowDown, Paperclip } from '@element-plus/icons-vue'
import PinnedProject from './PinnedProject.vue'
interface Props {
@@ -271,6 +285,34 @@ const handleCrawl = async () => {
}
}
+// PinnedProject 组件引用
+const pinnedProjectRef = ref(null)
+
+// 处理 PinnedProject 组件的 pin 状态改变事件
+const handlePinChanged = async (title: string) => {
+ // 更新 todayBids 中对应项目的 pin 状态
+ const bid = props.todayBids.find(b => b.title === title)
+ if (bid) {
+ bid.pin = false
+ }
+}
+
+// 切换 Today's Bids 的 Pin 状态
+const togglePin = async (item: any) => {
+ try {
+ const newPinStatus = !item.pin
+ await axios.patch(`/api/bids/${encodeURIComponent(item.title)}/pin`, { pin: newPinStatus })
+ item.pin = newPinStatus
+ ElMessage.success(newPinStatus ? '已置顶' : '已取消置顶')
+ // 刷新 PinnedProject 组件的数据
+ if (pinnedProjectRef.value) {
+ pinnedProjectRef.value.loadPinnedBids()
+ }
+ } catch (error) {
+ ElMessage.error('操作失败')
+ }
+}
+
// 初始化时加载保存的关键字和日期范围
loadSavedKeywords()
loadSavedDateRange()
diff --git a/frontend/src/components/PinnedProject.vue b/frontend/src/components/PinnedProject.vue
index adff2a2..6939dc2 100644
--- a/frontend/src/components/PinnedProject.vue
+++ b/frontend/src/components/PinnedProject.vue
@@ -52,6 +52,10 @@ import axios from 'axios'
import { ElMessage } from 'element-plus'
import { Loading, InfoFilled, Paperclip } from '@element-plus/icons-vue'
+const emit = defineEmits<{
+ pinChanged: [title: string]
+}>()
+
const pinnedBids = ref([])
const pinnedLoading = ref(false)
@@ -77,6 +81,8 @@ const togglePin = async (item: any) => {
pinnedBids.value.splice(index, 1)
}
ElMessage.success('已取消置顶')
+ // 通知父组件 pin 状态已改变,传递 title
+ emit('pinChanged', item.title)
} catch (error) {
ElMessage.error('操作失败')
}
@@ -96,6 +102,11 @@ const formatDate = (dateStr: string) => {
onMounted(() => {
loadPinnedBids()
})
+
+// 暴露方法给父组件调用
+defineExpose({
+ loadPinnedBids
+})