feat: 在AI仪表板中添加高优先级投标展示
This commit is contained in:
@@ -53,6 +53,7 @@
|
|||||||
<DashboardAI
|
<DashboardAI
|
||||||
v-if="activeIndex === '2'"
|
v-if="activeIndex === '2'"
|
||||||
:bids="bids"
|
:bids="bids"
|
||||||
|
:high-priority-bids="highPriorityBids"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Bids
|
<Bids
|
||||||
|
|||||||
@@ -7,6 +7,38 @@
|
|||||||
获取 AI 推荐
|
获取 AI 推荐
|
||||||
</el-button>
|
</el-button>
|
||||||
</div>
|
</div>
|
||||||
|
<el-row :gutter="20">
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-card class="box-card" shadow="hover">
|
||||||
|
<template #header>
|
||||||
|
<div class="card-header" @click="toggleHighPriority" style="cursor: pointer;">
|
||||||
|
<span>High Priority Bids</span>
|
||||||
|
<div style="display: flex; align-items: center; gap: 10px;">
|
||||||
|
<el-tag type="danger">Top 10</el-tag>
|
||||||
|
<el-icon :style="{ transform: highPriorityCollapsed ? 'rotate(-90deg)' : 'rotate(0deg)', transition: 'transform 0.3s' }">
|
||||||
|
<ArrowDown />
|
||||||
|
</el-icon>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<el-collapse-transition>
|
||||||
|
<div v-show="!highPriorityCollapsed">
|
||||||
|
<el-table :data="highPriorityBids" style="width: 100%" size="small">
|
||||||
|
<el-table-column prop="title" label="Title">
|
||||||
|
<template #default="scope">
|
||||||
|
<a :href="scope.row.url" target="_blank">{{ scope.row.title }}</a>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="source" label="Source" width="240" />
|
||||||
|
<el-table-column prop="publishDate" label="Date" width="120">
|
||||||
|
<template #default="scope">{{ formatDate(scope.row.publishDate) }}</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</div>
|
||||||
|
</el-collapse-transition>
|
||||||
|
</el-card>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 10px;">
|
||||||
<h3 style="margin: 0;">选择日期范围</h3>
|
<h3 style="margin: 0;">选择日期范围</h3>
|
||||||
<div style="display: flex; gap: 10px;">
|
<div style="display: flex; gap: 10px;">
|
||||||
@@ -114,7 +146,7 @@
|
|||||||
import { ref, watch } from 'vue'
|
import { ref, watch } from 'vue'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { MagicStick, Loading, InfoFilled, List } from '@element-plus/icons-vue'
|
import { MagicStick, Loading, InfoFilled, List, ArrowDown } from '@element-plus/icons-vue'
|
||||||
|
|
||||||
|
|
||||||
interface AIRecommendation {
|
interface AIRecommendation {
|
||||||
@@ -127,6 +159,7 @@ interface AIRecommendation {
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
bids: any[]
|
bids: any[]
|
||||||
|
highPriorityBids: any[]
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<Props>()
|
const props = defineProps<Props>()
|
||||||
@@ -137,6 +170,7 @@ const dateRange = ref<[string, string] | null>(null)
|
|||||||
const showAllBids = ref(false)
|
const showAllBids = ref(false)
|
||||||
const bidsLoading = ref(false)
|
const bidsLoading = ref(false)
|
||||||
const bidsByDateRange = ref<any[]>([])
|
const bidsByDateRange = ref<any[]>([])
|
||||||
|
const highPriorityCollapsed = ref(false)
|
||||||
|
|
||||||
// 从 localStorage 加载保存的日期范围
|
// 从 localStorage 加载保存的日期范围
|
||||||
const loadSavedDateRange = () => {
|
const loadSavedDateRange = () => {
|
||||||
@@ -155,6 +189,18 @@ watch(dateRange, (newDateRange) => {
|
|||||||
localStorage.setItem('dashboardAI_dateRange', JSON.stringify(newDateRange))
|
localStorage.setItem('dashboardAI_dateRange', JSON.stringify(newDateRange))
|
||||||
}, { deep: true })
|
}, { deep: true })
|
||||||
|
|
||||||
|
// 切换 High Priority Bids 的折叠状态
|
||||||
|
const toggleHighPriority = () => {
|
||||||
|
highPriorityCollapsed.value = !highPriorityCollapsed.value
|
||||||
|
}
|
||||||
|
|
||||||
|
// 监听 highPriorityBids,当没有数据时自动折叠
|
||||||
|
watch(() => props.highPriorityBids, (newBids) => {
|
||||||
|
if (newBids.length === 0) {
|
||||||
|
highPriorityCollapsed.value = true
|
||||||
|
}
|
||||||
|
}, { immediate: true })
|
||||||
|
|
||||||
// 从数据库加载最新的 AI 推荐
|
// 从数据库加载最新的 AI 推荐
|
||||||
const loadLatestRecommendations = async () => {
|
const loadLatestRecommendations = async () => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ export const ChngCrawler = {
|
|||||||
await page.waitForNavigation({ waitUntil: 'networkidle2' });
|
await page.waitForNavigation({ waitUntil: 'networkidle2' });
|
||||||
|
|
||||||
logger.log('Clicking search result...');
|
logger.log('Clicking search result...');
|
||||||
await page.screenshot({ path: 'bing.png' });
|
// await page.screenshot({ path: 'bing.png' });
|
||||||
const firstResultSelector = '#b_results .b_algo h2 a';
|
const firstResultSelector = '#b_results .b_algo h2 a';
|
||||||
await page.waitForSelector(firstResultSelector);
|
await page.waitForSelector(firstResultSelector);
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ export const ChngCrawler = {
|
|||||||
const newPage = await newTarget.page();
|
const newPage = await newTarget.page();
|
||||||
|
|
||||||
if (newPage) {
|
if (newPage) {
|
||||||
await newPage.screenshot({ path: 'newPage.png' });
|
// await newPage.screenshot({ path: 'newPage.png' });
|
||||||
await page.close();
|
await page.close();
|
||||||
page = newPage;
|
page = newPage;
|
||||||
if (username && password) {
|
if (username && password) {
|
||||||
@@ -125,7 +125,7 @@ export const ChngCrawler = {
|
|||||||
// PAUSE 15 SECONDS as requested
|
// PAUSE 15 SECONDS as requested
|
||||||
logger.log('Pausing 15 seconds before looking for "采购专栏"...');
|
logger.log('Pausing 15 seconds before looking for "采购专栏"...');
|
||||||
await new Promise(r => setTimeout(r, 15000));
|
await new Promise(r => setTimeout(r, 15000));
|
||||||
await page.screenshot({ path: 'huaneng.png' });
|
// await page.screenshot({ path: 'huaneng.png' });
|
||||||
|
|
||||||
logger.log('Looking for "采购专栏" link...');
|
logger.log('Looking for "采购专栏" link...');
|
||||||
await page.waitForFunction(() => {
|
await page.waitForFunction(() => {
|
||||||
|
|||||||
Reference in New Issue
Block a user