1
This commit is contained in:
647
components/Index/Category.vue
Normal file
647
components/Index/Category.vue
Normal file
@@ -0,0 +1,647 @@
|
||||
<script setup lang="ts">
|
||||
import {treeNavigation} from '~/api/cms/cmsNavigation';
|
||||
import type {CmsNavigation} from '~/api/cms/cmsNavigation/model';
|
||||
import NewsList from '~/components/Index/NewsList.vue';
|
||||
import NewsListSimple from '~/components/Index/NewsListSimple.vue';
|
||||
import NewsCard from '~/components/Index/NewsCard.vue';
|
||||
import {pageCmsArticle} from "~/api/cms/cmsArticle";
|
||||
import type {CmsArticle} from "~/api/cms/cmsArticle/model";
|
||||
import {getCmsAd} from "~/api/cms/cmsAd";
|
||||
import type {CmsAd} from "~/api/cms/cmsAd/model";
|
||||
|
||||
const categoryList = ref<CmsNavigation[]>([]);
|
||||
const hotNews = ref<CmsArticle[]>([]);
|
||||
|
||||
// 当前激活的分类ID
|
||||
const activeCategoryId = ref<number>(4264);
|
||||
|
||||
// 其他栏目数据
|
||||
const memberNews = ref<CmsArticle[]>([]); // 会员之家
|
||||
const brandNews = ref<CmsArticle[]>([]); // 品牌建设
|
||||
const industryNews = ref<CmsArticle[]>([]); // 行业自律
|
||||
const partyNews = ref<CmsArticle[]>([]); // 协会党建
|
||||
const productNews = ref<CmsArticle[]>([]); // 名优产品
|
||||
const bannerAd = ref<any>(); // 广告位441
|
||||
|
||||
// 产品轮播相关
|
||||
const productCarousel = ref<HTMLElement>();
|
||||
let carouselTimer: NodeJS.Timeout | null = null;
|
||||
|
||||
// 分类选项
|
||||
const categoryTabs = [
|
||||
{id: 4266, name: '行业新闻'},
|
||||
{id: 4267, name: '工作动态'}
|
||||
];
|
||||
|
||||
// 切换分类
|
||||
const switchCategory = (categoryId: number) => {
|
||||
activeCategoryId.value = categoryId;
|
||||
};
|
||||
|
||||
// 格式化日期
|
||||
const formatDate = (dateStr: string | undefined) => {
|
||||
if (!dateStr) return '';
|
||||
const date = new Date(dateStr);
|
||||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||||
const day = String(date.getDate()).padStart(2, '0');
|
||||
return `${month}-${day}`;
|
||||
};
|
||||
|
||||
// 启动产品轮播
|
||||
const startProductCarousel = () => {
|
||||
if (!productCarousel.value || productNews.value.length <= 4) return;
|
||||
|
||||
carouselTimer = setInterval(() => {
|
||||
const container = productCarousel.value;
|
||||
if (!container) return;
|
||||
|
||||
const itemWidth = 200; // 每个产品项的宽度
|
||||
const currentScroll = container.scrollLeft;
|
||||
const maxScroll = container.scrollWidth - container.clientWidth;
|
||||
|
||||
if (currentScroll >= maxScroll) {
|
||||
// 滚动到末尾,重置到开始
|
||||
container.scrollTo({left: 0, behavior: 'smooth'});
|
||||
} else {
|
||||
// 继续向右滚动
|
||||
container.scrollTo({left: currentScroll + itemWidth, behavior: 'smooth'});
|
||||
}
|
||||
}, 3000); // 每3秒滚动一次
|
||||
};
|
||||
|
||||
// 停止产品轮播
|
||||
const stopProductCarousel = () => {
|
||||
if (carouselTimer) {
|
||||
clearInterval(carouselTimer);
|
||||
carouselTimer = null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const reload = async () => {
|
||||
treeNavigation({
|
||||
recommend: true
|
||||
}).then(data => {
|
||||
categoryList.value = data || [];
|
||||
console.log(data, '123132');
|
||||
});
|
||||
|
||||
// 获取热门新闻
|
||||
const hot_news = await pageCmsArticle({
|
||||
limit: 5,
|
||||
recommend: 1
|
||||
});
|
||||
if (hot_news) {
|
||||
hotNews.value = hot_news?.list || [];
|
||||
}
|
||||
|
||||
// 获取会员之家数据
|
||||
const memberData = await pageCmsArticle({
|
||||
limit: 4,
|
||||
parentId: 4297
|
||||
});
|
||||
if (memberData) {
|
||||
memberNews.value = memberData?.list || [];
|
||||
}
|
||||
|
||||
// 获取品牌建设数据
|
||||
const brandData = await pageCmsArticle({
|
||||
limit: 4,
|
||||
parentId: 4301
|
||||
});
|
||||
if (brandData) {
|
||||
brandNews.value = brandData?.list || [];
|
||||
}
|
||||
|
||||
// 获取行业自律数据
|
||||
const industryData = await pageCmsArticle({
|
||||
limit: 4,
|
||||
parentId: 4300
|
||||
});
|
||||
if (industryData) {
|
||||
industryNews.value = industryData?.list || [];
|
||||
}
|
||||
|
||||
// 获取协会党建数据
|
||||
const partyData = await pageCmsArticle({
|
||||
limit: 4,
|
||||
categoryId: 4310
|
||||
});
|
||||
if (partyData) {
|
||||
partyNews.value = partyData?.list || [];
|
||||
}
|
||||
|
||||
// 获取名优产品数据
|
||||
const productData = await pageCmsArticle({
|
||||
limit: 8,
|
||||
categoryId: 4299
|
||||
});
|
||||
if (productData) {
|
||||
productNews.value = productData?.list || [];
|
||||
}
|
||||
|
||||
// 获取广告位441数据
|
||||
try {
|
||||
const adData = await getCmsAd(441);
|
||||
if (adData && adData.status == 0) {
|
||||
bannerAd.value = adData.imageList[0];
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('获取广告位441失败:', error);
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
reload();
|
||||
// 延迟启动轮播,确保DOM已渲染
|
||||
nextTick(() => {
|
||||
setTimeout(() => {
|
||||
startProductCarousel();
|
||||
}, 1000);
|
||||
});
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
stopProductCarousel();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- 通知公告样式的新闻专区 -->
|
||||
<div class="news-section-wrapper">
|
||||
<div class="xl:w-screen-xl m-auto">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="8">
|
||||
<el-carousel height="324px" class="bg-white rounded-lg overflow-hidden">
|
||||
<el-carousel-item v-for="(item,index) in hotNews" :key="index">
|
||||
<el-image :src="item.image" fit="cover" class="w-full h-full"
|
||||
@click="navigateTo(`/detail/${item.articleId}.html`, { target: '_blank' })"/>
|
||||
</el-carousel-item>
|
||||
</el-carousel>
|
||||
</el-col>
|
||||
<el-col :span="16">
|
||||
<div
|
||||
class="w-full h-[324px] bg-white border-1 border-solid border-gray-200 rounded-lg overflow-hidden flex flex-col">
|
||||
<div
|
||||
class="title flex justify-between items-center bg-green-50 py-3 px-4 text-lg border-b-1 border-b-solid border-gray-200 flex-shrink-0"
|
||||
>
|
||||
<a-space class="flex items-center gap-1">
|
||||
|
||||
<span
|
||||
class="cursor-pointer transition-colors duration-200"
|
||||
:class="{ 'active': activeCategoryId === 4264 }"
|
||||
@click="switchCategory(4264)"
|
||||
>
|
||||
通知公告
|
||||
</span>
|
||||
<el-divider direction="vertical"/>
|
||||
<span
|
||||
class="cursor-pointer transition-colors duration-200"
|
||||
:class="{ 'active': activeCategoryId === 4266 }"
|
||||
@click="switchCategory(4266)"
|
||||
>
|
||||
行业新闻
|
||||
</span>
|
||||
<el-divider direction="vertical"/>
|
||||
<span
|
||||
class="cursor-pointer transition-colors duration-200"
|
||||
:class="{ 'active': activeCategoryId === 4267 }"
|
||||
@click="switchCategory(4267)"
|
||||
>
|
||||
工作动态
|
||||
</span>
|
||||
</a-space>
|
||||
<a :href="`/article/${activeCategoryId}`" class="text-sm hover:text-green-600 transition-colors">更多</a>
|
||||
</div>
|
||||
<div class="flex-1 overflow-hidden">
|
||||
<NewsListSimple :categoryId="activeCategoryId" :row="6" :key="activeCategoryId"/>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 其他栏目内容 -->
|
||||
<div class="other-sections-wrapper">
|
||||
<div class="xl:w-screen-xl m-auto">
|
||||
<!-- 会员之家单独一排 -->
|
||||
<el-row :gutter="20" class="mb-8">
|
||||
<!-- 名优产品(带封面图) -->
|
||||
<el-col :span="16">
|
||||
<div class="section-card product-card">
|
||||
<div class="section-header">
|
||||
<h3 class="section-title">名优产品</h3>
|
||||
<a href="/article/4299" class="more-link">更多</a>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<div class="product-carousel-container">
|
||||
<div class="product-carousel" ref="productCarousel">
|
||||
<div v-for="(item, index) in productNews" :key="index" class="product-item">
|
||||
<a :href="`/detail/${item.articleId}`" class="product-link">
|
||||
<div class="product-image">
|
||||
<el-image
|
||||
:src="item.image || '/default-product.jpg'"
|
||||
fit="cover"
|
||||
class="w-full h-full"
|
||||
:alt="item.title"
|
||||
/>
|
||||
</div>
|
||||
<div class="product-info">
|
||||
<h4 class="product-title">{{ item.title }}</h4>
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
<!-- 协会党建 -->
|
||||
<el-col :span="8">
|
||||
<div class="section-card">
|
||||
<div class="section-header">
|
||||
<h3 class="section-title">协会党建</h3>
|
||||
<a href="/article/4310" class="more-link">更多</a>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<div class="news-list">
|
||||
<div v-for="(item, index) in partyNews" :key="index" class="news-item">
|
||||
<a :href="`/detail/${item.articleId}`" class="news-link">
|
||||
<span class="news-title">{{ item.title }}</span>
|
||||
<span class="news-date">{{ formatDate(item.createTime) }}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
</el-row>
|
||||
|
||||
|
||||
<!-- 广告位1000x125 -->
|
||||
<div v-if="bannerAd" class="ad-banner-wrapper">
|
||||
<div class="xl:w-screen-xl m-auto">
|
||||
<div class="ad-banner-container">
|
||||
<a
|
||||
:href="bannerAd.url || '#'"
|
||||
:target="bannerAd.url ? '_blank' : '_self'"
|
||||
class="ad-banner-link"
|
||||
>
|
||||
<el-image
|
||||
:src="bannerAd.url"
|
||||
:alt="bannerAd.url"
|
||||
fit="cover"
|
||||
class="ad-banner-image"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 其他三个栏目一排 -->
|
||||
<el-row :gutter="20" class="mb-8">
|
||||
|
||||
<!-- 会员之家文本列表 -->
|
||||
<el-col :span="8">
|
||||
<div class="section-card">
|
||||
<div class="section-header">
|
||||
<h3 class="section-title">会员之家</h3>
|
||||
<a href="/article/4297" class="more-link">更多</a>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<div class="news-list">
|
||||
<div v-for="(item, index) in memberNews" :key="index" class="news-item">
|
||||
<a :href="`/detail/${item.articleId}`" class="news-link">
|
||||
<span class="news-title">{{ item.title }}</span>
|
||||
<span class="news-date">{{ formatDate(item.createTime) }}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<!-- 品牌建设 -->
|
||||
<el-col :span="8">
|
||||
<div class="section-card">
|
||||
<div class="section-header">
|
||||
<h3 class="section-title">品牌建设</h3>
|
||||
<a href="/article/4301" class="more-link">更多</a>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<div class="news-list">
|
||||
<div v-for="(item, index) in brandNews" :key="index" class="news-item">
|
||||
<a :href="`/detail/${item.articleId}`" class="news-link">
|
||||
<span class="news-title">{{ item.title }}</span>
|
||||
<span class="news-date">{{ formatDate(item.createTime) }}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
<!-- 行业自律 -->
|
||||
<el-col :span="8">
|
||||
<div class="section-card">
|
||||
<div class="section-header">
|
||||
<h3 class="section-title">政策法规</h3>
|
||||
<a href="/article/4419" class="more-link">更多</a>
|
||||
</div>
|
||||
<div class="section-content">
|
||||
<div class="news-list">
|
||||
<div v-for="(item, index) in industryNews" :key="index" class="news-item">
|
||||
<a :href="`/detail/${item.articleId}`" class="news-link">
|
||||
<span class="news-title">{{ item.title }}</span>
|
||||
<span class="news-date">{{ formatDate(item.createTime) }}</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.news-section-wrapper {
|
||||
background: linear-gradient(135deg, #f8fafc 0%, #e2e8f0 100%);
|
||||
padding: 40px 0;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.active {
|
||||
font-weight: bold;
|
||||
color: #1b850c;
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
bottom: -8px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 2px;
|
||||
border-radius: 1px;
|
||||
}
|
||||
}
|
||||
|
||||
.cursor-pointer {
|
||||
padding: 4px 8px;
|
||||
border-radius: 4px;
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
background-color: rgba(27, 133, 12, 0.1);
|
||||
color: #1b850c;
|
||||
}
|
||||
|
||||
&:not(.active):hover {
|
||||
font-weight: 500;
|
||||
}
|
||||
}
|
||||
|
||||
// 轮播图样式优化
|
||||
.el-carousel {
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
// 新闻区域卡片样式
|
||||
.bg-white {
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
// 其他栏目样式
|
||||
.other-sections-wrapper {
|
||||
background: #f8fafc;
|
||||
padding: 40px 0;
|
||||
}
|
||||
|
||||
.section-card {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
overflow: hidden;
|
||||
height: 280px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
}
|
||||
|
||||
.section-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 16px 20px;
|
||||
background: linear-gradient(135deg, #1b850c 0%, #22c55e 100%);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.section-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.more-link {
|
||||
color: white;
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
opacity: 0.9;
|
||||
transition: opacity 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.section-content {
|
||||
flex: 1;
|
||||
padding: 16px 20px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.news-list {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.news-item {
|
||||
margin-bottom: 12px;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.news-link {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px 0;
|
||||
text-decoration: none;
|
||||
color: #333;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
color: #1b850c;
|
||||
background-color: rgba(27, 133, 12, 0.05);
|
||||
padding-left: 8px;
|
||||
border-radius: 4px;
|
||||
border-bottom-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.news-title {
|
||||
flex: 1;
|
||||
font-size: 14px;
|
||||
line-height: 1.4;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.news-date {
|
||||
font-size: 12px;
|
||||
color: #999;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
// 产品轮播样式
|
||||
.product-card {
|
||||
height: 280px;
|
||||
}
|
||||
|
||||
.product-carousel-container {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.product-carousel {
|
||||
display: flex;
|
||||
gap: 16px;
|
||||
height: 100%;
|
||||
overflow-x: auto;
|
||||
scroll-behavior: smooth;
|
||||
scrollbar-width: none; /* Firefox */
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none; /* Chrome, Safari and Opera */
|
||||
}
|
||||
}
|
||||
|
||||
.product-item {
|
||||
flex: 0 0 180px; /* 固定宽度,不收缩不扩展 */
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-4px);
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
}
|
||||
|
||||
.product-link {
|
||||
display: block;
|
||||
height: 100%;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.product-image {
|
||||
height: 135px; /* 4:3 比例,宽度180px对应高度135px */
|
||||
width: 100%;
|
||||
background: #f5f5f5;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.product-info {
|
||||
padding: 12px;
|
||||
height: calc(100% - 135px);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.product-title {
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
color: #333;
|
||||
margin: 0;
|
||||
line-height: 1.4;
|
||||
text-align: center;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
display: -webkit-box;
|
||||
-webkit-line-clamp: 2;
|
||||
-webkit-box-orient: vertical;
|
||||
}
|
||||
|
||||
// 广告位样式
|
||||
.ad-banner-wrapper {
|
||||
padding-bottom: 30px;
|
||||
}
|
||||
|
||||
.ad-banner-container {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.ad-banner-link {
|
||||
display: block;
|
||||
width: 1000px;
|
||||
height: 125px;
|
||||
overflow: hidden;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.15);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
}
|
||||
|
||||
.ad-banner-image {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
// 响应式设计
|
||||
@media (max-width: 1200px) {
|
||||
.ad-banner-link {
|
||||
width: 100%;
|
||||
max-width: 1000px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.ad-banner-link {
|
||||
height: 80px;
|
||||
}
|
||||
|
||||
.ad-banner-wrapper {
|
||||
padding: 15px 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user