From 8f57683dd5b66c1c73ec388d556e55ecfd359e4f Mon Sep 17 00:00:00 2001 From: qiuxiao <2280807541@qq.com> Date: Wed, 12 Nov 2025 18:11:11 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=8E=E6=9C=9F=E4=BF=AE=E6=94=B9=E5=AE=8C?= =?UTF-8?q?=E5=96=84=EF=BC=8C=E4=B8=8A=E7=BA=BF=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- api/tools.js | 4 +- components/Footer.vue | 35 +-- components/GlobalLoading.vue | 2 +- components/Header.vue | 81 +++-- components/HorizontalDateList.vue | 11 +- components/MyTabs/MyTabs.vue | 2 +- components/Pagination.vue | 1 + components/Rate.vue | 6 +- components/SearchSelectInput.vue | 80 +++-- layouts/default.vue | 6 +- nuxt.config.js | 20 +- package.json | 2 + pages/AIHub/AITools.vue | 6 +- pages/AIHub/AIToolsDetail.vue | 101 ++++-- pages/AIHub/Frameworks.vue | 6 +- pages/AIHub/components/ListCardItem.vue | 22 +- pages/AIHub/index.vue | 8 +- pages/About/About.vue | 26 +- pages/About/Privacy.vue | 130 +++++--- pages/About/Service.vue | 107 ++++--- .../DailyNews/NewsDetailIndex/NewsDetail.vue | 10 +- pages/DailyNews/NewsDetailIndex/index.vue | 52 +++- pages/DailyNews/NewsList.vue | 20 +- .../DailyNews/components/ArticleCardItem.vue | 60 ++-- .../components/ArticleTextListItem.vue | 6 +- pages/DailyNews/components/NewsCardItem.vue | 37 ++- pages/DailyNews/index.vue | 83 +++-- pages/Home/components/PopularToolList.vue | 15 +- pages/Home/components/ToolItem.vue | 189 ++++++++++++ pages/Home/components/ToolItemCard.vue | 8 +- pages/Home/components/ToolList.vue | 94 ++---- pages/Home/components/Toolbar.vue | 70 ++++- pages/Home/index.vue | 42 ++- pages/Home/views/List.vue | 44 ++- pages/Home/views/ViewMore.vue | 9 +- pages/Launches/Detail/FinanceItem.vue | 22 +- pages/Launches/Detail/ProjectItem.vue | 30 +- pages/Launches/Detail/RelatedTool.vue | 47 ++- pages/Launches/Detail/index.vue | 292 +++++++++++------- .../FinanceDetail/SpecialFinanceItem.vue | 33 +- pages/Launches/FinanceDetail/index.vue | 176 ++++++++--- pages/Launches/components/ListItem.vue | 70 ++++- pages/Launches/components/OptionDates.vue | 131 +++++++- pages/Launches/components/SwitchDate.vue | 28 +- pages/Launches/components/SwitchMonth.vue | 29 +- pages/Launches/components/SwitchSort.vue | 16 +- pages/Launches/components/SwitchYear.vue | 31 +- pages/Launches/index.vue | 203 ++++++++++-- pages/Learn/Depth.vue | 6 +- pages/Learn/Observer.vue | 6 +- pages/Learn/Pioneer.vue | 6 +- pages/Learn/index.vue | 20 +- pages/ToolDetail/Comment/index.vue | 41 ++- pages/ToolDetail/Product/index.vue | 70 +++-- pages/ToolDetail/components/CommentBtn.vue | 8 +- pages/ToolDetail/components/CommentItem.vue | 17 +- .../ToolDetail/components/SimilarToolCard.vue | 41 ++- pages/ToolDetail/components/ThumbBtn.vue | 8 +- pages/ToolDetail/index.vue | 129 +++++--- router.js | 12 +- static/ToolDetail/icon_star.png | Bin 0 -> 1136 bytes static/font/Poppins-BlackItalic.otf | Bin 101016 -> 0 bytes static/font/Poppins-BoldItalic.otf | Bin 106216 -> 0 bytes static/font/Poppins-ExtraBoldItalic.otf | Bin 106072 -> 0 bytes static/font/Poppins-ExtraLight.otf | Bin 95476 -> 0 bytes static/font/Poppins-ExtraLightItalic.otf | Bin 107932 -> 0 bytes static/font/Poppins-Italic.otf | Bin 106944 -> 0 bytes static/font/Poppins-LightItalic.otf | Bin 107924 -> 0 bytes static/font/Poppins-MediumItalic.otf | Bin 105848 -> 0 bytes static/font/Poppins-SemiBoldItalic.otf | Bin 107144 -> 0 bytes static/font/Poppins-Thin.otf | Bin 90036 -> 0 bytes static/font/Poppins-ThinItalic.otf | Bin 101460 -> 0 bytes static/launches/icon_next.png | Bin 881 -> 446 bytes static/launches/icon_next_disabled.png | Bin 908 -> 451 bytes static/launches/icon_prev.png | Bin 909 -> 470 bytes static/launches/icon_prev_disabled.png | Bin 900 -> 446 bytes static/launches/link/icon_Facebook.png | Bin 0 -> 671 bytes .../launches/link/icon_Facebook_selected.png | Bin 0 -> 524 bytes static/launches/link/icon_Github.png | Bin 0 -> 803 bytes static/launches/link/icon_Github_selected.png | Bin 0 -> 603 bytes static/launches/link/icon_Instagram.png | Bin 0 -> 1155 bytes .../launches/link/icon_Instagram_selected.png | Bin 0 -> 651 bytes static/launches/link/icon_LikendIn.png | Bin 0 -> 743 bytes .../launches/link/icon_LikendIn_selected.png | Bin 0 -> 705 bytes static/launches/link/icon_Twitter.png | Bin 0 -> 1151 bytes .../launches/link/icon_Twitter_selected.png | Bin 0 -> 638 bytes static/launches/link/icon_Website.png | Bin 0 -> 681 bytes .../launches/link/icon_Website_selected.png | Bin 0 -> 830 bytes static/menu/analysis.png | Bin 0 -> 690 bytes static/menu/frameworks.png | Bin 0 -> 1411 bytes static/menu/observer.png | Bin 0 -> 1159 bytes static/menu/pioneer.png | Bin 0 -> 733 bytes static/menu/tools.png | Bin 0 -> 740 bytes styles/article.scss | 6 +- styles/font.scss | 30 +- styles/index.scss | 39 ++- styles/text.scss | 2 +- yarn.lock | 33 +- 98 files changed, 2110 insertions(+), 867 deletions(-) create mode 100644 pages/Home/components/ToolItem.vue create mode 100644 static/ToolDetail/icon_star.png delete mode 100644 static/font/Poppins-BlackItalic.otf delete mode 100644 static/font/Poppins-BoldItalic.otf delete mode 100644 static/font/Poppins-ExtraBoldItalic.otf delete mode 100644 static/font/Poppins-ExtraLight.otf delete mode 100644 static/font/Poppins-ExtraLightItalic.otf delete mode 100644 static/font/Poppins-Italic.otf delete mode 100644 static/font/Poppins-LightItalic.otf delete mode 100644 static/font/Poppins-MediumItalic.otf delete mode 100644 static/font/Poppins-SemiBoldItalic.otf delete mode 100644 static/font/Poppins-Thin.otf delete mode 100644 static/font/Poppins-ThinItalic.otf create mode 100644 static/launches/link/icon_Facebook.png create mode 100644 static/launches/link/icon_Facebook_selected.png create mode 100644 static/launches/link/icon_Github.png create mode 100644 static/launches/link/icon_Github_selected.png create mode 100644 static/launches/link/icon_Instagram.png create mode 100644 static/launches/link/icon_Instagram_selected.png create mode 100644 static/launches/link/icon_LikendIn.png create mode 100644 static/launches/link/icon_LikendIn_selected.png create mode 100644 static/launches/link/icon_Twitter.png create mode 100644 static/launches/link/icon_Twitter_selected.png create mode 100644 static/launches/link/icon_Website.png create mode 100644 static/launches/link/icon_Website_selected.png create mode 100644 static/menu/analysis.png create mode 100644 static/menu/frameworks.png create mode 100644 static/menu/observer.png create mode 100644 static/menu/pioneer.png create mode 100644 static/menu/tools.png diff --git a/api/tools.js b/api/tools.js index 38656e0..ddf0a31 100644 --- a/api/tools.js +++ b/api/tools.js @@ -3,7 +3,7 @@ export default ($axios) => ({ return $axios.get('/tool', { params }) }, getCategoryList(params) { - return $axios.get('/category', { params }) + return $axios.get('/category/tree', { params }) }, getToolByCategory(params) { return $axios.get('/tool/group', { params }) @@ -19,5 +19,5 @@ export default ($axios) => ({ }, searchToolByWord(word) { return $axios.get('/tool/search', { params:{q: word, limit:50}}) - } + }, }) diff --git a/components/Footer.vue b/components/Footer.vue index 61b4e0b..540605c 100644 --- a/components/Footer.vue +++ b/components/Footer.vue @@ -44,13 +44,14 @@ export default { name: "Footer", data() { return { - first: [{ - name: 'Home', - path: '/home/list', - meta: { - parent: 'Home', + first: [ + { + name: 'Home', + path: '/home/list', + meta: { + parent: 'Home', + }, }, - }, { name: 'AI Daily News', path: '/dailyNews', @@ -59,15 +60,10 @@ export default { }, }, { - name: 'AI Hub', + name: 'AI Launches', + path: '/launches', meta: { - parent: 'Hub', - } - }, - { - name: 'Learn', - meta: { - parent: 'Learn', + parent: 'Launches', } }, { @@ -99,11 +95,6 @@ export default { goto(path) { this.$router.push(path); }, - /** - * 判断当前导航项是否应该被选中 - * @param {Object} item 导航项 - * @returns {Boolean} 是否选中 - */ isParentMatch(item) { // 首先检查路径匹配逻辑,保持向后兼容性 const pathMatch = item.path && item.path === this.$route.path; @@ -159,7 +150,7 @@ export default { font-size: $larg-font-size; color: $main-color; font-weight: bold; - font-family: 'Poppins-Bold', serif; + font-family: 'Poppins-Bold'; } } @@ -172,14 +163,14 @@ export default { .bottom-span { color: $grey-color; - font-family: 'Poppins-Regular', serif; + font-family: 'Poppins-Regular'; } .navigation-bottom { margin-bottom: 14px; span { display: inline-block; - font-family: 'Poppins-Medium', serif; + font-family: 'Poppins-Medium'; cursor: pointer; margin-left: 30px; &:hover { diff --git a/components/GlobalLoading.vue b/components/GlobalLoading.vue index 5c46e11..4cedf37 100644 --- a/components/GlobalLoading.vue +++ b/components/GlobalLoading.vue @@ -61,7 +61,7 @@ export default { .loading-text { margin-top: 15px; - font-family: 'Poppins-Medium', serif; + font-family: 'Poppins-Medium'; color: #7B61FF; } diff --git a/components/Header.vue b/components/Header.vue index 582e03b..6181e49 100644 --- a/components/Header.vue +++ b/components/Header.vue @@ -9,16 +9,19 @@
@@ -122,11 +125,13 @@ export default { diff --git a/components/HorizontalDateList.vue b/components/HorizontalDateList.vue index 09e78ec..c6f49e2 100644 --- a/components/HorizontalDateList.vue +++ b/components/HorizontalDateList.vue @@ -147,12 +147,11 @@ export default { width: 100%; .nav-button { - width: 44px; - height: 44px; + width: 36px; + height: 36px; cursor: pointer; - background-color: #FFFFFF; + background: transparent !important; border-radius: 4px; - box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); flex-shrink: 0; display: flex; align-items: center; @@ -163,8 +162,8 @@ export default { } img { - width: 44px; - height: 44px; + width: 36px; + height: 36px; } &.disabled { diff --git a/components/MyTabs/MyTabs.vue b/components/MyTabs/MyTabs.vue index 73610c4..02c7425 100644 --- a/components/MyTabs/MyTabs.vue +++ b/components/MyTabs/MyTabs.vue @@ -151,7 +151,7 @@ export default { .my-tabs__item.is-disabled { color: #1e293b; cursor: not-allowed; - font-family: 'Poppins-Regular', serif; + font-family: 'Poppins-Regular'; } .my-tabs__close { margin-left: 6px; color: #999; } .my-tabs__close:hover { color: #f56c6c; } diff --git a/components/Pagination.vue b/components/Pagination.vue index e93b2e3..085d09d 100644 --- a/components/Pagination.vue +++ b/components/Pagination.vue @@ -84,6 +84,7 @@ background-color: $white; color: $main-font-color; cursor: pointer; + font-weight: 'Poppins-Regular'; } .pagination-number { diff --git a/components/Rate.vue b/components/Rate.vue index 2e03a67..093c6c7 100644 --- a/components/Rate.vue +++ b/components/Rate.vue @@ -34,7 +34,7 @@ export default { :size="24" :disabled="readonly"> -
{{ value }}
+
{{ (value).toFixed(1) }}
@@ -46,7 +46,7 @@ export default { } } .rate-num { - width: 28px; + width: 36px; height: 28px; line-height: 28px; text-align: center; @@ -54,7 +54,7 @@ export default { color: #fff; border-radius: 12px; margin-left: 8px; - font-family: 'Poppins-Regular', serif; + font-family: 'Poppins-Regular'; } .gradient-box { background: $header-backgroungd; diff --git a/components/SearchSelectInput.vue b/components/SearchSelectInput.vue index 9b88ab1..6756e5c 100644 --- a/components/SearchSelectInput.vue +++ b/components/SearchSelectInput.vue @@ -1,5 +1,5 @@ @@ -52,11 +53,32 @@ export default { return this.searchResults && this.searchResults.length > 0; } }, + mounted() { + // 添加点击事件监听 + document.addEventListener('click', this.handleDocumentClick); + }, + beforeDestroy() { + // 移除事件监听,避免内存泄漏 + document.removeEventListener('click', this.handleDocumentClick); + }, methods: { + handleDocumentClick(event) { + // 判断点击是否在搜索容器内部 + const searchContainer = this.$refs.searchContainer; + if (searchContainer && !searchContainer.contains(event.target)) { + // 点击在搜索容器外部,清空搜索状态 + this.clearSearchState(); + } + }, + + clearSearchState() { + this.searched = false; + this.searchResults = []; + }, + async handleSearch(value) { if (!value) { - this.searched = false; - this.searchResults = []; + this.clearSearchState(); return; } @@ -73,8 +95,7 @@ export default { }, selectItem(item) { - this.searched = false; - this.searchResults = []; + this.clearSearchState(); this.jumpToToolDetail(item); }, @@ -112,6 +133,7 @@ export default { } .results-list { + position: absolute; padding: 30px 20px; margin-top: 10px; border-radius: 12px; @@ -119,6 +141,8 @@ export default { overflow-y: auto; background: white; box-shadow: 0 10px 30px #0000000d; + width: 100%; + z-index: 999; .result-item { padding: 20px 30px; @@ -147,14 +171,16 @@ export default { .no-results { gap: 30px; - padding: 10px 16px; - text-align: center; - border-radius: 8px; - margin: 16px auto 0; color: #1E293B; - font-family: 'Poppins-SemiBold', serif; - @include gradient-border($linear-gradient-start, $linear-gradient-end); - width: fit-content; // 改为自适应内容宽度 + font-family: 'Poppins-SemiBold'; + width: 100%; + cursor: pointer; + padding: 20px 30px; + + &:hover { + color: #7C62FF; + background: #F5F6F9; + } img { width: 24px; diff --git a/layouts/default.vue b/layouts/default.vue index 9414044..d4be3a6 100644 --- a/layouts/default.vue +++ b/layouts/default.vue @@ -3,7 +3,10 @@
- + + + +
@@ -59,7 +62,6 @@ export default { #home-container { width: 100%; - // min-height: 100vh; background-color: $background-color; } diff --git a/nuxt.config.js b/nuxt.config.js index 7d2f7f2..6f1cd93 100644 --- a/nuxt.config.js +++ b/nuxt.config.js @@ -57,9 +57,9 @@ export default { 'normalize.css/normalize.css', // 引入 '@/styles/index.scss', //引入全局样式 '@/styles/text.scss', - '@/styles/font.scss', '@/styles/flex.scss', '@/styles/article.scss', + '@/styles/font.scss', ], // Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins @@ -100,6 +100,24 @@ export default { // Build Configuration: https://go.nuxtjs.dev/config-build build: { + postcss: { + plugins: { + 'postcss-px-to-viewport': { + unitToConvert: 'px', // 需要转换的单位 + viewportWidth: 1920, // 设计稿基准宽度(1470px) + unitPrecision: 5, // 转换后的小数位数 + propList: ['*'], // 转换所有属性 + viewportUnit: 'vw', // 转换后的单位 + fontViewportUnit: 'vw', // 字体单位也使用 vw + selectorBlackList: [], // 不转换的选择器 + minPixelValue: 1, // 小于等于 1px 不转换 + mediaQuery: false, // 不转换媒体查询中的 px + replace: true, // 直接替换原属性 + exclude: [/node_modules/], // 忽略 node_modules + landscape: false // 不生成横屏适配 + } + } + } }, axios: { diff --git a/package.json b/package.json index 44fdac4..f51818c 100644 --- a/package.json +++ b/package.json @@ -18,9 +18,11 @@ "axios": "^1.12.2", "cookie-universal-nuxt": "^2.2.2", "core-js": "^3.25.3", + "dayjs": "^1.11.19", "element-ui": "^2.15.14", "normalize.css": "^8.0.1", "nuxt": "^2.15.8", + "postcss-px-to-viewport": "^1.1.1", "vue": "^2.7.10", "vue-server-renderer": "^2.7.10", "vue-template-compiler": "^2.7.10" diff --git a/pages/AIHub/AITools.vue b/pages/AIHub/AITools.vue index 8c141ca..3f385b9 100644 --- a/pages/AIHub/AITools.vue +++ b/pages/AIHub/AITools.vue @@ -79,14 +79,14 @@ display: flex; justify-content: flex-end; .input-container { - margin-top: 100px; - margin-bottom: 60px; + margin-top: 30px; + margin-bottom: 30px; } } .list { display: flex; flex-direction: column; gap: 30px; - margin-bottom: 60px; + margin-bottom: 40px; } diff --git a/pages/AIHub/AIToolsDetail.vue b/pages/AIHub/AIToolsDetail.vue index 3f052b8..75d1895 100644 --- a/pages/AIHub/AIToolsDetail.vue +++ b/pages/AIHub/AIToolsDetail.vue @@ -2,19 +2,24 @@
+
+ {{ type ? titleKey[type] : '' }} + + {{newsDetail.title || ''}} +
{{ newsDetail.title || '' }}
{{ newsDetail.summary || '' }}
-
-
+
+
-
- -
+
+ +
{{ formatDate(newsDetail.publishTime) }}
@@ -23,7 +28,7 @@
- +
@@ -34,21 +39,21 @@
- +
-
+
-
+
- + Latest Article
@@ -60,9 +65,9 @@
-
+
Related news
-
+
@@ -99,6 +104,14 @@ export default { type: '', commentCount: 0, fullscreenLoading: false, + titleKey: { + tool: 'AI Tools', + framework: 'Frameworks', + news: 'AI Days News', + observer: 'AI Observer', + analysis: 'In-depth Analysis', + pioneer: 'Pioneer In The Field', + }, } }, methods: { @@ -173,7 +186,7 @@ export default { if (this.news_slug && this.type) { await this.$store.dispatch('getBannerConfig'); await this.getNewsDetail(this.news_slug); - await this.getArticleListData(1, 4, this.type); + await this.getArticleListData(1, 6, this.type); await this.getLatestArticleListData(); } this.fullscreenLoading = false; @@ -211,34 +224,73 @@ export default { diff --git a/pages/AIHub/components/ListCardItem.vue b/pages/AIHub/components/ListCardItem.vue index 046bb66..a23b5e0 100644 --- a/pages/AIHub/components/ListCardItem.vue +++ b/pages/AIHub/components/ListCardItem.vue @@ -14,20 +14,20 @@
-
+
{{ item.slug || ''}}
- + {{ item.likeCount || 0 }}
- {{ item.publishTime || '' }} + {{ formatPublishTime(item.publishTime || '') }}
@@ -63,12 +63,26 @@ export default { if (id) { await this.$api.article.recordArticleClick(id); } - } + }, + formatPublishTime(timeString) { + if (!timeString) return ''; + + const date = new Date(timeString); + + const month = String(date.getMonth() + 1).padStart(2, '0'); + const day = String(date.getDate()).padStart(2, '0'); + const year = date.getFullYear(); + + return `${year}-${month}-${day}`; + }, }, } diff --git a/pages/About/About.vue b/pages/About/About.vue index 39de82f..982f6a9 100644 --- a/pages/About/About.vue +++ b/pages/About/About.vue @@ -2,17 +2,17 @@
- About AIToolsFinder + About AIProdLaunches
The Ultimate Global AI Tools Directory, Discover the Best New AI Products
- Welcome to AIToolsFinder – your all-in-one gateway to the world of artificial intelligence. + Welcome to AIProdLaunches – your all-in-one gateway to the world of artificial intelligence.
- We’re more than just a directory. AIToolsFinder is designed to help you discover, learn, and apply AI in ways that truly make a difference in your personal and professional life. Whether you’re a student exploring new technologies, a designer looking for creative tools, a developer in need of coding assistance, or a business team seeking automation solutions—AIToolsFinder is here to guide you. + We’re more than just a directory. AIProdLaunches is designed to help you discover, learn, and apply AI in ways that truly make a difference in your personal and professional life. Whether you’re a student exploring new technologies, a designer looking for creative tools, a developer in need of coding assistance, or a business team seeking automation solutions—AIProdLaunches is here to guide you.
Here’s what you’ll find with us: @@ -49,7 +49,7 @@
Disclaimer – - AIToolsFinder is the official and only website under this name. We do not operate paid groups, courses, or third-party affiliates. Please always verify you’re on the official site. + AIProdLaunches is the official and only website under this name. We do not operate paid groups, courses, or third-party affiliates. Please always verify you’re on the official site.
@@ -57,7 +57,7 @@
Get in Touch – - Got a new AI tool to share, want to collaborate, or have ideas for improving AIToolsFinder? Reach us anytime at + Got a new AI tool to share, want to collaborate, or have ideas for improving AIProdLaunches? Reach us anytime at corina@inziqi.com.
@@ -89,25 +89,25 @@ color: #3a4a65; font-size: 20px; font-weight: 600; - font-family: 'Poppins-SemiBold', serif; + font-family: 'Poppins-SemiBold'; margin-top: 30px; text-align: center; } .content { color: #64748B; font-size: 18px; - font-family: 'Poppins-Medium', serif; + font-family: 'Poppins-Medium'; } .terms-title { color: #64748B; font-size: 18px; - font-family: 'Poppins-Bold', serif; + font-family: 'Poppins-Bold'; margin-top: 30px; margin-bottom: 20px; font-weight: bold; } .little-title { - font-family: 'Poppins-Medium', serif; + font-family: 'Poppins-Medium'; font-size: 18px; color: #64748B; margin-top: 20px; @@ -133,18 +133,18 @@ .item-title { color: #64748B; font-size: 18px; - font-family: 'Poppins-Bold', serif; + font-family: 'Poppins-Bold'; font-weight: bold; } .item-text { color: #64748B; font-size: 18px; - font-family: 'Poppins-Medium', serif; + font-family: 'Poppins-Medium'; } .item-link { color: #7B61FF; font-size: 18px; - font-family: 'Poppins-Medium', serif; + font-family: 'Poppins-Medium'; } } .bottom-line { @@ -156,7 +156,7 @@ .bottom-text { font-weight: 600; font-size: 28px; - font-family: 'Poppins-SemiBold', serif; + font-family: 'Poppins-SemiBold'; @include text-gradient(90deg, #2563eb, 22%, #7B61FF, 73%); } .bottom-line-left { diff --git a/pages/About/Privacy.vue b/pages/About/Privacy.vue index cf081fd..02b009f 100644 --- a/pages/About/Privacy.vue +++ b/pages/About/Privacy.vue @@ -5,62 +5,83 @@ Privacy Policy
- Last updated April 4, 2024 + Effective Date: October 27, 2025
-
This privacy notice for Futurepedia LLC (doing business as Futurepedia) ("we," "us," or "our") describes how and why we might collect, store, use, and/or share ("process") your information when you use our services ("Services"), such as when you:
-
- Visit our website at http://www.futurepedia.io/ or any website of ours that links to this privacy notice +
+ 1. Introduction
-
Engage with us in other related ways, including any sales, marketing, or events
-
Questions or concerns?
-
Reading this privacy notice will help you understand your privacy rights and choices. If you do not agree with our policies and practices, please do not use our Services. If you still have questions or concerns, please contact us at
- -
SUMMARY OF KEY POINTS
-
This summary provides key points from our privacy notice, but you can find out more details about any of these topics by clicking the link following each key point or by using our table of contents below to find the section you are looking for.
-
What personal information do we process?
-
When you visit, use, or navigate our Services, we may process personal information depending on how you interact with us and the Services, the choices you make, and the products and features you use.
-
Do we process any sensitive personal information? 
-
We do not process sensitive personal information.
-
Do we receive any information from third parties?
-
We do not receive any information from third parties.
-
How do we process your information?
-
We process your information to provide, improve, and administer our Services, communicate with you, for security and fraud prevention, and to comply with law. We may also process your information for other purposes with your consent. about how we process your information.We process your information to provide, improve, and administer our Services, communicate with you, for security and fraud prevention, and to comply with law. We may also process your information for other purposes with your consent. about how we process your information.
-
TABLE OF CONTENTS
-
1. WHAT INFORMATION DO WE COLLECT?
-
2. HOW DO WE PROCESS YOUR INFORMATION?
-
1. WHAT INFORMATION DO WE COLLECT?
-
Personal information you disclose to us
-
In Short:
-
We collect personal information that you provide to us. - We collect personal information that you voluntarily provide us when you register on the Services, express an interest in obtaining information about us or our products and Services when participating in activities on the Services, or otherwise when you contact us. +
+ Welcome to AIProdLaunch (“we”, “our”, “us”). We provide a collection of AI tools and resources. Your privacy is important to us. This policy explains how we handle information when you use our website. By visiting or using AIProdLaunch, you agree to this Privacy Policy. +
-
Personal Information Provided by You.
-
- The personal information we collect depends on the context of your interactions with us and the Services, your choices, and the products and features you use. The personal information we collect may include the following: +
2. Information We Collect
+
+ We do not require accounts and do not collect personal information. We may collect anonymous data to improve our website, such as:
-
- names +
+ Browser type and version
-
- email addresses +
+ Pages you visit and time spent
-
- job titles +
+ Referring websites
-
Sensitive Information.
-
We do not process sensitive information.
-
Social Media Login Data. We may provide you with the option to register with us using your existing social media account details, like your Facebook, Twitter, or other social media accounts. If you choose to register in this way, we will collect the information described in the section called "HOW DO WE HANDLE YOUR SOCIAL LOGINS?" below.
-
2. HOW DO WE PROCESS YOUR INFORMATION?
-
In Short:
-
- We process your information to provide, improve, and administer our Services, communicate with you, for security and fraud prevention, and to comply with law. We may also process your information for other purposes with your consent. +
+ Aggregated IP addresses +
+
+ This information is used only for analytics and site improvement. +
+
3. Cookies and Analytics
+
+ We may use cookies or similar technologies to track anonymous usage data, such as with Google Analytics. Cookies help us understand traffic, improve features, and optimize content. +
+
+ You can disable cookies in your browser, but some features may not work properly. +
+
4. Advertising and Affiliate Links
+
+ We may show third-party ads or include affiliate links. Advertisers may use cookies or tracking tools. +
+
+ We do not control how third parties use data. Please check their privacy policies if you click their links or ads. +
+
5. Third-Party Links and Content
+
+ Our site may link to external websites, including AI tool providers or platforms like ProductHunt. We are not responsible for their privacy practices or content. +
+
6. Data Storage and Security
+
+ Our servers are located overseas. We implement standard security measures to protect the anonymous data we collect. Since we do not store personal information, your privacy is well protected. +
+
7. Your Rights and Choices
+
+ You can: +
+
+ Disable cookies via your browser +
+
+ Opt-out of personalized ads through your browser or ad network settings +
+
+ Contact us with questions about this Privacy Policy +
+
8. Updates to This Policy
+
+ We may update this policy from time to time. Updated versions will appear on this page with the revision date. Your continued use of AIProdLaunch means you accept the updated policy. +
+
9. Contact Us
+
+ If you have questions, please reach out to: +
+
+ Email: corina@inziqi.com
-
We process your personal information for a variety of reasons, depending on how you interact with our Services, including:
-
To facilitate account creation and authentication and otherwise manage user accounts. We may process your information so you can create and log in to your account, as well as keep your account in working order.
-
To save or protect an individual's vital interest. We may process your information when necessary to save or protect an individual’s vital interest, such as to prevent harm.
@@ -79,11 +100,17 @@ diff --git a/pages/DailyNews/components/ArticleTextListItem.vue b/pages/DailyNews/components/ArticleTextListItem.vue index c8a8057..8b53454 100644 --- a/pages/DailyNews/components/ArticleTextListItem.vue +++ b/pages/DailyNews/components/ArticleTextListItem.vue @@ -73,19 +73,19 @@ export default { .title { font-size: 18px; - font-family: 'Poppins-SemiBold', serif; + font-family: 'Poppins-SemiBold'; font-weight: 600; color: #3A4A65; } .content { - font-family: 'Poppins-Regular', serif; + font-family: 'Poppins-Regular'; color: #64748B; margin-top: 20px; } .source { - font-family: 'Poppins-Regular', serif; + font-family: 'Poppins-Regular'; color: #C8CFD7; margin-top: 10px; font-size: 14px; diff --git a/pages/DailyNews/components/NewsCardItem.vue b/pages/DailyNews/components/NewsCardItem.vue index 497dee0..8c54890 100644 --- a/pages/DailyNews/components/NewsCardItem.vue +++ b/pages/DailyNews/components/NewsCardItem.vue @@ -3,19 +3,19 @@
-
-
{{ item.title || '' }}
-
+
+
{{ item.title || '' }}
+
{{ item.summary || '' }}
-
+
-
{{ item.slug || '' }}
+
{{ item.author || '' }}
-
- +
+
{{ item.likeCount || 0 }}
@@ -44,6 +44,18 @@ export default { diff --git a/pages/Home/components/ToolItemCard.vue b/pages/Home/components/ToolItemCard.vue index cb968b4..50f5458 100644 --- a/pages/Home/components/ToolItemCard.vue +++ b/pages/Home/components/ToolItemCard.vue @@ -15,9 +15,9 @@ export default { }, methods: { goToToolDetail() { - if (this.config.slug && this.categorySlug) { + if (this.config.slug && this.config.categoryName && this.categorySlug) { this.recordToolClick(this.config); - this.$router.push(`/detail?tool_slug=${this.config.slug}&category_slug=${this.categorySlug}`); + this.$router.push(`/detail?tool_slug=${this.config.slug}&category_slug=${this.categorySlug}&category_name=${this.config.categoryName}`); } }, // 记录点击次数 @@ -109,7 +109,7 @@ export default { color: $main-font-color; font-size: $big-font-size; font-weight: 600; - font-family: 'Poppins-SemiBold', serif; + font-family: 'Poppins-SemiBold'; flex: 1; overflow: hidden; text-overflow: ellipsis; @@ -119,7 +119,7 @@ export default { .text { color: $grey-color; - font-family: 'Poppins-Regular', serif; + font-family: 'Poppins-Regular'; margin-top: 4px; overflow: hidden; text-overflow: ellipsis; diff --git a/pages/Home/components/ToolList.vue b/pages/Home/components/ToolList.vue index b6213aa..799e2b9 100644 --- a/pages/Home/components/ToolList.vue +++ b/pages/Home/components/ToolList.vue @@ -1,83 +1,47 @@ diff --git a/pages/Home/components/Toolbar.vue b/pages/Home/components/Toolbar.vue index 21f5632..4378e92 100644 --- a/pages/Home/components/Toolbar.vue +++ b/pages/Home/components/Toolbar.vue @@ -3,7 +3,7 @@
- + {{tool.categoryName}} @@ -15,14 +15,24 @@
-
- {{ item }} +
+ {{ item.categoryName }}
+
+
+ View more +
+
+
+ +
+
+
-
+
View more
@@ -57,23 +67,49 @@ type: String, default: '', }, - category_icon: { - type: String, - default: '', - } }, data() { return { + activeCategorySlug: '', + activeCategoryName: '', + activeSubCategories: [], } }, methods: { // 查看更多 goToViewMore() { - if (this.categorySlug) { - this.$router.push('/home/more?category_slug=' + this.categorySlug) + if (this.categorySlug && this.tool.categoryName) { + this.$router.push('/home/more?category_slug=' + this.categorySlug + '&tag_name=' + this.tool.categoryName); } + }, + handleTagClick(item) { + this.activeCategorySlug = item.categorySlug; + // 设置二级分类列表 + this.activeSubCategories = item.tools || []; + this.activeCategoryName = item.categoryName; + }, + tagGoToViewMore() { + if (this.activeCategorySlug && this.activeCategoryName) { + this.$router.push('/home/more?category_slug=' + this.activeCategorySlug + '&tag_name=' + this.activeCategoryName); + } + }, + }, + watch: { + tool: { + handler(newTool) { + // 检查 tool 中 tagList 是否存在且为数组长度不为0 + if (newTool && + newTool.tagList && + Array.isArray(newTool.tagList) && + newTool.tagList.length > 0) { + this.activeCategorySlug = newTool.tagList[0].categorySlug || ''; + this.activeCategoryName = newTool.tagList[0].categoryName || ''; + this.activeSubCategories = newTool.tagList[0].tools || []; + } + }, + immediate: true // 立即执行,确保组件初始化时也会执行 } - } + }, } @@ -100,7 +136,7 @@ .title-text { font-weight: 600; font-size: $larg-font-size; - font-family: 'Poppins-SemiBold', serif; + font-family: 'Poppins-SemiBold'; } } @@ -120,10 +156,16 @@ padding: 10px; @include gradient-border($linear-gradient-start, $linear-gradient-end); /* 显示抓取手势 */ - font-family: 'Poppins-SemiBold', sans-serif; + font-family: 'Poppins-SemiBold'; color: #64748B; font-weight: 600; + cursor: pointer; + &.active { + color: #fff; + background: $header-backgroungd; + border: none; + } } .more { @@ -131,7 +173,7 @@ text-align: right; color: $grey-color; font-size: $mid-font-size; - font-family: 'Poppins-Regular', serif; + font-family: 'Poppins-Regular'; &:active { opacity: 0.8; diff --git a/pages/Home/index.vue b/pages/Home/index.vue index 83e020f..e9443ea 100644 --- a/pages/Home/index.vue +++ b/pages/Home/index.vue @@ -11,19 +11,21 @@
It includes over a thousand global AI tools, covering writing, images, videos, audio, programming, - music, design, chatting, etc., and recommends learning platforms, frameworks and models + music, design, chatting, etc, and recommends learning platforms, frameworks and models
-
+
- + - +
+ +
@@ -60,13 +62,31 @@ export default { }, methods: { }, + watch: { + '$route'() { + // 当路由变化时滚动到顶部 + window.scrollTo(0, 0); + } + }, mounted() { this.$store.dispatch('getBannerConfig'); } } - diff --git a/pages/Launches/Detail/ProjectItem.vue b/pages/Launches/Detail/ProjectItem.vue index 427e921..bcc22b6 100644 --- a/pages/Launches/Detail/ProjectItem.vue +++ b/pages/Launches/Detail/ProjectItem.vue @@ -1,9 +1,9 @@ @@ -19,12 +19,30 @@ export default { }, data() { return { + isHovered: false } }, - methods: {} + methods: { + // 跳转链接 + gotoLink(url) { + if (!url) { + return false; + } + window.open(url, '_blank'); + }, + + // 获取图标路径 + getImageSrc() { + if (this.isHovered && this.item.key) { + return `/launches/link/icon_${this.item.key}_selected.png`; + } + return this.item.key ? `/launches/link/icon_${this.item.key}.png` : ''; + } + } } + diff --git a/pages/Launches/Detail/index.vue b/pages/Launches/Detail/index.vue index 4d1407f..8f8956a 100644 --- a/pages/Launches/Detail/index.vue +++ b/pages/Launches/Detail/index.vue @@ -2,86 +2,83 @@
-
{{ news_detail.title || '' }}
-
- -
+
+ AI Launches + + {{newsDetail.title || ''}} +
+
{{ newsDetail.title || '' }}
+
+
+
+
+ + Score: +
{{ (newsDetail.rating || 0).toFixed(1) }}
+
+
+
+
+ + Introduction: +
+
+ {{ newsDetail.summary || '' }} +
+
+
+
+ + Data update: +
+
{{ formatPublishTime(newsDetail.publishTime || '') }}
+
+
+
{{ it }}
+
+
+
+
-
-
- - Introduction: -
-
- {{ news_detail.summary || '' }} -
-
-
-
- - Data update: -
-
{{ news_detail.publishTime || '' }}
-
-
-
- - Like: -
-
{{ news_detail.likeCount || 0 }}
-
-
-
{{ it }}
-
- - - - - - - - - -
-
+
-
+
Company Information
- - - - - -
-
A total of 8 projects were released
- +
+
+ + + +
-
-
+
+
Special Financing
- - - -
-
+
+
+ +
+
+
+
View more
@@ -97,29 +94,14 @@
-
- - - +
+
+ +
- +
@@ -131,25 +113,59 @@ import Comment from "@/pages/ToolDetail/Comment/index.vue"; import RelatedTool from "@/pages/Launches/Detail/RelatedTool.vue"; import ProjectItem from "@/pages/Launches/Detail/ProjectItem.vue"; import FinanceItem from "@/pages/Launches/Detail/FinanceItem.vue"; +import ThumbBtn from "@/pages/ToolDetail/components/ThumbBtn.vue"; export default { - components: {FinanceItem, ProjectItem, RelatedTool, CommentBtn, Comment}, + components: {ThumbBtn, FinanceItem, ProjectItem, RelatedTool, CommentBtn, Comment}, data() { return { - news_detail: {}, + newsDetail: {}, commentCount: 0, news_slug: '', + otherList: [], } }, methods: { + // 刷新工具详情数据 + refreshToolDetail() { + if (this.news_slug) { + this.getNewsDetail(this.news_slug); + } + }, // 获取新闻详情 async getNewsDetail(newsSlug) { const {data: res} = await this.$api.article.getArticleDetail(newsSlug); const {code, data} = res; if (code === 0 && data) { - this.news_detail = {...data}; + this.newsDetail = {...data, extra: this.stringJsonToObject(data.extra || '[]')}; + // 处理socialLinks + if (this.newsDetail.extra && Array.isArray(this.newsDetail.extra.socialLinks)) { + const socialLinks = this.newsDetail.extra.socialLinks; + // 查找Website选项的索引 + const websiteIndex = socialLinks.findIndex(item => item && item.key === 'Website'); + // 如果找到Website选项且不在第一个位置,则移到第一个位置 + if (websiteIndex !== -1 && websiteIndex !== 0) { + const websiteItem = socialLinks.splice(websiteIndex, 1)[0]; + socialLinks.unshift(websiteItem); + } + } } }, + formatPublishTime(timeString) { + if (!timeString) return ''; + + const date = new Date(timeString); + const months = [ + 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' + ]; + + const month = months[date.getMonth()]; + const day = String(date.getDate()).padStart(2, '0'); + const year = date.getFullYear(); + + return `${month} ${day} ${year}`; + }, stringJsonToObject(str) { // 将json字符串转为对象,捕获错误,当str为空或者转对象失败时默认返回空数组 try { @@ -161,63 +177,116 @@ export default { }, goToViewMore() { // 返回上一页 - this.$router.go(-1); + this.$router.push('/launches'); }, handleCommentCountUpdate(count) { this.commentCount = count; }, + goToFinanceDetail() { + if (!this.news_slug) { + return false; + } + this.$router.push('/finance-detail?news_slug=' + this.news_slug) + }, + async getArticleListData() { + const params = {page: 1, limit: 4, articleType: 'launches'}; + const {data: res} = await this.$api.article.getArticleList(params); + const {code, data} = res; + if (code === 0 && data.list && Array.isArray(data.list)) { + let processedList = [...data.list]; + // 判断列表中是否有与当前详情id一致的项 + if (this.newsDetail && this.newsDetail.id) { + const currentIdIndex = processedList.findIndex(item => item && item.id === this.newsDetail.id); + + if (currentIdIndex !== -1) { + // 有一致的id,删除该项 + processedList.splice(currentIdIndex, 1); + } else if (processedList.length > 0) { + // 没有一致的id,删除最后一个项 + processedList = processedList.slice(0, -1); + } + } + this.otherList = processedList; + } + }, + async onLoad() { + this.news_slug = this.$route.query.news_slug; + if (this.news_slug) { + await this.getNewsDetail(this.news_slug); + await this.getArticleListData(); + } + } }, watch: { '$route'(to, from) { // 当路由参数发生变化时重新加载数据 if (to.query.news_slug !== from.query.news_slug) { - this.news_slug = to.query.news_slug; - if (this.news_slug) { - this.getNewsDetail(this.news_slug); - } + this.onLoad(); } } }, mounted() { - this.news_slug = this.$route.query.news_slug; - if (this.news_slug) { - this.getNewsDetail(this.news_slug); - } + this.onLoad(); }, computed: { tagList() { - if (!this.news_detail.tags) { + if (!this.newsDetail.tags) { return []; } - return this.stringJsonToObject(this.news_detail.tags || '[]'); + return this.stringJsonToObject(this.newsDetail.tags || '[]'); } }, } diff --git a/pages/Launches/components/SwitchMonth.vue b/pages/Launches/components/SwitchMonth.vue index 30a3a4d..5bbe74b 100644 --- a/pages/Launches/components/SwitchMonth.vue +++ b/pages/Launches/components/SwitchMonth.vue @@ -3,7 +3,7 @@
Previous Year
-
{{ monthName }}
+
{{ monthName }}
@@ -16,6 +16,20 @@ import IconNext from '@/static/launches/icon_next.png'; import IconNextDisabled from '@/static/launches/icon_next_disabled.png'; import IconPrevDisabled from '@/static/launches/icon_prev_disabled.png'; +// 从 sessionStorage 获取缓存数据的辅助函数 +function getCachedMonth() { + try { + const cachedData = sessionStorage.getItem('launches_search_cache'); + if (cachedData) { + const parsedData = JSON.parse(cachedData); + return parsedData.currentMonth || (new Date().getMonth() + 1); + } + } catch (e) { + console.error('获取缓存的月份失败', e); + } + return new Date().getMonth() + 1; +} + export default { data() { return { @@ -24,7 +38,7 @@ export default { props: { value: { type: Number, - default: () => new Date().getMonth() + 1 + default: getCachedMonth } }, methods: { @@ -60,15 +74,13 @@ export default { diff --git a/pages/Launches/components/SwitchSort.vue b/pages/Launches/components/SwitchSort.vue index b50011a..9f82c5d 100644 --- a/pages/Launches/components/SwitchSort.vue +++ b/pages/Launches/components/SwitchSort.vue @@ -1,9 +1,23 @@ diff --git a/pages/Learn/Observer.vue b/pages/Learn/Observer.vue index fd82683..e47e787 100644 --- a/pages/Learn/Observer.vue +++ b/pages/Learn/Observer.vue @@ -88,8 +88,8 @@ export default { display: flex; justify-content: flex-end; .input-container { - margin-top: 100px; - margin-bottom: 60px; + margin-top: 60px; + margin-bottom: 40px; } } @@ -97,7 +97,7 @@ export default { display: flex; flex-direction: column; gap: 30px; - margin-bottom: 60px; + margin-bottom: 40px; } } diff --git a/pages/Learn/Pioneer.vue b/pages/Learn/Pioneer.vue index 285ac0d..6d9391b 100644 --- a/pages/Learn/Pioneer.vue +++ b/pages/Learn/Pioneer.vue @@ -88,8 +88,8 @@ export default { display: flex; justify-content: flex-end; .input-container { - margin-top: 100px; - margin-bottom: 60px; + margin-top: 60px; + margin-bottom: 40px; } } @@ -97,7 +97,7 @@ export default { display: flex; flex-direction: column; gap: 30px; - margin-bottom: 60px; + margin-bottom: 40px; } } diff --git a/pages/Learn/index.vue b/pages/Learn/index.vue index a33e1b0..f02df94 100644 --- a/pages/Learn/index.vue +++ b/pages/Learn/index.vue @@ -3,7 +3,7 @@
- AI Hub + Learn {{$route.name}}
@@ -28,13 +28,25 @@ export default { padding-bottom: 100px; .bread-menu { font-size: $mid-font-size; - margin: 100px 0; - font-family: 'Poppins-Medium', serif; + margin: 24px 0 16px; + font-family: 'Poppins-Medium'; .crumbs { - font-family: 'Poppins-SemiBold', serif; + font-family: 'Poppins-SemiBold'; font-weight: 600; } } + + .title { + font-weight: bold; + font-size: $huge-font-size1; + font-family: 'Poppins-Bold'; + } + + .description { + font-size: $big-font-size; + color: $grey-color; + font-family: 'Poppins-Medium'; + } } diff --git a/pages/ToolDetail/Comment/index.vue b/pages/ToolDetail/Comment/index.vue index aa76539..88d6904 100644 --- a/pages/ToolDetail/Comment/index.vue +++ b/pages/ToolDetail/Comment/index.vue @@ -6,17 +6,17 @@
-
+

Would you recommend Skywork?

- Full score: 5 points + Full score: 5 points
-
- -

{{ alarmText }}

+
+ +

{{ alarmText }}

@@ -225,6 +225,15 @@ export default { diff --git a/pages/ToolDetail/Product/index.vue b/pages/ToolDetail/Product/index.vue index 5b238f1..9686275 100644 --- a/pages/ToolDetail/Product/index.vue +++ b/pages/ToolDetail/Product/index.vue @@ -6,9 +6,9 @@
-
+
Special Announcement -
+

Without the explicit written permission of this platform, no unit or individual may copy, reprint, quote, modify, disseminate or use all or part of the content of this website in any way. It is strictly prohibited to establish a mirror image or conduct illegal collection on any unofficially authorized server. For any infringement, this platform will hold the offender legally responsible in accordance with the law.

@@ -17,23 +17,25 @@
- + Similar Tools
- + View more
- +
+ +
- + - +
@@ -68,6 +70,10 @@ export default { type: String, default: "", }, + categoryName: { + type: String, + default: "", + } }, data() { return {} @@ -97,7 +103,7 @@ export default { if (this.categorySlug) { this.$router.push('/home/more?category_slug=' + this.categorySlug) } - } + }, }, mounted() { this.$store.dispatch('getBannerConfig'); @@ -106,13 +112,16 @@ export default { diff --git a/pages/ToolDetail/components/ThumbBtn.vue b/pages/ToolDetail/components/ThumbBtn.vue index f50bcdd..4cd9bd2 100644 --- a/pages/ToolDetail/components/ThumbBtn.vue +++ b/pages/ToolDetail/components/ThumbBtn.vue @@ -26,14 +26,14 @@ export default { getImageSrc() { // 如果已经点赞,显示选中的图片 if (this.isActive) { - return '/ToolDetail/icon_thumb_selected.png'; + return require('/static/ToolDetail/icon_thumb_selected.png'); } // 如果鼠标悬停或点击,显示高亮的图片 if (this.isHovered) { - return '/ToolDetail/icon_thumb_selected.png'; + return require('/static/ToolDetail/icon_thumb_selected.png'); } // 默认显示普通图片 - return '/ToolDetail/icon_thumb.png'; + return require('/static/ToolDetail/icon_thumb.png'); } }, methods: { @@ -107,7 +107,7 @@ export default { box-shadow: 0 4px 6px 0 #0000000d; background: #fff; padding: 5px; - font-family: 'Poppins-Regular', serif; + font-family: 'Poppins-Regular'; font-size: 12px; cursor: pointer; img { diff --git a/pages/ToolDetail/index.vue b/pages/ToolDetail/index.vue index 8254f2e..5ffad78 100644 --- a/pages/ToolDetail/index.vue +++ b/pages/ToolDetail/index.vue @@ -12,22 +12,18 @@

{{ tool_detail.name || '' }}

- -
- -
- - -
-
+
+
+ + Score: +
+
+ {{ (tool_detail.rating || 0).toFixed(1) }} +
+
@@ -42,20 +38,31 @@ Data update:
-
{{ tool_detail.updatedAt || '' }}
+
{{ formatPublishTime(tool_detail.updatedAt || '') }}
-
{{ it }}
+
{{ it.value }}
@@ -67,6 +74,7 @@ :tool-slug="tool_slug || ''" :category-slug="category_slug || ''" :tool_content="tool_detail.description || ''" + :category-name="category_name || ''" /> @@ -100,16 +108,18 @@ export default { data() { return { activeName: 'product', - tool_slug: null, + tool_slug: '', tool_detail: {}, commentCount: 0, other_tools: [], - category_slug: null, + category_slug: '', + category_name: '', } }, mounted() { this.tool_slug = this.$route.query.tool_slug; this.category_slug = this.$route.query.category_slug; + this.category_name = this.$route.query.category_name || ''; this.getAsyncToolDetailData(); this.getAsyncOtherTools(); }, @@ -119,6 +129,7 @@ export default { if (to.query.tool_slug !== from.query.tool_slug) { this.tool_slug = to.query.tool_slug; this.category_slug = to.query.category_slug; + this.category_name = to.query.category_name || ''; this.resetAndReloadData(); } } @@ -128,6 +139,21 @@ export default { async refreshToolDetail() { await this.getAsyncToolDetailData(); }, + formatPublishTime(timeString) { + if (!timeString) return ''; + + const date = new Date(timeString); + const months = [ + 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', + 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec' + ]; + + const month = months[date.getMonth()]; + const day = String(date.getDate()).padStart(2, '0'); + const year = date.getFullYear(); + + return `${month} ${day} ${year}`; + }, // 获取详情数据 async getAsyncToolDetailData() { if (this.tool_slug) { @@ -184,22 +210,34 @@ export default {