Files
AIProd/pages/Launches/index.vue
2025-10-24 15:45:38 +08:00

221 lines
6.2 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div id="normal-container" class="launches-content" v-loading.fullscreen.lock="fullscreenLoading">
<IntegratedLayout>
<div class="content">
<div class="launches-header">
<h1 class="launches-title-text">
AI Launches
</h1>
<p class="launches-subtitle-text">A daily curated selection of the newest AI applications and products. Explore the most talked-about innovations, trending technologies, and hot new releases shaping the AI landscape. Stay ahead by discovering whats capturing attention in the AI community.</p>
</div>
<div class="flex justify-center">
<SwitchDate v-model="currentMode" />
</div>
<div class="list-header flex-between-center">
<SwitchSort v-model="sortType" />
<div class="flex items-center" style="gap: 60px">
<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" />
<div class="diver"></div>
<div class="list">
<ListItem v-for="(it, i) in articleList" :key="it.id" :config="it" :sort-index="i + 1" />
</div>
</div>
<div class="flex-bottom-right">
<Pagination :current-page="currentPage" :total-pages="totalPages" @page-change="handlePageChange" />
</div>
</div>
</IntegratedLayout>
</div>
</template>
<script>
import SwitchDate from "@/pages/Launches/components/SwitchDate.vue";
import SwitchSort from "@/pages/Launches/components/SwitchSort.vue";
import SwitchYear from "@/pages/Launches/components/SwitchYear.vue";
import SwitchMonth from "@/pages/Launches/components/SwitchMonth.vue";
import ListItem from "@/pages/Launches/components/ListItem.vue";
import OptionDates from "@/pages/Launches/components/OptionDates.vue";
export default {
components: {
SwitchDate,
SwitchSort,
SwitchYear,
ListItem,
OptionDates,
SwitchMonth,
},
data() {
return {
lastSelectedValue: null,
currentPage: 1,
totalPages: 1,
pageSize: 10,
total: 0,
currentYear: new Date().getFullYear(),
currentMode: 'Daily',
currentMonth: new Date().getMonth() + 1,
articleList: [],
sortType: 'popular',
fullscreenLoading: false,
}
},
watch: {
total() {
this.calculateTotalPages();
},
pageSize() {
this.calculateTotalPages();
},
sortType(newVal, oldVal) {
if (oldVal !== null) { // 避免初始化时触发
let startTime = '';
let endTime = '';
if (this.lastSelectedValue) {
try {
const selectedValue = JSON.parse(this.lastSelectedValue);
if (selectedValue instanceof Array) {
startTime = selectedValue[0] + ' 00:00:00';
endTime = selectedValue[1] + ' 23:59:59';
} else {
startTime = selectedValue + ' 00:00:00';
endTime = selectedValue + ' 23:59:59';
}
} catch (e) {
console.error('解析时间参数失败', e);
}
}
// 重新获取文章列表,传入新的排序类型
this.getArticleListData(this.currentPage, this.pageSize, startTime, endTime, newVal);
}
},
},
methods: {
calculateTotalPages() {
// 当 total 为 0 时 totalPages 为 1
// 否则向上取整计算总页数
this.totalPages = this.total === 0 ? 1 : Math.ceil(this.total / this.pageSize);
},
handleDateSelect(selectedValue) {
const stringValue = JSON.stringify(selectedValue);
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';
} else {
startTime = selectedValue + ' 00:00:00';
endTime = selectedValue + ' 23:59:59';
}
this.getArticleListData(this.currentPage, this.pageSize, startTime, endTime, this.sortType);
},
// 获取文章列表
async getArticleListData(page = 1, limit = 10, startTime, endTime, sortType = 'popular') {
const params = {page, limit, startTime, endTime, articleType: 'launches'};
if (sortType === 'popular') {
params.isHot = 1;
} else {
params.sortField = 'publish_time';
params.sortOrder = 'desc';
}
this.fullscreenLoading = true;
const {data: res} = await this.$api.article.getArticleList(params);
const {code, data} = res;
if (code === 0 && data.list) {
this.articleList = data.list;
this.total = data.total;
this.calculateTotalPages();
} else {
this.articleList = [];
this.total = 0;
this.calculateTotalPages();
}
this.fullscreenLoading = false;
},
handlePageChange(pageNumber) {
this.currentPage = pageNumber;
// 从 lastSelectedValue 中提取时间参数
let startTime = '';
let endTime = '';
if (this.lastSelectedValue) {
try {
const selectedValue = JSON.parse(this.lastSelectedValue);
if (selectedValue instanceof Array) {
startTime = selectedValue[0] + ' 00:00:00';
endTime = selectedValue[1] + ' 23:59:59';
} else {
startTime = selectedValue + ' 00:00:00';
endTime = selectedValue + ' 23:59:59';
}
} catch (e) {
console.error('解析时间参数失败', e);
}
}
this.getArticleListData(pageNumber, this.pageSize, startTime, endTime, this.sortType);
},
},
}
</script>
<style scoped lang="scss">
.card {
padding: 60px 30px;
background-color: #FFFFFF;
border-radius: 12px;
box-shadow: 0 10px 30px 0 rgba(0, 0, 0, 0.08);
}
.launches-content {
flex: 1;
overflow-y: auto;
position: relative;
.content {
padding-top: 190px;
padding-bottom: 100px;
.launches-header {
margin-bottom: 114px;
.launches-title-text {
margin: 0;
font-size: 40px;
font-weight: bold;
font-family: 'Poppins-Bold', serif;
}
.launches-subtitle-text {
font-family: 'Poppins-Medium', serif;
color: #64748B;
margin-top: 10px;
}
}
.list-header {
margin-top: 56px;
}
.list-container {
margin-top: 60px;
margin-bottom: 50px;
.diver {
height: 1px;
border-top-color: #E2E8F0;
border-top-style: solid;
border-top-width: 2px;
margin-top: 40px;
margin-bottom: 40px;
}
.list {
gap: 30px;
display: flex;
flex-direction: column;
}
}
}
}
</style>