345 lines
8.9 KiB
Vue
345 lines
8.9 KiB
Vue
<script lang='ts' setup>
|
|
import {
|
|
calendarOutline,
|
|
chatbubblesOutline,
|
|
chevronForwardOutline,
|
|
eyeOutline,
|
|
megaphoneOutline,
|
|
newspaperOutline,
|
|
peopleOutline,
|
|
rocketOutline,
|
|
timeOutline,
|
|
} from "ionicons/icons";
|
|
import { onMounted, onUnmounted, ref } from "vue";
|
|
|
|
// 公告数据
|
|
const announcements = ref([
|
|
{ id: 1, title: "关于深化改革的重要通知", time: "2026-01-16" },
|
|
{ id: 2, title: "平台升级维护公告", time: "2026-01-15" },
|
|
{ id: 3, title: "新年贺词:砥砺前行,共创辉煌", time: "2026-01-01" },
|
|
]);
|
|
|
|
// 新闻数据(模拟数据)
|
|
const newsList = ref([
|
|
{
|
|
id: 1,
|
|
title: "深化改革进入新阶段",
|
|
subtitle: "全面推进现代化建设,开创新局面",
|
|
time: "2026-01-16 10:30",
|
|
views: 1520,
|
|
image: "https://picsum.photos/seed/news1/400/250",
|
|
},
|
|
{
|
|
id: 2,
|
|
title: "团队协作再创佳绩",
|
|
subtitle: "凝心聚力,共筑梦想,携手共进新时代",
|
|
time: "2026-01-15 16:20",
|
|
views: 2340,
|
|
image: "https://picsum.photos/seed/news2/400/250",
|
|
},
|
|
{
|
|
id: 3,
|
|
title: "战略布局取得重大突破",
|
|
subtitle: "科学谋划,精准施策,推动高质量发展",
|
|
time: "2026-01-14 09:15",
|
|
views: 1890,
|
|
image: "https://picsum.photos/seed/news3/400/250",
|
|
},
|
|
{
|
|
id: 4,
|
|
title: "深化改革进入新阶段",
|
|
subtitle: "全面推进现代化建设,开创新局面",
|
|
time: "2026-01-16 10:30",
|
|
views: 1520,
|
|
image: "https://picsum.photos/seed/news1/400/250",
|
|
},
|
|
{
|
|
id: 5,
|
|
title: "团队协作再创佳绩",
|
|
subtitle: "凝心聚力,共筑梦想,携手共进新时代",
|
|
time: "2026-01-15 16:20",
|
|
views: 2340,
|
|
image: "https://picsum.photos/seed/news2/400/250",
|
|
},
|
|
]);
|
|
|
|
// 快捷入口
|
|
const quickActions = ref([
|
|
{ id: 1, name: "签到", icon: calendarOutline, color: "#c32120" },
|
|
{ id: 2, name: "团队中心", icon: peopleOutline, color: "#c32120" },
|
|
{ id: 3, name: "战略改革", icon: rocketOutline, color: "#c32120" },
|
|
{ id: 4, name: "在线客服", icon: chatbubblesOutline, color: "#c32120" },
|
|
]);
|
|
|
|
function handleQuickAction(action: any) {
|
|
console.log("点击快捷入口:", action.name);
|
|
// TODO: 实现各个快捷入口的功能
|
|
}
|
|
|
|
function handleAnnouncementClick(announcement: any) {
|
|
console.log("查看公告:", announcement.title);
|
|
// TODO: 跳转到公告详情
|
|
}
|
|
|
|
function handleNewsClick(news: any) {
|
|
console.log("查看新闻:", news.title);
|
|
// TODO: 跳转到新闻详情
|
|
}
|
|
|
|
// 走马灯相关
|
|
const currentAnnouncementIndex = ref(0);
|
|
let announcementTimer: number | null = null;
|
|
|
|
function startAnnouncementCarousel() {
|
|
announcementTimer = setInterval(() => {
|
|
currentAnnouncementIndex.value = (currentAnnouncementIndex.value + 1) % announcements.value.length;
|
|
}, 3000); // 每3秒切换
|
|
}
|
|
|
|
function stopAnnouncementCarousel() {
|
|
if (announcementTimer) {
|
|
clearInterval(announcementTimer);
|
|
announcementTimer = null;
|
|
}
|
|
}
|
|
|
|
onMounted(() => {
|
|
startAnnouncementCarousel();
|
|
});
|
|
|
|
onUnmounted(() => {
|
|
stopAnnouncementCarousel();
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<ion-page>
|
|
<ion-content :fullscreen="true" class="home-page">
|
|
<!-- <ion-header class="ion-no-border header">
|
|
<ion-toolbar class="ion-toolbar">
|
|
<div slot="start" class="flex items-center px-3 py-3">
|
|
<img src="@/assets/images/guohui.png" alt="国徽" class="inline-block h-10 mr-2">
|
|
<div class="font-semibold text-lg">
|
|
国务院深化改革战略推进委员会
|
|
</div>
|
|
</div>
|
|
</ion-toolbar>
|
|
</ion-header> -->
|
|
|
|
<img src="@/assets/images/home-banner.jpg" class="h-60 w-full object-cover" alt="首页横幅">
|
|
|
|
<div class="ion-padding-horizontal">
|
|
<!-- 快捷入口区域 -->
|
|
<section class="my-5 grid grid-cols-4 gap-4">
|
|
<!-- <div class="grid grid-cols-4 gap-4 bg-white/95 p-5 rounded-2xl shadow-lg"> -->
|
|
<div
|
|
v-for="action in quickActions"
|
|
:key="action.id"
|
|
class="flex flex-col items-center gap-2 cursor-pointer transition-transform active:scale-95"
|
|
@click="handleQuickAction(action)"
|
|
>
|
|
<div
|
|
class="w-12 h-12 rounded-full flex-center shadow-lg"
|
|
:style="{ background: action.color }"
|
|
>
|
|
<ion-icon :icon="action.icon" class="text-xl text-white" />
|
|
</div>
|
|
<span class="text-xs text-[#333] font-medium text-center">{{ action.name }}</span>
|
|
</div>
|
|
<!-- </div> -->
|
|
</section>
|
|
|
|
<!-- 新闻列表区域 -->
|
|
<section class="mt-10 mb-5">
|
|
<div class="flex justify-between items-center mb-4">
|
|
<div class="flex items-center gap-2">
|
|
<img src="@/assets/images/icon.png" class="size-7">
|
|
<div class="text-xl font-bold text-[#1a1a1a]">
|
|
新闻动态
|
|
</div>
|
|
</div>
|
|
<ion-button fill="clear" size="small" class="text-sm text-white h-8">
|
|
更多
|
|
<ion-icon slot="end" :icon="chevronForwardOutline" />
|
|
</ion-button>
|
|
</div>
|
|
<div class="flex flex-col gap-4">
|
|
<div
|
|
v-for="news in newsList"
|
|
:key="news.id"
|
|
class="bg-white rounded-2xl overflow-hidden shadow-sm cursor-pointer transition-all active:translate-y-0.5 active:shadow-sm flex"
|
|
@click="handleNewsClick(news)"
|
|
>
|
|
<div class="relative w-28 h-28 flex-shrink-0 overflow-hidden">
|
|
<img :src="news.image" :alt="news.title" class="w-full h-full object-cover">
|
|
<div class="news-badge absolute top-2 left-2 bg-gradient-to-br from-[#c41e3a] to-[#8b1a2e] text-white px-2 py-0.5 rounded-lg text-xs font-semibold shadow-lg">
|
|
热点
|
|
</div>
|
|
</div>
|
|
<div class="flex-1 p-4 flex flex-col justify-between">
|
|
<div>
|
|
<div class="text-base font-bold text-[#1a1a1a] mb-1 leading-snug line-clamp-2">
|
|
{{ news.title }}
|
|
</div>
|
|
<p class="text-sm text-[#666] leading-relaxed line-clamp-2">
|
|
{{ news.subtitle }}
|
|
</p>
|
|
</div>
|
|
<div class="flex items-center gap-4 text-xs text-[#999] mt-2">
|
|
<span class="flex items-center gap-1">
|
|
<ion-icon :icon="timeOutline" class="text-sm" />
|
|
{{ news.time }}
|
|
</span>
|
|
<span class="flex items-center gap-1">
|
|
<ion-icon :icon="eyeOutline" class="text-sm" />
|
|
{{ news.views }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</ion-content>
|
|
</ion-page>
|
|
</template>
|
|
|
|
<style lang='css' scoped>
|
|
.ion-toolbar {
|
|
/* --background: #c32120; */
|
|
/* --color: #fff; */
|
|
}
|
|
|
|
.home-pg {
|
|
background: linear-gradient(180deg, #c32120 0%, #c32120 55%, #fef5f1 100%);
|
|
}
|
|
/* .home-page {
|
|
--background: linear-gradient(180deg, #c41e3a 0%, #e8756d 15%, #f5d5c8 35%, #fef5f1 50%, #fef5f1 65%, #f5d5c8 85%);
|
|
} */
|
|
|
|
/* 中国风图案 */
|
|
.chinese-pattern {
|
|
position: absolute;
|
|
width: 100%;
|
|
height: 100%;
|
|
opacity: 0.8;
|
|
}
|
|
|
|
.pattern-svg {
|
|
position: absolute;
|
|
animation: rotate-pattern 30s linear infinite;
|
|
}
|
|
|
|
.pattern-1 {
|
|
width: 150px;
|
|
height: 150px;
|
|
top: 20px;
|
|
right: 30px;
|
|
}
|
|
|
|
.pattern-2 {
|
|
width: 120px;
|
|
height: 120px;
|
|
top: 100px;
|
|
left: 40px;
|
|
animation-direction: reverse;
|
|
animation-duration: 40s;
|
|
}
|
|
|
|
@keyframes rotate-pattern {
|
|
from {
|
|
transform: rotate(0deg);
|
|
}
|
|
to {
|
|
transform: rotate(360deg);
|
|
}
|
|
}
|
|
|
|
/* 五角星装饰 */
|
|
.stars-decoration {
|
|
position: absolute;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
.star {
|
|
position: absolute;
|
|
color: rgba(255, 215, 0, 0.3);
|
|
font-size: 24px;
|
|
animation: twinkle 3s ease-in-out infinite;
|
|
}
|
|
|
|
.star-1 {
|
|
top: 40px;
|
|
left: 25%;
|
|
animation-delay: 0s;
|
|
}
|
|
|
|
.star-2 {
|
|
top: 80px;
|
|
right: 30%;
|
|
font-size: 18px;
|
|
animation-delay: 1s;
|
|
}
|
|
|
|
.star-3 {
|
|
top: 130px;
|
|
left: 15%;
|
|
font-size: 20px;
|
|
animation-delay: 2s;
|
|
}
|
|
|
|
@keyframes twinkle {
|
|
0%,
|
|
100% {
|
|
opacity: 0.3;
|
|
transform: scale(1);
|
|
}
|
|
50% {
|
|
opacity: 0.7;
|
|
transform: scale(1.2);
|
|
}
|
|
}
|
|
|
|
/* 底部波浪 */
|
|
.wave-bottom {
|
|
position: absolute;
|
|
bottom: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 120px;
|
|
opacity: 0.6;
|
|
}
|
|
|
|
/* 新闻标签渐变 - 使用 @apply 不支持渐变,需要保留 */
|
|
.news-badge {
|
|
box-shadow: 0 2px 8px rgba(196, 30, 58, 0.3);
|
|
}
|
|
|
|
/* 走马灯动画 */
|
|
.announcement-carousel {
|
|
transition: height 0.3s ease;
|
|
}
|
|
|
|
.slide-enter-active,
|
|
.slide-leave-active {
|
|
transition: all 0.5s ease;
|
|
}
|
|
|
|
.slide-enter-from {
|
|
transform: translateX(100%);
|
|
opacity: 0;
|
|
}
|
|
|
|
.slide-leave-to {
|
|
transform: translateX(-100%);
|
|
opacity: 0;
|
|
}
|
|
|
|
.slide-enter-to,
|
|
.slide-leave-from {
|
|
transform: translateX(0);
|
|
opacity: 1;
|
|
}
|
|
</style>
|