diff --git a/frontend/package.json b/frontend/package.json index 32f7de3..0cf7659 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -17,9 +17,13 @@ "vue": "^3.5.24" }, "devDependencies": { + "@tailwindcss/postcss": "^4.1.18", "@types/node": "^24.10.1", "@vitejs/plugin-vue": "^6.0.1", "@vue/tsconfig": "^0.8.1", + "autoprefixer": "^10.4.23", + "postcss": "^8.5.6", + "tailwindcss": "^4.1.18", "typescript": "~5.9.3", "vite": "^7.2.4", "vue-tsc": "^3.1.4" diff --git a/frontend/postcss.config.js b/frontend/postcss.config.js new file mode 100644 index 0000000..1c87846 --- /dev/null +++ b/frontend/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + '@tailwindcss/postcss': {}, + autoprefixer: {}, + }, +} diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 36ed741..872e2c4 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -4,18 +4,19 @@ + - - - - Dashboard - - Dashboard AI + + + + + Dashboard + @@ -43,8 +44,8 @@ - - + diff --git a/frontend/src/style.css b/frontend/src/style.css index f691315..beb8313 100644 --- a/frontend/src/style.css +++ b/frontend/src/style.css @@ -1,3 +1,5 @@ +@import "tailwindcss"; + :root { font-family: system-ui, Avenir, Helvetica, Arial, sans-serif; line-height: 1.5; diff --git a/src/crawler/services/cdt_target.ts b/src/crawler/services/cdt_target.ts index df3c436..2661e7a 100644 --- a/src/crawler/services/cdt_target.ts +++ b/src/crawler/services/cdt_target.ts @@ -55,7 +55,7 @@ export interface CdtResult { export const CdtCrawler = { name: '中国大唐集团电子商务平台', url: 'https://tang.cdt-ec.com/home/index.html', - baseUrl: 'https://tang.cdt-ec.com/', + baseUrl: 'https://tang.cdt-ec.com', async crawl(browser: puppeteer.Browser): Promise { const logger = new Logger('CdtCrawler'); @@ -252,10 +252,11 @@ export const CdtCrawler = { const dateStr = match[3]?.trim(); if (title && url) { + const fullUrl = url.startsWith('http') ? url : this.baseUrl + url; results.push({ title, publishDate: dateStr ? new Date(dateStr) : new Date(), - url: url.startsWith('http') ? url : this.baseUrl + url + url: fullUrl.replace(/\/\//g, '/') }); } } diff --git a/src/crawler/services/ceic_target.ts b/src/crawler/services/ceic_target.ts index 5d85bbd..f31170e 100644 --- a/src/crawler/services/ceic_target.ts +++ b/src/crawler/services/ceic_target.ts @@ -132,7 +132,7 @@ export const CeicCrawler = { allResults.push(...pageResults.map(r => ({ title: r.title, publishDate: r.dateStr ? new Date(r.dateStr) : new Date(), - url: r.url + url: r.url.replace(/\/\//g, '/') }))); logger.log(`Extracted ${pageResults.length} items.`); diff --git a/src/crawler/services/cgnpc_target.ts b/src/crawler/services/cgnpc_target.ts index 3b833bc..886ef2a 100644 --- a/src/crawler/services/cgnpc_target.ts +++ b/src/crawler/services/cgnpc_target.ts @@ -190,10 +190,11 @@ export const CgnpcCrawler = { const dateStr = match[3]?.trim(); if (title && url) { + const fullUrl = url.startsWith('http') ? url : this.baseUrl + url; results.push({ title, publishDate: dateStr ? new Date(dateStr) : new Date(), - url: url.startsWith('http') ? url : this.baseUrl + url + url: fullUrl.replace(/\/\//g, '/') }); } } diff --git a/src/crawler/services/chdtp_target.ts b/src/crawler/services/chdtp_target.ts index b6fe939..653df77 100644 --- a/src/crawler/services/chdtp_target.ts +++ b/src/crawler/services/chdtp_target.ts @@ -105,10 +105,11 @@ export const ChdtpCrawler = { const dateStr = match[5]?.trim(); if (title && urlSuffix) { + const fullUrl = this.baseUrl + urlSuffix; results.push({ title, publishDate: dateStr ? new Date(dateStr) : new Date(), - url: this.baseUrl + urlSuffix + url: fullUrl.replace(/\/\//g, '/') }); } } diff --git a/src/crawler/services/chng_target.ts b/src/crawler/services/chng_target.ts index 6ab2815..2604cef 100644 --- a/src/crawler/services/chng_target.ts +++ b/src/crawler/services/chng_target.ts @@ -206,7 +206,7 @@ export const ChngCrawler = { allResults.push(...pageResults.map(r => ({ title: r!.title, publishDate: new Date(r!.dateStr), - url: r!.url + url: r!.url.replace(/\/\//g, '/') }))); logger.log(`Extracted ${pageResults.length} items.`); diff --git a/src/crawler/services/cnncecp_target.ts b/src/crawler/services/cnncecp_target.ts index 725ce26..514bb6e 100644 --- a/src/crawler/services/cnncecp_target.ts +++ b/src/crawler/services/cnncecp_target.ts @@ -181,10 +181,11 @@ export const CnncecpCrawler = { const title = match[3]?.trim(); if (title && url) { + const fullUrl = url.startsWith('http') ? url : this.baseUrl + url; results.push({ title, publishDate: dateStr ? new Date(dateStr) : new Date(), - url: url.startsWith('http') ? url : this.baseUrl + url + url: fullUrl.replace(/\/\//g, '/') }); } } diff --git a/src/crawler/services/cnooc_target.ts b/src/crawler/services/cnooc_target.ts index e85ab01..cfbdbae 100644 --- a/src/crawler/services/cnooc_target.ts +++ b/src/crawler/services/cnooc_target.ts @@ -182,10 +182,11 @@ export const CnoocCrawler = { const dateStr = match[3]?.trim(); if (title && url) { + const fullUrl = url.startsWith('http') ? url : this.baseUrl + url; results.push({ title, publishDate: dateStr ? new Date(dateStr) : new Date(), - url: url.startsWith('http') ? url : this.baseUrl + url + url: fullUrl.replace(/\/\//g, '/') }); } } diff --git a/src/crawler/services/eps_target.ts b/src/crawler/services/eps_target.ts index 0344322..78b8a62 100644 --- a/src/crawler/services/eps_target.ts +++ b/src/crawler/services/eps_target.ts @@ -188,10 +188,11 @@ export const EpsCrawler = { const dateStr = match[3]?.trim(); if (title && url) { + const fullUrl = url.startsWith('http') ? url : this.baseUrl + url; results.push({ title, publishDate: dateStr ? new Date(dateStr) : new Date(), - url: url.startsWith('http') ? url : this.baseUrl + url + url: fullUrl.replace(/\/\//g, '/') }); } } diff --git a/src/crawler/services/espic_target.ts b/src/crawler/services/espic_target.ts index 341f9ec..9075750 100644 --- a/src/crawler/services/espic_target.ts +++ b/src/crawler/services/espic_target.ts @@ -234,10 +234,11 @@ export const EspicCrawler = { const dateStr = match[3]?.trim(); if (title && url) { + const fullUrl = url.startsWith('http') ? url : this.baseUrl + url; results.push({ title, publishDate: dateStr ? new Date(dateStr) : new Date(), - url: url.startsWith('http') ? url : this.baseUrl + url + url: fullUrl.replace(/\/\//g, '/') }); } } diff --git a/src/crawler/services/powerbeijing_target.ts b/src/crawler/services/powerbeijing_target.ts index 842b0e2..d5aaf2b 100644 --- a/src/crawler/services/powerbeijing_target.ts +++ b/src/crawler/services/powerbeijing_target.ts @@ -185,10 +185,11 @@ export const PowerbeijingCrawler = { const dateStr = match[3]?.trim(); if (title && url) { + const fullUrl = url.startsWith('http') ? url : this.baseUrl + url; results.push({ title, publishDate: dateStr ? new Date(dateStr) : new Date(), - url: url.startsWith('http') ? url : this.baseUrl + url + url: fullUrl.replace(/\/\//g, '/') }); } } diff --git a/src/crawler/services/sdicc_target.ts b/src/crawler/services/sdicc_target.ts index e3ff710..9f9464d 100644 --- a/src/crawler/services/sdicc_target.ts +++ b/src/crawler/services/sdicc_target.ts @@ -190,10 +190,11 @@ export const SdiccCrawler = { const dateStr = match[4]?.trim(); if (title && ggGuid && gcGuid) { + const fullUrl = `${this.baseUrl}/cgxx/ggDetail?gcGuid=${gcGuid}&ggGuid=${ggGuid}`; results.push({ title, publishDate: dateStr ? new Date(dateStr) : new Date(), - url: `${this.baseUrl}/cgxx/ggDetail?gcGuid=${gcGuid}&ggGuid=${ggGuid}` + url: fullUrl.replace(/\/\//g, '/') }); } } diff --git a/src/crawler/services/szecp_target.ts b/src/crawler/services/szecp_target.ts index 81007f1..498f59f 100644 --- a/src/crawler/services/szecp_target.ts +++ b/src/crawler/services/szecp_target.ts @@ -134,7 +134,7 @@ export const SzecpCrawler = { allResults.push(...pageResults.map(r => ({ title: r!.title, publishDate: new Date(r!.dateStr), - url: r!.url + url: r!.url.replace(/\/\//g, '/') }))); logger.log(`Extracted ${pageResults.length} items.`);