Commit ff20fbee by York

初版完成

parent e9938e34
import request from "@/utils/request";
// 轮播图
export function getBanner(query) {
return request({
url: "/exam/setup/list",
method: "get",
params: query,
});
}
// http://192.168.19.142:9002/cms/category/list?categoryFlag=tyshlwyjzhhjbzx
export function getTab(data) {
return request({
......@@ -16,6 +8,14 @@ export function getTab(data) {
params: data,
});
}
//获取友情链接
export function getLink(data) {
return request({
url: "/cms/websitelink/list",
method: "post",
params: data,
});
}
// // 查询考试设置详细
// export function getSetup(id) {
......
......@@ -3,8 +3,8 @@ import request from "@/utils/request";
// 热点留言列表
export function getHotList(data) {
return request({
url: "/cms/content/list",
method: "get",
url: "/cms/leavemessage/list",
method: "post",
data: data,
});
}
......@@ -12,8 +12,8 @@ export function getHotList(data) {
// 最新回复列表
export function getRecoverList(data) {
return request({
url: "/cms/content/list",
method: "get",
url: "/cms/leavemessage/replyList",
method: "post",
data: data,
});
}
......@@ -21,18 +21,17 @@ export function getRecoverList(data) {
// 我要留言
export function getWantMessage(data) {
return request({
url: "/cms/content/list",
url: "/cms/leavemessage/saveEntity",
method: "post",
data: data,
});
}
// 留言详情
export function getMessageDetail(data) {
export function getMessageDetail(id) {
return request({
url: "/cms/content/list",
url: "/cms/leavemessage/get?id=" + id,
method: "get",
data: data,
});
}
......
......@@ -156,17 +156,21 @@ function iMessageClick() {
}
function handleSearch() {
if (searchQuery.value) {
router.push({
path: "/wm/search",
query: { searchQuery: searchQuery.value },
});
} else {
ElMessage({
message: "请输入搜索内容",
type: "warning",
});
}
router.push({
path: "/wm/messagelist",
query: { keywords: searchQuery.value },
});
// if (searchQuery.value) {
// router.push({
// path: "/wm/search",
// query: { searchQuery: searchQuery.value },
// });
// } else {
// ElMessage({
// message: "请输入搜索内容",
// type: "warning",
// });
// }
}
</script>
<style scoped>
......
import { createRouter, createWebHistory } from "vue-router";
import { createRouter, createWebHashHistory } from "vue-router";
// 首页新闻
import NewsLayout from "../layout/news.vue";
......@@ -32,7 +32,7 @@ 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),
history: createWebHashHistory(import.meta.env.BASE_URL),
routes: [
{
path: "/",
......
let baseImageUrl;
if (process.env.NODE_ENV === "development") {
// baseImageUrl = (path) => `${window.location.origin}${path}`;
baseImageUrl = (path) => "http://192.168.19.142:9002" + path;
// console.log(baseImageUrl);
} else {
baseImageUrl = (path) => path;
baseImageUrl = (path) => "http://yjzh.sxyztech.cn" + path;
}
export { baseImageUrl };
export { baseImageUrl };
// 栏目属性
export const HLW_YJZH_JBZX = "tyshlwyjzhhjbzx"; //太原市互联网应急指挥和举报中心
export const HLW_LH_PYPT = "sxhlwlhpypt"; //山西互联网联合辟谣平台
......
......@@ -264,7 +264,7 @@
<a
v-for="(link, index) in friendLinks"
:key="index"
:href="link.url"
:href="link.webLinkUrl"
target="_blank"
class="text-gray-600 hover:text-blue-600 text-center"
>
......@@ -292,8 +292,9 @@ import "swiper/css";
import "swiper/css/pagination";
import "swiper/css/autoplay";
import "swiper/css/navigation";
import { getBanner } from "@/api/home/home";
import { getLink } from "@/api/home/home";
import { getNewsList } from "@/api/home/news/list";
import {
baseImageUrl,
rdxw,
......@@ -329,10 +330,6 @@ const tyNews = ref([]);
const hotNews = ref([]);
const authoritativeNews = ref([]);
const rumourNews = ref([]);
//获取轮播图数据
getBanner().then((response) => {
console.log(response);
});
getTyNewsList(5, 1);
......@@ -481,6 +478,17 @@ function getLbtList(pageSize: number, pageNo: number) {
});
}
getLinkLists();
//获取首页轮播图
function getLinkLists() {
getLink().then((response) => {
const data = response.data;
const rowsList = data.rows;
friendLinks.value = rowsList;
});
}
const friendLinks = ref([]);
const slides = ref([]);
const quickEntries = [
......@@ -514,14 +522,14 @@ const quickEntries = [
// },
// ];
const friendLinks = [
{ name: "太原市人民政府", url: "https://www.taiyuan.gov.cn" },
{ name: "山西省网信办", url: "http://www.casx.gov.cn" },
{ name: "太原日报", url: "http://www.tynews.com.cn" },
{ name: "山西新闻网", url: "https://www.sxgov.cn" },
{ name: "太原广播电视台", url: "https://www.sxtygdy.com" },
{ name: "太原市公安局", url: "https://gaj.taiyuan.gov.cn" },
];
// const friendLinks = [
// { name: "太原市人民政府", url: "https://www.taiyuan.gov.cn" },
// { name: "山西省网信办", url: "http://www.casx.gov.cn" },
// { name: "太原日报", url: "http://www.tynews.com.cn" },
// { name: "山西新闻网", url: "https://www.sxgov.cn" },
// { name: "太原广播电视台", url: "https://www.sxtygdy.com" },
// { name: "太原市公安局", url: "https://gaj.taiyuan.gov.cn" },
// ];
</script>
<style scoped>
.swiper {
......
......@@ -17,20 +17,25 @@
</div>
<div class="space-y-3">
<div
v-for="(item, index) in hotTopics"
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)"
@click="messageClick(item.id)"
>
<div class="flex items-center justify-between">
<span class="text-gray-400 text-sm">{{ item.date }}</span>
<div class="flex items-center text-sm text-gray-500">
<span>{{ item.contentDatetime }}</span>
<span class="mx-5">留言人:{{ item.name }}</span>
</div>
<el-tag
size="small"
:type="item.status === '已回复' ? 'success' : 'warning'"
:type="item.replyStatus === '1' ? 'success' : 'warning'"
>
{{ item.status }}
{{ item.replyStatus === "1" ? "已回复" : "未回复" }}
</el-tag>
</div>
<h4 class="text-gray-900 font-medium mt-3">{{ item.title }}</h4>
<p class="mt-2 text-gray-700">{{ item.content }}</p>
</div>
</div>
......@@ -50,7 +55,7 @@
</div>
<div class="space-y-3">
<div
v-for="(item, index) in replies"
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)"
......@@ -59,7 +64,13 @@
<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.date }}</span>
<!-- <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">留言人:{{ item.name }}</span>
</div>
</div>
</div>
</div>
......@@ -163,7 +174,6 @@ const replies = ref([
// path: "/wm/messagelist",
// });
// }
const hotList = ref([]);
const recoverList = ref([]);
......@@ -207,7 +217,7 @@ function messageClick(id: number) {
}
function recoverClick(id: number) {
router.push({
path: "/wm/recoverdetail",
path: "/wm/messagedetail",
query: {
pathType: "-1",
id: id,
......
......@@ -73,6 +73,7 @@
<div class="col-span-8">
<div class="bg-white rounded-lg shadow-sm p-8">
<h2 class="text-2xl font-bold text-gray-800 mb-6">提交留言</h2>
=
<form @submit.prevent="handleSubmit" class="space-y-6">
<div class="space-y-2">
<label class="block text-sm font-medium text-gray-700">
......@@ -86,51 +87,51 @@
</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"
placeholder="请输入留言标题"
v-model="formData.phoneNumber"
placeholder="请输入联系电话"
class="!rounded-button"
/>
</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"
type="textarea"
:rows="6"
placeholder="请输入详细内容"
v-model="formData.title"
placeholder="请输入留言标题"
class="!rounded-button"
/>
</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"
placeholder="请输入联系电话"
v-model="formData.content"
type="textarea"
:rows="6"
placeholder="请输入留言内容"
class="!rounded-button"
/>
</div>
<div class="space-y-2">
<!-- <div class="space-y-2">
<label class="block text-sm font-medium text-gray-700">
上传附件
</label>
<el-upload
:file-list="fileList"
class="upload-demo"
action="https://jsonplaceholder.typicode.com/posts/"
action="/ms/file/upload.do"
: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
......@@ -144,7 +145,7 @@
</div>
</template>
</el-upload>
</div>
</div> -->
<div class="space-y-2">
<label class="block text-sm font-medium text-gray-700">
<span class="text-red-500">*</span> 验证码
......@@ -190,6 +191,8 @@ 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";
import { baseImageUrl } from "@/utils/config";
// const { proxy } = getCurrentInstance();
const breadcrumbItems = ref([
......@@ -197,69 +200,18 @@ const breadcrumbItems = ref([
{ title: "我要留言" },
]);
const letters = Array.from("ABCDEFGHJKLMNPQRSTUVWXYZ23456789");
const generateCaptcha = () => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
if (!ctx) return "";
canvas.width = 128;
canvas.height = 40;
// 设置背景
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 生成验证码文字
const captchaText = Array.from(
{ length: 4 },
() => letters[Math.floor(Math.random() * letters.length)]
).join("");
// 绘制文字
ctx.font = "bold 24px Arial";
ctx.textBaseline = "middle";
// 随机颜色和位置绘制每个字符
for (let i = 0; i < captchaText.length; i++) {
const x = 20 + i * 25;
const y = 20 + Math.random() * 8 - 4;
const angle = (Math.random() - 0.5) * 0.4;
ctx.save();
ctx.translate(x, y);
ctx.rotate(angle);
// 随机颜色
const hue = Math.floor(Math.random() * 360);
ctx.fillStyle = `hsl(${hue}, 70%, 40%)`;
ctx.fillText(captchaText[i], 0, 0);
ctx.restore();
}
// 添加干扰线
for (let i = 0; i < 3; i++) {
ctx.beginPath();
ctx.strokeStyle = `rgba(${Math.random() * 255}, ${Math.random() * 255}, ${
Math.random() * 255
}, 0.5)`;
ctx.lineWidth = 1;
ctx.moveTo(Math.random() * canvas.width, Math.random() * canvas.height);
ctx.lineTo(Math.random() * canvas.width, Math.random() * canvas.height);
ctx.stroke();
}
// 添加噪点
for (let i = 0; i < 50; i++) {
const x = Math.random() * canvas.width;
const y = Math.random() * canvas.height;
ctx.fillStyle = `rgba(${Math.random() * 255}, ${Math.random() * 255}, ${
Math.random() * 255
}, 0.5)`;
ctx.fillRect(x, y, 2, 2);
}
return {
text: captchaText,
image: canvas.toDataURL(),
};
};
const captchaText = ref("");
const captchaImage = ref("");
const fileList = ref([]);
const uploadRef = ref();
const formData = ref({
name: "",
title: "",
content: "",
phoneNumber: "",
// contentImg: "",
captcha: "",
});
const refreshCaptcha = () => {
const captcha = generateCaptcha();
......@@ -277,7 +229,14 @@ function handleExceed(files: any, fileList: any) {
}
//文件移除回调
function beforeRemove(file: any, fileList: any) {
return ElMessageBox.confirm(`确定移除 ${file.name}这个文件?`);
// var index = -1;
// index = formData.value.contentImg.findIndex(function (text) {
// return text.uid == file.uid;
// });
// if (index != -1) {
// formData.value.contentImg.splice(index, 1);
// }
// return ElMessageBox.confirm(`确定移除 ${file.name}这个文件?`);
}
//文件上传成功回调
function handleSuccess() {
......@@ -287,25 +246,39 @@ function handleSuccess() {
});
}
const formData = ref({
name: "",
title: "",
content: "",
phone: "",
captcha: "",
});
//提交表单
const handleSubmit = () => {
if (
!formData.value.name ||
!formData.value.title ||
!formData.value.content ||
!formData.value.phone ||
!formData.value.captcha
) {
if (!formData.value.name) {
ElMessage({
message: "请填写姓名",
type: "warning",
});
return;
}
if (!formData.value.phoneNumber) {
ElMessage({
message: "请填写联系方式",
type: "warning",
});
return;
}
if (!formData.value.title) {
ElMessage({
message: "请填写留言标题",
type: "warning",
});
return;
}
if (!formData.value.content) {
ElMessage({
message: "请填写必填项",
message: "请填写留言内容",
type: "warning",
});
return;
}
if (!formData.value.captcha) {
ElMessage({
message: "请填写验证码",
type: "warning",
});
return;
......@@ -319,7 +292,13 @@ const handleSubmit = () => {
formData.value.captcha = "";
return;
}
// uploadRef.value.submit();
//将fileList中的文件逗号拼接,赋值给FormData.contentImg
// formData.value.contentImg = fileList.value.map((file) => file.raw).join(",");
// const formData = new FormData();
// fileList.value.forEach((file) => {
// formData.append("file", file.raw);
// });
// 提交表单
getWantMessage(formData.value).then((res) => {
ElMessage({
......@@ -331,13 +310,73 @@ const handleSubmit = () => {
name: "",
title: "",
content: "",
phone: "",
phoneNumber: "",
contentImg: "",
captcha: "",
};
uploadRef.value.clearFiles(); // 清空文件列表
refreshCaptcha();
});
};
const letters = Array.from("ABCDEFGHJKLMNPQRSTUVWXYZ23456789");
const generateCaptcha = () => {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
if (!ctx) return "";
canvas.width = 128;
canvas.height = 40;
// 设置背景
ctx.fillStyle = "#fff";
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 生成验证码文字
const captchaText = Array.from(
{ length: 4 },
() => letters[Math.floor(Math.random() * letters.length)]
).join("");
// 绘制文字
ctx.font = "bold 24px Arial";
ctx.textBaseline = "middle";
// 随机颜色和位置绘制每个字符
for (let i = 0; i < captchaText.length; i++) {
const x = 20 + i * 25;
const y = 20 + Math.random() * 8 - 4;
const angle = (Math.random() - 0.5) * 0.4;
ctx.save();
ctx.translate(x, y);
ctx.rotate(angle);
// 随机颜色
const hue = Math.floor(Math.random() * 360);
ctx.fillStyle = `hsl(${hue}, 70%, 40%)`;
ctx.fillText(captchaText[i], 0, 0);
ctx.restore();
}
// 添加干扰线
for (let i = 0; i < 3; i++) {
ctx.beginPath();
ctx.strokeStyle = `rgba(${Math.random() * 255}, ${Math.random() * 255}, ${
Math.random() * 255
}, 0.5)`;
ctx.lineWidth = 1;
ctx.moveTo(Math.random() * canvas.width, Math.random() * canvas.height);
ctx.lineTo(Math.random() * canvas.width, Math.random() * canvas.height);
ctx.stroke();
}
// 添加噪点
for (let i = 0; i < 50; i++) {
const x = Math.random() * canvas.width;
const y = Math.random() * canvas.height;
ctx.fillStyle = `rgba(${Math.random() * 255}, ${Math.random() * 255}, ${
Math.random() * 255
}, 0.5)`;
ctx.fillRect(x, y, 2, 2);
}
return {
text: captchaText,
image: canvas.toDataURL(),
};
};
</script>
<style scoped>
:deep(.el-input__wrapper) {
......
......@@ -11,31 +11,34 @@
<!-- 主要内容卡片 -->
<div class="rounded-lg bg-white p-6 shadow-sm">
<!-- 标题区域 -->
<div class="mb-6">
<h1 class="mb-4 text-xl font-medium text-gray-900">
东湖新区排水管网改造工程环境污染问题
<div class="mb-3">
<h1 class="mb-2 text-xl font-medium text-gray-900">
{{ detail.title }}
</h1>
<div class="flex items-center space-x-4 text-sm text-gray-500">
<span
class="inline-flex items-center rounded-md bg-blue-50 px-2 py-1 text-xs font-medium text-blue-700"
<!-- <span
class="inline-flex items-center rounded-md bg-blue-50 px-2 py-1 text-xs font-medium text-green-600"
>
{{ detail.replyStatus == "1" ? "已回复" : "未回复" }}
</span> -->
<el-tag
size="small"
class="inline-flex items-center rounded-md bg-blue-50 px-2 py-1 text-xs font-medium text-green-600"
:type="detail.replyStatus === '1' ? 'success' : 'warning'"
>
已回复
</span>
<span>留言人: 李**</span>
<span>时间: 2024年1月15日 09:23</span>
{{ detail.replyStatus === "1" ? "已回复" : "未回复" }}
</el-tag>
<span>留言人: {{ detail.name }}</span>
<span>时间: {{ detail.contentDatetime }}</span>
</div>
</div>
<!-- 问题描述 -->
<div class="mb-6">
<p class="text-gray-600">
施工扬尘污染问题严重影响了周边居民的正常生活,希望相关部门能够重视此事。主要存在以下问题:
<br />施工现场未按要求设置防尘设施 <br />运输车辆未做好防尘措施
<br />现场积尘较多,未及时清理
<br />建议加强监管力度,落实各项防尘措施,保障居民生活环境。
</p>
<div class="space-y-4 text-gray-600" v-html="detail.content"></div>
<!-- 附件区域 -->
<div
<!-- <div
v-if="attachments.length > 0"
class="mt-1 border-t border-gray-200 pt-3"
>
......@@ -49,7 +52,7 @@
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">
<el-icon class="mr-2 text-gray-400" color="gray">
<Document
v-if="
file.type === 'pdf' ||
......@@ -71,7 +74,7 @@
}}</span>
</div>
</div>
</div>
</div> -->
</div>
<!-- 预览弹窗 -->
<el-dialog
......@@ -118,20 +121,9 @@
</el-dialog>
<!-- 官方回复 -->
<div class="rounded-lg bg-gray-50 p-5">
<div class="rounded-lg bg-gray-50 p-5" v-if="detail.reply != null">
<h2 class="mb-4 text-lg font-medium text-red-500">官方回复:</h2>
<div class="space-y-4 text-gray-600">
<p>
网友您好!收到您的投诉后,我局高度重视,立即组织相关部门进行实地调查和处理。经查:
<br />1.
关于城东新区排水管网改造工程施工现场扬尘污染问题,我局已要求施工单位立即采取以下整改措施:
<br />增设雾炮机和喷淋设备,加强施工现场降尘
<br />对裸露土地进行苫盖,设置防尘网
<br />增加洒水车频次,保持路面湿润 <br />2.
目前整改措施已全部落实到位,扬尘污染问题得到有效控制。后续我局将继续加强监管,确保施工期间不发生扬尘污染问题。
<br />感谢您对我们工作的监督,我们将持续改进服务质量。
</p>
</div>
<div class="space-y-4 text-gray-600" v-html="detail.reply"></div>
</div>
</div>
</div>
......@@ -170,8 +162,12 @@ const breadcrumbItems2 = ref([
{ title: "详情", path: "" },
]);
const detail = ref({});
// 获取留言详情
getMessageDetail(route.query.id).then((res) => {});
getMessageDetail(route.query.id).then((res) => {
detail.value = res.data;
});
interface FileItem {
name: string;
......
<!-- 代码已包含 CSS:使用 TailwindCSS , 安装 TailwindCSS 后方可看到布局样式效果 -->
<template>
<div class="w-[1440px] mx-auto px-4">
<!-- 面包屑导航 -->
<div class="flex items-center justify-between py-2 border-b mb-5">
<bread-crumb :breadcrumbItems="breadcrumbItems" />
<div class="w-[1440px] mx-auto px-4">
<!-- 面包屑导航 -->
<div class="flex items-center justify-between py-2 border-b mb-5">
<bread-crumb :breadcrumbItems="breadcrumbItems" />
<!-- 搜索框 -->
<div class="relative">
<input
type="text"
v-model="searchText"
placeholder="搜索留言"
class="w-[300px] h-8 pl-4 pr-10 rounded-lg border-none bg-white shadow-sm focus:ring-2 focus:ring-blue-500 text-sm"
/>
<el-icon
class="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400"
><Search
/></el-icon>
</div>
<!-- 搜索框 -->
<div class="relative">
<input
type="text"
v-model="searchText"
placeholder="搜索留言"
class="w-[300px] h-8 pl-4 pr-10 rounded-lg border-none bg-white shadow-sm focus:ring-2 focus:ring-blue-500 text-sm"
@keyup.enter="handleSearch"
/>
<el-icon class="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400"
><Search
/></el-icon>
</div>
<!-- 留言列表 -->
<div class="space-y-4">
<div
v-for="(item, index) in messageList"
:key="index"
class="bg-white rounded-lg shadow-sm p-6 transition-all duration-300 hover:shadow-lg hover:scale-[1.01] cursor-pointer"
@click="clickList(item.id)"
>
<h2 class="text-lg font-medium text-gray-900 mb-3">
{{ item.title }}
</h2>
<p class="text-gray-600 mb-4 leading-relaxed">{{ item.content }}</p>
<div class="flex items-center text-sm text-gray-500">
<span>{{ item.date }}</span>
<span class="mx-2">留言人:{{ item.author }}</span>
</div>
</div>
<!-- 留言列表 -->
<div class="space-y-4">
<div
v-for="(item, index) in hotList"
:key="index"
class="bg-white rounded-lg shadow-sm p-6 transition-all duration-300 hover:shadow-lg hover:scale-[1.01] cursor-pointer"
@click="clickList(item.id)"
>
<!-- <h2 class="text-lg font-medium text-gray-900 mb-3">
{{ item.title }}
</h2> -->
<div class="flex justify-between items-start mb-1">
<h3 class="text-lg font-medium text-gray-900">{{ item.title }}</h3>
<span
:class="[
'px-3 py-1 rounded-full text-sm',
item.replyStatus === '1'
? 'bg-green-50 text-green-600'
: 'bg-orange-50 text-orange-600',
]"
>{{ item.replyStatus === "1" ? "已回复" : "未回复" }}</span
>
</div>
<p class="text-gray-600 mb-4 leading-relaxed">{{ item.content }}</p>
<div class="flex items-center text-sm text-gray-500">
<span>{{ item.contentDatetime }}</span>
<span class="mx-5">留言人:{{ item.name }}</span>
</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="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>
</template>
<script lang="ts" setup>
import { ref } from "vue";
import { useRouter } from "vue-router";
import { ref, watch } from "vue";
import { useRouter, useRoute } from "vue-router";
import { Search, ArrowRight } from "@element-plus/icons-vue";
import BreadCrumb from "@/components/breadcrumb/BreadCrumb.vue";
import { getHotList } from "@/api/wm/wm";
import { onMounted } from "vue";
const router = useRouter();
const searchText = ref("");
const route = useRoute();
const searchText = ref();
const pageNo = ref(1);
const pageSize = ref(10);
const hotList = ref([]);
......@@ -76,11 +92,35 @@ const handleCurrentChange = (val: number) => {
getList(pageSize.value, pageNo.value);
};
getList(pageSize.value, pageNo.value);
function handleSearch() {
getList(10, 1);
}
onMounted(() => {
if (route.query.keywords) {
searchText.value = route.query.keywords;
console.log(route.query.keywords);
}
getList(pageSize.value, pageNo.value);
});
// watch route.query.keywords
watch(
() => route.query.keywords,
(newVal) => {
searchText.value = newVal;
getList(pageSize.value, pageNo.value);
}
);
//获取新闻热点列表
function getList(pageSize: number, pageNo: number) {
// if (route.query.keywords) {
// searchText.value = route.query.keywords;
// console.log(route.query.keywords);
// }
const datas = {
title: searchText.value,
pageSize: pageSize,
pageNo: pageNo,
};
......@@ -96,36 +136,6 @@ const breadcrumbItems = ref([
{ title: "留言列表" },
]);
const messageList = ref([
{
title: "反映某建筑公司拖欠农民工工资问题",
content:
"太原市建筑工人反映某建筑公司拖欠其与工友共计 50 余人约 156 万元工资。经劳动监察部门介入调查,目前该公司已全额支付拖欠资金,并按规定支付赔偿金。",
date: "2024-12-27 09:41",
author: "张先生",
},
{
title: "某快递公司拖欠快递员工资及社保问题",
content:
"市民李师傅反映某快递公司拖欠员工工资 3 个月,且未缴纳社会保险。经调查核实并约谈该公司负责人,该公司已补发全部工资并补缴社保,承诺今后按时发放工资。",
date: "2024-12-02 12:24",
author: "李先生",
},
{
title: "反映某餐饮企业克扣服务员工资问题",
content:
"服务员投诉某连锁餐饮企业以各种理由克扣工资。经查实,该企业存在违规罚款、未按约定发放绩效工资等问题。目前已责令整改,并补发被克扣工资。",
date: "2024-12-12 09:02",
author: "张女士",
},
{
title: "某科技公司拖欠开发人员工资及年终奖",
content:
"工程师等 12 名技术人员投诉某科技公司拖欠 2023 年 11-12 月工资及年终奖共计 89 万元。经多方协调,该公司已筹措资金完成全部支付。",
date: "2024-12-11 15:00",
author: "王先生",
},
]);
function clickList(id: number) {
router.push({
path: "/wm/messagedetail",
......
......@@ -6,7 +6,6 @@
<!-- 面包屑导航 -->
<div class="flex items-center justify-between py-2 border-b mb-5">
<bread-crumb :breadcrumbItems="breadcrumbItems" />
<!-- 搜索框 -->
<div class="relative">
<input
......@@ -14,6 +13,7 @@
v-model="searchText"
placeholder="搜索回复"
class="w-[300px] h-8 pl-4 pr-10 rounded-lg border-none bg-white shadow-sm focus:ring-2 focus:ring-blue-500 text-sm"
@keyup.enter="handleSearch"
/>
<el-icon
class="absolute left-3 top-1/2 -translate-y-1/2 text-gray-400"
......@@ -24,25 +24,31 @@
<!-- 回复列表 -->
<div>
<div
v-for="(item, index) in displayItems"
v-for="(item, index) in recoverList"
: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">
<div class="flex justify-between items-start mb-1">
<h3 class="text-lg font-medium text-gray-900">{{ item.title }}</h3>
<span
:class="[
'px-3 py-1 rounded-full text-sm',
item.status === '已处理'
item.replyStatus === '1'
? 'bg-green-50 text-green-600'
: 'bg-orange-50 text-orange-600',
]"
>{{ item.status }}</span
>{{ item.replyStatus === "1" ? "已回复" : "未回复" }}</span
>
</div>
<p class="text-gray-600 mb-4">{{ item.content }}</p>
<div class="text-sm text-gray-400">{{ item.time }}</div>
<!-- <p class="text-gray-600 mb-4">{{ item.content }}</p>
<div class="text-sm text-gray-400">{{ item.contentDatetime }}</div> -->
<div class="flex items-center text-sm text-gray-500">
<span>{{ item.contentDatetime }}</span>
<span class="mx-5">留言人:{{ item.name }}</span>
</div>
<p class="mt-2 text-gray-700">{{ item.content }}</p>
</div>
</div>
......@@ -89,9 +95,13 @@ const handleCurrentChange = (val: number) => {
getList(pageSize.value, pageNo.value);
function handleSearch() {
getList(10, 1);
}
//获取新闻热点列表
function getList(pageSize: number, pageNo: number) {
const datas = {
title: searchText.value,
pageSize: pageSize,
pageNo: pageNo,
};
......@@ -107,58 +117,9 @@ const breadcrumbItems = ref([
{ 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 = (pageNo.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",
path: "/wm/messagedetail",
query: {
title: "回复列表",
pathType: "/wm/recoverlist",
......
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