后期修改完善,上线版本
This commit is contained in:
@ -1,12 +1,12 @@
|
||||
<template>
|
||||
<div @click="goToFinanceDetail">
|
||||
<div>
|
||||
<div class="finance-item flex">
|
||||
<div class="dot-container">
|
||||
<div class="dot"></div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="title">2025-2-01</div>
|
||||
<div class="content-text">Koah参与$ 500万美元种子轮融资,领投Forerunner ,参与投资South Park Commons 。</div>
|
||||
<div class="title">{{ item.date || '' }}</div>
|
||||
<div class="content-text">{{ item.info || '' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="diver-line"></div>
|
||||
@ -27,13 +27,6 @@ export default {
|
||||
return {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
goToFinanceDetail() {
|
||||
this.$router.push({
|
||||
path: '/finance-detail',
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@ -60,13 +53,18 @@ export default {
|
||||
}
|
||||
.title {
|
||||
color: #aebadee6;
|
||||
font-family: 'Poppins-Medium', serif;
|
||||
font-family: 'Poppins-Medium';
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.content-text {
|
||||
color: #64748B;
|
||||
font-family: 'Poppins-Medium', serif;
|
||||
font-family: 'Poppins-Medium';
|
||||
font-size: 20px;
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: 2;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
<template>
|
||||
<div class="item flex items-center">
|
||||
<div class="item flex items-center" @click="gotoLink(item.value)" @mouseenter="isHovered = true" @mouseleave="isHovered = false">
|
||||
<div class="icon flex items-center justify-center">
|
||||
<img :src="item.iconUrl || ''" alt="" />
|
||||
<img :src="getImageSrc()" alt="" />
|
||||
</div>
|
||||
<div class="text">{{ item.name || '' }}</div>
|
||||
<div class="text">{{ item.key || '' }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -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` : '';
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style scoped lang="scss">
|
||||
.item {
|
||||
border-radius: 12px;
|
||||
@ -33,11 +51,13 @@ export default {
|
||||
margin-bottom: 6px;
|
||||
color: #64748B;
|
||||
font-size: 18px;
|
||||
font-family: 'Poppins-Medium', serif;
|
||||
font-family: 'Poppins-Medium';
|
||||
cursor: pointer;
|
||||
.icon {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
border-radius: 4px;
|
||||
padding: 5px;
|
||||
box-shadow: 0 4px 6px 0 rgba(0, 0, 0, 0.08);
|
||||
img {
|
||||
width: 14px;
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
<template>
|
||||
<div class="item">
|
||||
<div class="item" @click="goToDetail">
|
||||
<div class="flex items-center">
|
||||
<img class="icon" :src="item.iconUrl || ''" alt="" />
|
||||
<img class="icon" :src="item.coverImage || ''" alt="" />
|
||||
<div class="flex-1 flex flex-col justify-between">
|
||||
<div class="title">{{ item.title || '' }}</div>
|
||||
<div class="flex items-center" style="gap: 30px">
|
||||
<div class="flex items-center data" style="gap: 12px">
|
||||
<img alt="" src="/launches/detail/icon_thumb.png" style="width: 24px; height: 24px;" />
|
||||
<div class="flex items-center gap-30">
|
||||
<div class="flex items-center data gap-12">
|
||||
<img alt="" src="/launches/detail/icon_thumb.png" class="wh-24" />
|
||||
<div>{{ item.likeCount || 0 }}</div>
|
||||
</div>
|
||||
<div class="flex items-center data" style="gap: 12px">
|
||||
<img alt="" src="/launches/detail/icon_star.png" style="width: 24px; height: 24px;" />
|
||||
<div class="flex items-center data gap-12">
|
||||
<img alt="" src="/launches/detail/icon_star.png" class="wh-24" />
|
||||
<div>{{ item.rating || 0 }}</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -32,12 +32,30 @@ export default {
|
||||
return {
|
||||
}
|
||||
},
|
||||
methods: {},
|
||||
methods: {
|
||||
goToDetail() {
|
||||
if (this.item && this.item.slug) {
|
||||
this.$router.push(`/launches/detail?news_slug=${this.item.slug}`);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.gap-30 {
|
||||
gap: 30px;
|
||||
}
|
||||
.item {
|
||||
cursor: pointer;
|
||||
transition: all 0.3s ease;
|
||||
max-width: 330px;
|
||||
overflow: hidden;
|
||||
|
||||
&:hover {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.icon {
|
||||
width: 70px;
|
||||
height: 70px;
|
||||
@ -45,19 +63,26 @@ export default {
|
||||
margin-right: 20px;
|
||||
}
|
||||
.title {
|
||||
font-family: 'Poppins-SemiBold', serif;
|
||||
flex: 1;
|
||||
font-family: 'Poppins-SemiBold';
|
||||
font-size: 24px;
|
||||
color: #1E293B;
|
||||
font-weight: 600;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.data {
|
||||
font-family: 'Poppins-Regular', serif;
|
||||
font-family: 'Poppins-Regular';
|
||||
color: #64748B;
|
||||
}
|
||||
.summary {
|
||||
font-family: 'Poppins-Regular', serif;
|
||||
font-family: 'Poppins-Regular';
|
||||
color: #64748B;
|
||||
margin-top: 12px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -2,86 +2,83 @@
|
||||
<div id="normal-container">
|
||||
<IntegratedLayout>
|
||||
<div class="content">
|
||||
<div class="title-text">{{ news_detail.title || '' }}</div>
|
||||
<div class="rate-box">
|
||||
<Rate v-model="news_detail.rating" readonly />
|
||||
<div class="flex" style="gap: 20px">
|
||||
<div class="bread-menu">
|
||||
<span>AI Launches</span>
|
||||
<i class="el-icon-arrow-right"></i>
|
||||
<span class="crumbs gradient-color">{{newsDetail.title || ''}}</span>
|
||||
</div>
|
||||
<div class="title-text">{{ newsDetail.title || '' }}</div>
|
||||
<div class="flex mt-24">
|
||||
<div class="flex-1">
|
||||
<div class="terms-item">
|
||||
<div class="item-title">
|
||||
<img src="/ToolDetail/icon_star.png" alt="">
|
||||
<span>Score: </span>
|
||||
<div class="score color-01">{{ (newsDetail.rating || 0).toFixed(1) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="terms-item">
|
||||
<div class="item-title">
|
||||
<img src="/ToolDetail/icon_note.png" alt="">
|
||||
<span>Introduction: </span>
|
||||
</div>
|
||||
<div class="item-content">
|
||||
{{ newsDetail.summary || '' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="terms-item">
|
||||
<div class="item-title">
|
||||
<img src="/ToolDetail/icon_clock.png" alt="">
|
||||
<span>Data update: </span>
|
||||
</div>
|
||||
<div class="item-content">{{ formatPublishTime(newsDetail.publishTime || '') }}</div>
|
||||
</div>
|
||||
<div class="tags">
|
||||
<div class="tag-item" v-for="(it, index) in tagList" :key="index">{{ it }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-20">
|
||||
<ThumbBtn :like-count="newsDetail.likeCount || 0" :id="newsDetail.id || 0" type="article" @like-success="refreshToolDetail" />
|
||||
<CommentBtn :comment-count="commentCount" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="terms-item">
|
||||
<div class="item-title">
|
||||
<img src="/ToolDetail/icon_note.png" alt="">
|
||||
<span>Introduction: </span>
|
||||
</div>
|
||||
<div class="item-content">
|
||||
{{ news_detail.summary || '' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="terms-item">
|
||||
<div class="item-title">
|
||||
<img src="/ToolDetail/icon_clock.png" alt="">
|
||||
<span>Data update: </span>
|
||||
</div>
|
||||
<div class="item-content">{{ news_detail.publishTime || '' }}</div>
|
||||
</div>
|
||||
<div class="terms-item">
|
||||
<div class="item-title">
|
||||
<img src="/ToolDetail/like_icon.png" alt="">
|
||||
<span>Like: </span>
|
||||
</div>
|
||||
<div class="item-content">{{ news_detail.likeCount || 0 }}</div>
|
||||
</div>
|
||||
<div class="tags">
|
||||
<div class="tag-item" v-for="(it, index) in tagList" :key="index">{{ it }}</div>
|
||||
</div>
|
||||
<div class="diver"></div>
|
||||
<div class="container flex">
|
||||
<div class="left-content flex-1 flex flex-col">
|
||||
<!--<div class="sketch flex justify-between">-->
|
||||
<!-- <div class="flex items-center" style="gap: 8px">-->
|
||||
<!-- <img style="width: 18px; height: 18px" src="/launches/detail/icon_fly.png" alt="" />-->
|
||||
<!-- <div class="text">This is the <span style="color: #7B61FF">6</span> release of Sketch</div>-->
|
||||
<!-- </div>-->
|
||||
<!-- <div class="flex items-center more">-->
|
||||
<!-- <div>View more</div>-->
|
||||
<!-- <img src="/launches/detail/icon_arrow.png" alt="" />-->
|
||||
<!-- </div>-->
|
||||
<!--</div>-->
|
||||
<div class="card flex-1">
|
||||
<div class="article-content">
|
||||
<div v-html="news_detail.content || ''"></div>
|
||||
<div v-html="newsDetail.content || ''"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right-content">
|
||||
<div class="card">
|
||||
<div class="flex items-center" style="margin-top: 20px">
|
||||
<div class="flex items-center mt-20">
|
||||
<img alt="" src="/launches/detail/icon_hourse.png" class="icon" />
|
||||
<div class="content-title">Company Information</div>
|
||||
</div>
|
||||
<div class="diver-line"></div>
|
||||
<ProjectItem :item="{name: 'Sketch.com', iconUrl: '/launches/web/sketch.png'}" />
|
||||
<ProjectItem :item="{name: 'Github.com', iconUrl: '/launches/web/github.png'}" />
|
||||
<ProjectItem :item="{name: 'Facebook.com', iconUrl: '/launches/web/facebook.png'}" />
|
||||
<ProjectItem :item="{name: 'Instagram.com', iconUrl: '/launches/web/instagram.png'}" />
|
||||
<ProjectItem :item="{name: 'Twitter.com', iconUrl: '/launches/web/twitter.png'}" />
|
||||
<div class="more flex items-center justify-between" style="margin-top: 20px">
|
||||
<div>A total of 8 projects were released</div>
|
||||
<img src="/launches/detail/icon_arrow.png" alt="" />
|
||||
<div v-if="newsDetail.extra && Array.isArray(newsDetail.extra.socialLinks)" class="mt-30">
|
||||
<ProjectItem v-for="(item, index) in newsDetail.extra.socialLinks" :key="index" :item="item" />
|
||||
</div>
|
||||
<!--<div class="more flex items-center justify-between mt-20">-->
|
||||
<!-- <div>A total of 8 projects were released</div>-->
|
||||
<!-- <img src="/launches/detail/icon_arrow.png" alt="" />-->
|
||||
<!--</div>-->
|
||||
</div>
|
||||
<div class="card" style="margin-top: 20px">
|
||||
<div class="flex items-center" style="margin-top: 20px">
|
||||
<div class="card mt-20">
|
||||
<div class="flex items-center mt-20">
|
||||
<img alt="" src="/launches/detail/icon_finance.png" class="icon" />
|
||||
<div class="content-title">Special Financing</div>
|
||||
</div>
|
||||
<div class="diver-line"></div>
|
||||
<FinanceItem />
|
||||
<FinanceItem />
|
||||
<FinanceItem />
|
||||
<div class="flex justify-end" style="margin-top: 30px">
|
||||
<div class="more flex items-center justify-between" style="gap: 14px">
|
||||
<div class="scroll">
|
||||
<div v-if="newsDetail.extra && Array.isArray(newsDetail.extra.financing)">
|
||||
<FinanceItem v-for="(item, index) in newsDetail.extra.financing" :key="index" :item="item" :slug="news_slug" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex justify-end mt-30">
|
||||
<div class="more flex items-center justify-between gap-14" @click="goToFinanceDetail">
|
||||
<div>View more</div>
|
||||
<img src="/launches/detail/icon_arrow.png" alt="" />
|
||||
</div>
|
||||
@ -97,29 +94,14 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="card">
|
||||
<div class="flex-between-center list">
|
||||
<RelatedTool :item="{
|
||||
title: 'Figma',
|
||||
summary: 'Easily create highly interactive prototypes',
|
||||
likeCount: 123,
|
||||
rating: 4.5
|
||||
}" />
|
||||
<RelatedTool :item="{
|
||||
title: 'Figma',
|
||||
summary: 'Easily create highly interactive prototypes',
|
||||
likeCount: 123,
|
||||
rating: 4.5
|
||||
}" />
|
||||
<RelatedTool :item="{
|
||||
title: 'Figma',
|
||||
summary: 'Easily create highly interactive prototypes',
|
||||
likeCount: 123,
|
||||
rating: 4.5
|
||||
}" />
|
||||
<div class="list">
|
||||
<div class="item" v-for="(item, index) in otherList" :key="index">
|
||||
<RelatedTool :item="item" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Comment comment-type="article" :id="news_detail.id" @update:commentCount="handleCommentCountUpdate" />
|
||||
<Comment comment-type="article" :id="newsDetail.id" @update:commentCount="handleCommentCountUpdate" />
|
||||
</div>
|
||||
</IntegratedLayout>
|
||||
</div>
|
||||
@ -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 || '[]');
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mt-24 {
|
||||
margin-top: 24px;
|
||||
}
|
||||
.color-01 {
|
||||
color: #7B61FF;
|
||||
}
|
||||
.mt-20 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.mt-30 {
|
||||
margin-top: 30px;
|
||||
}
|
||||
.card {
|
||||
padding: 20px;
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 10px 30px 0 rgba(0, 0, 0, 0.08);
|
||||
}
|
||||
.scroll {
|
||||
max-height: 500px; overflow-y: auto; overflow-x: hidden;
|
||||
}
|
||||
.content {
|
||||
padding-top: 100px;
|
||||
padding-top: 25px;
|
||||
padding-bottom: 100px;
|
||||
|
||||
.bread-menu {
|
||||
font-size: $mid-font-size;
|
||||
font-family: 'Poppins-Medium';
|
||||
margin-bottom: 25px;
|
||||
|
||||
.crumbs {
|
||||
font-family: 'Poppins-SemiBold';
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.diver {
|
||||
margin-top: 20px;
|
||||
margin-top: 30px;
|
||||
border-top: 4px solid #E2E8F0;
|
||||
margin-bottom: 20px;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
|
||||
.title-text {
|
||||
font-size: 34px;
|
||||
color: #1E293B;
|
||||
font-family: 'Poppins-SemiBold', serif;
|
||||
font-family: 'Poppins-SemiBold';
|
||||
font-weight: 600;
|
||||
margin-top: 80px;
|
||||
}
|
||||
|
||||
.rate-box {
|
||||
@ -244,7 +313,7 @@ export default {
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: #1E293B;
|
||||
font-family: 'Poppins-Medium', serif;
|
||||
font-family: 'Poppins-Medium';
|
||||
|
||||
img {
|
||||
width: 24px;
|
||||
@ -253,7 +322,7 @@ export default {
|
||||
}
|
||||
|
||||
.item-content {
|
||||
font-family: 'Poppins-Regular', serif;
|
||||
font-family: 'Poppins-Regular';
|
||||
color: #64748B;
|
||||
}
|
||||
}
|
||||
@ -269,7 +338,7 @@ export default {
|
||||
width: 80%;
|
||||
|
||||
.tag-item {
|
||||
font-family: 'Poppins-Medium', serif;
|
||||
font-family: 'Poppins-Medium';
|
||||
flex-shrink: 0;
|
||||
padding: 4px 12px;
|
||||
border-radius: 12px;
|
||||
@ -290,7 +359,7 @@ export default {
|
||||
|
||||
.content-title {
|
||||
margin-left: 6px;
|
||||
font-family: 'Poppins-SemiBold', serif;
|
||||
font-family: 'Poppins-SemiBold';
|
||||
font-size: 24px;
|
||||
color: #1E293B;
|
||||
font-weight: 600;
|
||||
@ -306,9 +375,13 @@ export default {
|
||||
border-radius: 6px;
|
||||
padding: 8px 15px;
|
||||
border: 1px solid #e2e8f0;
|
||||
font-family: 'Poppins-Regular', serif;
|
||||
font-family: 'Poppins-Regular';
|
||||
color: #64748B;
|
||||
|
||||
&:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
img {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
@ -322,7 +395,7 @@ export default {
|
||||
background-color: #F5F4FF;
|
||||
border-radius: 12px;
|
||||
.text {
|
||||
font-family: 'Poppins-Regular', serif;
|
||||
font-family: 'Poppins-Regular';
|
||||
color: #64748B;
|
||||
font-size: 18px;
|
||||
}
|
||||
@ -332,7 +405,7 @@ export default {
|
||||
border-radius: 6px;
|
||||
padding: 8px 15px;
|
||||
border: 1px solid #e2e8f0;
|
||||
font-family: 'Poppins-Regular', serif;
|
||||
font-family: 'Poppins-Regular';
|
||||
color: #64748B;
|
||||
|
||||
img {
|
||||
@ -344,13 +417,13 @@ export default {
|
||||
}
|
||||
}
|
||||
.related {
|
||||
margin-top: 60px;
|
||||
margin-top: 40px;
|
||||
.related-title {
|
||||
.title {
|
||||
margin-bottom: 20px;
|
||||
font-size: 30px;
|
||||
color: #1E293B;
|
||||
font-family: 'Poppins-SemiBold', serif;
|
||||
font-family: 'Poppins-SemiBold';
|
||||
font-weight: 600;
|
||||
&::before {
|
||||
content: '';
|
||||
@ -367,12 +440,19 @@ export default {
|
||||
text-align: right;
|
||||
color: $grey-color;
|
||||
font-size: $mid-font-size;
|
||||
font-family: 'Poppins-Regular', serif;
|
||||
font-family: 'Poppins-Regular';
|
||||
}
|
||||
}
|
||||
.list {
|
||||
gap: 60px;
|
||||
margin: 40px 10px 40px 10px;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
.item {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
min-height: 110px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,8 +2,10 @@
|
||||
<div class="special-finance-item flex">
|
||||
<div class="dot"></div>
|
||||
<div class="flex-1 container">
|
||||
<div class="time">2025-2-1</div>
|
||||
<div class="content">Koah participated in a $5 million seed round, led Forerunner, and participated in The Timeline Of Sketch Commons.</div>
|
||||
<div class="time">{{ item.date || '' }}</div>
|
||||
<div class="content">
|
||||
{{ item.info || '' }}
|
||||
</div>
|
||||
<div class="tag-list flex flex-wrap">
|
||||
<div v-for="(it, i) in tag" :key="i" class="tag-item flex items-center">
|
||||
<img src="/" alt="" />
|
||||
@ -17,21 +19,15 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
item: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tag: [{
|
||||
name: 'Mask Network',
|
||||
isLead: true,
|
||||
}, {
|
||||
name: 'CatcherVC',
|
||||
isLead: true,
|
||||
}, {
|
||||
name: 'CREDIT SCEND',
|
||||
isLead: false,
|
||||
}, {
|
||||
name: 'Ribbit Capital',
|
||||
isLead: false,
|
||||
}],
|
||||
tag: [],
|
||||
}
|
||||
},
|
||||
methods: {},
|
||||
@ -42,6 +38,7 @@ export default {
|
||||
.special-finance-item {
|
||||
border-bottom: 1px solid #E2E8F0;
|
||||
gap: 14px;
|
||||
margin-bottom: 50px;
|
||||
.dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
@ -54,13 +51,13 @@ export default {
|
||||
.time {
|
||||
font-size: 16px;
|
||||
color: #7B61FF;
|
||||
font-family: 'Poppins-Medium', serif;
|
||||
font-family: 'Poppins-Medium';
|
||||
margin-bottom: 22px;
|
||||
}
|
||||
.content {
|
||||
color: #64748B;
|
||||
font-size: 20px;
|
||||
font-family: 'Poppins-Medium', serif;
|
||||
font-family: 'Poppins-Medium';
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.tag-list {
|
||||
@ -78,7 +75,7 @@ export default {
|
||||
span {
|
||||
font-size: 14px;
|
||||
color: #64748B;
|
||||
font-family: 'Poppins-Regular', serif;
|
||||
font-family: 'Poppins-Regular';
|
||||
line-height: 14px;
|
||||
}
|
||||
.lead {
|
||||
|
||||
@ -2,45 +2,46 @@
|
||||
<div id="normal-container">
|
||||
<IntegratedLayout>
|
||||
<div class="content">
|
||||
<div class="title-text">{{ financeDetail.title || '' }}</div>
|
||||
<div class="rate-box">
|
||||
<Rate v-model="financeDetail.rating" readonly />
|
||||
<div class="flex" style="gap: 20px">
|
||||
<CommentBtn :comment-count="commentCount" />
|
||||
</div>
|
||||
<div class="bread-menu">
|
||||
<span>AI Launches</span>
|
||||
<i class="el-icon-arrow-right"></i>
|
||||
<span class="crumbs gradient-color">{{newsDetail.title || ''}}</span>
|
||||
</div>
|
||||
<div class="terms-item">
|
||||
<div class="item-title">
|
||||
<img src="/ToolDetail/icon_note.png" alt="">
|
||||
<span>Introduction: </span>
|
||||
</div>
|
||||
<div class="item-content">
|
||||
<div style="padding-right: 70px">
|
||||
{{ financeDetail.summary || '' }}
|
||||
<div class="title-text">{{ newsDetail.title || '' }}</div>
|
||||
<div class="flex mt-24">
|
||||
<div>
|
||||
<div class="terms-item">
|
||||
<div class="item-title">
|
||||
<img src="/ToolDetail/icon_star.png" alt="">
|
||||
<span>Score: </span>
|
||||
<div class="score color-01">{{ (newsDetail.rating || 0).toFixed(1) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="terms-item">
|
||||
<div class="item-title">
|
||||
<img src="/ToolDetail/icon_note.png" alt="">
|
||||
<span>Introduction: </span>
|
||||
</div>
|
||||
<div class="item-content">
|
||||
{{ newsDetail.summary || '' }}
|
||||
</div>
|
||||
</div>
|
||||
<div class="terms-item">
|
||||
<div class="item-title">
|
||||
<img src="/ToolDetail/icon_clock.png" alt="">
|
||||
<span>Data update: </span>
|
||||
</div>
|
||||
<div class="item-content">{{ formatPublishTime(newsDetail.publishTime || '') }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="terms-item">
|
||||
<div class="item-title">
|
||||
<img src="/ToolDetail/icon_clock.png" alt="">
|
||||
<span>Data update: </span>
|
||||
</div>
|
||||
<div class="item-content">{{ financeDetail.publishTime || '' }}</div>
|
||||
</div>
|
||||
<div class="terms-item">
|
||||
<div class="item-title">
|
||||
<img src="/ToolDetail/like_icon.png" alt="">
|
||||
<span>Like: </span>
|
||||
</div>
|
||||
<div class="item-content">{{ financeDetail.likeCount || 0 }}</div>
|
||||
</div>
|
||||
<div class="tags">
|
||||
<div class="tag-item" v-for="(it, index) in tagList" :key="index">{{ it }}</div>
|
||||
</div>
|
||||
<div class="diver"></div>
|
||||
<div class="title">Special Financing</div>
|
||||
<div class="card content-box">
|
||||
<SpecialFinanceItem />
|
||||
<div class="card content-box" v-if="newsDetail.extra && Array.isArray(newsDetail.extra.financing)">
|
||||
<SpecialFinanceItem v-for="(it, i) in newsDetail.extra.financing" :key="i" :item="it" />
|
||||
</div>
|
||||
</div>
|
||||
</IntegratedLayout>
|
||||
@ -50,12 +51,15 @@
|
||||
<script>
|
||||
import CommentBtn from "@/pages/ToolDetail/components/CommentBtn.vue";
|
||||
import SpecialFinanceItem from "@/pages/Launches/FinanceDetail/SpecialFinanceItem.vue";
|
||||
import ThumbBtn from "@/pages/ToolDetail/components/ThumbBtn.vue";
|
||||
|
||||
export default {
|
||||
components: {CommentBtn, SpecialFinanceItem},
|
||||
components: {ThumbBtn, CommentBtn, SpecialFinanceItem},
|
||||
data() {
|
||||
return {
|
||||
commentCount: 0,
|
||||
news_slug: '',
|
||||
newsDetail: {},
|
||||
financeDetail: {
|
||||
title: 'The Timeline Of Sketch',
|
||||
rating: 1,
|
||||
@ -63,22 +67,88 @@ export default {
|
||||
publishTime: 'Sep 03 2025',
|
||||
likeCount: 100,
|
||||
},
|
||||
tagList: [
|
||||
'Sketch',
|
||||
'Athens',
|
||||
'Offline Maps',
|
||||
'AR',
|
||||
'Navigation',
|
||||
'Scenic Spots',
|
||||
'Exploration',
|
||||
],
|
||||
}
|
||||
},
|
||||
methods: {},
|
||||
methods: {
|
||||
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 {
|
||||
return JSON.parse(str);
|
||||
} catch (e) {
|
||||
console.error('Error parsing JSON string:', e);
|
||||
return [];
|
||||
}
|
||||
},
|
||||
// 获取新闻详情
|
||||
async getNewsDetail(newsSlug) {
|
||||
const {data: res} = await this.$api.article.getArticleDetail(newsSlug);
|
||||
const {code, data} = res;
|
||||
if (code === 0 && 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.news_slug = this.$route.query.news_slug;
|
||||
if (this.news_slug) {
|
||||
this.getNewsDetail(this.news_slug);
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
tagList() {
|
||||
if (!this.newsDetail.tags) {
|
||||
return [];
|
||||
}
|
||||
return this.stringJsonToObject(this.newsDetail.tags || '[]');
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mt-24 {
|
||||
margin-top: 24px;
|
||||
}
|
||||
.color-01 {
|
||||
color: #7B61FF;
|
||||
}
|
||||
.card {
|
||||
padding: 50px 30px;
|
||||
background-color: #FFFFFF;
|
||||
@ -89,7 +159,7 @@ export default {
|
||||
margin-bottom: 20px;
|
||||
font-size: 30px;
|
||||
color: #1E293B;
|
||||
font-family: 'Poppins-SemiBold', serif;
|
||||
font-family: 'Poppins-SemiBold';
|
||||
font-weight: 600;
|
||||
&::before {
|
||||
content: '';
|
||||
@ -102,9 +172,20 @@ export default {
|
||||
}
|
||||
}
|
||||
.content {
|
||||
padding-top: 180px;
|
||||
padding-top: 25px;
|
||||
padding-bottom: 100px;
|
||||
|
||||
.bread-menu {
|
||||
font-size: $mid-font-size;
|
||||
font-family: 'Poppins-Medium';
|
||||
margin-bottom: 25px;
|
||||
|
||||
.crumbs {
|
||||
font-family: 'Poppins-SemiBold';
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.content-box {
|
||||
padding: 50px 30px;
|
||||
}
|
||||
@ -118,9 +199,8 @@ export default {
|
||||
.title-text {
|
||||
font-size: 34px;
|
||||
color: #1E293B;
|
||||
font-family: 'Poppins-SemiBold', serif;
|
||||
font-family: 'Poppins-SemiBold';
|
||||
font-weight: 600;
|
||||
margin-top: 80px;
|
||||
}
|
||||
|
||||
.rate-box {
|
||||
@ -147,7 +227,7 @@ export default {
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
color: #1E293B;
|
||||
font-family: 'Poppins-Medium', serif;
|
||||
font-family: 'Poppins-Medium';
|
||||
|
||||
img {
|
||||
width: 24px;
|
||||
@ -156,7 +236,7 @@ export default {
|
||||
}
|
||||
|
||||
.item-content {
|
||||
font-family: 'Poppins-Regular', serif;
|
||||
font-family: 'Poppins-Regular';
|
||||
color: #64748B;
|
||||
}
|
||||
}
|
||||
@ -172,7 +252,7 @@ export default {
|
||||
width: 80%;
|
||||
|
||||
.tag-item {
|
||||
font-family: 'Poppins-Medium', serif;
|
||||
font-family: 'Poppins-Medium';
|
||||
flex-shrink: 0;
|
||||
padding: 4px 12px;
|
||||
border-radius: 12px;
|
||||
|
||||
@ -5,30 +5,32 @@
|
||||
<div class="preview-box">
|
||||
<img :src="config.coverImage || ''" alt="" />
|
||||
</div>
|
||||
<div class="tool-content flex flex-col justify-between">
|
||||
<div class="tool-content flex flex-1 flex-col justify-between">
|
||||
<div class="content-top flex items-start">
|
||||
<div class="icon">
|
||||
<img src="/" alt="" />
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<div class="title">{{ config.title || '' }}</div>
|
||||
<div class="sub-title" style="padding-right: 30px">{{ config.summary || '' }}</div>
|
||||
<div class="sub-title pr-30">{{ config.summary || '' }}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-bottom flex items-center">
|
||||
<img src="/launches/item/icon_clock.png" alt="" />
|
||||
<div class="time-style">{{ config.publishTime || '' }}</div>
|
||||
<div class="time-style">{{ formatPublishTime(config.publishTime) }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right-content flex">
|
||||
<div class="flex items-center">
|
||||
<div class="right-content flex items-center">
|
||||
<div class="flex items-center btn">
|
||||
<img :src="hovered ? '/launches/item/icon_thumb_grey.png' : '/launches/item/icon_thumb.png'" alt="" />
|
||||
<div :class="{ 'hover-text': hovered }">{{ config.likeCount || 0 }}</div>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<div class="flex items-center btn">
|
||||
<img :src="hovered ? '/launches/item/icon_star_grey.png' : '/launches/item/icon_star.png'" alt="" />
|
||||
<div :class="{ 'hover-text': hovered }">{{ config.rating || 0 }}</div>
|
||||
<div :class="{ 'hover-text': hovered }">
|
||||
{{ (config.rating || 0).toFixed(1) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -54,6 +56,21 @@ export default {
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
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} Released in ${year}`;
|
||||
},
|
||||
handleMouseEnter() {
|
||||
this.hovered = true;
|
||||
},
|
||||
@ -78,7 +95,7 @@ export default {
|
||||
if (id) {
|
||||
await this.$api.article.recordArticleClick(id);
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
const itemContent = this.$el;
|
||||
@ -94,19 +111,27 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.pr-30 {
|
||||
padding-right: 30px;
|
||||
}
|
||||
.item-content {
|
||||
border-radius: 12px;
|
||||
padding: 30px 20px;
|
||||
padding: 25px 20px;
|
||||
transition: background-color 0.3s ease;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: #F5F4FF;
|
||||
|
||||
.order-num {
|
||||
background: #fff;
|
||||
background: #fff !important;
|
||||
}
|
||||
}
|
||||
|
||||
&:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.left-content {
|
||||
gap: 30px;
|
||||
.order-num {
|
||||
@ -118,12 +143,13 @@ export default {
|
||||
text-align: center;
|
||||
line-height: 36px;
|
||||
font-size: 18px;
|
||||
font-family: 'Poppins-Regular', serif;
|
||||
font-family: 'Poppins-Regular';
|
||||
transition: background-color 0.3s ease;
|
||||
color: #506179;
|
||||
}
|
||||
.preview-box {
|
||||
width: 228px;
|
||||
height: 133px;
|
||||
height: 110px;
|
||||
border-radius: 6px;
|
||||
background-color: #FFFFFF;
|
||||
img {
|
||||
@ -145,15 +171,19 @@ export default {
|
||||
}
|
||||
.title {
|
||||
font-size: 20px;
|
||||
font-family: 'Poppins-SemiBold', serif;
|
||||
font-family: 'Poppins-SemiBold';
|
||||
font-weight: 600;
|
||||
line-height: 24px;
|
||||
color: #3A4A65;
|
||||
}
|
||||
.sub-title {
|
||||
color: #64748B;
|
||||
font-family: 'Poppins-Regular', serif;
|
||||
font-family: 'Poppins-Regular';
|
||||
margin-top: 10px;
|
||||
max-width: 420px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
||||
.content-bottom {
|
||||
@ -164,7 +194,7 @@ export default {
|
||||
}
|
||||
.time-style {
|
||||
color: #64748B;
|
||||
font-family: 'Poppins-Regular', serif;
|
||||
font-family: 'Poppins-Regular';
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -172,9 +202,15 @@ export default {
|
||||
.right-content {
|
||||
padding-right: 23px;
|
||||
gap: 33px;
|
||||
font-family: 'Poppins-Regular', serif;
|
||||
font-family: 'Poppins-Regular';
|
||||
color: #E2E8F0;
|
||||
height: 24px;
|
||||
max-width: 192px;
|
||||
.btn {
|
||||
cursor: pointer;
|
||||
&:active {
|
||||
opacity: 0.8;
|
||||
}
|
||||
}
|
||||
img {
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
<div v-if="mode === 'Daily'" class="daily-picker">
|
||||
<HorizontalDateList>
|
||||
<button
|
||||
style="width: 36px"
|
||||
class="bt-d"
|
||||
v-for="day in dailyDays"
|
||||
:key="day.dateStr"
|
||||
:class="{ 'selected': day.dateStr === selectedDate }"
|
||||
@ -19,7 +19,7 @@
|
||||
<div v-else-if="mode === 'Weekly'" class="weekly-picker">
|
||||
<HorizontalDateList>
|
||||
<button
|
||||
style="margin: 0 30px; width: 105px"
|
||||
class="bt-w"
|
||||
v-for="week in weeklyRanges"
|
||||
:key="week.start"
|
||||
:class="{ 'selected': week.start === selectedDate[0] && week.end === selectedDate[1] }"
|
||||
@ -32,7 +32,7 @@
|
||||
<div v-else class="monthly-picker">
|
||||
<HorizontalDateList>
|
||||
<button
|
||||
style="margin: 0 9px; width: 55px"
|
||||
class="bt-m"
|
||||
v-for="(monthAbbr, index) in monthAbbrs"
|
||||
:key="index"
|
||||
:class="{ 'selected': (index + 1) === selectedMonth }"
|
||||
@ -47,6 +47,17 @@
|
||||
<script>
|
||||
import HorizontalDateList from '@/components/HorizontalDateList.vue';
|
||||
|
||||
// 从 sessionStorage 获取缓存数据的辅助函数
|
||||
function getCachedData() {
|
||||
try {
|
||||
const cachedData = sessionStorage.getItem('launches_search_cache');
|
||||
return cachedData ? JSON.parse(cachedData) : null;
|
||||
} catch (e) {
|
||||
// console.error('获取缓存数据失败', e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'OptionDates',
|
||||
components: {
|
||||
@ -72,9 +83,34 @@ export default {
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const cachedData = getCachedData();
|
||||
let initialSelectedDate = this.mode === 'Daily' ? '' : ['', ''];
|
||||
let initialSelectedMonth = this.month;
|
||||
|
||||
// 改进:优先从缓存中获取月份
|
||||
if (cachedData && cachedData.currentMonth) {
|
||||
initialSelectedMonth = cachedData.currentMonth;
|
||||
}
|
||||
|
||||
// 如果有缓存数据,优先使用缓存数据
|
||||
if (cachedData && cachedData.lastSelectedValue) {
|
||||
try {
|
||||
const lastSelectedValue = JSON.parse(cachedData.lastSelectedValue);
|
||||
if (lastSelectedValue) {
|
||||
if (this.mode === 'Daily' && typeof lastSelectedValue === 'string') {
|
||||
initialSelectedDate = lastSelectedValue;
|
||||
} else if (this.mode !== 'Daily' && Array.isArray(lastSelectedValue)) {
|
||||
initialSelectedDate = lastSelectedValue;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('解析缓存的lastSelectedValue失败', e);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
selectedDate: this.mode === 'Daily' ? '' : ['', ''], // 选中的日期/日期范围
|
||||
selectedMonth: this.month // 月模式下选中的月份
|
||||
selectedDate: initialSelectedDate,
|
||||
selectedMonth: initialSelectedMonth,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@ -102,10 +138,60 @@ export default {
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 组件创建时自动选中当前日期或周
|
||||
this.autoSelectCurrentDate();
|
||||
// 先从props获取月份,避免初始为null
|
||||
this.selectedMonth = this.month;
|
||||
|
||||
// 立即尝试获取缓存数据
|
||||
this.updateFromCache();
|
||||
|
||||
// 添加一个小延迟再次尝试,确保父组件的loadSearchCache执行完毕
|
||||
setTimeout(() => {
|
||||
this.updateFromCache();
|
||||
// 强制更新UI,确保选中状态正确显示
|
||||
this.$forceUpdate();
|
||||
}, 100);
|
||||
},
|
||||
methods: {
|
||||
updateFromCache() {
|
||||
const cachedData = getCachedData();
|
||||
|
||||
if (cachedData) {
|
||||
// 优先从缓存获取currentMonth
|
||||
if (cachedData.currentMonth) {
|
||||
this.selectedMonth = cachedData.currentMonth;
|
||||
}
|
||||
|
||||
// 处理lastSelectedValue
|
||||
if (cachedData.lastSelectedValue) {
|
||||
try {
|
||||
const lastSelectedValue = JSON.parse(cachedData.lastSelectedValue);
|
||||
if (lastSelectedValue) {
|
||||
if (this.mode === 'Monthly') {
|
||||
// 月模式下,确保selectedMonth和lastSelectedValue一致
|
||||
let monthToUse = this.selectedMonth;
|
||||
// 如果缓存中有currentMonth,优先使用
|
||||
if (cachedData.currentMonth) {
|
||||
monthToUse = cachedData.currentMonth;
|
||||
this.selectedMonth = monthToUse;
|
||||
}
|
||||
// 生成与selectedMonth对应的日期范围
|
||||
const [start, end] = this.getMonthRange(this.year, monthToUse);
|
||||
// 使用$nextTick确保DOM更新后再发出事件
|
||||
this.$nextTick(() => {
|
||||
this.$emit('select', [start, end]);
|
||||
this.$emit('month-change', monthToUse);
|
||||
});
|
||||
} else if ((this.mode === 'Daily' && typeof lastSelectedValue === 'string') ||
|
||||
(this.mode !== 'Daily' && Array.isArray(lastSelectedValue))) {
|
||||
this.$emit('select', lastSelectedValue);
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('使用缓存的lastSelectedValue失败', e);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
// 自动选中当前日期或周
|
||||
autoSelectCurrentDate(shouldEmit = true) {
|
||||
const now = new Date();
|
||||
@ -162,8 +248,15 @@ export default {
|
||||
|
||||
// 处理月模式的选择
|
||||
handleMonthSelect(month) {
|
||||
// 确保状态立即更新
|
||||
this.selectedMonth = month;
|
||||
// 强制更新UI
|
||||
this.$forceUpdate();
|
||||
|
||||
const [start, end] = this.getMonthRange(this.year, month);
|
||||
// 先发出month-change事件,确保父组件的currentMonth先更新
|
||||
this.$emit('month-change', month);
|
||||
// 然后发出select事件更新lastSelectedValue,包含正确的时间格式
|
||||
this.$emit('select', [start, end]);
|
||||
},
|
||||
|
||||
@ -184,7 +277,15 @@ export default {
|
||||
getMonthRange(year, month) {
|
||||
const start = new Date(year, month - 1, 1);
|
||||
const end = new Date(year, month, 0);
|
||||
return [this.formatDate(start), this.formatDate(end)];
|
||||
const formatDateWithTime = (date, isStart = true) => {
|
||||
const year = date.getFullYear();
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
const time = isStart ? '00:00:00' : '23:59:59';
|
||||
return `${year}-${month}-${day} ${time}`;
|
||||
};
|
||||
return [formatDateWithTime(start), formatDateWithTime(end, false)];
|
||||
|
||||
},
|
||||
|
||||
// 辅助:获取某年的所有完整周区间(假设周从周日开始,到周六结束)
|
||||
@ -253,23 +354,27 @@ export default {
|
||||
month() {
|
||||
if (this.mode === 'Daily') {
|
||||
this.selectedDate = '';
|
||||
this.autoSelectCurrentDate();
|
||||
}
|
||||
this.autoSelectCurrentDate();
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.date-picker-core {
|
||||
padding: 10px;
|
||||
.bt-d {
|
||||
width: 36px; margin: 0 10px;
|
||||
}
|
||||
.bt-w {
|
||||
margin: 0 30px; width: 105px;
|
||||
}
|
||||
.bt-m {
|
||||
margin: 0 20px; width: 55px;
|
||||
}
|
||||
|
||||
.picker-container {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 8px;
|
||||
padding: 12px;
|
||||
border-radius: 4px;
|
||||
width: 100%;
|
||||
box-sizing: border-box;
|
||||
|
||||
@ -9,11 +9,25 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// 从 sessionStorage 获取缓存数据的辅助函数
|
||||
function getCachedMode() {
|
||||
try {
|
||||
const cachedData = sessionStorage.getItem('launches_search_cache');
|
||||
if (cachedData) {
|
||||
const parsedData = JSON.parse(cachedData);
|
||||
return parsedData.currentMode || 'Daily';
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('获取缓存的模式失败', e);
|
||||
}
|
||||
return 'Daily';
|
||||
}
|
||||
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
default: 'Daily'
|
||||
default: getCachedMode,
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@ -29,22 +43,22 @@ export default {
|
||||
|
||||
<style scoped lang="scss">
|
||||
.switch-box {
|
||||
padding: 22px 40px;
|
||||
padding: 12px 40px;
|
||||
border-radius: 12px;
|
||||
background-color: #fff;
|
||||
box-shadow: 0 10px 30px 0 #0000000d;
|
||||
.diver {
|
||||
width: 1px;
|
||||
height: 36px;
|
||||
margin-left: 70px;
|
||||
margin-right: 70px;
|
||||
height: 29px;
|
||||
margin-left: 33px;
|
||||
margin-right: 33px;
|
||||
border-left-width: 1px;
|
||||
border-left-style: solid;
|
||||
border-left-color: #E2E8F0;
|
||||
}
|
||||
.item-text {
|
||||
font-size: 24px;
|
||||
font-family: 'Poppins-Regular', serif;
|
||||
font-family: 'Poppins-Regular';
|
||||
color: #3A4A65;
|
||||
&:active {
|
||||
opacity: 0.8;
|
||||
@ -53,7 +67,7 @@ export default {
|
||||
.active {
|
||||
color: #7B61FF;
|
||||
font-weight: 900 !important;
|
||||
font-family: 'Poppins-Bold', serif;
|
||||
font-family: 'Poppins-Bold';
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
<div class="btn" @click="prevYear">
|
||||
<img :src="prevIcon" alt="Previous Year" />
|
||||
</div>
|
||||
<div style="width: 60px;text-align: center; font-family: 'Poppins-Regular', serif">{{ monthName }}</div>
|
||||
<div class="text">{{ monthName }}</div>
|
||||
<div class="btn" @click="nextYear">
|
||||
<img :src="nextIcon" :alt="isNextDisabled ? 'Next Year Disabled' : 'Next Year'" />
|
||||
</div>
|
||||
@ -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 {
|
||||
|
||||
<style scoped lang="scss">
|
||||
.box {
|
||||
gap: 16px;
|
||||
color: #3A4A65;
|
||||
font-size: 24px;
|
||||
font-family: 'Poppins-SemiBold', serif;
|
||||
font-family: 'Poppins-SemiBold';
|
||||
.btn {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
cursor: pointer;
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 4px;
|
||||
|
||||
&:active {
|
||||
@ -80,5 +92,8 @@ export default {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.text {
|
||||
width: 60px;text-align: center; font-family: 'Poppins-Regular';
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -1,9 +1,23 @@
|
||||
<script>
|
||||
// 从 sessionStorage 获取缓存数据的辅助函数
|
||||
function getCachedSortType() {
|
||||
try {
|
||||
const cachedData = sessionStorage.getItem('launches_search_cache');
|
||||
if (cachedData) {
|
||||
const parsedData = JSON.parse(cachedData);
|
||||
return parsedData.sortType || 'popular';
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('获取缓存的排序类型失败', e);
|
||||
}
|
||||
return 'popular';
|
||||
}
|
||||
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: String,
|
||||
default: 'popular'
|
||||
default: getCachedSortType
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
||||
@ -3,11 +3,25 @@ import IconPrev from '@/static/launches/icon_prev.png';
|
||||
import IconNext from '@/static/launches/icon_next.png';
|
||||
import IconNextDisabled from '@/static/launches/icon_next_disabled.png';
|
||||
|
||||
// 从 sessionStorage 获取缓存数据的辅助函数
|
||||
function getCachedYear() {
|
||||
try {
|
||||
const cachedData = sessionStorage.getItem('launches_search_cache');
|
||||
if (cachedData) {
|
||||
const parsedData = JSON.parse(cachedData);
|
||||
return parsedData.currentYear || new Date().getFullYear();
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('获取缓存的年份失败', e);
|
||||
}
|
||||
return new Date().getFullYear();
|
||||
}
|
||||
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Number,
|
||||
default: () => new Date().getFullYear()
|
||||
default: getCachedYear
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@ -45,7 +59,7 @@ export default {
|
||||
<div class="btn" @click="prevYear">
|
||||
<img :src="prevIcon" alt="Previous Year" />
|
||||
</div>
|
||||
<div style="width: 60px;text-align: center; font-family: 'Poppins-Regular', serif">{{ year }}</div>
|
||||
<div class="text">{{ year }}</div>
|
||||
<div class="btn" @click="nextYear">
|
||||
<img :src="nextIcon" :alt="isNextDisabled ? 'Next Year Disabled' : 'Next Year'" />
|
||||
</div>
|
||||
@ -54,15 +68,15 @@ export default {
|
||||
|
||||
<style scoped lang="scss">
|
||||
.box {
|
||||
gap: 16px;
|
||||
gap: 6px;
|
||||
color: #3A4A65;
|
||||
font-size: 24px;
|
||||
font-family: 'Poppins-SemiBold', serif;
|
||||
font-family: 'Poppins-SemiBold';
|
||||
.btn {
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
cursor: pointer;
|
||||
background-color: #FFFFFF;
|
||||
//background-color: #FFFFFF;
|
||||
border-radius: 4px;
|
||||
|
||||
&:active {
|
||||
@ -74,5 +88,8 @@ export default {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
.text {
|
||||
width: 60px;text-align: center; font-family: 'Poppins-Regular';
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -2,6 +2,9 @@
|
||||
<div id="normal-container" class="launches-content" v-loading.fullscreen.lock="fullscreenLoading">
|
||||
<IntegratedLayout>
|
||||
<div class="content">
|
||||
<div class="bread-menu">
|
||||
<span class="gradient-color crumbs">AI Launches</span>
|
||||
</div>
|
||||
<div class="launches-header">
|
||||
<h1 class="launches-title-text">
|
||||
AI Launches
|
||||
@ -13,13 +16,13 @@
|
||||
</div>
|
||||
<div class="list-header flex-between-center">
|
||||
<SwitchSort v-model="sortType" />
|
||||
<div class="flex items-center" style="gap: 60px">
|
||||
<div class="flex items-center gap-40">
|
||||
<SwitchMonth v-show="currentMode === 'Daily'" v-model="currentMonth" />
|
||||
<SwitchYear v-model="currentYear" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="card list-container">
|
||||
<OptionDates :year="currentYear" :mode="currentMode" :month="currentMonth" @select="handleDateSelect" />
|
||||
<OptionDates :year="currentYear" :mode="currentMode" :month="currentMonth" @select="handleDateSelect" @month-change="handleMonthChange" />
|
||||
<div class="diver"></div>
|
||||
<div class="list">
|
||||
<ListItem v-for="(it, i) in articleList" :key="it.id" :config="it" :sort-index="i + 1" />
|
||||
@ -41,6 +44,8 @@ import SwitchMonth from "@/pages/Launches/components/SwitchMonth.vue";
|
||||
import ListItem from "@/pages/Launches/components/ListItem.vue";
|
||||
import OptionDates from "@/pages/Launches/components/OptionDates.vue";
|
||||
|
||||
const SEARCH_CACHE_KEY = 'launches_search_cache';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
SwitchDate,
|
||||
@ -90,32 +95,176 @@ export default {
|
||||
console.error('解析时间参数失败', e);
|
||||
}
|
||||
}
|
||||
this.saveSearchCache();
|
||||
// 重新获取文章列表,传入新的排序类型
|
||||
this.getArticleListData(this.currentPage, this.pageSize, startTime, endTime, newVal);
|
||||
}
|
||||
},
|
||||
// 监听其他搜索条件变化
|
||||
currentPage() {
|
||||
this.saveSearchCache();
|
||||
},
|
||||
currentYear() {
|
||||
this.saveSearchCache();
|
||||
},
|
||||
currentMode() {
|
||||
this.saveSearchCache();
|
||||
},
|
||||
currentMonth() {
|
||||
this.saveSearchCache();
|
||||
},
|
||||
lastSelectedValue() {
|
||||
this.saveSearchCache();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleMonthChange(month) {
|
||||
this.currentMonth = month;
|
||||
// 无论当前模式是什么,都更新lastSelectedValue
|
||||
const [start, end] = this.getMonthRange(this.currentYear, month);
|
||||
this.lastSelectedValue = JSON.stringify([start, end]);
|
||||
},
|
||||
getMonthRange(year, month) {
|
||||
const start = new Date(year, month - 1, 1);
|
||||
const end = new Date(year, month, 0);
|
||||
// 格式化为 yyyy-mm-dd HH:MM:SS
|
||||
const formatDate = (date, isStart = true) => {
|
||||
const y = date.getFullYear();
|
||||
const m = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const d = String(date.getDate()).padStart(2, '0');
|
||||
const time = isStart ? '00:00:00' : '23:59:59';
|
||||
return `${y}-${m}-${d} ${time}`;
|
||||
};
|
||||
return [formatDate(start), formatDate(end)];
|
||||
},
|
||||
// 保存搜索条件到sessionStorage
|
||||
saveSearchCache() {
|
||||
const cacheData = {
|
||||
currentPage: this.currentPage,
|
||||
currentYear: this.currentYear,
|
||||
currentMode: this.currentMode,
|
||||
currentMonth: this.currentMonth,
|
||||
sortType: this.sortType,
|
||||
lastSelectedValue: this.lastSelectedValue
|
||||
};
|
||||
try {
|
||||
sessionStorage.setItem(SEARCH_CACHE_KEY, JSON.stringify(cacheData));
|
||||
} catch (e) {
|
||||
console.error('保存搜索缓存失败', e);
|
||||
}
|
||||
},
|
||||
// 从sessionStorage加载搜索条件
|
||||
loadSearchCache() {
|
||||
try {
|
||||
const cachedData = sessionStorage.getItem(SEARCH_CACHE_KEY);
|
||||
if (cachedData) {
|
||||
const parsedData = JSON.parse(cachedData);
|
||||
// 恢复各个搜索条件
|
||||
if (parsedData.currentPage !== undefined) {
|
||||
this.currentPage = parsedData.currentPage;
|
||||
}
|
||||
if (parsedData.currentYear !== undefined) {
|
||||
this.currentYear = parsedData.currentYear;
|
||||
}
|
||||
if (parsedData.currentMode !== undefined) {
|
||||
this.currentMode = parsedData.currentMode;
|
||||
}
|
||||
if (parsedData.currentMonth !== undefined) {
|
||||
this.currentMonth = parsedData.currentMonth;
|
||||
}
|
||||
if (parsedData.sortType !== undefined) {
|
||||
this.sortType = parsedData.sortType;
|
||||
}
|
||||
if (parsedData.lastSelectedValue !== undefined) {
|
||||
this.lastSelectedValue = parsedData.lastSelectedValue;
|
||||
}
|
||||
|
||||
// 确保数据同步:在月模式下,如果currentMonth和lastSelectedValue不一致,以currentMonth为准
|
||||
this.$nextTick(() => {
|
||||
if (this.currentMode === 'Monthly' && this.currentMonth) {
|
||||
// 解析lastSelectedValue获取其中的月份
|
||||
let cachedMonth = null;
|
||||
try {
|
||||
if (this.lastSelectedValue) {
|
||||
const selectedValue = JSON.parse(this.lastSelectedValue);
|
||||
if (Array.isArray(selectedValue) && selectedValue.length > 0) {
|
||||
// 从日期字符串中提取月份
|
||||
const dateParts = selectedValue[0].split('-');
|
||||
if (dateParts.length >= 2) {
|
||||
cachedMonth = parseInt(dateParts[1], 10);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('解析lastSelectedValue失败', e);
|
||||
}
|
||||
|
||||
// 如果lastSelectedValue中的月份与currentMonth不一致,更新lastSelectedValue
|
||||
if (cachedMonth !== this.currentMonth) {
|
||||
this.handleMonthChange(this.currentMonth);
|
||||
}
|
||||
}
|
||||
|
||||
// 从lastSelectedValue中提取时间参数并重新请求数据
|
||||
let startTime = '';
|
||||
let endTime = '';
|
||||
if (this.lastSelectedValue) {
|
||||
try {
|
||||
const selectedValue = JSON.parse(this.lastSelectedValue);
|
||||
if (selectedValue instanceof Array) {
|
||||
startTime = selectedValue[0];
|
||||
endTime = selectedValue[1];
|
||||
} else {
|
||||
startTime = selectedValue;
|
||||
endTime = selectedValue;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('解析时间参数失败', e);
|
||||
}
|
||||
}
|
||||
// 调用数据加载方法
|
||||
this.getArticleListData(this.currentPage, this.pageSize, startTime, endTime, this.sortType);
|
||||
});
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('加载搜索缓存失败', e);
|
||||
}
|
||||
},
|
||||
calculateTotalPages() {
|
||||
// 当 total 为 0 时 totalPages 为 1
|
||||
// 否则向上取整计算总页数
|
||||
this.totalPages = this.total === 0 ? 1 : Math.ceil(this.total / this.pageSize);
|
||||
},
|
||||
handleDateSelect(selectedValue) {
|
||||
const stringValue = JSON.stringify(selectedValue);
|
||||
// 确保selectedValue已经包含时分秒
|
||||
let valueToSave = selectedValue;
|
||||
|
||||
// 处理日期字符串或日期范围数组,添加时分秒
|
||||
if (typeof selectedValue === 'string' && !selectedValue.includes(' ')) {
|
||||
// 单个日期,添加时间
|
||||
valueToSave = selectedValue + ' 00:00:00';
|
||||
} else if (Array.isArray(selectedValue) && selectedValue.length === 2) {
|
||||
// 日期范围数组,确保每个日期都有时间
|
||||
const start = selectedValue[0].includes(' ') ? selectedValue[0] : selectedValue[0] + ' 00:00:00';
|
||||
const end = selectedValue[1].includes(' ') ? selectedValue[1] : selectedValue[1] + ' 23:59:59';
|
||||
valueToSave = [start, end];
|
||||
}
|
||||
|
||||
const stringValue = JSON.stringify(valueToSave);
|
||||
if (this.lastSelectedValue === stringValue) {
|
||||
return;
|
||||
}
|
||||
this.lastSelectedValue = stringValue;
|
||||
|
||||
// 获取开始和结束时间
|
||||
let startTime = '';
|
||||
let endTime = '';
|
||||
if (selectedValue instanceof Array) {
|
||||
startTime = selectedValue[0] + ' 00:00:00';
|
||||
endTime = selectedValue[1] + ' 23:59:59';
|
||||
if (valueToSave instanceof Array) {
|
||||
startTime = valueToSave[0];
|
||||
endTime = valueToSave[1];
|
||||
} else {
|
||||
startTime = selectedValue + ' 00:00:00';
|
||||
endTime = selectedValue + ' 23:59:59';
|
||||
startTime = valueToSave;
|
||||
endTime = valueToSave;
|
||||
}
|
||||
this.getArticleListData(this.currentPage, this.pageSize, startTime, endTime, this.sortType);
|
||||
},
|
||||
@ -164,12 +313,18 @@ export default {
|
||||
this.getArticleListData(pageNumber, this.pageSize, startTime, endTime, this.sortType);
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.loadSearchCache();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.gap-40 {
|
||||
gap: 40px;
|
||||
}
|
||||
.card {
|
||||
padding: 60px 30px;
|
||||
padding: 20px 30px;
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 12px;
|
||||
box-shadow: 0 10px 30px 0 rgba(0, 0, 0, 0.08);
|
||||
@ -179,35 +334,47 @@ export default {
|
||||
overflow-y: auto;
|
||||
position: relative;
|
||||
.content {
|
||||
padding-top: 190px;
|
||||
padding-top: 25px;
|
||||
padding-bottom: 100px;
|
||||
|
||||
.bread-menu {
|
||||
font-size: 18px;
|
||||
font-family: 'Poppins-Medium';
|
||||
margin-bottom: 25px;
|
||||
|
||||
.crumbs {
|
||||
font-family: 'Poppins-SemiBold';
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
|
||||
.launches-header {
|
||||
margin-bottom: 114px;
|
||||
margin-bottom: 25px;
|
||||
.launches-title-text {
|
||||
margin: 0;
|
||||
font-size: 40px;
|
||||
font-weight: bold;
|
||||
font-family: 'Poppins-Bold', serif;
|
||||
font-family: 'Poppins-Bold';
|
||||
}
|
||||
.launches-subtitle-text {
|
||||
font-family: 'Poppins-Medium', serif;
|
||||
font-family: 'Poppins-Medium';
|
||||
color: #64748B;
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
.list-header {
|
||||
margin-top: 56px;
|
||||
margin-top: 25px;
|
||||
}
|
||||
.list-container {
|
||||
margin-top: 60px;
|
||||
margin-bottom: 50px;
|
||||
margin-top: 30px;
|
||||
margin-bottom: 40px;
|
||||
.diver {
|
||||
height: 1px;
|
||||
border-top-color: #E2E8F0;
|
||||
border-top-style: solid;
|
||||
border-top-width: 2px;
|
||||
margin-top: 40px;
|
||||
margin-bottom: 40px;
|
||||
margin-top: 15px;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
.list {
|
||||
gap: 30px;
|
||||
|
||||
Reference in New Issue
Block a user