Commit e9938e34 by York

提交

parent af7382ab
......@@ -8,11 +8,18 @@
"name": "emergency-project",
"version": "0.0.0",
"dependencies": {
"@vue-office/docx": "^1.6.3",
"@vue-office/excel": "^1.7.14",
"@vue-office/pdf": "^2.0.10",
"@vue-office/pptx": "^1.0.1",
"axios": "^1.7.9",
"element-plus": "^2.9.1",
"element-plus": "^2.9.3",
"file-saver": "^2.0.5",
"nprogress": "^0.2.0",
"pinia": "^2.3.0",
"swiper": "^11.1.15",
"swiper": "^11.2.1",
"vue": "^3.5.13",
"vue-demi": "^0.14.6",
"vue-router": "^4.5.0"
},
"devDependencies": {
......@@ -1408,6 +1415,70 @@
"vscode-uri": "^3.0.8"
}
},
"node_modules/@vue-office/docx": {
"version": "1.6.3",
"resolved": "https://repo.huaweicloud.com/repository/npm/@vue-office/docx/-/docx-1.6.3.tgz",
"integrity": "sha512-Cs+3CAaRBOWOiW4XAhTwwxJ0dy8cPIf6DqfNvYcD3YACiLwO4kuawLF2IAXxyijhbuOeoFsfvoVbOc16A/4bZA==",
"hasInstallScript": true,
"peerDependencies": {
"@vue/composition-api": "^1.7.1",
"vue": "^2.0.0 || >=3.0.0",
"vue-demi": "^0.14.6"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/@vue-office/excel": {
"version": "1.7.14",
"resolved": "https://repo.huaweicloud.com/repository/npm/@vue-office/excel/-/excel-1.7.14.tgz",
"integrity": "sha512-pVUgt+emDQUnW7q22CfnQ+jl43mM/7IFwYzOg7lwOwPEbiVB4K4qEQf+y/bc4xGXz75w1/e3Kz3G6wAafmFBFg==",
"hasInstallScript": true,
"peerDependencies": {
"@vue/composition-api": "^1.7.1",
"vue": "^2.0.0 || >=3.0.0",
"vue-demi": "^0.14.6"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/@vue-office/pdf": {
"version": "2.0.10",
"resolved": "https://repo.huaweicloud.com/repository/npm/@vue-office/pdf/-/pdf-2.0.10.tgz",
"integrity": "sha512-yHVLrMAKpMPBkhBwofFyGEtEeJF0Zd7oGmf56Pe5aj/xObdRq3E1CIZqTqhWJNgHV8oLQqaX0vs4p5T1zq+GIA==",
"hasInstallScript": true,
"peerDependencies": {
"@vue/composition-api": "^1.7.1",
"vue": "^2.0.0 || >=3.0.0",
"vue-demi": "^0.14.6"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/@vue-office/pptx": {
"version": "1.0.1",
"resolved": "https://repo.huaweicloud.com/repository/npm/@vue-office/pptx/-/pptx-1.0.1.tgz",
"integrity": "sha512-+V7Kctzl6f6+Yk4NaD/wQGRIkqLWcowe0jEhPexWQb8Oilbzt1OyhWRWcMsxNDTdrgm6aMLP+0/tmw27cxddMg==",
"hasInstallScript": true,
"peerDependencies": {
"@vue/composition-api": "^1.7.1",
"vue": "^2.0.0 || >=3.0.0",
"vue-demi": "^0.14.6"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/@vue/babel-helper-vue-transform-on": {
"version": "1.2.5",
"resolved": "https://repo.huaweicloud.com/repository/npm/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.2.5.tgz",
......@@ -2192,9 +2263,9 @@
"dev": true
},
"node_modules/element-plus": {
"version": "2.9.1",
"resolved": "https://repo.huaweicloud.com/repository/npm/element-plus/-/element-plus-2.9.1.tgz",
"integrity": "sha512-9Agqf/jt4Ugk7EZ6C5LME71sgkvauPCsnvJN12Xid2XVobjufxMGpRE4L7pS4luJMOmFAH3J0NgYEGZT5r+NDg==",
"version": "2.9.3",
"resolved": "https://repo.huaweicloud.com/repository/npm/element-plus/-/element-plus-2.9.3.tgz",
"integrity": "sha512-6tSLp5XytDS4TMZ0P3aGZnr7MXTagfNycepNfIDitd9IgwM9y01+Ssu6mglNi8RiXYhek6LBWNOd/cvpIO12+w==",
"dependencies": {
"@ctrl/tinycolor": "^3.4.1",
"@element-plus/icons-vue": "^2.3.1",
......@@ -2379,6 +2450,11 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/file-saver": {
"version": "2.0.5",
"resolved": "https://repo.huaweicloud.com/repository/npm/file-saver/-/file-saver-2.0.5.tgz",
"integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA=="
},
"node_modules/fill-range": {
"version": "7.1.1",
"resolved": "https://repo.huaweicloud.com/repository/npm/fill-range/-/fill-range-7.1.1.tgz",
......@@ -3154,6 +3230,11 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/nprogress": {
"version": "0.2.0",
"resolved": "https://repo.huaweicloud.com/repository/npm/nprogress/-/nprogress-0.2.0.tgz",
"integrity": "sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA=="
},
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://repo.huaweicloud.com/repository/npm/object-assign/-/object-assign-4.1.1.tgz",
......@@ -3322,6 +3403,31 @@
}
}
},
"node_modules/pinia/node_modules/vue-demi": {
"version": "0.14.10",
"resolved": "https://repo.huaweicloud.com/repository/npm/vue-demi/-/vue-demi-0.14.10.tgz",
"integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
"vue-demi-switch": "bin/vue-demi-switch.js"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
},
"peerDependencies": {
"@vue/composition-api": "^1.0.0-rc.1",
"vue": "^3.0.0-0 || ^2.6.0"
},
"peerDependenciesMeta": {
"@vue/composition-api": {
"optional": true
}
}
},
"node_modules/pirates": {
"version": "4.0.6",
"resolved": "https://repo.huaweicloud.com/repository/npm/pirates/-/pirates-4.0.6.tgz",
......@@ -3914,9 +4020,9 @@
"dev": true
},
"node_modules/swiper": {
"version": "11.1.15",
"resolved": "https://repo.huaweicloud.com/repository/npm/swiper/-/swiper-11.1.15.tgz",
"integrity": "sha512-IzWeU34WwC7gbhjKsjkImTuCRf+lRbO6cnxMGs88iVNKDwV+xQpBCJxZ4bNH6gSrIbbyVJ1kuGzo3JTtz//CBw==",
"version": "11.2.1",
"resolved": "https://repo.huaweicloud.com/repository/npm/swiper/-/swiper-11.2.1.tgz",
"integrity": "sha512-62G69+iQRIfUqTmJkWpZDcX891Ra8O9050ckt1/JI2H+0483g+gq0m7gINecDqMtDh2zt5dK+uzBRxGhGOOvQA==",
"funding": [
{
"type": "patreon",
......@@ -4274,9 +4380,9 @@
}
},
"node_modules/vue-demi": {
"version": "0.14.10",
"resolved": "https://repo.huaweicloud.com/repository/npm/vue-demi/-/vue-demi-0.14.10.tgz",
"integrity": "sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==",
"version": "0.14.6",
"resolved": "https://repo.huaweicloud.com/repository/npm/vue-demi/-/vue-demi-0.14.6.tgz",
"integrity": "sha512-8QA7wrYSHKaYgUxDA5ZC24w+eHm3sYCbp0EzcDwKqN3p6HqtTCGR/GVsPyZW92unff4UlcSh++lmqDWN3ZIq4w==",
"hasInstallScript": true,
"bin": {
"vue-demi-fix": "bin/vue-demi-fix.js",
......
......@@ -10,13 +10,18 @@
"type-check": "vue-tsc --build"
},
"dependencies": {
"@vue-office/docx": "^1.6.3",
"@vue-office/excel": "^1.7.14",
"@vue-office/pdf": "^2.0.10",
"@vue-office/pptx": "^1.0.1",
"axios": "^1.7.9",
"element-plus": "^2.9.1",
"element-plus": "^2.9.3",
"file-saver": "^2.0.5",
"nprogress": "^0.2.0",
"pinia": "^2.3.0",
"swiper": "^11.1.15",
"swiper": "^11.2.1",
"vue": "^3.5.13",
"vue-demi": "^0.14.6",
"vue-router": "^4.5.0"
},
"devDependencies": {
......
No preview for this file type
<template>
<ElConfigProvider :locale="zhCn">
<router-view />
</ElConfigProvider>
</template>
<script setup></script>
<script setup lang="ts">
import { ElConfigProvider } from "element-plus";
import { zhCn } from "element-plus/es/locale/index";
</script>
......@@ -5,7 +5,7 @@ export function getHotList(data) {
return request({
url: "/cms/content/list",
method: "get",
params: data,
data: data,
});
}
......@@ -14,7 +14,7 @@ export function getRecoverList(data) {
return request({
url: "/cms/content/list",
method: "get",
params: data,
data: data,
});
}
......@@ -23,6 +23,24 @@ export function getWantMessage(data) {
return request({
url: "/cms/content/list",
method: "post",
params: data,
data: data,
});
}
// 留言详情
export function getMessageDetail(data) {
return request({
url: "/cms/content/list",
method: "get",
data: data,
});
}
//多文件上传
export function uploadFile(data) {
return request({
url: "/cms/content/list",
method: "post",
data: data,
});
}
......@@ -4,7 +4,7 @@
<el-breadcrumb-item
v-for="(item, index) in breadcrumbItems"
:key="index"
:to="{ path: item.path }"
:to="{ path: item.path, query: { searchQuery: item.contentTitle } }"
>
{{ item.title }}
</el-breadcrumb-item>
......
......@@ -13,7 +13,10 @@
class="group p-4 flex items-start border-b border-gray-100 hover:bg-gray-50 transition-colors cursor-pointer"
@click="getToDetail(item.id)"
>
<div class="w-32 h-32 flex-shrink-0 overflow-hidden rounded-lg">
<div
v-if="item.images != null"
class="w-32 h-32 flex-shrink-0 overflow-hidden rounded-lg"
>
<img :src="item.images" class="w-full h-full object-cover" />
</div>
<div class="flex-grow px-6">
......@@ -30,10 +33,10 @@
<el-icon class="mr-1"><Clock /></el-icon>
{{ item.contentDatetime }}
</span>
<span class="text-sm text-gray-500 flex items-center">
<!-- <span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1"><Document /></el-icon>
{{ item.contentTags }}
</span>
</span> -->
<span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1"><View /></el-icon>
{{ item.contentHit }}
......@@ -103,7 +106,10 @@
class="group cursor-pointer"
@click="getToDetail(item.id)"
>
<div class="h-32 mb-2 overflow-hidden rounded-lg">
<div
v-if="item.images != null"
class="h-32 mb-2 overflow-hidden rounded-lg"
>
<img :src="item.images" class="w-full h-full object-cover" />
</div>
<div
......
......@@ -3,11 +3,7 @@
<!-- 顶部横幅 -->
<header class="bg-white shadow">
<div class="container mx-auto px-0 h-20 flex items-center">
<img
src="https://ai-public.mastergo.com/ai/img_res/38fd70bdc77f4305c862a0962f46c48c.jpg"
alt="国徽"
class="h-14 mr-4"
/>
<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">
太原市互联网应急指挥和举报中心
......@@ -16,7 +12,7 @@
<el-input
v-model="searchQuery"
class="!rounded-full"
placeholder="搜索新闻、通知、政策文件..."
placeholder="搜索新闻、通知..."
:prefix-icon="Search"
@keyup.enter="handleSearch"
/>
......@@ -121,7 +117,10 @@ function navigateTo(index, item) {
function handleSearch() {
if (searchQuery.value) {
router.push({ path: "/home/search", query: { searchQuery: searchQuery.value } });
router.push({
path: "/home/search",
query: { searchQuery: searchQuery.value },
});
} else {
ElMessage({
message: "请输入搜索内容",
......
......@@ -5,10 +5,15 @@
<div class="container mx-auto px-8 py-4">
<div class="flex items-center justify-between">
<div class="flex items-center space-x-4">
<h1 class="text-2xl font-bold">山西互联网联合辟谣平台</h1>
<p class="text-sm opacity-80">主办:山西省互联网信息办公室</p>
<h1 class="text-2xl font-bold cursor-pointer" @click="goToHome()">
太原市互联网联合辟谣平台
</h1>
<!-- <p class="text-sm opacity-80">主办:山西省互联网信息办公室</p> -->
</div>
<div class="text-sm opacity-80">承办:黄河新闻网</div>
<p class="text-sm opacity-80 cursor-pointer" @click="goToHome()">
主办:太原市互联网应急指挥和举报中心
</p>
<!-- <div class="text-sm opacity-80">承办:黄河新闻网</div> -->
</div>
</div>
<nav class="bg-white/10 backdrop-blur-sm">
......@@ -65,6 +70,13 @@ const router = useRouter();
const navItems = ref([]);
function goToHome() {
if (window.opener && !window.opener.closed) {
window.opener.focus(); // 将焦点返回到原始窗口
window.close(); // 关闭当前新窗口
}
}
const data = {
categoryFlag: HLW_LH_PYPT,
};
......
<!-- 代码已包含 CSS:使用 TailwindCSS , 安装 TailwindCSS 后方可看到布局样式效果 -->
<template>
<div class="min-h-screen bg-gray-50">
<div class="min-h-screen bg-gray-100">
<div class="mx-auto">
<!-- Hero区域 -->
<div class="relative h-[330px] mb-8 overflow-hidden">
......@@ -14,10 +14,14 @@
class="absolute inset-0 bg-gradient-to-r from-blue-900/90 via-blue-900/70 to-transparent"
></div>
</div>
<div class="relative flex flex-col justify-center h-full px-12">
<div class="relative flex flex-col justify-center h-full px-12 ms-24">
<!-- 顶部区域 -->
<div class="flex items-center justify-between mb-12">
<h2 class="text-5xl font-bold text-white max-w-xl leading-tight">
<div class="mb-10">
<h2
@click="goToHome()"
class="text-5xl font-bold text-white max-w-xl leading-tight cursor-pointer"
>
网民
<span
class="text-6xl"
......@@ -25,11 +29,13 @@
>有话说</span
>
</h2>
<div class="max-w-2xl bg-white/10 backdrop-blur-sm p-4 rounded-lg">
<div
class="max-w-2xl bg-white/0 backdrop-blur-sm p-2 rounded-lg cursor-pointer"
@click="goToHome()"
>
<p class="text-gray-100 text-sm leading-relaxed">
"倾听民声,解决民忧。让我们共同建设更美好的城市生活。各级政府部门要深入基层,了解群众所需所盼,及时回应群众关切,让互联网成为连接政府与群众的新桥梁。"
主办:太原市互联网应急指挥和举报中心
</p>
<p class="text-right mt-2 text-gray-200">—— 市长 陈志强</p>
</div>
</div>
<p class="text-xl text-gray-200 max-w-xl mb-6">
......@@ -40,6 +46,7 @@
v-model="searchQuery"
placeholder="搜索您关注的问题..."
class="!w-[360px] custom-input"
@keyup.enter="handleSearch"
>
<template #prefix>
<el-icon><Search /></el-icon>
......@@ -49,6 +56,7 @@
<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>
<span>搜索</span>
......@@ -69,7 +77,7 @@
<!-- 页脚 -->
<footer class="footer-footer py-12 mt-8">
<div class="max-w-7xl mx-auto px-6">
<div class="w-[1440px] mx-auto px-6">
<div class="grid grid-cols-3 gap-8 mb-8">
<div>
<h4 class="font-bold text-lg mb-4 text-white">联系我们</h4>
......@@ -125,8 +133,16 @@ import {
Message,
} from "@element-plus/icons-vue";
import { useRouter } from "vue-router";
import { ElMessage } from "element-plus";
const router = useRouter();
function goToHome() {
if (window.opener && !window.opener.closed) {
window.opener.focus(); // 将焦点返回到原始窗口
window.close(); // 关闭当前新窗口
}
}
router.push({
path: "/wm/wmhome",
});
......@@ -138,6 +154,20 @@ function iMessageClick() {
path: "/wm/imessage",
});
}
function handleSearch() {
if (searchQuery.value) {
router.push({
path: "/wm/search",
query: { searchQuery: searchQuery.value },
});
} else {
ElMessage({
message: "请输入搜索内容",
type: "warning",
});
}
}
</script>
<style scoped>
.footer-footer {
......
......@@ -29,6 +29,7 @@ import RecoverList from "../views/wm/recover/RecoverList.vue";
import MessageDetail from "../views/wm/message/MessageDetail.vue";
import RecoverDetail from "../views/wm/recover/RecoverDetail.vue";
import IMessage from "../views/wm/imessage/IMessage.vue";
import WmSearchList from "../views/wm/search/WmSearchList.vue";
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
......@@ -159,6 +160,11 @@ const router = createRouter({
path: "/wm/imessage",
component: IMessage,
},
{
name: "WmSearchList",
path: "/wm/search",
component: WmSearchList,
},
],
},
],
......
......@@ -29,7 +29,7 @@
</div>
</div>
<div v-html="details.content"></div>
<div class="editor-content" v-html="details.content"></div>
</div>
<!-- 右侧边栏 -->
......@@ -47,7 +47,10 @@
class="group cursor-pointer"
@click="itemTyClick(item.id)"
>
<div class="relative h-40 mb-2 overflow-hidden rounded-lg">
<div
v-if="item.images != null"
class="relative h-40 mb-2 overflow-hidden rounded-lg"
>
<img
:src="item.images"
:alt="item.contentTitle"
......@@ -119,9 +122,13 @@ const route = useRoute();
const router = useRouter();
const breadcrumbItems = ref([
{ title: "首页", path: "/home/home" },
{ title: route.query.title, path: route.query.titlePath },
{ title: "详情", path: "" },
{ title: "首页", path: "/home/home", contentTitle: "" },
{
title: route.query.title,
path: route.query.titlePath,
contentTitle: route.query.contentTitle,
},
{ title: "详情", path: "", contentTitle: "" },
]);
const breadcrumbItems2 = ref([
......@@ -129,36 +136,6 @@ const breadcrumbItems2 = ref([
{ title: "详情", path: "" },
]);
function toRouteName() {
switch (route.query.type) {
case "0":
return "首页";
case "1":
return "新闻热点";
case "2":
return "太原新闻";
case "3":
return "山西新闻";
case "4":
return "通知公告";
}
}
function toRoute() {
switch (route.query.type) {
case "0":
return "/home/home";
case "1":
return "/home/news";
case "2":
return "/home/tynews";
case "3":
return "/home/sxnews";
case "4":
return "/home/announcements";
}
}
const hotNews = ref([]);
const announcements = ref([]);
......@@ -183,30 +160,8 @@ function getHotsNewsList(pageSize: number, pageNo: number) {
});
}
function itemTyClick(id: number) {
router.push({
path: "/home/news/detail",
query: {
type: toType(),
id: id,
tabId: route.query.tabId,
},
});
}
function toType() {
switch (route.query.type) {
case "0":
return "0";
case "1":
return "1";
case "2":
return "2";
case "3":
return "3";
case "4":
return "4";
}
function itemTyClick(id: any) {
getNewsDetails(id);
}
getTzGgNewsList(5, 1);
......@@ -244,27 +199,20 @@ watch(
() => route.query.id,
(newVal, oldVal) => {
if (newVal) {
data.id = newVal;
getNewsDetail(data).then((res) => {
details.value = res.data;
console.log(details.value);
});
getNewsDetails(newVal);
}
}
);
getNewsDetail(data).then((res) => {
details.value = res.data;
console.log(details.value);
});
getNewsDetails(route.query.id);
function itemClicks(id: number) {
router.push({
path: "/home/news/detail",
query: {
function getNewsDetails(id: any) {
const data = {
id: id,
tabId: route.query.tabId,
},
};
getNewsDetail(data).then((res) => {
details.value = res.data;
console.log(details.value);
});
}
</script>
......@@ -279,4 +227,8 @@ function itemClicks(id: number) {
margin-bottom: 1.5rem;
line-height: 1.75;
}
:deep(.editor-content p img) {
max-width: 100%;
}
</style>
......@@ -29,7 +29,7 @@
</swiper>
</div>
<!-- 快捷入口 -->
<div class="container mx-auto px-4 mt-10 w-[1440px]">
<div class="container mx-auto px-4 mt-8 w-[1440px]">
<div class="grid grid-cols-3 gap-6">
<div
v-for="(entry, index) in quickEntries"
......@@ -61,16 +61,17 @@
</div>
</div>
<!-- 新闻内容区 -->
<div class="container mx-auto px-4 mt-10 grid grid-cols-3 gap-6 w-[1440px]">
<div class="container mx-auto px-4 mt-8 grid grid-cols-3 gap-6 w-[1440px]">
<!-- 最新新闻 -->
<div class="col-span-2 bg-white rounded-lg p-6 shadow-sm">
<div class="flex justify-between items-center mb-4">
<h2 class="text-xl font-bold" style="color: #000">太原新闻</h2>
<el-button
v-if="true"
type="primary"
class="!rounded-button"
text
@click="goToTyMoreList()"
@click="goToTyMoreList(1)"
>更多</el-button
>
</div>
......@@ -86,7 +87,11 @@
:src="item.images"
fit="fill"
/> -->
<img :src="item.images" class="w-32 h-24 object-cover rounded" />
<img
v-if="item.images != null"
:src="item.images"
class="w-32 h-24 object-cover rounded"
/>
<div>
<h3
......@@ -109,8 +114,18 @@
<div class="space-y-6">
<!-- 热门新闻 -->
<div class="bg-white rounded-lg p-6 shadow-sm">
<h2 class="text-xl font-bold mb-4" style="color: #000">热门新闻</h2>
<div class="space-y-4">
<div class="flex justify-between items-center mb-4">
<h2 class="text-xl font-bold" style="color: #000">热门新闻</h2>
<el-button
v-if="true"
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"
......@@ -160,15 +175,19 @@
</div>
</div>
<!-- 权威发布与辟谣专区 -->
<div class="container mx-auto px-4 mt-10 w-[1440px]">
<div class="container mx-auto px-4 mt-8 w-[1440px]">
<div class="grid grid-cols-2 gap-6">
<!-- 权威发布 -->
<div class="bg-white rounded-lg p-6 shadow-sm">
<div class="flex justify-between items-center mb-4">
<h2 class="text-xl font-bold text-black">权威发布</h2>
<!-- <el-button type="primary" class="!rounded-button" text
<el-button
type="primary"
class="!rounded-button"
text
@click="goToTyMoreList(3)"
>更多</el-button
> -->
>
</div>
<div class="space-y-4">
<div
......@@ -195,9 +214,13 @@
<div class="bg-white rounded-lg p-6 shadow-sm">
<div class="flex justify-between items-center mb-4">
<h2 class="text-xl font-bold text-black">辟谣专区</h2>
<!-- <el-button type="primary" class="!rounded-button" text
<el-button
type="primary"
class="!rounded-button"
text
@click="goToTyMoreList(4)"
>更多</el-button
> -->
>
</div>
<div class="space-y-4">
<div
......@@ -208,6 +231,7 @@
>
<div class="flex-shrink-0 w-24 h-16">
<img
v-if="item.images != null"
:src="item.images"
class="w-full h-full object-cover rounded"
/>
......@@ -233,7 +257,7 @@
</div>
</div>
<!-- 友情链接 -->
<div class="container mx-auto px-4 mt-10 mb-10 w-[1440px]">
<div class="container mx-auto px-4 mt-8 mb-8 w-[1440px]">
<div class="bg-white rounded-lg p-6 shadow-sm">
<h2 class="text-xl font-bold mb-4 text-black">友情链接</h2>
<div class="grid grid-cols-6 gap-4">
......@@ -242,7 +266,7 @@
:key="index"
:href="link.url"
target="_blank"
class="text-gray-600 hover:text-blue-600"
class="text-gray-600 hover:text-blue-600 text-center"
>
{{ link.name }}
</a>
......@@ -342,16 +366,48 @@ function goToDetail(id: number) {
});
}
//太原更多
function goToTyMoreList() {
function goToTyMoreList(index: number) {
switch (index) {
case 1: //太原新闻-更多
router.push({
path: "/home/tynews",
query: {
type: 0,
},
});
break;
case 2: //热门新闻-更多
router.push({
path: "/home/news",
query: {
type: 1,
},
});
break;
case 3: //辟谣专区-更多
// 打开新标签
let routeData1 = router.resolve({
path: "/py/authority",
query: {
type: 1,
},
});
window.open(routeData1.href, "_blank");
break;
case 4: //辟谣专区-更多
// 打开新标签
let routeData2 = router.resolve({
path: "/py/rumor",
query: {
type: 1,
},
});
window.open(routeData2.href, "_blank");
break;
}
}
getHotsNewsList(4, 1);
getHotsNewsList(5, 1);
//获取新闻热点
function getHotsNewsList(pageSize: number, pageNo: number) {
......@@ -367,7 +423,7 @@ function getHotsNewsList(pageSize: number, pageNo: number) {
});
}
getQwList(5, 1);
getQwList(4, 1);
//获取权威发布
function getQwList(pageSize: number, pageNo: number) {
......
......@@ -15,6 +15,7 @@
>
<div class="w-32 h-32 flex-shrink-0 overflow-hidden rounded-lg">
<el-image
v-if="news.images != null"
class="w-full h-full object-cover"
:src="news.images"
fit="fill"
......@@ -34,17 +35,17 @@
<el-icon class="mr-1"><Clock /></el-icon>
{{ news.contentDatetime }}
</span>
<span class="text-sm text-gray-500 flex items-center">
<!-- <span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1"><Document /></el-icon>
{{ news.contentTags }}
</span>
</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">
<!-- <div class="w-24 flex-shrink-0 text-right text-blue-500">
<el-tag
:type="news.contentTags"
size="small"
......@@ -52,7 +53,7 @@
>
{{ news.contentTags }}
</el-tag>
</div>
</div> -->
</div>
</div>
<div class="flex justify-center mt-8">
......@@ -99,6 +100,7 @@
:fit="fit"
></el-image> -->
<img
v-if="item.images != null"
:src="item.images"
:alt="item.title"
class="w-full h-full object-cover"
......
......@@ -9,7 +9,7 @@
>首页</router-link
>
<el-icon class="mx-2"><ArrowRight /></el-icon>
<span class="text-gray-900">留言列表</span>
<span class="text-gray-900">太原市互联网违法和不良信息举报平台</span>
</div>
<!-- 页面标题 -->
......@@ -44,7 +44,7 @@
<div class="grid grid-cols-3 gap-8">
<!-- 中央网信办举报入口 -->
<div
class="border rounded-lg p-6 flex flex-col items-center justify-center hover:shadow-md transition-shadow bg-gray-50"
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
......@@ -59,7 +59,7 @@
</div>
<!-- 山西省举报入口 -->
<div
class="border rounded-lg p-6 flex flex-col items-center justify-center hover:shadow-md transition-shadow bg-gray-50"
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
......@@ -76,7 +76,7 @@
</div>
<!-- 太原市举报入口 -->
<div
class="border rounded-lg p-6 flex flex-col items-center justify-center hover:shadow-md transition-shadow bg-gray-50"
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
......@@ -116,7 +116,7 @@
</ol>
</div>
<div>
<h3 class="font-medium mb-4">二、注意事项</h3>
<h3 class="font-medium mb-4 text-black">二、注意事项</h3>
<ol class="list-decimal list-inside space-y-2 text-gray-700">
<li>请您自觉遵守中华人民共和国宪法和法律。</li>
<li>举报应当实事求是,应对举报内容的真实性、客观性负责。</li>
......@@ -178,13 +178,15 @@ import { Phone, Message, ArrowRight } from "@element-plus/icons-vue";
function goUrl(type: number) {
switch (type) {
case 1: //中央网信办
window.open("https://www.baidu.com/");
window.open("https://www.12377.cn");
break;
case 2: //山西省举报中心
window.open("https://www.tynews.cn/");
window.open("https://www.sxgov.cn/node_280205.htm");
break;
case 3: //太原市举报平台
window.open("https://www.tynews.cn/");
window.open(
"http://oa.wangxinban.cn/jb/#/Home/Home?agencyID=52340bbb-f782-4886-02c4-08d9605acd8c&agencyName=太原市网信"
);
break;
}
}
......
......@@ -34,17 +34,17 @@
<el-icon class="mr-1"><Clock /></el-icon>
{{ news.contentDatetime }}
</span>
<span class="text-sm text-gray-500 flex items-center">
<!-- <span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1"><Document /></el-icon>
{{ news.contentTags }}
</span>
</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">
<!-- <div class="w-24 flex-shrink-0 text-right text-blue-500">
<el-tag
:type="news.contentTags"
size="small"
......@@ -52,7 +52,7 @@
>
{{ news.contentTags }}
</el-tag>
</div>
</div> -->
</div>
</div>
<div class="flex justify-center mt-8">
......@@ -139,7 +139,7 @@
</div>
</template>
<script lang="ts" setup>
import { ref } from "vue";
import { ref, watch } from "vue";
import { getNewsList } from "@/api/home/news/list";
import { baseImageUrl, rdxw, tyxw, tzgg } from "@/utils/config";
import {
......@@ -174,7 +174,7 @@ const handleSizeChange = (val: number) => {
const handleCurrentChange = (val: number) => {
pageSize.value = pageSize.value;
pageNo.value = val;
getList(pageSize.value, pageNo.value);
getList(route.query.searchQuery, pageSize.value, pageNo.value);
};
const newsList = ref([]);
const tyNews = ref([]);
......@@ -222,13 +222,22 @@ function getTzGgNewsList(pageSize: number, pageNo: number) {
});
}
getList(pageSize.value, pageNo.value);
// 监听数据变化
watch(
() => route.query.searchQuery,
(newVal, oldVal) => {
if (newVal) {
getList(newVal, pageSize.value, pageNo.value);
}
}
);
getList(searchQuery, pageSize.value, pageNo.value);
//获取新闻热点列表
function getList(pageSize: number, pageNo: number) {
// newsList.value = [];
function getList(searchQuery: any, pageSize: number, pageNo: number) {
const datas = {
contentType: rdxw,
contentTitle: searchQuery,
pageSize: pageSize,
pageNo: pageNo,
};
......@@ -253,6 +262,7 @@ function getToDetail(id: number) {
query: {
title: "搜索结果",
titlePath: "/home/search",
contentTitle: route.query.searchQuery,
type: 1,
id: id,
},
......
......@@ -15,6 +15,7 @@
>
<div class="w-32 h-32 flex-shrink-0 overflow-hidden rounded-lg">
<el-image
v-if="news.images != null"
class="w-full h-full object-cover"
:src="news.images"
fit="fill"
......@@ -34,17 +35,17 @@
<el-icon class="mr-1"><Clock /></el-icon>
{{ news.contentDatetime }}
</span>
<span class="text-sm text-gray-500 flex items-center">
<!-- <span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1"><Document /></el-icon>
{{ news.contentTags }}
</span>
</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">
<!-- <div class="w-24 flex-shrink-0 text-right text-blue-500">
<el-tag
:type="news.contentTags"
size="small"
......@@ -52,7 +53,7 @@
>
{{ news.contentTags }}
</el-tag>
</div>
</div> -->
</div>
</div>
<div class="flex justify-center mt-8">
......
......@@ -15,6 +15,7 @@
>
<div class="w-32 h-32 flex-shrink-0 overflow-hidden rounded-lg">
<el-image
v-if="news.images != null"
class="w-full h-full object-cover"
:src="news.images"
fit="fill"
......@@ -34,17 +35,17 @@
<el-icon class="mr-1"><Clock /></el-icon>
{{ news.contentDatetime }}
</span>
<span class="text-sm text-gray-500 flex items-center">
<!-- <span class="text-sm text-gray-500 flex items-center">
<el-icon class="mr-1"><Document /></el-icon>
{{ news.contentTags }}
</span>
</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">
<!-- <div class="w-24 flex-shrink-0 text-right text-blue-500">
<el-tag
:type="news.contentTags"
size="small"
......@@ -52,7 +53,7 @@
>
{{ news.contentTags }}
</el-tag>
</div>
</div> -->
</div>
</div>
<div class="flex justify-center mt-8">
......
......@@ -29,7 +29,7 @@
</div>
</div>
<div v-html="details.content"></div>
<div class="editor-content" v-html="details.content"></div>
</div>
<!-- 右侧边栏 -->
......@@ -47,7 +47,10 @@
class="group cursor-pointer"
@click="goToDetail(item.id)"
>
<div class="relative h-40 mb-2 overflow-hidden rounded-lg">
<div
v-if="item.images != null"
class="relative h-40 mb-2 overflow-hidden rounded-lg"
>
<img
:src="item.images"
:alt="item.contentTitle"
......@@ -126,40 +129,6 @@ const breadcrumbItems2 = ref([
{ title: "详情", path: "" },
]);
// function toRouteName() {
// switch (route.query.type) {
// case "0":
// return "首页";
// case "1":
// return "权威发布";
// case "2":
// return "辟谣专区";
// case "3":
// return "专家解读";
// case "4":
// return "法律法规";
// case "5":
// return "读图识谣";
// }
// }
// function toRoute() {
// switch (route.query.type) {
// case "0":
// return "/py/pyhome";
// case "1":
// return "/py/authority";
// case "2":
// return "/py/rumor";
// case "3":
// return "/py/expert";
// case "4":
// return "/py/law";
// case "5":
// return "/py/reading";
// }
// }
getList1(3, 1);
getList2(5, 1);
......@@ -182,13 +151,7 @@ function getList1(pageSize: number, pageNo: number) {
}
function goToDetail(id: number) {
router.push({
path: "/py/news/detail",
query: {
type: route.query.type,
id: id,
},
});
getNewsDetails(id);
}
//获取通知公告
......@@ -213,28 +176,27 @@ function getList2(pageSize: number, pageNo: number) {
//统计点击数量
getHit(route.query.id);
const data = {
id: route.query.id,
};
// 监听数据变化
watch(
() => route.query.id,
(newVal, oldVal) => {
if (newVal) {
data.id = newVal;
// watch(
// () => route.query.id,
// (newVal, oldVal) => {
// if (newVal) {
// data.id = newVal;
// getNewsDetails(newVal);
// }
// }
// );
getNewsDetails(route.query.id);
function getNewsDetails(id: any) {
const data = {
id: id,
};
getNewsDetail(data).then((res) => {
details.value = res.data;
console.log(details.value);
});
}
}
);
getNewsDetail(data).then((res) => {
details.value = res.data;
console.log(details.value);
});
}
</script>
<style scoped>
......@@ -247,4 +209,7 @@ getNewsDetail(data).then((res) => {
margin-bottom: 1.5rem;
line-height: 1.75;
}
:deep(.editor-content p img) {
max-width: 100%;
}
</style>
......@@ -327,8 +327,8 @@ function getToDetail(id: number) {
path: "/py/news/detail",
query: {
pathType: "-1",
type1: zjjd,
type2: pyzq,
type1: pyzq,
type2: zjjd,
title1: "辟谣专区",
title2: "专家解读",
id: id,
......
......@@ -59,7 +59,7 @@
<div class="flex-1">
<div class="flex items-center justify-between">
<h4 class="text-gray-900 font-medium">{{ item.title }}</h4>
<span class="text-gray-500 text-sm">{{ item.department }}</span>
<span class="text-gray-500 text-sm">{{ item.date }}</span>
</div>
</div>
</div>
......@@ -164,34 +164,35 @@ const replies = ref([
// });
// }
const hotList = ref([]);
const recoverList = ref([]);
getList1(6, 1);
getList2(5, 1);
getList2(6, 1);
//热点留言
function getList1(pageSize: number, pageNo: number) {
const datas = {
contentType: "",
pageSize: pageSize,
pageNo: pageNo,
};
getHotList(datas).then((response) => {
const data = response.data;
const rowsList = data.rows;
// list1.value = rowsList;
hotList.value = rowsList;
});
}
//热点留言
//最新回复
function getList2(pageSize: number, pageNo: number) {
const datas = {
contentType: "",
pageSize: pageSize,
pageNo: pageNo,
};
getRecoverList(datas).then((response) => {
const data = response.data;
const rowsList = data.rows;
// list1.value = rowsList;
recoverList.value = rowsList;
});
}
......
<!-- 代码已包含 CSS:使用 TailwindCSS , 安装 TailwindCSS 后方可看到布局样式效果 -->
<template>
<div class="bg-gray-50">
<div>
<!-- 主要内容区域 -->
<div class="container mx-auto px-0 py-0 w-[1440px]">
<bread-crumb :breadcrumbItems="breadcrumbItems" />
......@@ -76,7 +76,7 @@
<form @submit.prevent="handleSubmit" class="space-y-6">
<div class="space-y-2">
<label class="block text-sm font-medium text-gray-700">
姓名 <span class="text-red-500">*</span>
<span class="text-red-500">*</span> 姓名
</label>
<el-input
v-model="formData.name"
......@@ -86,7 +86,7 @@
</div>
<div class="space-y-2">
<label class="block text-sm font-medium text-gray-700">
留言标题 <span class="text-red-500">*</span>
<span class="text-red-500">*</span> 留言标题
</label>
<el-input
v-model="formData.title"
......@@ -96,7 +96,7 @@
</div>
<div class="space-y-2">
<label class="block text-sm font-medium text-gray-700">
详细内容 <span class="text-red-500">*</span>
<span class="text-red-500">*</span> 详细内容
</label>
<el-input
v-model="formData.content"
......@@ -108,7 +108,7 @@
</div>
<div class="space-y-2">
<label class="block text-sm font-medium text-gray-700">
联系电话 <span class="text-red-500">*</span>
<span class="text-red-500">*</span> 联系电话
</label>
<el-input
v-model="formData.phone"
......@@ -120,7 +120,19 @@
<label class="block text-sm font-medium text-gray-700">
上传附件
</label>
<el-upload class="upload-demo" :auto-upload="false" action="#">
<el-upload
class="upload-demo"
action="https://jsonplaceholder.typicode.com/posts/"
:before-remove="beforeRemove"
multiple
:limit="3"
ref="uploadRef"
:on-success="handleSuccess"
:on-exceed="handleExceed"
:file-list="fileList"
:auto-upload="true"
accept=".jpg,.png,.doc,.docx,.xslx,pdf"
>
<el-button
type="danger"
class="!rounded-button whitespace-nowrap"
......@@ -128,14 +140,14 @@
>
<template #tip>
<div class="text-sm text-gray-500 mt-1">
支持 jpg、png、pdf 格式文件
支持 jpg、jpeg、png、pdf、doc、docx、xslx 格式文件
</div>
</template>
</el-upload>
</div>
<div class="space-y-2">
<label class="block text-sm font-medium text-gray-700">
验证码 <span class="text-red-500">*</span>
<span class="text-red-500">*</span> 验证码
</label>
<div class="flex items-center space-x-4">
<el-input
......@@ -172,10 +184,13 @@
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted } from "vue";
import { ref, onMounted, getCurrentInstance, watch } from "vue";
import { ElMessage } from "element-plus";
import { Warning, ArrowRight } from "@element-plus/icons-vue";
import { Warning, ArrowRight, Message } from "@element-plus/icons-vue";
import BreadCrumb from "@/components/breadcrumb/BreadCrumb.vue";
import { getWantMessage, uploadFile } from "@/api/wm/wm";
import { ElMessageBox } from "element-plus";
// const { proxy } = getCurrentInstance();
const breadcrumbItems = ref([
{ title: "首页", path: "/wm/wmhome" },
......@@ -183,6 +198,7 @@ const breadcrumbItems = ref([
]);
const letters = Array.from("ABCDEFGHJKLMNPQRSTUVWXYZ23456789");
const generateCaptcha = () => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
......@@ -239,16 +255,38 @@ const generateCaptcha = () => {
image: canvas.toDataURL(),
};
};
const captchaText = ref("");
const captchaImage = ref("");
const fileList = ref([]);
const uploadRef = ref();
const refreshCaptcha = () => {
const captcha = generateCaptcha();
captchaText.value = captcha.text;
captchaImage.value = captcha.image;
};
onMounted(() => {
refreshCaptcha();
});
// 文件上传个数限制
function handleExceed(files: any, fileList: any) {
ElMessageBox.alert(`最多只能上传 3 个文件`);
}
//文件移除回调
function beforeRemove(file: any, fileList: any) {
return ElMessageBox.confirm(`确定移除 ${file.name}这个文件?`);
}
//文件上传成功回调
function handleSuccess() {
ElMessage({
message: "上传成功",
type: "success",
});
}
const formData = ref({
name: "",
title: "",
......@@ -256,6 +294,8 @@ const formData = ref({
phone: "",
captcha: "",
});
//提交表单
const handleSubmit = () => {
if (
!formData.value.name ||
......@@ -279,6 +319,9 @@ const handleSubmit = () => {
formData.value.captcha = "";
return;
}
// uploadRef.value.submit();
// 提交表单
getWantMessage(formData.value).then((res) => {
ElMessage({
message: "提交成功",
type: "success",
......@@ -291,7 +334,9 @@ const handleSubmit = () => {
phone: "",
captcha: "",
};
uploadRef.value.clearFiles(); // 清空文件列表
refreshCaptcha();
});
};
</script>
<style scoped>
......
<!-- 代码已包含 CSS:使用 TailwindCSS , 安装 TailwindCSS 后方可看到布局样式效果 -->
<template>
<div class="bg-gray-50">
<div class="mx-auto w-[1440px] px-4 py-0">
<bread-crumb
:breadcrumbItems="
......@@ -20,7 +19,7 @@
<span
class="inline-flex items-center rounded-md bg-blue-50 px-2 py-1 text-xs font-medium text-blue-700"
>
已办理
已回复
</span>
<span>留言人: 李**</span>
<span>时间: 2024年1月15日 09:23</span>
......@@ -28,42 +27,110 @@
</div>
<!-- 问题描述 -->
<div class="mb-8">
<p class="mb-4 text-gray-600">
<div class="mb-6">
<p class="text-gray-600">
施工扬尘污染问题严重影响了周边居民的正常生活,希望相关部门能够重视此事。主要存在以下问题:
<br />施工现场未按要求设置防尘设施 <br />运输车辆未做好防尘措施
<br />现场积尘较多,未及时清理
<br />建议加强监管力度,落实各项防尘措施,保障居民生活环境。
</p>
<ul class="ml-6 list-disc space-y-2 text-gray-600">
<li>施工现场未按要求设置防尘设施</li>
<li>运输车辆未做好防尘措施</li>
<li>现场积尘较多,未及时清理</li>
</ul>
<p class="mt-4 text-gray-600">
建议加强监管力度,落实各项防尘措施,保障居民生活环境。
</p>
<!-- 附件区域 -->
<div
v-if="attachments.length > 0"
class="mt-1 border-t border-gray-200 pt-3"
>
<h3 class="mb-3 text-sm font-medium text-gray-900 weight-bold">
附件:
</h3>
<div class="space-y-1">
<div
v-for="(file, index) in attachments"
:key="index"
class="group flex cursor-pointer items-center rounded-md p-1 hover:bg-gray-50"
@click="handlePreview(file)"
>
<el-icon class="mr-2 text-gray-400" color="blue">
<Document
v-if="
file.type === 'pdf' ||
file.type === 'doc' ||
file.type === 'docx'
"
/>
<Picture
v-else-if="
file.type === 'jpg' ||
file.type === 'png' ||
file.type === 'jpeg'
"
/>
<Grid v-else-if="file.type === 'xlsx'" />
</el-icon>
<span class="text-sm text-gray-600 group-hover:text-blue-600">{{
file.name
}}</span>
</div>
</div>
</div>
</div>
<!-- 预览弹窗 -->
<el-dialog
custom-class="preview-dialog"
v-model="previewVisible"
:title="currentFile?.name"
destroy-on-close
style="margin-top: 10vh; width: 80%"
>
<div style="min-height: 75vh">
<img
class="center-block h-full w-full object-contain"
v-if="
currentFile?.type === 'jpg' ||
currentFile?.type === 'png' ||
currentFile?.type === 'jpeg'
"
:src="currentFile.url"
style="height: 75vh"
/>
<vue-office-pdf
v-if="currentFile?.type === 'pdf'"
class="h-full w-full min-h-[600px]"
:src="currentFile.url"
style="height: 75vh"
/>
<vue-office-docx
v-if="currentFile?.type === 'doc' || currentFile?.type === 'docx'"
:src="currentFile.url"
style="height: 75vh"
/>
<vue-office-excel
v-if="currentFile?.type === 'xlsx'"
:src="currentFile.url"
style="height: 75vh"
/>
<!-- <vue-office-pptx
v-if="currentFile?.type === 'ppt'"
:src="currentFile.url"
style="height: 75vh"
/> -->
</div>
</el-dialog>
<!-- 官方回复 -->
<div class="rounded-lg bg-gray-50 p-6">
<h2 class="mb-4 text-lg font-medium text-gray-900">官方回复:</h2>
<div class="rounded-lg bg-gray-50 p-5">
<h2 class="mb-4 text-lg font-medium text-red-500">官方回复:</h2>
<div class="space-y-4 text-gray-600">
<p>
网友您好!收到您的投诉后,我局高度重视,立即组织相关部门进行实地调查和处理。经查:
</p>
<p>
1.
<br />1.
关于城东新区排水管网改造工程施工现场扬尘污染问题,我局已要求施工单位立即采取以下整改措施:
</p>
<ul class="ml-6 list-disc space-y-2">
<li>增设雾炮机和喷淋设备,加强施工现场降尘</li>
<li>对裸露土地进行苫盖,设置防尘网</li>
<li>增加洒水车频次,保持路面湿润</li>
</ul>
<p>
2.
<br />增设雾炮机和喷淋设备,加强施工现场降尘
<br />对裸露土地进行苫盖,设置防尘网
<br />增加洒水车频次,保持路面湿润 <br />2.
目前整改措施已全部落实到位,扬尘污染问题得到有效控制。后续我局将继续加强监管,确保施工期间不发生扬尘污染问题。
<br />感谢您对我们工作的监督,我们将持续改进服务质量。
</p>
<p>感谢您对我们工作的监督,我们将持续改进服务质量。</p>
</div>
</div>
</div>
</div>
......@@ -71,10 +138,24 @@
</template>
<script lang="ts" setup>
import { ArrowRight } from "@element-plus/icons-vue";
import {
ArrowRight,
Document,
Picture,
Grid,
DataBoard,
} from "@element-plus/icons-vue";
import { useRoute } from "vue-router";
import BreadCrumb from "@/components/breadcrumb/BreadCrumb.vue";
import { ref } from "vue";
import { getMessageDetail } from "@/api/wm/wm";
//引入VueOfficeDocx组件
import VueOfficeDocx from "@vue-office/docx";
import VueOfficePdf from "@vue-office/pdf";
import VueOfficeExcel from "@vue-office/excel";
import VueOfficePptx from "@vue-office/pptx";
import "@vue-office/excel/lib/index.css";
import "@vue-office/docx/lib/index.css";
const route = useRoute();
......@@ -88,6 +169,41 @@ const breadcrumbItems2 = ref([
{ title: "首页", path: "/wm/wmhome" },
{ title: "详情", path: "" },
]);
// 获取留言详情
getMessageDetail(route.query.id).then((res) => {});
interface FileItem {
name: string;
type: string;
url: string;
}
const attachments = ref<FileItem[]>([
{
name: "现场照片1.jpeg",
type: "jpeg",
url: "https://q7.itc.cn/images01/20240805/c433884dec2943c7ac15098e4f940e96.jpeg",
},
{
name: "污染情况报告.pdf",
type: "pdf",
url: "http://static.shanhuxueyuan.com/test.pdf",
},
{
name: "监测数据.xlsx",
type: "xlsx",
url: "http://static.shanhuxueyuan.com/demo/excel.xlsx",
},
]);
const previewVisible = ref(false);
const currentFile = ref<FileItem | null>(null);
const handlePreview = (file: FileItem) => {
currentFile.value = file;
previewVisible.value = true;
};
</script>
<style scoped>
......
<!-- 代码已包含 CSS:使用 TailwindCSS , 安装 TailwindCSS 后方可看到布局样式效果 -->
<template>
<div class="bg-gray-50">
<div class="w-[1440px] mx-auto px-4">
<!-- 面包屑导航 -->
<div class="flex items-center justify-between py-2 border-b mb-5">
......@@ -41,26 +40,56 @@
<!-- 分页 -->
<div class="flex justify-center mt-8">
<el-pagination
v-model:current-page="currentPage"
:page-size="10"
:total="50"
:pager-count="5"
v-model:current-page="pageNo"
v-model:page-size="pageSize"
background
:total="total"
:page-sizes="[10, 20, 30, 40]"
layout="prev, pager, next"
class="!rounded-button"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref } from "vue";
import { useRouter } from "vue-router";
import { Search, ArrowRight } from "@element-plus/icons-vue";
import BreadCrumb from "@/components/breadcrumb/BreadCrumb.vue";
import { getHotList } from "@/api/wm/wm";
const router = useRouter();
const searchText = ref("");
const currentPage = ref(1);
const pageNo = ref(1);
const pageSize = ref(10);
const hotList = ref([]);
const total = ref(0);
const handleSizeChange = (val: number) => {
pageSize.value = val;
pageNo.value = pageNo.value;
};
const handleCurrentChange = (val: number) => {
pageSize.value = pageSize.value;
pageNo.value = val;
getList(pageSize.value, pageNo.value);
};
getList(pageSize.value, pageNo.value);
//获取新闻热点列表
function getList(pageSize: number, pageNo: number) {
const datas = {
pageSize: pageSize,
pageNo: pageNo,
};
getHotList(datas).then((response) => {
const data = response.data;
const rowsList = data.rows;
hotList.value = rowsList;
});
}
const breadcrumbItems = ref([
{ title: "首页", path: "/wm/wmhome" },
......
<!-- 代码已包含 CSS:使用 TailwindCSS , 安装 TailwindCSS 后方可看到布局样式效果 -->
<template>
<div class="bg-gray-50">
<div class="mx-auto w-[1440px] px-4 py-0">
<!-- 面包屑导航 -->
<bread-crumb
:breadcrumbItems="
route.query.pathType == '-1' ? breadcrumbItems2 : breadcrumbItems
......@@ -21,7 +19,7 @@
<span
class="inline-flex items-center rounded-md bg-blue-50 px-2 py-1 text-xs font-medium text-blue-700"
>
已办理
已回复
</span>
<span>留言人: 李**</span>
<span>时间: 2024年1月15日 09:23</span>
......@@ -29,42 +27,110 @@
</div>
<!-- 问题描述 -->
<div class="mb-8">
<p class="mb-4 text-gray-600">
<div class="mb-6">
<p class="text-gray-600">
施工扬尘污染问题严重影响了周边居民的正常生活,希望相关部门能够重视此事。主要存在以下问题:
<br />施工现场未按要求设置防尘设施 <br />运输车辆未做好防尘措施
<br />现场积尘较多,未及时清理
<br />建议加强监管力度,落实各项防尘措施,保障居民生活环境。
</p>
<ul class="ml-6 list-disc space-y-2 text-gray-600">
<li>施工现场未按要求设置防尘设施</li>
<li>运输车辆未做好防尘措施</li>
<li>现场积尘较多,未及时清理</li>
</ul>
<p class="mt-4 text-gray-600">
建议加强监管力度,落实各项防尘措施,保障居民生活环境。
</p>
<!-- 附件区域 -->
<div
v-if="attachments.length > 0"
class="mt-1 border-t border-gray-200 pt-3"
>
<h3 class="mb-3 text-sm font-medium text-gray-900 weight-bold">
附件:
</h3>
<div class="space-y-1">
<div
v-for="(file, index) in attachments"
:key="index"
class="group flex cursor-pointer items-center rounded-md p-1 hover:bg-gray-50"
@click="handlePreview(file)"
>
<el-icon class="mr-2 text-gray-400" color="blue">
<Document
v-if="
file.type === 'pdf' ||
file.type === 'doc' ||
file.type === 'docx'
"
/>
<Picture
v-else-if="
file.type === 'jpg' ||
file.type === 'png' ||
file.type === 'jpeg'
"
/>
<Grid v-else-if="file.type === 'xlsx'" />
</el-icon>
<span class="text-sm text-gray-600 group-hover:text-blue-600">{{
file.name
}}</span>
</div>
</div>
</div>
</div>
<!-- 预览弹窗 -->
<el-dialog
custom-class="preview-dialog"
v-model="previewVisible"
:title="currentFile?.name"
destroy-on-close
style="margin-top: 10vh; width: 80%"
>
<div style="min-height: 75vh">
<img
class="center-block h-full w-full object-contain"
v-if="
currentFile?.type === 'jpg' ||
currentFile?.type === 'png' ||
currentFile?.type === 'jpeg'
"
:src="currentFile.url"
style="height: 75vh"
/>
<vue-office-pdf
v-if="currentFile?.type === 'pdf'"
class="h-full w-full min-h-[600px]"
:src="currentFile.url"
style="height: 75vh"
/>
<vue-office-docx
v-if="currentFile?.type === 'doc' || currentFile?.type === 'docx'"
:src="currentFile.url"
style="height: 75vh"
/>
<vue-office-excel
v-if="currentFile?.type === 'xlsx'"
:src="currentFile.url"
style="height: 75vh"
/>
<!-- <vue-office-pptx
v-if="currentFile?.type === 'ppt'"
:src="currentFile.url"
style="height: 75vh"
/> -->
</div>
</el-dialog>
<!-- 官方回复 -->
<div class="rounded-lg bg-gray-50 p-6">
<h2 class="mb-4 text-lg font-medium text-gray-900">官方回复:</h2>
<div class="rounded-lg bg-gray-50 p-5">
<h2 class="mb-4 text-lg font-medium text-red-500">官方回复:</h2>
<div class="space-y-4 text-gray-600">
<p>
网友您好!收到您的投诉后,我局高度重视,立即组织相关部门进行实地调查和处理。经查:
</p>
<p>
1.
<br />1.
关于城东新区排水管网改造工程施工现场扬尘污染问题,我局已要求施工单位立即采取以下整改措施:
</p>
<ul class="ml-6 list-disc space-y-2">
<li>增设雾炮机和喷淋设备,加强施工现场降尘</li>
<li>对裸露土地进行苫盖,设置防尘网</li>
<li>增加洒水车频次,保持路面湿润</li>
</ul>
<p>
2.
<br />增设雾炮机和喷淋设备,加强施工现场降尘
<br />对裸露土地进行苫盖,设置防尘网
<br />增加洒水车频次,保持路面湿润 <br />2.
目前整改措施已全部落实到位,扬尘污染问题得到有效控制。后续我局将继续加强监管,确保施工期间不发生扬尘污染问题。
<br />感谢您对我们工作的监督,我们将持续改进服务质量。
</p>
<p>感谢您对我们工作的监督,我们将持续改进服务质量。</p>
</div>
</div>
</div>
</div>
......@@ -72,13 +138,27 @@
</template>
<script lang="ts" setup>
import { ArrowRight } from "@element-plus/icons-vue";
import {
ArrowRight,
Document,
Picture,
Grid,
DataBoard,
} from "@element-plus/icons-vue";
import { useRoute } from "vue-router";
import BreadCrumb from "@/components/breadcrumb/BreadCrumb.vue";
import { ref } from "vue";
import { getMessageDetail } from "@/api/wm/wm";
//引入VueOfficeDocx组件
import VueOfficeDocx from "@vue-office/docx";
import VueOfficePdf from "@vue-office/pdf";
import VueOfficeExcel from "@vue-office/excel";
import VueOfficePptx from "@vue-office/pptx";
import "@vue-office/excel/lib/index.css";
import "@vue-office/docx/lib/index.css";
const route = useRoute();
const type = route.query.type;
const breadcrumbItems = ref([
{ title: "首页", path: "/wm/wmhome" },
{ title: route.query.title, path: route.query.pathType },
......@@ -89,6 +169,41 @@ const breadcrumbItems2 = ref([
{ title: "首页", path: "/wm/wmhome" },
{ title: "详情", path: "" },
]);
// 获取留言详情
getMessageDetail(route.query.id).then((res) => {});
interface FileItem {
name: string;
type: string;
url: string;
}
const attachments = ref<FileItem[]>([
{
name: "现场照片1.jpeg",
type: "jpeg",
url: "https://q7.itc.cn/images01/20240805/c433884dec2943c7ac15098e4f940e96.jpeg",
},
{
name: "污染情况报告.pdf",
type: "pdf",
url: "http://static.shanhuxueyuan.com/test.pdf",
},
{
name: "监测数据.xlsx",
type: "xlsx",
url: "http://static.shanhuxueyuan.com/demo/excel.xlsx",
},
]);
const previewVisible = ref(false);
const currentFile = ref<FileItem | null>(null);
const handlePreview = (file: FileItem) => {
currentFile.value = file;
previewVisible.value = true;
};
</script>
<style scoped>
......
......@@ -49,12 +49,14 @@
<!-- 分页 -->
<div class="flex justify-center mt-8">
<el-pagination
v-model:current-page="currentPage"
:page-size="pageSize"
:total="totalItems"
:pager-count="5"
v-model:current-page="pageNo"
v-model:page-size="pageSize"
background
:total="total"
:page-sizes="[10, 20, 30, 40]"
layout="prev, pager, next"
class="!rounded-button"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
/>
</div>
</div>
......@@ -66,15 +68,45 @@ import { ref, computed } from "vue";
import { Search, ArrowRight } from "@element-plus/icons-vue";
import { useRouter } from "vue-router";
import BreadCrumb from "@/components/breadcrumb/BreadCrumb.vue";
import { getRecoverList } from "@/api/wm/wm";
const router = useRouter();
const searchText = ref("");
const currentPage = ref(1);
const pageSize = ref(5);
const pageNo = ref(1);
const pageSize = ref(10);
const recoverList = ref([]);
const total = ref(0);
const handleSizeChange = (val: number) => {
pageSize.value = val;
pageNo.value = pageNo.value;
};
const handleCurrentChange = (val: number) => {
pageSize.value = pageSize.value;
pageNo.value = val;
getList(pageSize.value, pageNo.value);
};
getList(pageSize.value, pageNo.value);
//获取新闻热点列表
function getList(pageSize: number, pageNo: number) {
const datas = {
pageSize: pageSize,
pageNo: pageNo,
};
getRecoverList(datas).then((response) => {
const data = response.data;
const rowsList = data.rows;
recoverList.value = rowsList;
});
}
const breadcrumbItems = ref([
{ title: "首页", path: "/wm/wmhome" },
{ title: "回复列表" },
]);
const allItems = [
{
title: "关于东湖公园设施改善的回复",
......@@ -116,7 +148,7 @@ const allItems = [
const totalItems = computed(() => allItems.length);
const displayItems = computed(() => {
const start = (currentPage.value - 1) * pageSize.value;
const start = (pageNo.value - 1) * pageSize.value;
const filtered = allItems.filter(
(item) =>
item.title.includes(searchText.value) ||
......
<!-- 代码已包含 CSS:使用 TailwindCSS , 安装 TailwindCSS 后方可看到布局样式效果 -->
<template>
<div class="mx-auto w-[1440px] px-4">
<!-- 面包屑导航 -->
<div class="flex items-center justify-between py-2 border-b mb-5">
<bread-crumb :breadcrumbItems="breadcrumbItems" />
</div>
<!-- 回复列表 -->
<div>
<div
v-for="(item, index) in displayItems"
:key="index"
class="bg-white rounded-lg p-6 mb-4 shadow-sm hover:shadow-md transition-shadow"
@click="clickList(item.id)"
>
<div class="flex justify-between items-start mb-3">
<h3 class="text-lg font-medium text-gray-900">{{ item.title }}</h3>
<span
:class="[
'px-3 py-1 rounded-full text-sm',
item.status === '已处理'
? 'bg-green-50 text-green-600'
: 'bg-orange-50 text-orange-600',
]"
>{{ item.status }}</span
>
</div>
<p class="text-gray-600 mb-4">{{ item.content }}</p>
<div class="text-sm text-gray-400">{{ item.time }}</div>
</div>
</div>
<!-- 分页 -->
<div class="flex justify-center mt-8">
<el-pagination
v-model:current-page="currentPage"
:page-size="pageSize"
:total="totalItems"
:pager-count="5"
layout="prev, pager, next"
class="!rounded-button"
/>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref, computed } from "vue";
import { Search, ArrowRight } from "@element-plus/icons-vue";
import { useRouter } from "vue-router";
import BreadCrumb from "@/components/breadcrumb/BreadCrumb.vue";
const router = useRouter();
const searchText = ref("");
const currentPage = ref(1);
const pageSize = ref(5);
const breadcrumbItems = ref([
{ title: "首页", path: "/wm/wmhome" },
{ title: "搜索结果" },
]);
const allItems = [
{
title: "关于东湖公园设施改善的回复",
content:
"感谢您的建议。我局已安排相关部门实地考察,将在东湖公园增设 25 组休闲椅和 10 处遮阳凉亭,预计本月内完工。",
time: "2024-12-27 09:41",
status: "已处理",
},
{
title: "关于龙泉山交通问题的回复",
content:
"关于龙泉山拥堵问题,我们已制定改善方案:1. 优化信号灯配时;2. 增设潮汐车道;3. 加强交通疏导。预计一周内见效。",
time: "2024-12-02 12:24",
status: "已处理",
},
{
title: "关于金融大厦停车问题的回复",
content:
"金融大厦地下停车场扩建工程已列入今年重点项目,将新增车位 600 个,预计 6 月完工。",
time: "2024-12-02 12:24",
status: "已处理",
},
{
title: "关于市民广场交通设施的回复",
content:
"我们将对市民广场周边道路进行优化:1. 新增人行天桥;2. 扩建非机动车道;3. 增设智能红绿灯。预计两周内完成。",
time: "2024-12-02 12:24",
status: "未处理",
},
{
title: "关于青山湖环境整治的回复",
content:
"青山湖环境整治工程已启动,包括水质净化、垃圾清理、绿化提升等多项工作,预计三个月内完成。",
time: "2024-12-02 12:24",
status: "未处理",
},
];
const totalItems = computed(() => allItems.length);
const displayItems = computed(() => {
const start = (currentPage.value - 1) * pageSize.value;
const filtered = allItems.filter(
(item) =>
item.title.includes(searchText.value) ||
item.content.includes(searchText.value)
);
return filtered.slice(start, start + pageSize.value);
});
function clickList(id: number) {
router.push({
path: "/wm/recoverdetail",
query: {
title: "搜索结果",
pathType: "/wm/search",
id: id,
},
});
}
</script>
<style scoped>
.el-pagination {
justify-content: center;
}
</style>
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