Commit 74fb72b7 by 吴春元

feat: 添加搜索功能并优化页面样式

refactor: 重构页面布局和样式

style: 更新字体和图片资源

perf: 优化页面加载性能

fix: 修复路由跳转问题

docs: 更新文档和注释

chore: 更新依赖和配置
parent 4ab41a59
......@@ -37,6 +37,36 @@ a,
::v-deep .el-select-dropdown__wrap {
max-height: 1.2rem ;
max-height: 1.2rem;
}
/* 全局字体 */
@font-face {
font-family: "heitizi";
src: url("/fonts/heitizi.ttf") format("truetype");
font-weight: normal;
font-style: normal;
font-display: swap;
/* 优化字体加载显示 */
}
/* 全局字体 */
@font-face {
font-family: "fangzheng";
src: url("/fonts/fangzheng.ttf") format("truetype");
font-weight: normal;
font-style: normal;
font-display: swap;
/* 优化字体加载显示 */
}
/* 全局字体 */
@font-face {
font-family: "AlibabaPuHuiTi95";
src: url("/fonts/AlibabaPuHuiTi105.ttf") format("truetype");
font-weight: normal;
font-style: normal;
font-display: swap;
/* 优化字体加载显示 */
}
\ No newline at end of file
<template>
<div class="bg-gray-50">
<!-- 页脚 -->
<footer class="bg-gray-800 text-gray-300">
<div class="container mx-auto px-4 pt-10 w-[1440px]">
<div class="grid grid-cols-3 gap-8">
<footer class="bg-[#247edb] text-gray-300 bg-gradient-to-r from-blue-900/80 via-blue-900/30 to-transparent">
<div class="container px-0 pt-5 w-[940px] mx-auto">
<div class="grid grid-cols-2 gap-2 justify-items-center">
<div>
<h3 class="text-lg font-medium mb-4">联系我们</h3>
<div class="space-y-2">
<p>地址:{{ inject("VITE_ADDRESS") }}</p>
<p>电话:{{ inject("VITE_PHONE") }}</p>
<p>邮箱:{{ inject("VITE_EMAIL") }}</p>
<!-- <p>
邮箱:<a href="mailto:{{ inject('VITE_EMAIL') }}">{{
inject("VITE_EMAIL")
}}</a>
</p> -->
<h3 class="text-lg mb-2 text-white font-bold">联系我们</h3>
<div class="space-y-1">
<p class="text-white text-[12px] font-[600]">地址:{{ inject("VITE_ADDRESS") }}</p>
<p class="text-white text-[12px] font-[600]">电话:{{ inject("VITE_PHONE") }}</p>
<p class="text-white text-[12px] font-[600]">邮箱:{{ inject("VITE_EMAIL") }}</p>
</div>
</div>
<div>
<h4 class="text-lg font-medium mb-4">主办单位</h4>
<p>{{ inject("VITE_APP_TITLE") }}</p>
<h4 class="text-lg mb-2 text-white font-bold">主办单位</h4>
<p class="text-white text-[12px] font-[600]">{{ inject("VITE_APP_TITLE") }}</p>
</div>
<div>
</div>
<div></div>
<!-- <div>
<h3 class="text-lg font-medium mb-4">关注我们</h3>
<div class="flex space-x-4">
<el-icon class="text-2xl"><Message /></el-icon>
<el-icon class="text-2xl"><Share /></el-icon>
<el-icon class="text-2xl"><Link /></el-icon>
</div>
</div> -->
</div>
<div class="mt-4 pt-2 pb-5 border-t border-gray-700 text-center">
<p>Copyright © 2025 {{ inject("VITE_APP_TITLE") }} 版权所有</p>
<div class="mt-2 pt-1 pb-3 border-t border-gray-700 text-center">
<p class="text-white text-[12px] font-[600]">Copyright © {{ inject("VITE_APP_TITLE") }} @版权所有</p>
<!-- <p class="mt-2">晋ICP备12345678号-1 | 晋公网安备 14010002000001号</p> -->
</div>
</div>
......
<template>
<div class="bg-gray-50">
<div class="bg-container">
<!-- 顶部横幅 -->
<header class="bg-white shadow">
<div class="container mx-auto px-0 h-20 flex items-center">
<img src="@/assets/logo1.png" alt="国徽" class="h-10 mr-4" />
<div class="flex-1 flex items-center justify-between">
<h1 class="text-2xl font-bold text-black">
{{ inject("VITE_APP_TITLE") }}
</h1>
<div class="flex relative w-[360px] gap-4">
<el-input
v-model="searchQuery"
class="!rounded-full"
placeholder="搜索新闻、通知..."
:prefix-icon="Search"
@keyup.enter="handleSearch"
/>
<button
class="flex items-center px-4 py-[9px] bg-blue-500 cursor-pointer text-white rounded-[10px] hover:bg-blue-600 transition-colors whitespace-nowrap"
style="border: none"
@click="handleSearch"
>
<el-icon class="mr-1"><Search /></el-icon>
<span>搜索</span>
</button>
<header class="shadow">
<div class="container mx-auto flex items-center" style="height:180px;width: 1440px;">
<img src="@/assets/logo1.png" alt="国徽" class="h-[100px] mr-6" />
<div>
<div class="text-title text-[45px] text-white mb-[-15px]">
太原市互联网应急指挥和举报中心
</div>
<div class="text-title text-[45px] text-white">
(太原市互联网宣传研究中心)
</div>
</div>
</div>
</header>
<!-- 主导航 -->
<nav class="bg-blue-800 text-white">
<div class="container mx-auto px-4">
<ul class="flex space-x-8 h-14">
<li
v-for="(item, index) in navItems"
:key="index"
class="flex items-center cursor-pointer hover:bg-blue-700 px-4"
:class="{ 'bg-blue-700': activeNav === index }"
@click="navigateTo(index, item)"
>
<span class="text-white">{{ item.categoryTitle }}</span>
</li>
</ul>
<nav class="text-white">
<div class="container mx-auto px-[30px]">
<div class="flex items-center justify-between h-[65px]">
<!-- 主导航菜单 -->
<ul class="flex justify-between w-full max-w-[calc(100%-320px)] h-14">
<li v-for="(item, index) in navItems" :key="index"
class="flex-1 flex items-center justify-center cursor-pointer px-4 relative transform transition-all duration-300 hover:scale-105 hover:-translate-y-2 shadow-lg hover:shadow-xl"
@click="navigateTo(index, item)">
<span class="text-white font-bold text-[20px]">{{ item.categoryTitle }}</span>
<!-- 点击在对应的选中下划线 -->
<div
class="absolute bottom-2 left-1/2 transform -translate-x-1/2 w-[30px] h-[3px] bg-white transition-all duration-300 rounded-[10px]"
:class="{ 'opacity-100': activeNav === index, 'opacity-0': activeNav !== index }">
</div>
</li>
</ul>
<!-- 搜索框 -->
<div class="flex relative w-[240px] mr-[50px]">
<el-input v-model="searchQuery" class="!rounded-full" placeholder="搜索新闻、通知..." :prefix-icon="Search"
@keyup.enter="handleSearch">
<template #append>
<el-icon class="mr-1 text-blue-400 hover:text-blue-600 cursor-pointer" style="color: #2E5BF6;"
@click="handleSearch">
<Search />
</el-icon>
</template>
</el-input>
</div>
</div>
</div>
</nav>
<router-view></router-view>
<Footer></Footer>
<!-- 页脚 -->
<!-- <footer class="bg-gray-800 text-gray-300 mt-10">
<div class="container mx-auto px-4 py-10 w-[1440px]">
<div class="grid grid-cols-2 gap-8">
<div>
<h3 class="text-lg font-medium mb-4">联系我们</h3>
<div class="space-y-2">
<p>地址:山西省太原市迎泽区迎泽大街 369 号</p>
<p>电话:0351-12345678</p>
<p>邮箱:te@tynet.gov.cn</p>
</div>
</div>
<div>
<h3 class="text-lg font-medium mb-4">关注我们</h3>
<div class="flex space-x-4">
<el-icon class="text-2xl"><Message /></el-icon>
<el-icon class="text-2xl"><Share /></el-icon>
<el-icon class="text-2xl"><Link /></el-icon>
</div>
</div> -->
<!-- </div>
<div class="mt-8 pt-8 border-t border-gray-700 text-center">
<p>Copyright © 2024 太原市互联网应急指挥和举报中心 版权所有</p>
<p class="mt-2">晋ICP备12345678号-1 | 晋公网安备 14010002000001号</p>
</div>
</div>
</footer> -->
</div>
</template>
<script setup lang="ts">
import { ref, watch, inject } from "vue";
import { useRouter, useRoute } from "vue-router";
import { Message, Share, Link, Search } from "@element-plus/icons-vue";
// @ts-ignore
import { getTab } from "@/api/home/home";
// @ts-ignore
import { HLW_YJZH_JBZX } from "@/utils/config";
import { ElMessage } from "element-plus";
import Footer from "@/components/footer.vue";
......@@ -124,17 +100,50 @@ function navigateTo(index: number, item: any) {
// { path: "/home/sxnews", query: { id: item.id } },
// { path: "/home/announcements", query: { id: item.id } },
// ];
// if (index == 0) {
// router.push({
// path: "/home/home",
// query: { categoryId: item.id, categoryTitle: item.categoryTitle },
// });
// } else {
// router.push({
// path: "/home/news",
// query: { categoryId: item.id, categoryTitle: item.categoryTitle },
// });
// }
if (index == 0) {
router.push({
path: "/home/home",
query: { categoryId: item.id, categoryTitle: item.categoryTitle },
});
} else {
} else if (index == 1) {
// 通知公告
router.push({
path: "/home/news",
query: { categoryId: item.id, categoryTitle: item.categoryTitle },
});
} else if (index == 2) {
//举报专区
router.push({
path: "/home/jb",
query: { categoryId: item.id, categoryTitle: item.categoryTitle },
});
} else if (index == 3) {
//辟谣平台 -router跳转新标签页/py/pyhome
const routeUrl = router.resolve({
path: "/py/pyhome",
query: { categoryId: item.id, categoryTitle: item.categoryTitle },
});
window.open(routeUrl.href, '_blank');
} else if (index == 4) {
const routeUrl = router.resolve({
path: "/wm/wmhome",
query: { categoryId: item.id, categoryTitle: item.categoryTitle },
});
window.open(routeUrl.href, '_blank');
}
activeNav.value = index;
}
......@@ -142,15 +151,14 @@ const data = {
categoryFlag: HLW_YJZH_JBZX,
};
getTab(data).then((res) => {
getTab(data).then((res: any) => {
console.log(res);
const data: any[] = res.data.rows;
// //用data内的categorySort排序
data.sort((a, b) => a.categorySort - b.categorySort);
//将data内categoryTitle等于“轮播图”的数据过滤不在navItems.value中显示
//将data内id等于“1876561611942682626”的数据过滤不在navItems.value中显示(轮播图和后台设置的不显示标签的新闻分类)
data.unshift({ categoryTitle: "首页", categoryId: "999" });
const filterData = data.filter((item) => item.categoryTitle !== "轮播图");
const filterData = data.filter((item) => item.categoryDisplay !== "disable");
navItems.value = filterData;
setNactiveNav(navItems.value);
});
......@@ -170,10 +178,18 @@ function handleSearch() {
}
</script>
<style scoped>
.text-title {
font-family: 'AlibabaPuHuiTi95';
}
.line-clamp-2 {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.bg-container {
background: url('@/assets/imgs/bg_header.jpg');
}
</style>
......@@ -2,31 +2,44 @@
<template>
<div class="mx-auto">
<header class="hero-bg text-white">
<div class="container mx-auto px-8 py-4">
<div class="container mx-auto px-8 py-8">
<div class="flex items-center justify-between">
<div class="flex items-center space-x-4">
<h1 class="text-2xl font-bold cursor-pointer" @click="goToHome()">
<h1 class="text-title font-bold cursor-pointer text-[49px]" @click="goToHome()">
太原市互联网联合辟谣平台
</h1>
<!-- <p class="text-[14px] opacity-90 cursor-pointer font-bold" @click="goToHome()">
主办:{{ inject("VITE_APP_TITLE") }}
</p> -->
<!-- <p class="text-sm opacity-80">主办:山西省互联网信息办公室</p> -->
</div>
<p class="text-sm opacity-80 cursor-pointer" @click="goToHome()">
<!-- <p class="text-[14px] opacity-90 cursor-pointer font-bold" @click="goToHome()">
主办:{{ inject("VITE_APP_TITLE") }}
</p>
</p> -->
<!-- <div class="text-sm opacity-80">承办:黄河新闻网</div> -->
</div>
<p class="text-[16px] opacity-90 cursor-pointer font-bold mt-0" @click="goToHome()">
主办:{{ inject("VITE_APP_TITLE") }}
</p>
</div>
<nav class="bg-white/10 backdrop-blur-sm">
<div class="container mx-auto px-8">
<div class="flex justify-between items-center">
<div
v-for="(item, index) in navItems"
:key="index"
class="py-4 px-6 cursor-pointer hover:bg-white/10 transition-colors"
:class="{ 'bg-white/10': activeIndex === index }"
@click="navigateTo(index, item)"
>
<span class="text-white">{{ item.categoryTitle }}</span>
<div v-for="(item, index) in navItems" :key="index"
class="py-4 px-6 cursor-pointer hover:bg-white/10 transition-colors transform transition-all duration-300 hover:scale-105 hover:-translate-y-2 shadow-lg hover:shadow-xl"
:class="{ 'bg-white/10': activeIndex === index }" @click="navigateTo(index, item)">
<span class="text-white text-[16px] font-bold">{{ item.categoryTitle }}</span>
</div>
<div class="flex relative w-[240px] mr-[50px]">
<el-input v-model="searchQuery" class="!rounded-full" placeholder="搜索辟谣、权威、法律、专家..." :prefix-icon="Search"
@keyup.enter="handleSearch">
<template #append>
<el-icon class="mr-1 text-blue-400 hover:text-blue-600 cursor-pointer" style="color: #2E5BF6;"
@click="handleSearch">
<Search />
</el-icon>
</template>
</el-input>
</div>
</div>
</div>
......@@ -55,6 +68,7 @@ import { Swiper, SwiperSlide } from "swiper/vue";
import { Pagination, Navigation, Autoplay } from "swiper/modules";
import { useRouter, useRoute } from "vue-router";
import Footer from "@/components/footer.vue";
import { ElMessage } from "element-plus";
import {
Document,
......@@ -64,15 +78,49 @@ import {
Service,
Bell,
Collection,
Search,
} from "@element-plus/icons-vue";
import { HLW_LH_PYPT } from "@/utils/config";
import { getTab } from "@/api/home/home";
import { log } from "console";
// 定义导航项接口
interface NavItem {
categoryTitle: string;
categoryId: string;
id?: string;
categorySort?: number;
}
// 定义API响应接口
interface ApiResponse {
data: {
rows: NavItem[];
};
}
const activeIndex = ref(0);
const router = useRouter();
const route = useRoute();
const navItems = ref([]);
const navItems = ref<NavItem[]>([]);
const searchQuery = ref("");
function handleSearch() {
// 搜索功能逻辑
console.log("搜索内容:", searchQuery.value);
// 可以在这里添加路由跳转或API调用等搜索逻辑
if (searchQuery.value) {
router.push({
path: "/py/search",
query: { searchQuery: searchQuery.value },
});
} else {
ElMessage({
message: "请输入搜索内容",
type: "warning",
});
}
}
//activeNav 监听
watch(
......@@ -82,9 +130,9 @@ watch(
}
);
function setNactiveNav(navItem?: any) {
function setNactiveNav(navItem?: NavItem[]) {
navItem = navItem || navItems.value;
navItem.forEach((item: any, index: number) => {
navItem.forEach((item: NavItem, index: number) => {
console.log(item.categoryId);
if (item.id == route.query.categoryId) {
activeIndex.value = index;
......@@ -103,21 +151,21 @@ const data = {
categoryFlag: HLW_LH_PYPT,
};
getTab(data).then((res) => {
getTab(data).then((res: ApiResponse) => {
console.log(res);
const data = res.data.rows;
// //用data内的categorySort排序
data.sort((a, b) => a.categorySort - b.categorySort);
// 用data内的categorySort排序
data.sort((a: NavItem, b: NavItem) => (a.categorySort || 0) - (b.categorySort || 0));
data.unshift({ categoryTitle: "首页", categoryId: "999" });
//将data内categoryTitle等于“权威发布”和“辟谣专区”和“轮播图”的数据过滤不在navItems.value中显示
// 将data内categoryTitle等于“轮播图”的数据过滤不在navItems.value中显示
const filterData = data
.filter(
(item) =>
(item: NavItem) =>
item.categoryTitle !== "轮播图" &&
item.categoryTitle !== "山西互联网联合辟谣平台"
)
.map((item) => {
.map((item: NavItem) => {
item.categoryId = item.categoryId.toString();
return item;
});
......@@ -133,16 +181,7 @@ getTab(data).then((res) => {
}
});
function navigateTo(index: number, item: any) {
// const routes = [
// { path: "/py/pyhome" },
// { path: "/py/authority" },
// { path: "/py/rumor" },
// { path: "/py/expert" },
// { path: "/py/law" },
// { path: "/py/reading" },
// ];
// router.push(routes[index].path).catch((err) => {});
function navigateTo(index: number, item: NavItem) {
if (index == 0) {
router.push({
path: "/py/pyhome",
......@@ -159,32 +198,41 @@ function navigateTo(index: number, item: any) {
</script>
<style scoped>
.hero-bg {
background: linear-gradient(135deg, #001f3f, #0047ab);
/* background: linear-gradient(135deg, #001f3f, #0047ab); */
background: url("@/assets/imgs/py-hearder-bg.png");
}
:deep(.el-card) {
border: 1px solid rgba(0, 31, 63, 0.1);
transition: all 0.3s ease;
}
:deep(.el-scrollbar__wrap) {
overflow-x: hidden;
}
:deep(.el-card.is-hover-shadow:hover) {
box-shadow: 0 8px 16px rgba(0, 31, 63, 0.12);
transform: translateY(-2px);
}
:deep(.el-card.is-hover-shadow) {
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
:deep(.el-card:hover) {
border-color: rgba(0, 31, 63, 0.3);
box-shadow: 0 12px 28px rgba(0, 31, 63, 0.15);
}
:deep(.el-card__body) {
padding: 16px;
}
:deep(.el-link.el-link--default:hover) {
color: #0047ab;
}
:deep(.service-swiper .swiper-button-prev),
:deep(.service-swiper .swiper-button-next) {
background-color: rgba(255, 255, 255, 0.9);
......@@ -194,17 +242,25 @@ function navigateTo(index: number, item: any) {
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
color: #001f3f;
}
:deep(.service-swiper .swiper-button-prev:after),
:deep(.service-swiper .swiper-button-next:after) {
font-size: 16px;
}
:deep(.service-swiper .swiper-button-prev) {
left: -20px;
}
:deep(.service-swiper .swiper-button-next) {
right: -20px;
}
:deep(.service-swiper .swiper-button-disabled) {
opacity: 0;
}
.text-title {
font-family: 'AlibabaPuHuiTi95';
}
</style>
......@@ -3,73 +3,61 @@
<div class="min-h-screen bg-gray-100">
<div class="mx-auto">
<!-- Hero区域 -->
<div class="relative h-[330px] mb-8 overflow-hidden">
<div class="relative h-[350px] mb-8 overflow-hidden">
<div class="absolute inset-0">
<img
<!-- <img
src="https://ai-public.mastergo.com/ai/img_res/b69747ed7038cf3b7a5da874d0fed0ab.jpg"
class="w-full h-full object-cover object-top"
alt="banner"
/>
/> -->
<img :src="wmyhsHeaderBg" class="w-full h-full object-cover object-top" />
<div
class="absolute inset-0 bg-gradient-to-r from-blue-900/90 via-blue-900/70 to-transparent"
></div>
<div class="absolute inset-0 bg-gradient-to-r from-blue-900/80 via-blue-900/30 to-transparent"></div>
</div>
<div
class="backdrop-blur-sm rounded-lg cursor-pointer flex justify-end items-end w-auto top-0 right-0"
@click="goToHome()"
>
<p class="text-white font-bold pt-3 pr-5">
<div class="backdrop-blur-sm rounded-lg cursor-pointer flex justify-end items-end w-auto top-0 right-0"
@click="goToHome()">
<p class="text-white font-bold pt-5 pr-5 text-[20px]">
主办:{{ inject("VITE_APP_TITLE") }}
</p>
</div>
<div class="relative flex-col justify-center h-full px-12 ms-24 mt-8">
<!-- 顶部区域 -->
<div class="mb-10">
<h2
@click="goToHome()"
class="text-5xl font-bold text-white max-w-xl leading-tight cursor-pointer"
>
<div class="mb-5">
<h2 @click="goToHome()" class="text-6xl font-bold text-white cursor-pointer">
网民
<span
class="text-6xl"
style="font-family: 'STXingkai', 'KaiTi', cursive"
>有话说</span
>
<span class="text-7xl" style="font-family: 'STXingkai', 'KaiTi', cursive">有话说</span>
</h2>
</div>
<p class="text-xl text-gray-200 max-w-xl mb-6">
<p class="text-xl text-gray-200 mb-6">
用真诚的态度和专业的服务,构建政民互动的新平台
</p>
<div class="flex items-center gap-4">
<el-input
v-model="searchQuery"
placeholder="搜索您关注的问题..."
class="!w-[360px] custom-input"
@keyup.enter="handleSearch"
>
<el-input v-model="searchQuery" placeholder="搜索您关注的问题..." class="!w-[360px] custom-input"
@keyup.enter="handleSearch">
<template #prefix>
<el-icon><Search /></el-icon>
<el-icon>
<Search />
</el-icon>
</template>
</el-input>
<button
class="flex items-center px-4 py-[9px] bg-blue-500 text-white rounded-[10px] hover:bg-blue-600 transition-colors whitespace-nowrap"
style="border: none"
@click="handleSearch"
>
<el-icon class="mr-1"><Search /></el-icon>
style="border: none" @click="handleSearch">
<el-icon class="mr-1">
<Search />
</el-icon>
<span>搜索</span>
</button>
<button
@click="iMessageClick"
<button @click="iMessageClick"
class="flex items-center px-6 py-[9px] bg-white text-blue-800 rounded-[10px] hover:bg-blue-50 transition-colors !rounded-button whitespace-nowrap"
style="border: none"
>
style="border: none">
<span>我要留言</span>
<el-icon class="ml-1"><ArrowRight /></el-icon>
<el-icon class="ml-1">
<ArrowRight />
</el-icon>
</button>
</div>
</div>
......@@ -138,6 +126,8 @@ import {
import { useRouter } from "vue-router";
import { ElMessage } from "element-plus";
import Footer from "@/components/footer.vue";
// 引入背景图片
import wmyhsHeaderBg from "@/assets/imgs/wmyhs-header-bg.jpg";
const router = useRouter();
......@@ -187,14 +177,17 @@ function handleSearch() {
box-shadow: none;
border: none;
}
.custom-select :deep(.el-input__wrapper) {
background-color: rgba(255, 255, 255, 0.9);
box-shadow: none;
border: none;
}
.custom-input :deep(.el-input__inner) {
height: 42px;
}
.custom-select :deep(.el-input__inner) {
height: 42px;
}
......
......@@ -20,6 +20,7 @@ import Expert from "../views/py/expert/Expert.vue";
import Law from "../views/py/law/Law.vue";
import Reading from "../views/py/reading/Reading.vue";
import PyNewsDetail from "../views/py/detail/NewsDetail.vue";
import SearchPYList from "../views/py/search/SearchList.vue";
//网名有话说
import WmLayout from "../layout/wm.vue";
......@@ -127,6 +128,11 @@ const router = createRouter({
path: "/py/news/detail",
component: PyNewsDetail,
},
{
name: "SearchPYList",
path: "/py/search",
component: SearchPYList,
},
],
},
......
<template>
<div class="min-h-screen bg-gray-50">
<!-- 轮播图 -->
<div class="container mx-auto px-4 mt-5 w-[1440px]">
<swiper
:modules="swiperModules"
:slides-per-view="1"
:loop="true"
:pagination="{ clickable: true, disableOnInteraction: false }"
:autoplay="{ delay: 3000 }"
class="h-[350px] rounded-lg overflow-hidden"
>
<div class="container mx-auto px-4 pt-5 w-[1440px]">
<swiper :modules="swiperModules" :slides-per-view="1" :loop="true" :pagination="{ clickable: true }"
:autoplay="{ delay: 3000 }" class="h-[390px] rounded-lg overflow-hidden">
<swiper-slide v-for="(slide, index) in slides" :key="index">
<div class="relative w-full h-full">
<img
:src="slide.images"
class="w-full h-full object-cover"
@click="goToDetail(slide)"
/>
<div
class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/70 to-transparent p-6"
>
<img :src="slide.images" class="w-full h-full object-cover" @click="goToDetail(slide)" />
<div class="absolute bottom-0 left-0 right-0 bg-gradient-to-t from-black/70 to-transparent p-6">
<h3 class="text-white text-xl font-medium">
{{ slide.contentTitle }}
</h3>
......@@ -31,28 +19,24 @@
<!-- 快捷入口 -->
<div class="container mx-auto px-4 mt-5 w-[1440px]">
<div class="grid grid-cols-3 gap-5">
<div
v-for="(entry, index) in quickEntries"
:key="index"
class="relative h-48 rounded-xl overflow-hidden group cursor-pointer transform transition-all duration-300 hover:scale-105 hover:-translate-y-1 shadow-lg hover:shadow-xl"
@click="handleClick(index, entry)"
>
<img
:src="entry.bg"
:alt="entry.title"
class="w-full h-full object-cover"
/>
<div
class="absolute inset-0 bg-gradient-to-br from-black/60 via-black/40 to-transparent backdrop-blur-[2px] group-hover:backdrop-blur-[4px] transition-all"
>
<div
class="h-full flex flex-col items-center justify-center text-white"
>
<el-icon
class="text-5xl mb-4 transform transition-transform duration-300 group-hover:scale-110"
><component :is="entry.icon"
/></el-icon>
<span class="text-xl font-semibold text-center px-6">{{
<div v-for="(entry, index) in quickEntries" :key="index"
class="relative h-[160px] rounded-xl overflow-hidden group cursor-pointer transform transition-all duration-300 hover:scale-105 hover:-translate-y-1 shadow-lg hover:shadow-xl"
@click="handleClick(index, entry)">
<img :src="entry.bg" :alt="entry.title"
class="w-full h-full object-cover transition-all duration-300 group-hover:scale-110" />
<div class="absolute inset-0 bg-gradient-to-br group-hover:backdrop-blur-[1px] transition-all">
<div class="h-full flex flex-col text-white"
:class="index == 0 ? 'items-start justify-center pl-8' : 'items-center justify-center'">
<!-- <el-icon class="text-5xl mb-4 transform transition-transform duration-300 group-hover:scale-110">
<component :is="entry.icon" />
</el-icon> -->
<span v-if="index == 0" class="text-4xl font-semibold px-6">{{
entry.title
}}</span>
<span v-else-if="index == 1" class="text-4xl font-semibold text-center px-6">{{
entry.title
}}</span>
<span v-else-if="index == 2" class="text-4xl font-semibold text-center px-6">{{
entry.title
}}</span>
</div>
......@@ -63,43 +47,23 @@
<!-- 新闻内容区 -->
<div class="container mx-auto px-4 mt-5 grid grid-cols-3 gap-5 w-[1440px]">
<!-- 最新新闻 -->
<div
class="col-span-2 bg-white rounded-lg p-6 shadow-[0_0_10px_rgba(5,157,254,0.32)]"
>
<div class="col-span-2 bg-white rounded-lg p-6 shadow-[0_0_10px_rgba(5,157,254,0.32)]">
<div class="flex justify-between items-center mb-4">
<h2 class="text-xl font-bold" style="color: #000">太原新闻</h2>
<el-button
v-if="tyNews.length > 0"
type="primary"
class="!rounded-button"
text
@click="goToTyMoreList(1)"
>更多</el-button
>
<div class="relative">
<h2 class="text-xl font-bold" style="color: #2f7ef6">太原新闻</h2>
<div class="w-[50px] h-[3px] bg-blue-500 rounded-full mt-1"></div>
</div>
<el-button v-if="tyNews.length > 0" type="primary" class="!rounded-button" text
@click="goToTyMoreList(1)">更多</el-button>
</div>
<div class="space-y-4">
<div
v-for="(item, index) in tyNews"
:key="index"
class="flex items-start space-x-4 pb-1 border-b last:border-0"
@click="goToDetail(item)"
>
<img
v-if="item.images != null"
:src="item.images"
class="w-32 h-24 object-cover rounded"
/>
<div v-for="(item, index) in tyNews" :key="index"
class="flex items-start space-x-4 pb-1 border-b last:border-0" @click="goToDetail(item)">
<img v-if="item.images != null" :src="item.images" class="w-32 h-24 object-cover rounded" />
<div>
<el-tooltip
popper-class="tooltip-width"
effect="dark"
:content="item.contentTitle"
placement="top-start"
>
<h3
class="text-lg font-medium mb-2 hover:text-blue-600 cursor-pointer text-black line-clamp-1"
>
<el-tooltip popper-class="tooltip-width" effect="dark" :content="item.contentTitle" placement="top-start">
<h3 class="text-lg font-medium mb-2 hover:text-blue-600 cursor-pointer text-black line-clamp-1">
{{ item.contentTitle }}
</h3>
</el-tooltip>
......@@ -109,12 +73,16 @@
</p>
<div class="mt-1 flex items-center space-x-4">
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1"><Clock /></el-icon>
<el-icon class="mr-1">
<Clock />
</el-icon>
{{ item.contentDatetime }}
</span>
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1"><View /></el-icon>
<el-icon class="mr-1">
<View />
</el-icon>
{{ item.contentHit }} 阅读
</span>
</div>
......@@ -125,37 +93,23 @@
<!-- 侧边栏 -->
<div class="space-y-6">
<!-- 热门新闻 -->
<div
class="bg-white rounded-lg p-5 shadow-[0_0_10px_rgba(5,157,254,0.32)]"
>
<div class="bg-white rounded-lg p-5 shadow-[0_0_10px_rgba(5,157,254,0.32)]">
<div class="flex justify-between items-center mb-4">
<h2 class="text-xl font-bold" style="color: #000">热门新闻</h2>
<el-button
v-if="hotNews.length > 0"
type="primary"
class="!rounded-button"
text
@click="goToTyMoreList(2)"
>更多</el-button
>
<div class="relative">
<h2 class="text-xl font-bold" style="color: #2f7ef6">热门新闻</h2>
<div class="w-[50px] h-[3px] bg-blue-500 rounded-full mt-1"></div>
</div>
<!-- <h2 class="text-xl font-bold" style="color: #2f7ef6">热门新闻</h2> -->
<el-button v-if="hotNews.length > 0" type="primary" class="!rounded-button" text
@click="goToTyMoreList(2)">更多</el-button>
</div>
<div class="space-y-1">
<div
v-for="(hot, index) in hotNews"
:key="index"
class="border-b last:border-0 pb-4"
@click="goToDetail(hot)"
>
<div v-for="(hot, index) in hotNews" :key="index" class="border-b last:border-0 pb-4"
@click="goToDetail(hot)">
<div>
<el-tooltip
popper-class="tooltip-width"
effect="dark"
:content="hot.contentTitle"
placement="top-start"
>
<h3
class="text-lg font-medium mb-2 hover:text-blue-600 cursor-pointer text-black line-clamp-1"
>
<el-tooltip popper-class="tooltip-width" effect="dark" :content="hot.contentTitle"
placement="top-start">
<h3 class="text-lg font-medium mb-2 hover:text-blue-600 cursor-pointer text-black line-clamp-1">
{{ hot.contentTitle }}
</h3>
</el-tooltip>
......@@ -165,12 +119,16 @@
</p>
<div class="mt-1 flex items-center space-x-4">
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1"><Clock /></el-icon>
<el-icon class="mr-1">
<Clock />
</el-icon>
{{ hot.contentDatetime }}
</span>
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1"><View /></el-icon>
<el-icon class="mr-1">
<View />
</el-icon>
{{ hot.contentHit }} 阅读
</span>
</div>
......@@ -179,75 +137,48 @@
</div>
</div>
<!-- 视频新闻 -->
<div
class="bg-white rounded-lg p-6 shadow-[0_0_10px_rgba(5,157,254,0.32)]"
v-if="0"
>
<!-- <div class="bg-white rounded-lg p-6 shadow-[0_0_10px_rgba(5,157,254,0.32)]" v-if="0">
<h2 class="text-xl font-bold mb-4 text-black">视频新闻</h2>
<div class="space-y-4">
<div
v-for="(video, index) in videoNews"
:key="index"
class="group cursor-pointer"
>
<div v-for="(video, index) in videoNews" :key="index" class="group cursor-pointer">
<div class="relative">
<img
:src="video.cover"
:alt="video.title"
class="w-full h-32 object-cover rounded"
/>
<div
class="absolute inset-0 bg-black/30 group-hover:bg-black/50 flex items-center justify-center"
>
<el-icon class="text-white text-4xl"><VideoPlay /></el-icon>
<img :src="video.cover" :alt="video.title" class="w-full h-32 object-cover rounded" />
<div class="absolute inset-0 bg-black/30 group-hover:bg-black/50 flex items-center justify-center">
<el-icon class="text-white text-4xl">
<VideoPlay />
</el-icon>
</div>
</div>
<h3
class="mt-2 text-base font-medium group-hover:text-blue-600 text-black line-clamp-2"
>
<h3 class="mt-2 text-base font-medium group-hover:text-blue-600 text-black line-clamp-2">
{{ video.title }}
</h3>
</div>
</div>
</div>
</div> -->
</div>
</div>
<!-- 权威发布与辟谣专区 -->
<div class="container mx-auto px-4 mt-5 w-[1440px]">
<div class="grid grid-cols-2 gap-5">
<!-- 权威发布 -->
<div
class="bg-white rounded-lg p-6 shadow-[0_0_10px_rgba(5,157,254,0.32)]"
>
<div class="bg-white rounded-lg p-6 shadow-[0_0_10px_rgba(5,157,254,0.32)]">
<div class="flex justify-between items-center mb-4">
<h2 class="text-xl font-bold text-black">权威发布</h2>
<el-button
v-if="authoritativeNews.length > 0"
type="primary"
class="!rounded-button"
text
@click="goToTyMoreList(3)"
>更多</el-button
>
<!-- <h2 class="text-xl font-bold" style="color: #2f7ef6">权威发布</h2> -->
<div class="relative">
<h2 class="text-xl font-bold" style="color: #2f7ef6">权威发布</h2>
<div class="w-[50px] h-[3px] bg-blue-500 rounded-full mt-1"></div>
</div>
<el-button v-if="authoritativeNews.length > 0" type="primary" class="!rounded-button" text
@click="goToTyMoreList(3)">更多</el-button>
</div>
<div class="space-y-4">
<div
v-for="(item, index) in authoritativeNews"
:key="index"
class="flex items-center space-x-3 pb-3 border-b last:border-b-0"
@click="goToDetail(item)"
>
<div v-for="(item, index) in authoritativeNews" :key="index"
class="flex items-center space-x-3 pb-3 border-b last:border-b-0" @click="goToDetail(item)">
<!-- <el-icon class="text-blue-600 text-xl"><Document /></el-icon> -->
<div>
<el-tooltip
popper-class="tooltip-width"
effect="dark"
:content="item.contentTitle"
placement="top-start"
>
<h3
class="text-lg font-medium mb-2 hover:text-blue-600 cursor-pointer text-black line-clamp-1"
>
<el-tooltip popper-class="tooltip-width" effect="dark" :content="item.contentTitle"
placement="top-start">
<h3 class="text-lg font-medium mb-2 hover:text-blue-600 cursor-pointer text-black line-clamp-1">
{{ item.contentTitle }}
</h3>
</el-tooltip>
......@@ -257,12 +188,16 @@
</p>
<div class="mt-1 flex items-center space-x-4">
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1"><Clock /></el-icon>
<el-icon class="mr-1">
<Clock />
</el-icon>
{{ item.contentDatetime }}
</span>
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1"><View /></el-icon>
<el-icon class="mr-1">
<View />
</el-icon>
{{ item.contentHit }} 阅读
</span>
</div>
......@@ -271,47 +206,28 @@
</div>
</div>
<!-- 辟谣专区 -->
<div
class="bg-white rounded-lg p-6 shadow-[0_0_10px_rgba(5,157,254,0.32)]"
>
<div class="bg-white rounded-lg p-6 shadow-[0_0_10px_rgba(5,157,254,0.32)]">
<div class="flex justify-between items-center mb-4">
<h2 class="text-xl font-bold text-black">辟谣专区</h2>
<el-button
v-if="rumourNews.length > 0"
type="primary"
class="!rounded-button"
text
@click="goToTyMoreList(4)"
>更多</el-button
>
<!-- <h2 class="text-xl font-bold" style="color: #2f7ef6">辟谣专区</h2> -->
<div class="relative">
<h2 class="text-xl font-bold" style="color: #2f7ef6">辟谣专区</h2>
<div class="w-[50px] h-[3px] bg-blue-500 rounded-full mt-1"></div>
</div>
<el-button v-if="rumourNews.length > 0" type="primary" class="!rounded-button" text
@click="goToTyMoreList(4)">更多</el-button>
</div>
<div class="space-y-4">
<div
v-for="(item, index) in rumourNews"
:key="index"
class="flex items-start space-x-3 pb-4 border-b last:border-b-0"
@click="goToDetail(item)"
>
<div v-for="(item, index) in rumourNews" :key="index"
class="flex items-start space-x-3 pb-4 border-b last:border-b-0" @click="goToDetail(item)">
<div v-if="item.images != null" class="flex-shrink-0 w-24 h-16">
<img
:src="item.images"
class="w-full h-full object-cover rounded"
/>
<img :src="item.images" class="w-full h-full object-cover rounded" />
</div>
<div class="flex-1">
<div class="flex items-center space-x-2">
<el-tag size="small" type="danger" class="!rounded-full"
>辟谣</el-tag
>
<el-tooltip
popper-class="tooltip-width"
effect="dark"
:content="item.contentTitle"
placement="top-start"
>
<h3
class="text-base font-medium hover:text-blue-600 cursor-pointer text-black line-clamp-1"
>
<el-tag size="small" type="danger" class="!rounded-full">辟谣</el-tag>
<el-tooltip popper-class="tooltip-width" effect="dark" :content="item.contentTitle"
placement="top-start">
<h3 class="text-base font-medium hover:text-blue-600 cursor-pointer text-black line-clamp-1">
{{ item.contentTitle }}
</h3>
</el-tooltip>
......@@ -322,12 +238,16 @@
<div class="mt-1 flex items-center space-x-4">
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1"><Clock /></el-icon>
<el-icon class="mr-1">
<Clock />
</el-icon>
{{ item.contentDatetime }}
</span>
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1"><View /></el-icon>
<el-icon class="mr-1">
<View />
</el-icon>
{{ item.contentHit }} 阅读
</span>
</div>
......@@ -338,19 +258,17 @@
</div>
</div>
<!-- 友情链接 -->
<div class="container mx-auto px-4 mt-5 mb-5 w-[1440px]">
<div
class="bg-white rounded-lg p-6 shadow-[0_0_10px_rgba(5,157,254,0.32)]"
>
<h2 class="text-xl font-bold mb-4 text-black">友情链接</h2>
<div class="grid grid-cols-6 gap-4">
<a
v-for="(link, index) in friendLinks"
:key="index"
:href="link.webLinkUrl"
target="_blank"
class="text-gray-600 hover:text-blue-600 text-center"
>
<div class="container mx-auto px-4 pt-5 pb-5 w-[1440px]">
<div class="bg-white rounded-lg p-6 shadow-[0_0_10px_rgba(5,157,254,0.32)]">
<!-- <h2 class="text-xl font-bold mb-4" style="color: #2f7ef6">友情链接</h2> -->
<div class="relative mb-4">
<div class="title report-orgs"><span>友情链接</span></div>
<!-- <h2 class="text-xl font-bold" style="color: #2f7ef6">友情链接</h2> -->
<!-- <div class="w-[50px] h-[3px] bg-blue-500 rounded-full mt-1"></div> -->
</div>
<div class="grid grid-cols-6 gap-3">
<a v-for="(link, index) in friendLinks" :key="index" :href="link.webLinkUrl" target="_blank"
class="text-gray-900 hover:text-white hover:bg-[#2f7ef6] text-center bg-white p-2 rounded-md shadow-[0_0_10px_rgba(5,157,254,0.22)] hover:scale-105 hover:-translate-y-1 shadow-lg hover:shadow-xl">
{{ link.name }}
</a>
</div>
......@@ -359,6 +277,7 @@
</div>
</template>
<script lang="ts" setup>
// @ts-ignore
import { ref } from "vue";
import { Swiper, SwiperSlide } from "swiper/vue";
import { Pagination, Autoplay } from "swiper/modules";
......@@ -382,9 +301,12 @@ import "swiper/css";
import "swiper/css/pagination";
import "swiper/css/autoplay";
import "swiper/css/navigation";
// @ts-ignore
import { getLink } from "@/api/home/home";
// @ts-ignore
import { getNewsList } from "@/api/home/news/list";
// @ts-ignore
import {
baseImageUrl,
rdxw,
......@@ -395,13 +317,42 @@ import {
pyzq,
qwfb,
} from "@/utils/config";
import PyNewsList from "@/components/news/PyNewsList.vue";
import jbzqBg from "@/assets/imgs/jbzq-bg.png";
import pyptBg from "@/assets/imgs/pypt-bg.png";
import wmyhsBg from "@/assets/imgs/wmyhs-bg.png";
// Define interfaces for data structures
interface NewsItem {
id: string | number;
categoryId: string | number;
categoryTitle?: string;
contentTitle: string;
contentDescription: string;
contentDatetime: string;
contentHit: number;
contentImg?: string;
contentOutLink?: string;
images?: string;
}
interface LinkItem {
id: string | number;
webLinkUrl: string;
name: string;
}
interface QuickEntry {
title: string;
icon: string;
bg: string;
}
const router = useRouter();
const swiperModules = [Pagination, Autoplay];
const searchQuery = ref("");
const activeNav = ref(0);
const handleClick = (index: number, entry: any) => {
const handleClick = (index: number, entry: QuickEntry) => {
switch (index) {
case 0:
router.push({ path: "/home/jb" });
......@@ -417,10 +368,10 @@ const handleClick = (index: number, entry: any) => {
}
// 处理点击事件
};
const tyNews = ref([]);
const hotNews = ref([]);
const authoritativeNews = ref([]);
const rumourNews = ref([]);
const tyNews = ref<NewsItem[]>([]);
const hotNews = ref<NewsItem[]>([]);
const authoritativeNews = ref<NewsItem[]>([]);
const rumourNews = ref<NewsItem[]>([]);
getTyNewsList(5, 1);
......@@ -432,7 +383,7 @@ function getTyNewsList(pageSize: number, pageNo: number) {
pageSize: pageSize,
pageNo: pageNo,
};
getNewsList(datas).then((response) => {
getNewsList(datas).then((response: any) => {
const data = response.data;
const rowsList = data.rows;
rowsList.forEach((item: any) => {
......@@ -444,7 +395,7 @@ function getTyNewsList(pageSize: number, pageNo: number) {
});
}
function goToDetail(item: any) {
function goToDetail(item: NewsItem) {
if (item.contentOutLink) {
window.open(item.contentOutLink, "_blank");
} else {
......@@ -465,8 +416,8 @@ function goToTyMoreList(index: number) {
path: "/home/news",
query: {
categoryTitle: "太原新闻",
categoryId: tyNews != null ? tyNews.value[0].categoryId : "0",
activeNav: 0,
// categoryId: tyNews.value.length > 0 ? tyNews.value[0].categoryId : "0",
// activeNav: 0,
},
});
break;
......@@ -475,8 +426,8 @@ function goToTyMoreList(index: number) {
path: "/home/news",
query: {
categoryTitle: "热门新闻",
categoryId: tyNews != null ? hotNews.value[0].categoryId : "0",
activeNav: 1,
// categoryId: hotNews.value.length > 0 ? hotNews.value[0].categoryId : "0",
// activeNav: 1,
},
});
break;
......@@ -486,8 +437,7 @@ function goToTyMoreList(index: number) {
path: "/py/authority",
query: {
categoryTitle: "权威发布",
categoryId:
tyNews != null ? authoritativeNews.value[0].categoryId : "0",
categoryId: authoritativeNews.value.length > 0 ? authoritativeNews.value[0].categoryId : "0",
activeNav: 2,
},
});
......@@ -499,7 +449,7 @@ function goToTyMoreList(index: number) {
path: "/py/rumor",
query: {
categoryTitle: "辟谣专区",
categoryId: tyNews != null ? rumourNews.value[0].categoryId : "0",
categoryId: rumourNews.value.length > 0 ? rumourNews.value[0].categoryId : "0",
activeNav: 3,
},
});
......@@ -518,7 +468,7 @@ function getHotsNewsList(pageSize: number, pageNo: number) {
pageSize: pageSize,
pageNo: pageNo,
};
getNewsList(datas).then((response) => {
getNewsList(datas).then((response: any) => {
const data = response.data;
const rowsList = data.rows;
hotNews.value = rowsList;
......@@ -535,7 +485,7 @@ function getQwList(pageSize: number, pageNo: number) {
pageSize: pageSize,
pageNo: pageNo,
};
getNewsList(datas).then((response) => {
getNewsList(datas).then((response: any) => {
const data = response.data;
const rowsList = data.rows;
authoritativeNews.value = rowsList;
......@@ -552,7 +502,7 @@ function getPyList(pageSize: number, pageNo: number) {
pageSize: pageSize,
pageNo: pageNo,
};
getNewsList(datas).then((response) => {
getNewsList(datas).then((response: any) => {
const data = response.data;
const rowsList = data.rows;
rowsList.forEach((item: any) => {
......@@ -574,7 +524,7 @@ function getLbtList(pageSize: number, pageNo: number) {
pageSize: pageSize,
pageNo: pageNo,
};
getNewsList(datas).then((response) => {
getNewsList(datas).then((response: any) => {
const data = response.data;
const rowsList = data.rows;
rowsList.forEach((item: any) => {
......@@ -594,31 +544,38 @@ function getLinkLists() {
pageNo: 1,
pageSize: 10000,
};
getLink(page).then((response) => {
getLink(page).then((response: any) => {
const data = response.data;
const rowsList = data.rows;
friendLinks.value = rowsList;
});
}
const friendLinks = ref([]);
const slides = ref([]);
const friendLinks = ref<LinkItem[]>([]);
const slides = ref<NewsItem[]>([]);
const quickEntries = [
const quickEntries: QuickEntry[] = [
{
title: "太原市互联网违法和不良信息举报平台",
// title: "太原市互联网违法和不良信息举报平台",
title: "举报专区",
icon: "Share",
bg: "https://ai-public.mastergo.com/ai/img_res/e3d550fe8d11531c42a774641cf3790a.jpg",
// bg: "https://ai-public.mastergo.com/ai/img_res/e3d550fe8d11531c42a774641cf3790a.jpg",
bg: jbzqBg,
},
{
title: "网民有话说",
icon: "Link",
bg: "https://ai-public.mastergo.com/ai/img_res/c907287d38d89eb460120dc7cf6b2d17.jpg",
// title: "太原市互联网联合辟谣平台",
title: "辟谣平台",
icon: "Message",
// bg: "https://ai-public.mastergo.com/ai/img_res/36f741de94394af113bc0d3c823df49a.jpg",
bg: pyptBg,
},
{
title: "太原市互联网联合辟谣平台",
icon: "Message",
bg: "https://ai-public.mastergo.com/ai/img_res/36f741de94394af113bc0d3c823df49a.jpg",
// title: "网民有话说",
title: "网民有话说",
icon: "Link",
// bg: "https://ai-public.mastergo.com/ai/img_res/c907287d38d89eb460120dc7cf6b2d17.jpg",
bg: wmyhsBg
},
];
</script>
<style>
......@@ -626,15 +583,33 @@ const quickEntries = [
max-width: 800px;
font-size: 14px;
}
.swiper {
--swiper-theme-color: #ffffff;
--swiper-pagination-bullet-inactive-color: #ffffff;
--swiper-pagination-bullet-inactive-opacity: 0.5;
}
.line-clamp-2 {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.title.report-orgs {
background: repeat-x center url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='20'%3E%3Cpath fill-rule='evenodd' fill='%2398BDFC' d='M9.776 19.672V.231h1.505v19.441H9.776zM5.224.231h1.505v19.441H5.224V.231zm-4.552 0h1.506v19.441H.672V.231z'/%3E%3C/svg%3E");
/* border-top: 1px solid #A4C6FF; */
color: #2F79F6;
font-size: 20px;
font-weight: bold;
text-align: center;
/* padding: 28px 0; */
}
.title.report-orgs span {
background: #FFF;
padding: 0 12px;
}
</style>
......@@ -5,10 +5,10 @@
<div class="w-[1440px] mx-auto px-0 py-8">
<!-- 面包屑导航 -->
<div class="flex items-center text-sm text-gray-500 mb-5">
<router-link to="/" class="text-gray-500 hover:text-blue-500"
>首页</router-link
>
<el-icon class="mx-2"><ArrowRight /></el-icon>
<router-link to="/" class="text-gray-500 hover:text-blue-500">首页</router-link>
<el-icon class="mx-2">
<ArrowRight />
</el-icon>
<span class="text-gray-900">太原市互联网违法和不良信息举报平台</span>
</div>
......@@ -18,7 +18,7 @@
涉网络暴力有害信息举报专区
</h1>
<div class="flex items-center justify-between">
<span class="text-gray-500 text-sm">2023年12月20日 14:43</span>
<!-- <span class="text-gray-500 text-sm">2023年12月20日 14:43</span> -->
<!-- <div class="flex gap-4">
<el-button
type="primary"
......@@ -37,57 +37,51 @@
</div>
<!-- 主要内容区域 -->
<div class="bg-white rounded-lg shadow-sm p-8">
<div class="bg-white rounded-lg p-8 shadow-[0_0_10px_rgba(5,157,254,0.32)]">
<!-- 举报入口区域 -->
<div class="mb-12">
<h2 class="text-xl font-bold mb-6 text-black">举报入口</h2>
<div class="grid grid-cols-3 gap-8">
<!-- 举报入口标题,左右带翅膀图片,居中显示 -->
<div class="flex items-center justify-center">
<img src="@/assets/imgs/bg_wing_left.png" alt="左侧翅膀" class="w-54 h-auto mr-14" />
<h2 class="text-2xl font-bold text-[#2f7ef6]">举报入口</h2>
<img src="@/assets/imgs/bg_wing_right.png" alt="右侧翅膀" class="w-54 h-auto ml-14" />
</div>
<!-- 下方灰色提示文字 -->
<div class="text-center text-gray-500 mb-6">您可选择相应入口进行举报</div>
<div class="grid grid-cols-3 gap-5">
<!-- 中央网信办举报入口 -->
<div
class="border rounded-lg p-6 flex flex-col items-center justify-center hover:shadow-md transition-shadow bg-gray-100"
@click="goUrl(1)"
>
<img
src="https://ai-public.mastergo.com/ai/img_res/57ebde68f473e914c107e3a025660439.jpg"
alt="中央网信办logo"
class="w-24 h-24 mb-4 object-contain"
/>
<h3 class="text-lg font-medium text-red-600 mb-2">中央网信办</h3>
<p class="text-gray-600 text-sm text-center">
<div class="border rounded-lg h-[180px] flex flex-col items-center justify-end hover:scale-90 transition-transform
bg-[url('@/assets/imgs/zywxb-bg.png')] bg-[length:100%_100%] bg-center" @click="goUrl(1)">
<!-- <img src="https://ai-public.mastergo.com/ai/img_res/57ebde68f473e914c107e3a025660439.jpg" alt="中央网信办logo"
class="w-24 h-24 mb-4 object-contain" /> -->
<h3 class="text-xl font-medium text-white mb-1">中央网信办</h3>
<p class="text-white text-sm text-center mb-4">
互联网违法和不良信息举报入口
</p>
</div>
<!-- 山西省举报入口 -->
<div
class="border rounded-lg p-6 flex flex-col items-center justify-center hover:shadow-md transition-shadow bg-gray-100"
@click="goUrl(2)"
>
<img
src="https://ai-public.mastergo.com/ai/img_res/7b97bd66edf931fe17054d9f3db69896.jpg"
alt="山西省logo"
class="w-24 h-24 mb-4 object-contain"
/>
<h3 class="text-lg font-medium text-red-600 mb-2">
<div class="border rounded-lg h-[180px] flex flex-col items-center justify-end hover:scale-90 transition-transform
bg-[url('@/assets/imgs/sxsjbzx-bg.png')] bg-[length:100%_100%] bg-center" @click="goUrl(2)">
<!-- <img src="https://ai-public.mastergo.com/ai/img_res/7b97bd66edf931fe17054d9f3db69896.jpg" alt="山西省logo"
class="w-24 h-24 mb-4 object-contain" /> -->
<h3 class="text-xl font-medium text-white mb-1">
山西省举报中心
</h3>
<p class="text-gray-600 text-sm text-center">
<p class="text-white text-sm text-center mb-4">
山西省互联网违法和不良信息举报入口
</p>
</div>
<!-- 太原市举报入口 -->
<div
class="border rounded-lg p-6 flex flex-col items-center justify-center hover:shadow-md transition-shadow bg-gray-100"
@click="goUrl(3)"
>
<img
src="https://ai-public.mastergo.com/ai/img_res/7b5a4b53e643dc61aa084b4a45069db3.jpg"
alt="太原市logo"
class="w-24 h-24 mb-4 object-contain"
/>
<h3 class="text-lg font-medium text-red-600 mb-2">
<div class="border rounded-lg h-[180px] flex flex-col items-center justify-end hover:scale-90 transition-transform
bg-[url('@/assets/imgs/tysjbpt-bg.png')] bg-[length:100%_100%] bg-center" @click="goUrl(3)">
<!-- <img src="https://ai-public.mastergo.com/ai/img_res/7b5a4b53e643dc61aa084b4a45069db3.jpg" alt="太原市logo"
class="w-24 h-24 mb-4 object-contain" /> -->
<h3 class="text-xl font-medium text-white mb-1">
太原市举报平台
</h3>
<p class="text-gray-600 text-sm text-center">
<p class="text-white text-sm text-center mb-4">
太原市互联网违法和不良信息举报入口
</p>
</div>
......@@ -98,7 +92,7 @@
<div class="grid grid-cols-2 gap-8">
<!-- 左侧举报须知 -->
<div class="space-y-6">
<h2 class="text-xl font-bold mb-6 text-black">网上举报须知</h2>
<h2 class="text-xl font-bold mb-6 text-[#2f7ef6]">网上举报须知</h2>
<div>
<h3 class="font-medium mb-4 text-black">一、受理举报范围</h3>
<ol class="list-decimal list-inside space-y-2 text-gray-700">
......@@ -128,8 +122,8 @@
</div>
<!-- 右侧联系方式 -->
<div class="space-y-8 border-l pl-8">
<h2 class="text-xl font-bold mb-6 text-black">联系方式</h2>
<div class="space-y-6 border-l pl-0">
<h2 class="text-xl font-bold mb-0 text-[#2f7ef6]">联系方式</h2>
<div class="space-y-8">
<section>
<h3 class="font-medium mb-4 text-black">
......@@ -137,15 +131,21 @@
</h3>
<ul class="space-y-2 text-gray-700">
<li class="flex items-center">
<!-- <el-icon class="mr-2"><Phone /></el-icon> -->
<el-icon class="mr-2" style="color: #2f7ef6;">
<Phone />
</el-icon>
举报电话:{{ inject("VITE_PHONE") }}
</li>
<li class="flex items-center">
<!-- <el-icon class="mr-2"><Message /></el-icon> -->
<el-icon class="mr-2" style="color: #2f7ef6;">
<Message />
</el-icon>
举报传真:{{ inject("VITE_FAX") }}
</li>
<li class="flex items-center">
<!-- <el-icon class="mr-2"><Message /></el-icon> -->
<el-icon class="mr-2" style="color: #2f7ef6;">
<Message />
</el-icon>
举报邮箱:{{ inject("VITE_EMAIL") }}
</li>
</ul>
......@@ -170,6 +170,7 @@ import { ElButton, ElIcon } from "element-plus";
import { Phone, Message, ArrowRight } from "@element-plus/icons-vue";
import { useRouter } from "vue-router";
import { inject } from "vue";
const router = useRouter();
function goUrl(type: number) {
......
......@@ -8,19 +8,14 @@
/> -->
<div class="mb-6">
<el-breadcrumb :separator-icon="ArrowRight">
<el-breadcrumb-item :to="{ path: '/py/pyhome' }"
>首页</el-breadcrumb-item
>
<el-breadcrumb-item
v-if="route.query.type != '0'"
:to="{
path: '/py/authority',
query: {
categoryTitle: route.query.categoryTitle,
categoryId: route.query.categoryId,
},
}"
>{{ route.query.categoryTitle }}
<el-breadcrumb-item :to="{ path: '/py/pyhome' }">首页</el-breadcrumb-item>
<el-breadcrumb-item v-if="route.query.type != '0'" :to="{
path: '/py/authority',
query: {
categoryTitle: route.query.categoryTitle,
categoryId: route.query.categoryId,
},
}">{{ route.query.categoryTitle }}
</el-breadcrumb-item>
<el-breadcrumb-item>详情</el-breadcrumb-item>
</el-breadcrumb>
......@@ -34,15 +29,21 @@
<div class="flex items-center text-gray-600 mb-6 space-x-4">
<div class="flex items-center">
<el-icon><User /></el-icon>
<el-icon>
<User />
</el-icon>
<span class="ml-1">{{ details.author }}</span>
</div>
<div class="flex items-center">
<el-icon><Clock /></el-icon>
<el-icon>
<Clock />
</el-icon>
<span class="ml-1">{{ details.date }}</span>
</div>
<div class="flex items-center">
<el-icon><View /></el-icon>
<el-icon>
<View />
</el-icon>
<span class="ml-1">阅读 {{ details.hit }}</span>
</div>
</div>
......@@ -55,29 +56,18 @@
<!-- 权威发布 -->
<div class="bg-white rounded-lg shadow-sm p-6">
<h2 class="text-xl font-bold mb-4 flex items-center text-black">
<el-icon class="text-red-500 mr-2"><Star /></el-icon>
<el-icon class="text-red-500 mr-2">
<Star />
</el-icon>
权威发布
</h2>
<div class="space-y-4">
<div
v-for="(item, index) in list0"
:key="index"
class="group cursor-pointer"
@click="goToDetail(item)"
>
<div
v-if="item.images != null"
class="relative h-40 mb-2 overflow-hidden rounded-lg"
>
<img
:src="item.images"
:alt="item.contentTitle"
class="w-full h-full object-cover object-center group-hover:scale-105 transition-transform duration-300"
/>
<div v-for="(item, index) in list0" :key="index" class="group cursor-pointer" @click="goToDetail(item)">
<div v-if="item.images != null" class="relative h-40 mb-2 overflow-hidden rounded-lg">
<img :src="item.images"
class="w-full h-full object-cover object-center group-hover:scale-105 transition-transform duration-300" />
</div>
<h3
class="text-base font-medium group-hover:text-blue-600 text-black line-clamp-1"
>
<h3 class="text-base font-medium group-hover:text-blue-600 text-black line-clamp-1">
{{ item.contentTitle }}
</h3>
<p class="text-gray-600 text-sm line-clamp-2 mt-1">
......@@ -85,12 +75,16 @@
</p>
<div class="mt-1 flex items-center space-x-4">
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1"><Clock /></el-icon>
<el-icon class="mr-1">
<Clock />
</el-icon>
{{ item.contentDatetime }}
</span>
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1"><View /></el-icon>
<el-icon class="mr-1">
<View />
</el-icon>
{{ item.contentHit }} 阅读
</span>
</div>
......@@ -100,29 +94,18 @@
<!-- 辟谣专区 -->
<div class="bg-white rounded-lg shadow-sm p-6">
<h2 class="text-xl font-bold mb-4 flex items-center text-black">
<el-icon class="text-red-500 mr-2"><Star /></el-icon>
<el-icon class="text-red-500 mr-2">
<Star />
</el-icon>
辟谣专区
</h2>
<div class="space-y-4">
<div
v-for="(item, index) in list1"
:key="index"
class="group cursor-pointer"
@click="goToDetail(item)"
>
<div
v-if="item.images != null"
class="relative h-40 mb-2 overflow-hidden rounded-lg"
>
<img
:src="item.images"
:alt="item.contentTitle"
class="w-full h-full object-cover object-center group-hover:scale-105 transition-transform duration-300"
/>
<div v-for="(item, index) in list1" :key="index" class="group cursor-pointer" @click="goToDetail(item)">
<div v-if="item.images != null" class="relative h-40 mb-2 overflow-hidden rounded-lg">
<img :src="item.images"
class="w-full h-full object-cover object-center group-hover:scale-105 transition-transform duration-300" />
</div>
<h3
class="text-base font-medium group-hover:text-blue-600 text-black line-clamp-1"
>
<h3 class="text-base font-medium group-hover:text-blue-600 text-black line-clamp-1">
{{ item.contentTitle }}
</h3>
<p class="text-gray-600 text-sm line-clamp-2 mt-1">
......@@ -130,12 +113,16 @@
</p>
<div class="mt-1 flex items-center space-x-4">
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1"><Clock /></el-icon>
<el-icon class="mr-1">
<Clock />
</el-icon>
{{ item.contentDatetime }}
</span>
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1"><View /></el-icon>
<el-icon class="mr-1">
<View />
</el-icon>
{{ item.contentHit }} 阅读
</span>
</div>
......@@ -145,19 +132,14 @@
<div class="bg-white rounded-lg shadow-sm p-6">
<h2 class="text-xl font-bold mb-4 flex items-center text-black">
<el-icon class="text-red-500 mr-2"><Bell /></el-icon>
<el-icon class="text-red-500 mr-2">
<Bell />
</el-icon>
专家解读
</h2>
<div class="space-y-4">
<div
v-for="(item, index) in list2"
:key="index"
class="group cursor-pointer"
@click="goToDetail(item)"
>
<h3
class="text-base font-medium group-hover:text-blue-600 text-black line-clamp-1"
>
<div v-for="(item, index) in list2" :key="index" class="group cursor-pointer" @click="goToDetail(item)">
<h3 class="text-base font-medium group-hover:text-blue-600 text-black line-clamp-1">
{{ item.contentTitle }}
</h3>
<p class="text-gray-600 text-sm line-clamp-2 mt-1">
......@@ -165,12 +147,16 @@
</p>
<div class="mt-1 flex items-center space-x-4">
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1"><Clock /></el-icon>
<el-icon class="mr-1">
<Clock />
</el-icon>
{{ item.contentDatetime }}
</span>
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1"><View /></el-icon>
<el-icon class="mr-1">
<View />
</el-icon>
{{ item.contentHit }} 阅读
</span>
</div>
......@@ -180,29 +166,18 @@
<!-- 法律法规 -->
<div class="bg-white rounded-lg shadow-sm p-6">
<h2 class="text-xl font-bold mb-4 flex items-center text-black">
<el-icon class="text-red-500 mr-2"><Star /></el-icon>
<el-icon class="text-red-500 mr-2">
<Star />
</el-icon>
法律法规
</h2>
<div class="space-y-4">
<div
v-for="(item, index) in list3"
:key="index"
class="group cursor-pointer"
@click="goToDetail(item)"
>
<div
v-if="item.images != null"
class="relative h-40 mb-2 overflow-hidden rounded-lg"
>
<img
:src="item.images"
:alt="item.contentTitle"
class="w-full h-full object-cover object-center group-hover:scale-105 transition-transform duration-300"
/>
<div v-for="(item, index) in list3" :key="index" class="group cursor-pointer" @click="goToDetail(item)">
<div v-if="item.images != null" class="relative h-40 mb-2 overflow-hidden rounded-lg">
<img :src="item.images"
class="w-full h-full object-cover object-center group-hover:scale-105 transition-transform duration-300" />
</div>
<h3
class="text-base font-medium group-hover:text-blue-600 text-black line-clamp-1"
>
<h3 class="text-base font-medium group-hover:text-blue-600 text-black line-clamp-1">
{{ item.contentTitle }}
</h3>
<p class="text-gray-600 text-sm line-clamp-2 mt-1">
......@@ -210,12 +185,16 @@
</p>
<div class="mt-1 flex items-center space-x-4">
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1"><Clock /></el-icon>
<el-icon class="mr-1">
<Clock />
</el-icon>
{{ item.contentDatetime }}
</span>
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1"><View /></el-icon>
<el-icon class="mr-1">
<View />
</el-icon>
{{ item.contentHit }} 阅读
</span>
</div>
......@@ -383,11 +362,13 @@ function getNewsDetails(id: any) {
margin-bottom: 1.5rem;
line-height: 1.75;
}
:deep(.editor-content p img) {
max-width: 100%;
display: block;
margin: 0 auto;
}
:deep(.editor-content video) {
max-width: 100%;
}
......
<!-- 首页 -->
<template>
<div class="mx-auto bg-gray-200">
<main class="container mx-auto px-8 py-8">
<div class="bg-white rounded-lg shadow-lg p-6 mb-8">
<main class="container mx-auto px-5 py-5 w-[1440px]">
<div class="rounded-lg p-0 mx-auto mb-5 w-full">
<h2 class="text-2xl font-bold mb-4 text-black line-clamp-1">
{{ title }}
</h2>
<p class="text-gray-600 mb-4 line-clamp-1">
{{ description }}
</p>
<div class="flex gap-8 mb-8">
<div class="relative w-2/3 rounded-lg overflow-hidden">
<swiper
:modules="swiperModules"
:pagination="{ clickable: true }"
:navigation="true"
:autoplay="{ delay: 3000, disableOnInteraction: false }"
class="swiper-container w-full h-full"
@swiper="onSwiper"
@slideChange="onSlideChange"
>
<div class="flex gap-5 mb-5">
<div class="relative w-2/3 h-[510px] rounded-lg overflow-hidden">
<swiper :modules="swiperModules" :pagination="{ clickable: true }" :navigation="true"
:autoplay="{ delay: 3000, disableOnInteraction: false }" class="swiper-container w-full h-full"
@swiper="onSwiper" @slideChange="onSlideChange">
<swiper-slide v-for="(slide, index) in list3" :key="index">
<el-image
:src="slide.images"
fit="cover"
class="w-full h-full object-cover"
@click="getToDetail(slide)"
/>
<el-image :src="slide.images" fit="cover" class="w-full h-full object-cover"
@click="getToDetail(slide)" />
<!-- 使用 el-image 组件显示图片,并设置图片填充方式为覆盖 -->
</swiper-slide>
</swiper>
</div>
<div class="w-1/3 flex flex-col gap-2">
<el-card
v-for="(item, index) in quickLinks"
:key="index"
<div class="w-1/2 flex flex-col gap-2">
<el-card v-for="(item, index) in quickLinks" :key="index"
class="hover:shadow-xl transition-all duration-300 transform hover:-translate-y-1 cursor-pointer"
shadow="hover"
>
<a
:href="item.url"
target="_blank"
class="flex items-center gap-4 p-1 bg-gradient-to-r from-blue-50 to-white rounded-lg"
>
<div
class="flex items-center gap-0 p-0 bg-gradient-to-r from-blue-50 to-white rounded-lg"
>
shadow="hover">
<a :href="item.url" target="_blank"
class="flex items-center gap-4 p-1 bg-gradient-to-r from-blue-50 to-white rounded-lg">
<div class="flex items-center gap-0 p-0 bg-gradient-to-r from-blue-50 to-white rounded-lg">
<el-icon :size="24" class="text-blue-600">
<component :is="item.icon" />
</el-icon>
<h4
:style="{ whiteSpace: 'pre-line' }"
class="font-bold text-base text-blue-900 flex items-center ml-5"
>
<h4 :style="{ whiteSpace: 'pre-line' }"
class="font-bold text-base text-[#2f7ef6] flex items-center ml-3">
{{ item.title }}
</h4>
</div>
......@@ -61,41 +41,250 @@
</el-card>
</div>
</div>
<div class="grid grid-cols-3 gap-6">
<el-card
v-for="(section, index) in list1"
:key="index"
class="h-full"
>
<div class="container mx-auto">
<div class="grid grid-cols-12 gap-5">
<!-- 辟谣专区 -->
<div class="bg-white rounded-lg p-6 shadow-[0_0_10px_rgba(5,157,254,0.32)] col-span-8">
<div class="flex justify-between items-center mb-4">
<!-- <h2 class="text-xl font-bold" style="color: #2f7ef6">辟谣专区</h2> -->
<div class="relative">
<h2 class="text-xl font-bold" style="color: #2f7ef6">辟谣专区</h2>
<div class="w-[50px] h-[3px] bg-blue-500 rounded-full mt-1"></div>
</div>
<el-button v-if="pyList.length > 0" type="primary" class="!rounded-button" text
@click="goToTyMoreList(1)">更多 ></el-button>
</div>
<div class="space-y-4">
<div v-for="(item, index) in pyList" :key="index"
class="flex items-start space-x-3 pb-4 border-b last:border-b-0 relative" @click="getToDetail(item)">
<div v-if="item.images" class="flex-shrink-0 w-[150px] h-[90px]">
<img :src="item.images" class="w-full h-full object-cover rounded" />
</div>
<div class="flex-1">
<div class="flex items-center space-x-2 relative">
<el-tag size="small" type="danger" class="!rounded-full">辟谣</el-tag>
<el-tooltip popper-class="tooltip-width" effect="dark" :content="item.contentTitle"
placement="top-start">
<h3 class="text-base font-medium hover:text-blue-600 cursor-pointer text-black line-clamp-1">
{{ item.contentTitle }}
</h3>
</el-tooltip>
<div class="absolute right-10 top-0">
<!-- transform旋转45度 -->
<img :src="yyIcon" class="w-[85px] h-[85px] object-contain transform rotate-[-20deg]"
alt="谣言标识" />
</div>
</div>
<p class="mt-1 text-sm text-gray-500 line-clamp-2">
{{ item.contentDescription }}
</p>
<div class="mt-2 flex items-center space-x-4">
<span class="text-[12px] text-[#2f7ef6] flex items-center">
<el-icon class="mr-1">
<View />
</el-icon>
线索来源:{{ item.contentSource }}
</span>
<span class="text-[12px] text-gray-500 flex items-center">
<el-icon class="mr-1">
<Clock />
</el-icon>
{{ item.contentDatetime }}
</span>
<span class="text-[12px] text-gray-500 flex items-center">
<el-icon class="mr-1">
<View />
</el-icon>
{{ item.contentHit }} 阅读
</span>
</div>
</div>
</div>
</div>
</div>
<!-- 权威发布 -->
<div class="bg-white rounded-lg p-6 shadow-[0_0_10px_rgba(5,157,254,0.32)] col-span-4">
<div class="flex justify-between items-center mb-4">
<div class="relative">
<h2 class="text-xl font-bold" style="color: #2f7ef6">权威发布</h2>
<div class="w-[50px] h-[3px] bg-blue-500 rounded-full mt-1"></div>
</div>
<el-button v-if="qwList.length > 0" type="primary" class="!rounded-button" text
@click="goToTyMoreList(4)">更多 ></el-button>
</div>
<div class="space-y-4">
<div v-for="(item, index) in qwList" :key="index"
class="flex items-start space-x-3 pb-4 border-b last:border-b-0" @click="getToDetail(item)">
<div v-if="item.images != null" class="flex-shrink-0 w-24 h-16">
<img :src="item.images" class="w-full h-full object-cover rounded" />
</div>
<div class="flex-1">
<div class="flex items-center space-x-2">
<el-tag size="small" type="primary" class="!rounded-full">权威发布</el-tag>
<el-tooltip popper-class="tooltip-width" effect="dark" :content="item.contentTitle"
placement="top-start">
<h3 class="text-base font-medium hover:text-blue-600 cursor-pointer text-black line-clamp-1">
{{ item.contentTitle }}
</h3>
</el-tooltip>
</div>
<p class="mt-1 text-sm text-gray-500 line-clamp-2">
{{ item.contentDescription }}
</p>
<div class="mt-1 flex items-center space-x-4">
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1">
<Clock />
</el-icon>
{{ item.contentDatetime }}
</span>
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1">
<View />
</el-icon>
{{ item.contentHit }} 阅读
</span>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="grid grid-cols-12 gap-5 mt-5">
<!-- 专家解读 -->
<div class="bg-white rounded-lg p-6 shadow-[0_0_10px_rgba(5,157,254,0.32)] col-span-6">
<div class="flex justify-between items-center mb-4">
<!-- <h2 class="text-xl font-bold" style="color: #2f7ef6">专家解读</h2> -->
<div class="relative">
<h2 class="text-xl font-bold" style="color: #2f7ef6">专家解读</h2>
<div class="w-[50px] h-[3px] bg-blue-500 rounded-full mt-1"></div>
</div>
<el-button v-if="zjList.length > 0" type="primary" class="!rounded-button" text
@click="goToTyMoreList(0)">更多></el-button>
</div>
<div class="space-y-4">
<div v-for="(item, index) in zjList" :key="index"
class="flex items-start space-x-3 pb-4 border-b last:border-b-0" @click="getToDetail(item)">
<div v-if="item.images != null" class="flex-shrink-0 w-24 h-16">
<img :src="item.images" class="w-full h-full object-cover rounded" />
</div>
<div class="flex-1">
<div class="flex items-center space-x-2">
<el-tag size="small" type="danger" class="!rounded-full">专家解读</el-tag>
<el-tooltip popper-class="tooltip-width" effect="dark" :content="item.contentTitle"
placement="top-start">
<h3 class="text-base font-medium hover:text-blue-600 cursor-pointer text-black line-clamp-1">
{{ item.contentTitle }}
</h3>
</el-tooltip>
</div>
<p class="mt-1 text-sm text-gray-500 line-clamp-2">
{{ item.contentDescription }}
</p>
<div class="mt-1 flex items-center space-x-4">
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1">
<Clock />
</el-icon>
{{ item.contentDatetime }}
</span>
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1">
<View />
</el-icon>
{{ item.contentHit }} 阅读
</span>
</div>
</div>
</div>
</div>
</div>
<!-- 法律法规 -->
<div class="bg-white rounded-lg p-6 shadow-[0_0_10px_rgba(5,157,254,0.32)] col-span-6">
<div class="flex justify-between items-center mb-4">
<div class="relative">
<h2 class="text-xl font-bold" style="color: #2f7ef6">法律法规</h2>
<div class="w-[50px] h-[3px] bg-blue-500 rounded-full mt-1"></div>
</div>
<el-button v-if="flfgList.length > 0" type="primary" class="!rounded-button" text
@click="goToTyMoreList(2)">更多</el-button>
</div>
<div class="space-y-4">
<div v-for="(item, index) in flfgList" :key="index"
class="flex items-start space-x-3 pb-4 border-b last:border-b-0" @click="getToDetail(item)">
<div v-if="item.images != null" class="flex-shrink-0 w-24 h-16">
<img :src="item.images" class="w-full h-full object-cover rounded" />
</div>
<div class="flex-1">
<div class="flex items-center space-x-2">
<el-tag size="small" type="primary" class="!rounded-full">法律法规</el-tag>
<el-tooltip popper-class="tooltip-width" effect="dark" :content="item.contentTitle"
placement="top-start">
<h3 class="text-base font-medium hover:text-blue-600 cursor-pointer text-black line-clamp-1">
{{ item.contentTitle }}
</h3>
</el-tooltip>
</div>
<p class="mt-1 text-sm text-gray-500 line-clamp-2">
{{ item.contentDescription }}
</p>
<div class="mt-1 flex items-center space-x-4">
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1">
<Clock />
</el-icon>
{{ item.contentDatetime }}
</span>
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1">
<View />
</el-icon>
{{ item.contentHit }} 阅读
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="grid grid-cols-3 gap-3" v-if="false">
<el-card v-for="(section, index) in list1" :key="index"
class="h-full rounded-xl p-0 shadow-[0_0_10px_rgba(5,157,254,0.32)]">
<template #header>
<div class="flex justify-between items-center">
<span class="text-xl font-bold text-primary">{{
section.title
}}</span>
<el-button type="primary" text @click="goToTyMoreList(index)"
>更多 ></el-button
>
<el-button type="primary" text @click="goToTyMoreList(index)">更多 ></el-button>
</div>
</template>
<el-scrollbar height="400px">
<div class="space-y-4">
<div
v-for="(item, index) in section.items"
:key="index"
class="group cursor-pointer flex items-center"
@click="getToDetail(item)"
>
<div v-for="(item, index) in section.items" :key="index" class="group cursor-pointer flex items-center"
@click="getToDetail(item)">
<!-- <span class="bg-gray-400 mr-2 w-1 h-1"></span> -->
<!-- <div class="bg-gray-400 mr-2 w-1 h-1"></div> -->
<el-tooltip
popper-class="tooltip-width"
effect="dark"
:content="item.contentTitle"
placement="top-start"
>
<div
class="text-sm group-hover:text-blue-600 line-clamp-1 text-gray-600 ml-2"
>
<el-tooltip popper-class="tooltip-width" effect="dark" :content="item.contentTitle"
placement="top-start">
<div class="text-sm group-hover:text-blue-600 line-clamp-1 text-gray-600 ml-2">
{{ item.contentTitle }}
</div>
</el-tooltip>
......@@ -105,48 +294,30 @@
</el-card>
</div>
</div>
<div class="bg-white rounded-lg shadow-lg p-6 mt-8">
<div class="flex justify-between items-center mb-6">
<div class="bg-white rounded-lg shadow-lg p-6">
<div class="flex justify-between items-center mb-5">
<h3 class="text-xl font-bold text-primary">读图识谣</h3>
<el-button type="primary" text @click="goToTyMoreList(3)"
>更多 ></el-button
>
<el-button type="primary" text @click="goToTyMoreList(3)">更多 ></el-button>
</div>
<div class="relative">
<swiper
:modules="swiperModules"
:slidesPerView="4"
:spaceBetween="24"
:navigation="true"
:autoplay="{ delay: 3000 }"
class="service-swiper"
>
<swiper :modules="swiperModules" :slidesPerView="4" :spaceBetween="24" :navigation="true"
:autoplay="{ delay: 3000 }" class="service-swiper">
<swiper-slide v-for="(item, index) in list2" :key="index">
<el-card
class="h-full hover:shadow-lg transition-shadow"
@click="getToDetail(item)"
>
<div class="h-full hover:shadow-lg transition-shadow cursor-pointer" @click="getToDetail(item)">
<div class="w-full mb-4 overflow-hidden rounded-lg h-56">
<img
v-if="item.images"
:src="item.images"
class="w-full h-full object-cover object-top"
/>
<img v-if="item.images" :src="item.images" class="w-full h-full object-cover object-top" />
</div>
<el-tooltip
popper-class="tooltip-width"
effect="dark"
:content="item.contentTitle"
placement="top-start"
>
<h4 class="font-bold mb-2 line-clamp-1">
<el-tooltip popper-class="tooltip-width" effect="dark" :content="item.contentTitle"
placement="top-start">
<h4 class="font-bold mb-1 line-clamp-1 text-black">
{{ item.contentTitle }}
</h4>
</el-tooltip>
<p class="text-sm text-gray-600 line-clamp-1">
<p class="text-[12px] text-gray-600 line-clamp-1">
{{ item.contentDescription }}
</p>
</el-card>
</div>
</swiper-slide>
</swiper>
</div>
......@@ -159,6 +330,8 @@ import { ref } from "vue";
import { Swiper, SwiperSlide } from "swiper/vue";
import { Pagination, Navigation, Autoplay } from "swiper/modules";
import {
View,
Clock,
Document,
UserFilled,
Lock,
......@@ -172,18 +345,19 @@ import "swiper/css/pagination";
import "swiper/css/autoplay";
import "swiper/css/navigation";
import { getNewsList } from "@/api/home/news/list";
import { baseImageUrl, lhpylbt, dtsy, zjjd, pyzq, flfg } from "@/utils/config";
import { baseImageUrl, lhpylbt, dtsy, zjjd, pyzq, flfg, qwfb } from "@/utils/config";
import { useRouter, useRoute } from "vue-router";
import yyIcon from "@/assets/imgs/yy-icon.png";
const title = ref();
const description = ref();
const list1 = ref([
{
title: "专家解读",
title: "辟谣专区",
items: [],
},
{
title: "辟谣专区",
title: "专家解读",
items: [],
},
{
......@@ -191,6 +365,11 @@ const list1 = ref([
items: [],
},
]);
const pyList = ref([]);
const qwList = ref([]);
const zjList = ref([]);
const flfgList = ref([]);
const list2 = ref([]);
const list3 = ref([]);
const router = useRouter();
......@@ -213,23 +392,56 @@ const onSlideChange = (swiper) => {
function goToTyMoreList(index: number) {
switch (index) {
case 0: //专家解读
// router.push({
// path: "/py/expert",
// });
router.push({
path: "/py/expert",
query: {
categoryTitle: "专家解读",
categoryId: zjList.value.length > 0 ? zjList.value[0].categoryId : "0",
activeNav: 0,
},
});
break;
case 1: //辟谣专区
router.push({
path: "/py/rumor",
query: {
categoryTitle: "辟谣专区",
categoryId: pyList.value.length > 0 ? pyList.value[0].categoryId : "0",
activeNav: 1,
},
});
break;
case 2: //法律法规
router.push({
path: "/py/law",
query: {
categoryTitle: "法律法规",
categoryId: flfgList.value.length > 0 ? flfgList.value[0].categoryId : "0",
activeNav: 2,
},
});
break;
case 3: //读图识谣
router.push({
path: "/py/reading",
query: {
categoryTitle: "读图识谣",
categoryId: list2.value.length > 0 ? list2.value[0].categoryId : "0",
activeNav: 3,
},
});
break;
case 4: //权威发布
router.push({
path: "/py/authority",
query: {
categoryTitle: "权威发布",
categoryId: qwList.value.length > 0 ? qwList.value[0].categoryId : "0",
activeNav: 4,
},
});
break;
}
......@@ -273,10 +485,11 @@ const quickLinks = [
},
];
getList(zjjd, 12, 1);
getList(pyzq, 12, 1);
getList(flfg, 12, 1);
getList2(dtsy, 12, 1);
getList(zjjd, 6, 1);
getList(pyzq, 6, 1);
getList(qwfb, 6, 1);
getList(flfg, 6, 1);
getList2(dtsy, 6, 1);
getList3(5, 1); //轮播图
//获取专家解读、辟谣专区、法律法规
......@@ -289,14 +502,25 @@ function getList(value: string, pageSize: number, pageNo: number) {
};
getNewsList(datas).then((response) => {
switch (value) {
case zjjd:
list1.value[0].items = response.data.rows;
break;
case pyzq:
list1.value[1].items = response.data.rows;
pyList.value = response.data.rows;
pyList.value.forEach((item: any) => {
if (item.contentImg) {
item.images = baseImageUrl(JSON.parse(item.contentImg)[0].path);
}
});
break;
case qwfb:
qwList.value = response.data.rows;
// list1.value[0].items = response.data.rows;
break;
case zjjd:
zjList.value = response.data.rows;
// list1.value[1].items = response.data.rows;
break;
case flfg:
list1.value[2].items = response.data.rows;
flfgList.value = response.data.rows;
// list1.value[2].items = response.data.rows;
break;
}
});
......@@ -361,33 +585,42 @@ function getToDetail(item: any) {
max-width: 800px;
font-size: 14px;
}
  .hero-bg {
.hero-bg {
background: linear-gradient(135deg, #001f3f, #0047ab);
}
:deep(.el-card) {
border: 1px solid rgba(0, 31, 63, 0.1);
transition: all 0.3s ease;
}
:deep(.el-scrollbar__wrap) {
overflow-x: hidden;
}
:deep(.el-card.is-hover-shadow:hover) {
box-shadow: 0 8px 16px rgba(0, 31, 63, 0.12);
transform: translateY(-2px);
}
:deep(.el-card.is-hover-shadow) {
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}
:deep(.el-card:hover) {
border-color: rgba(0, 31, 63, 0.3);
box-shadow: 0 12px 28px rgba(0, 31, 63, 0.15);
}
:deep(.el-card__body) {
padding: 16px;
}
:deep(.el-link.el-link--default:hover) {
color: #0047ab;
}
:deep(.service-swiper .swiper-button-prev),
:deep(.service-swiper .swiper-button-next) {
background-color: rgba(255, 255, 255, 0.9);
......@@ -398,16 +631,20 @@ function getToDetail(item: any) {
color: #001f3f;
/* left: 95%; */
}
:deep(.service-swiper .swiper-button-prev:after),
:deep(.service-swiper .swiper-button-next:after) {
font-size: 16px;
}
:deep(.service-swiper .swiper-button-prev) {
/* left: -20px; */
}
:deep(.service-swiper .swiper-button-next) {
/* right: -20px; */
}
:deep(.service-swiper .swiper-button-disabled) {
opacity: 0;
}
......
<!-- 代码已包含 CSS:使用 TailwindCSS , 安装 TailwindCSS 后方可看到布局样式效果 -->
<template>
<div class="min-h-screen bg-gray-50">
<div class="container mx-auto px-4 py-8 w-[1440px]">
<bread-crumb :breadcrumbItems="breadcrumbItems" />
<div class="flex gap-6">
<div class="flex-1">
<div class="bg-white rounded-lg shadow-sm">
<div v-for="(news, index) in newsList" :key="index"
class="group p-4 flex items-start border-b border-gray-100 hover:bg-gray-50 transition-colors cursor-pointer"
@click="getToDetail(news)">
<div v-if="news.images != null" class="w-32 h-32 flex-shrink-0 overflow-hidden rounded-lg">
<el-image class="w-full h-full object-cover" :src="news.images" fit="fill" />
</div>
<div class="flex-grow px-6">
<h2 class="text-lg font-semibold mb-2 group-hover:text-blue-600 line-clamp-2 text-black">
{{ news.contentTitle }}
</h2>
<p class="text-gray-600 text-sm line-clamp-2">
{{ news.contentDescription }}
</p>
<div class="mt-3 flex items-center space-x-4">
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1">
<Clock />
</el-icon>
{{ news.contentDatetime }}
</span>
<!-- <span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1"><Document /></el-icon>
{{ news.contentTags }}
</span> -->
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1">
<View />
</el-icon>
{{ news.contentHit }} 阅读
</span>
</div>
</div>
<!-- <div class="w-24 flex-shrink-0 text-right text-blue-500">
<el-tag
:type="news.contentTags"
size="small"
class="whitespace-nowrap"
>
{{ news.contentTags }}
</el-tag>
</div> -->
</div>
</div>
<div class="flex justify-center mt-8">
<el-pagination v-model:current-page="pageNo" v-model:page-size="pageSize" background :total="total"
:page-sizes="[10, 20, 30, 40]" layout="prev, pager, next" @size-change="handleSizeChange"
@current-change="handleCurrentChange" />
</div>
</div>
<div class="w-80 flex-shrink-0 space-y-3">
<!-- 权威发布 -->
<div class="bg-white rounded-lg shadow-sm p-4">
<h2 class="text-xl font-bold mb-4 flex items-center text-black">
<el-icon class="mr-2 text-red-500">
<Star />
</el-icon>
权威发布
</h2>
<div class="space-y-4">
<div v-for="(item, index) in list0" :key="index" class="group cursor-pointer" @click="getToDetail(item)">
<div v-if="item.images" class="h-32 mb-2 overflow-hidden rounded-lg">
<img :src="item.images" class="w-full h-full object-cover" />
</div>
<div class="text-sm font-medium group-hover:text-blue-600 line-clamp-1 text-black">
{{ item.contentTitle }}
</div>
<p class="text-gray-600 text-sm line-clamp-2 mt-1">
{{ item.contentDescription }}
</p>
<div class="mt-1 flex items-center space-x-4">
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1">
<Clock />
</el-icon>
{{ item.contentDatetime }}
</span>
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1">
<View />
</el-icon>
{{ item.contentHit }} 阅读
</span>
</div>
</div>
</div>
</div>
<!-- 辟谣专区 -->
<div class="bg-white rounded-lg shadow-sm p-4">
<h2 class="text-xl font-bold mb-4 flex items-center text-black">
<el-icon class="mr-2 text-red-500">
<Star />
</el-icon>
辟谣专区
</h2>
<div class="space-y-4">
<div v-for="(item, index) in list1" :key="index" class="group cursor-pointer" @click="getToDetail(item)">
<div v-if="item.images" class="h-32 mb-2 overflow-hidden rounded-lg">
<img :src="item.images" class="w-full h-full object-cover" />
</div>
<div class="text-sm font-medium group-hover:text-blue-600 line-clamp-1 text-black">
{{ item.contentTitle }}
</div>
<p class="text-gray-600 text-sm line-clamp-2 mt-1">
{{ item.contentDescription }}
</p>
<div class="mt-1 flex items-center space-x-4">
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1">
<Clock />
</el-icon>
{{ item.contentDatetime }}
</span>
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1">
<View />
</el-icon>
{{ item.contentHit }} 阅读
</span>
</div>
</div>
</div>
</div>
<!-- 专家解读-->
<div class="bg-white rounded-lg shadow-sm p-4">
<h2 class="text-xl font-bold mb-4 flex items-center text-black">
<el-icon class="mr-2 text-blue-500">
<Location />
</el-icon>
专家解读
</h2>
<div class="space-y-4">
<div v-for="(item, index) in list2" :key="index" class="group cursor-pointer" @click="getToDetail(item)">
<div v-if="item.images" class="h-32 mb-2 overflow-hidden rounded-lg">
<img :src="item.images" class="w-full h-full object-cover" />
</div>
<div class="text-sm font-medium group-hover:text-blue-600 line-clamp-1 text-black">
{{ item.contentTitle }}
</div>
<p class="text-gray-600 text-sm line-clamp-2 mt-1">
{{ item.contentDescription }}
</p>
<div class="mt-1 flex items-center space-x-4">
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1">
<Clock />
</el-icon>
{{ item.contentDatetime }}
</span>
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1">
<View />
</el-icon>
{{ item.contentHit }} 阅读
</span>
</div>
</div>
</div>
</div>
<!-- 法律法规 -->
<div class="bg-white rounded-lg shadow-sm p-4">
<h2 class="text-xl font-bold mb-4 flex items-center text-black">
<el-icon class="mr-2 text-blue-500">
<Location />
</el-icon>
法律法规
</h2>
<div class="space-y-4">
<div v-for="(item, index) in list3" :key="index" class="group cursor-pointer" @click="getToDetail(item)">
<div v-if="item.images" class="h-32 mb-2 overflow-hidden rounded-lg">
<img :src="item.images" class="w-full h-full object-cover" />
</div>
<div class="text-sm font-medium group-hover:text-blue-600 line-clamp-1 text-black">
{{ item.contentTitle }}
</div>
<p class="text-gray-600 text-sm line-clamp-2 mt-1">
{{ item.contentDescription }}
</p>
<div class="mt-1 flex items-center space-x-4">
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1">
<Clock />
</el-icon>
{{ item.contentDatetime }}
</span>
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1">
<View />
</el-icon>
{{ item.contentHit }} 阅读
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, watch } from "vue";
import { getNewsList } from "@/api/home/news/list";
import { baseImageUrl, qwfb, pyzq, zjjd, flfg } from "@/utils/config";
import {
Clock,
Document,
View,
Star,
Location,
Bell,
ArrowRight,
} from "@element-plus/icons-vue";
import { useRouter, useRoute } from "vue-router";
import BreadCrumb from "@/components/breadcrumb/BreadCrumb.vue";
const router = useRouter();
const route = useRoute();
const pageNo = ref(1);
const pageSize = ref(10);
const total = ref(0);
//搜索内容
const searchQuery = route.query.searchQuery;
const breadcrumbItems = ref([
{ title: "首页", path: "/py/pyhome" },
{ title: "搜索结果" },
]);
const handleSizeChange = (val: number) => {
pageSize.value = val;
pageNo.value = pageNo.value;
};
const handleCurrentChange = (val: number) => {
pageSize.value = pageSize.value;
pageNo.value = val;
getList(route.query.searchQuery, pageSize.value, pageNo.value);
};
const newsList = ref([]);
const tyNews = ref([]);
const announcements = ref([]);
const list0 = ref([]);
const list1 = ref([]);
const list2 = ref([]);
const list3 = ref([]);
getList0();
getList1();
getList2();
getList3();
//获取测边列表 0
function getList0() {
const datas = {
contentDisplay: "0",
contentType: qwfb,
pageSize: 3,
pageNo: 1,
};
getNewsList(datas).then((response) => {
const data = response.data;
const rowsList = data.rows;
rowsList.forEach((item: any) => {
if (item.contentImg) {
item.images = baseImageUrl(JSON.parse(item.contentImg)[0].path);
}
});
list0.value = rowsList;
});
}
//获取测边列表 1
function getList1() {
const datas = {
contentDisplay: "0",
contentType: pyzq,
pageSize: 3,
pageNo: 1,
};
getNewsList(datas).then((response) => {
const data = response.data;
const rowsList = data.rows;
rowsList.forEach((item: any) => {
if (item.contentImg) {
item.images = baseImageUrl(JSON.parse(item.contentImg)[0].path);
}
});
list1.value = rowsList;
});
}
//获取测边列表 2
function getList2() {
const datas = {
contentDisplay: "0",
contentType: zjjd,
pageSize: 3,
pageNo: 1,
};
getNewsList(datas).then((response) => {
const data = response.data;
const rowsList = data.rows;
rowsList.forEach((item: any) => {
if (item.contentImg) {
item.images = baseImageUrl(JSON.parse(item.contentImg)[0].path);
}
});
list2.value = rowsList;
});
}
//获取测边列表 3
function getList3() {
const datas = {
contentDisplay: "0",
contentType: flfg,
pageSize: 2,
pageNo: 1,
};
getNewsList(datas).then((response) => {
const data = response.data;
const rowsList = data.rows;
rowsList.forEach((item: any) => {
if (item.contentImg) {
item.images = baseImageUrl(JSON.parse(item.contentImg)[0].path);
}
});
list3.value = rowsList;
});
}
// 监听数据变化
watch(
() => route.query.searchQuery,
(newVal, oldVal) => {
if (newVal) {
getList(newVal, pageSize.value, pageNo.value);
}
}
);
getList(searchQuery, pageSize.value, pageNo.value);
//获取新闻热点列表
function getList(searchQuery: any, pageSize: number, pageNo: number) {
const datas = {
contentDisplay: "0",
categoryId: "1876565269077975042",
contentTitle: searchQuery,
pageSize: pageSize,
pageNo: pageNo,
};
getNewsList(datas).then((response) => {
const data = response.data;
const rowsList = data.rows;
rowsList.forEach((item: any) => {
if (item.contentImg) {
item.images = baseImageUrl(JSON.parse(item.contentImg)[0].path);
}
});
total.value = data.total;
newsList.value = rowsList;
// console.log(newsList.value);
});
}
function getToDetail(item: any) {
if (item.contentOutLink) {
window.open(item.contentOutLink, "_blank");
} else {
router.push({
path: "/py/news/detail",
query: {
title: "搜索结果",
titlePath: "/py/search",
contentTitle: route.query.searchQuery,
type: 1,
id: item.id,
},
});
}
}
</script>
<style scoped>
.line-clamp-2 {
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
overflow: hidden;
}
.line-clamp-1 {
display: -webkit-box;
-webkit-line-clamp: 1;
-webkit-box-orient: vertical;
overflow: hidden;
}
</style>
......@@ -2,84 +2,148 @@
<!-- 主体内容区 -->
<!-- 居中 -->
<div class="grid grid-cols-12 gap-6 w-[1440px] mx-auto mb-10">
<!-- 左侧热点 -->
<div class="col-span-6">
<div class="col-span-2">
<div class="flex items-center justify-between mb-4">
<div class="flex items-center space-x-2">
<el-icon class="text-red-500"><ChatDotRound /></el-icon>
<h3 class="text-xl font-bold text-black">热点留言</h3>
<div class="flex items-center">
<div>
<h3 class="text-xl font-bold text-black">矩阵媒体号</h3>
<div class="w-[50px] h-1 bg-blue-500 mt-1"></div>
</div>
</div>
<router-link
class="text-sm text-blue-600 hover:text-blue-300 flex items-center"
to="/wm/messagelist"
>更多留言 <el-icon class="ml-1"><ArrowRight /></el-icon
></router-link>
</div>
<div class="space-y-3">
<div
v-for="(item, index) in hotList"
:key="index"
class="p-4 bg-white rounded-lg hover:shadow-md transition-shadow border-l-4 border-red-500"
@click="messageClick(item.id)"
>
<div class="flex items-center justify-between">
<div class="flex items-center text-sm text-gray-500">
<span>{{ item.contentDatetime }}</span>
<span class="mx-5">留言人:***</span>
<div class="grid grid-cols-2 gap-5 pt-5 pb-5 pl-8 pr-8 bg-white rounded-lg">
<div v-for="(item, index) in mediaAccountList" :key="index"
class="relative hover:scale-105 hover:-translate-y-2">
<el-popover v-if="item.qrCode" trigger="hover" placement="left" width="180">
<template #reference>
<div class="w-full">
<div class="rounded-lg">
<div class="h-[40px] flex items-center justify-center">
<img :src="item.img" class="w-full h-full object-contain rounded-lg" alt="{{ item.name }}">
</div>
<div class="text-center text-[12px] text-black mb-3">{{ item.name }}</div>
</div>
</div>
</template>
<div class="p-0 bg-white rounded-lg">
<img :src="item.qrCode" class="w-full h-auto object-contain p-0">
</div>
</el-popover>
<!-- 无二维码时的普通展示 -->
<div v-else class="w-full">
<div class="rounded-lg overflow-hidden">
<div class="h-[40px] flex items-center justify-center">
<img :src="item.img" class="w-full h-full object-contain rounded-xl" alt="{{ item.name }}">
</div>
<div class="text-center text-[12px] text-black">{{ item.name }}</div>
</div>
<el-tag
size="small"
:type="item.replyStatus === '1' ? 'success' : 'warning'"
>
{{ item.replyStatus === "1" ? "已回复" : "未回复" }}
</el-tag>
</div>
<h4 class="text-gray-900 font-medium mt-3 line-clamp-2">
{{ item.title }}
</h4>
<p class="mt-2 text-gray-700 line-clamp-3">{{ item.content }}</p>
<!-- 点击跳转链接 -->
<!-- <a v-if="item.url" :href="item.url" target="_blank" class="absolute inset-0 z-10 rounded-lg"></a> -->
<div v-if="item.url" @click="handleClick(item.url)"
class="absolute inset-0 z-10 rounded-lg hover:scale-105 hover:-translate-y-2"></div>
</div>
</div>
</div>
<!-- 左侧热点 -->
<div class="col-span-5">
<div class="flex items-center justify-between mb-4">
<div class="flex items-center">
<div>
<h3 class="text-xl font-bold text-black">热点留言</h3>
<div class="w-[50px] h-1 bg-blue-500 mt-1"></div>
</div>
</div>
<router-link class="text-sm text-blue-600 hover:text-blue-300 flex items-center" to="/wm/messagelist">更多留言
<el-icon class="ml-1">
<ArrowRight />
</el-icon></router-link>
</div>
<div class="space-y-3">
<!-- 当有数据时显示留言列表 -->
<template v-if="hotList && hotList.length > 0">
<div v-for="(item, index) in hotList" :key="index"
class="p-4 bg-white rounded-lg hover:shadow-md transition-shadow border-l-4 border-red-500"
@click="messageClick(item.id)">
<div class="flex items-center justify-between">
<div class="flex items-center text-sm text-gray-500">
<span>{{ item.contentDatetime }}</span>
<span class="mx-5">留言人:***</span>
</div>
<el-tag size="small" :type="item.replyStatus === '1' ? 'success' : 'warning'">
{{ item.replyStatus === "1" ? "已回复" : "未回复" }}
</el-tag>
</div>
<h4 class="text-gray-900 font-medium mt-3 line-clamp-2">
{{ item.title }}
</h4>
<p class="mt-2 text-gray-700 line-clamp-3">{{ item.content }}</p>
</div>
</template>
<!-- 当没有数据时显示空状态 -->
<template v-else>
<div class="flex flex-col items-center justify-center p-10 bg-white rounded-lg">
<img src="@/assets/imgs/nothing.png" alt="暂无数据" class="w-[200px] h-[200px] mb-0">
<span class="text-gray-400 text-[14px]">暂无热点留言</span>
</div>
</template>
</div>
</div>
<!-- 右侧回复 -->
<div class="col-span-6">
<div class="col-span-5">
<div class="flex items-center justify-between mb-4">
<div class="flex items-center space-x-2">
<el-icon class="text-red-500"><ChatDotRound /></el-icon>
<h3 class="text-xl font-bold text-black">最新回复</h3>
<div class="flex items-center">
<div class="w-full">
<h3 class="text-xl font-bold text-black">最新回复</h3>
<div class="w-[50px] h-1 bg-blue-500 mt-1 rounded-full"></div>
</div>
</div>
<router-link
class="text-sm text-blue-600 hover:text-blue-300 flex items-center"
to="/wm/recoverlist"
>更多回复 <el-icon class="ml-1"><ArrowRight /></el-icon
></router-link>
<router-link class="text-sm text-blue-600 hover:text-blue-300 flex items-center" to="/wm/recoverlist">更多回复
<el-icon class="ml-1">
<ArrowRight />
</el-icon></router-link>
</div>
<div class="space-y-3">
<div
v-for="(item, index) in recoverList"
:key="index"
class="p-4 bg-white rounded-lg hover:shadow-md transition-shadow border-l-4 border-blue-500"
@click="recoverClick(item.id)"
>
<div class="flex items-center justify-between mb-3">
<div class="flex-1">
<div class="flex items-center justify-between">
<h4 class="text-gray-900 font-medium line-clamp-2">
{{ item.title }}
</h4>
<!-- <span class="text-gray-500 text-sm">{{
item.contentDatetime
}}</span> -->
<div class="flex items-center text-sm text-gray-500">
<span>{{ item.contentDatetime }}</span>
<span class="mx-5">留言人:***</span>
<!-- 当有数据时显示回复列表 -->
<template v-if="recoverList && recoverList.length > 0">
<div v-for="(item, index) in recoverList" :key="index"
class="p-4 bg-white rounded-lg hover:shadow-md transition-shadow border-l-4 border-blue-500"
@click="recoverClick(item.id)">
<div class="flex items-center justify-between mb-3">
<div class="flex-1">
<div class="flex items-center justify-between">
<h4 class="text-gray-900 font-medium line-clamp-2">
</h4>
<!-- <span class="text-gray-500 text-sm">{{
item.contentDatetime
}}</span> -->
<div class="flex items-center text-sm text-gray-500">
<span>{{ item.contentDatetime }}</span>
<span class="mx-5">留言人:***</span>
</div>
</div>
</div>
</div>
<h4 class="text-gray-900 font-medium line-clamp-2 mb-2">
{{ item.title }}
</h4>
<p class="text-gray-700 line-clamp-3">{{ item.content }}</p>
</div>
<p class="text-gray-700 line-clamp-3">{{ item.content }}</p>
</div>
</template>
<!-- 当没有数据时显示空状态 -->
<template v-else>
<div class="flex flex-col items-center justify-center p-10 bg-white rounded-lg">
<img src="@/assets/imgs/nothing.png" alt="暂无数据" class="w-[200px] h-[200px] mb-0">
<span class="text-gray-400 text-[14px]">暂无任何回复内容</span>
</div>
</template>
</div>
</div>
</div>
......@@ -99,87 +163,83 @@ import {
Message,
} from "@element-plus/icons-vue";
import { useRouter } from "vue-router";
import { getHotList, getRecoverList } from "@/api/wm/wm";
import { getHotList as rawGetHotList, getRecoverList as rawGetRecoverList } from "@/api/wm/wm";
// 热点留言列表项接口
interface HotListItem {
id: number;
contentDatetime: string;
replyStatus: string;
title: string;
content: string;
}
// 最新回复列表项接口
interface RecoverListItem {
id: number;
contentDatetime: string;
title: string;
content: string;
}
// API响应数据接口
interface ApiResponse<T> {
data: {
rows: T[];
total?: number;
};
code?: number;
message?: string;
}
// 为API函数添加类型断言
type ApiFunction<T> = (params: any) => Promise<ApiResponse<T>>;
const getHotList = rawGetHotList as ApiFunction<HotListItem>;
const getRecoverList = rawGetRecoverList as ApiFunction<RecoverListItem>;
const router = useRouter();
const hotTopics = ref([
{
date: "2024-01-05",
status: "已回复",
content: "建议在东湖公园增设休息座椅和遮阳设施",
},
{
date: "2024-01-04",
status: "处理中",
content: "关于西山路交通拥堵问题的建议",
},
{
date: "2024-01-04",
status: "已回复",
content: "希望增加春熙路商圈的停车位",
},
{
date: "2024-01-03",
status: "已回复",
content: "建议优化公交线路覆盖范围",
},
{
date: "2024-01-03",
status: "已回复",
content: "建议优化公交线路覆盖范围",
},
{
date: "2024-01-03",
status: "已回复",
content: "建议优化公交线路覆盖范围",
},
]);
const replies = ref([
{
department: "市政服务中心",
title: "关于公园设施改善的回复",
date: "2024-01-05",
content:
"感谢您的建议。我局已安排相关部门实地考察,将在东湖公园增设 20 组休息座椅和 8 处遮阳凉亭,预计本月内完工。",
},
import gzhIcon from "@/assets/imgs/gzh-icon.png";
import wxIcon from "@/assets/imgs/wx-icon.png";
import dyIcon from "@/assets/imgs/dy-icon.png";
import sphIcon from "@/assets/imgs/sph-icon.png";
import jrttIcon from "@/assets/imgs/jrtt-icon.png";
const mediaAccountList = ref([
{
department: "公共服务管理处",
title: "关于西山路交通问题的回复",
date: "2024-01-04",
content:
"关于西山路拥堵问题,我们已制定改善方案:1. 优化信号灯配时;2. 增设潮汐车道;3. 加强交通疏导。预计一周内见效。",
name: "公众号",
img: wxIcon,
qrCode: "",
url: "http://wlwz.taiyuan.gov.cn:9092/wmyhs/#/",
},
{
department: "城建服务中心",
title: "关于春熙路停车问题的答复",
date: "2024-01-04",
content:
"春熙路地下停车场扩建工程已列入今年重点项目,将新增车位 500 个,预计 6 月完工。",
name: "抖⾳号",
img: dyIcon,
qrCode: "",
url: "https://v.douyin.com/j6f2GF1moCg/",
},
{
department: "城建服务中心",
title: "关于春熙路停车问题的答复",
date: "2024-01-04",
content:
"春熙路地下停车场扩建工程已列入今年重点项目,将新增车位 500 个,预计 6 月完工。",
name: "视频号",
img: sphIcon,
qrCode: sphIcon,
url: "",
},
{
department: "城建服务中心",
title: "关于春熙路停车问题的答复",
date: "2024-01-04",
content:
"春熙路地下停车场扩建工程已列入今年重点项目,将新增车位 500 个,预计 6 月完工。",
name: "今⽇头条号",
img: jrttIcon,
qrCode: "",
url: "https://profile.zjurl.cn/rogue/ugc/profile/?active_tab=dongtai&app_name=news_article&device_id=65&media_id=1749004825668611&module_name=iOS_tt_url&request_source=1&share_token=8A789140-6E78-4E94-8126-3061A3884A82&tt_from=copy_link&upstream_biz=iOS_url&user_id=734914904863531&utm_campaign=client_share&utm_medium=toutiao_ios&utm_source=copy_link&version_code=14.7.0&version_name=140700",
},
]);
// //更多留言
// function moreMessageClick() {
// // router.push(path:"/wm/messagelist");
// router.push({
// path: "/wm/messagelist",
// });
// }
const hotList = ref([]);
const recoverList = ref([]);
function handleClick(url: string) {
if (url) {
window.open(url, "_blank");
}
}
const hotList = ref<HotListItem[]>([]);
const recoverList = ref<RecoverListItem[]>([]);
getList1(6, 1);
getList2(6, 1);
......@@ -190,7 +250,7 @@ function getList1(pageSize: number, pageNo: number) {
pageSize: pageSize,
pageNo: pageNo,
};
getHotList(datas).then((response) => {
getHotList(datas).then((response: ApiResponse<HotListItem>) => {
const data = response.data;
const rowsList = data.rows;
hotList.value = rowsList;
......@@ -203,7 +263,7 @@ function getList2(pageSize: number, pageNo: number) {
pageSize: pageSize,
pageNo: pageNo,
};
getRecoverList(datas).then((response) => {
getRecoverList(datas).then((response: ApiResponse<RecoverListItem>) => {
const data = response.data;
const rowsList = data.rows;
recoverList.value = rowsList;
......@@ -229,7 +289,7 @@ function recoverClick(id: number) {
});
}
//更多回复
function moreRecoverClick() {}
function moreRecoverClick() { }
</script>
<style lang="scss" scoped></style>
......@@ -42,7 +42,7 @@ export default defineConfig({
// 是否开启 https
https: false,
// 端口号
port: 8080,
port: 8081,
host: "0.0.0.0",
// 本地跨域代理 https://cn.vitejs.dev/config/server-options.html#server-proxy
proxy: {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment