Files
AIProd/pages/DailyNews/NewsList.vue

177 lines
4.5 KiB
Vue

<template>
<div class="news-list-wrap flex flex-col" v-loading.fullscreen.lock="fullscreenLoading">
<div class="input">
<SearchInput v-model="searchText" placeholder="Please enter the key words" @search="handleTextSearch" />
</div>
<div class="card flex flex-col flex-1">
<div class="flex-1 pad-10">
<div class="scroll-box">
<div class="daily-content" v-for="(it, i) in groupedArticles" :key="i">
<div class="date-title flex items-center">
<img src="/about/icon_title_date.png" alt="Daily News" />
<div class="gradient-color">{{ it.date }}</div>
</div>
<div class="flex-col flex gap-40">
<ArticleTextListItem v-for="item in it.list" :key="item.id" :item="item" />
</div>
<div class="diver"></div>
</div>
</div>
</div>
<div class="flex-middle-left">
<Pagination :current-page="currentPage" :total-pages="totalPages" @page-change="handlePageChange" />
</div>
</div>
</div>
</template>
<script>
import ArticleTextListItem from "@/pages/DailyNews/components/ArticleTextListItem.vue";
export default {
components: {
ArticleTextListItem,
},
data() {
return {
currentPage: 1,
totalPages: 1,
pageSize: 10,
articleList: [],
searchText: '',
total: 0,
fullscreenLoading: false,
}
},
methods: {
// 模糊搜索
async handleTextSearch() {
await this.getArticleListData(this.currentPage, this.pageSize, this.searchText);
},
calculateTotalPages() {
// 否则向上取整计算总页数
this.totalPages = this.total === 0 ? 1 : Math.ceil(this.total / this.pageSize);
},
// 获取文章数据列表
async getArticleListData(page = 1, limit = 10, searchText) {
const params = {page, limit, title: searchText, articleType: 'news', sortField: 'publish_time', sortOrder: 'desc'};
if (!searchText) {
delete params.title;
}
this.fullscreenLoading = true;
const {data: res} = await this.$api.article.getArticleList(params);
const {code, data} = res;
if (code === 0 && data.list) {
this.total = data.total;
this.articleList = data.list;
this.calculateTotalPages();
}
this.fullscreenLoading = false;
},
handlePageChange(pageNumber) {
this.currentPage = pageNumber;
this.getArticleListData(pageNumber, 10);
},
// 添加日期格式化方法
formatDate(date) {
const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
const month = months[date.getMonth()];
const day = date.getDate().toString().padStart(2, '0');
const year = date.getFullYear();
return `${month} ${day} ${year}`;
},
},
computed: {
// 添加计算属性,将文章列表按日期分组
groupedArticles() {
if (!this.articleList || this.articleList.length === 0) {
return [];
}
// 创建一个对象来存储按日期分组的文章
const groups = {};
// 遍历文章列表,按日期分组
this.articleList.forEach(article => {
// 假设 publishTime 是时间戳或可被解析的时间字符串
const date = new Date(article.publishTime);
// 格式化日期为 YYYY-MM-DD 格式作为键
const dateKey = date.toISOString().split('T')[0];
// 如果该日期还没有分组,则初始化
if (!groups[dateKey]) {
groups[dateKey] = {
date: this.formatDate(date), // 格式化为 Sep 04 2025 这样的格式
list: []
};
}
// 将文章添加到对应日期的分组中
groups[dateKey].list.push(article);
});
// 将分组对象转换为数组并按日期降序排列
return Object.values(groups).sort((a, b) => {
// 解析日期字符串进行比较
const dateA = new Date(a.date);
const dateB = new Date(b.date);
return dateB - dateA;
});
}
},
mounted() {
this.getArticleListData(this.currentPage, this.pageSize);
}
}
</script>
<style scoped lang="scss">
.pad-10 {
padding: 10px 0;
}
.gap-40 {
gap: 40px;
}
.scroll-box {
max-height: 1600px;
overflow-y: auto;
}
.card {
padding: 20px;
background-color: #FFFFFF;
border-radius: 12px;
box-shadow: 0 10px 30px 0 rgba(0, 0, 0, 0.08);
}
.news-list-wrap {
height: 100%;
gap: 16px;
.input {
display: flex;
margin-top: 20px;
}
.daily-content {
.date-title {
gap: 8px;
font-family: 'Poppins-SemiBold';
font-size: 24px;
font-weight: 600;
margin-bottom: 40px;
img {
width: 28px;
height: 28px;
}
}
}
.diver {
width: 100%;
height: 2px;
border-top-color: #f3f8fe;
border-top-style: solid;
border-top-width: 2px;
margin: 40px 0;
}
}
</style>