新加信息中心页面

main
zhong-hongye12355 1 week ago
parent d9d0dfb57d
commit d236217c22

@ -1,38 +1,50 @@
<template> <template>
<div class="message-container">
<div class="left-nav"> <div class="left-nav">
<div class="nav-title">消息中心</div> <div class="nav-title">消息中心</div>
<ul class="nav-list"> <ul class="nav-list">
<li <li
v-for="(item, index) in navItems" v-for="(item, index) in navItems"
:key="index" :key="index"
:class="['nav-item', { active: activeIndex === index }]" :class="['nav-item', { active: $route.path === item.path }]"
@click="handleNavClick(index)" @click="handleNavClick(item.path)"
> >
<span>{{ item.text }}</span> <span>{{ item.text }}</span>
</li> </li>
</ul> </ul>
</div> </div>
</template> <div class="center-message">
<p v-if="showWelcomeMessage">(^ω^)</p>
<script setup lang="ts"> <router-view />
import { ref } from 'vue'; </div>
</div>
const emit = defineEmits(['nav-change']); </template>
const activeIndex = ref(0); <script setup lang="ts">
import { useRouter, useRoute } from "vue-router";
const navItems = [ import { computed } from "vue";
{ text: '通知消息' },
{ text: '系统通知' }, const emit = defineEmits(['nav-change']);
{ text: '用户消息' },
{ text: '系统消息' } const router = useRouter();
]; const route = useRoute();
const handleNavClick = (index: number) => { const navItems = [
activeIndex.value = index; { text: '私信消息', path: '/messageNav/directMessage' },
emit('nav-change', index); { text: '评论回复', path: '/messageNav/comments' },
}; { text: '收到的赞', path: '/messageNav/goods' },
</script> { text: '系统通知', path: '/messageNav/system-notification' },
];
const showWelcomeMessage = computed(() => {
return route.path === '/MessageNav';
});
const handleNavClick = (path: string) => {
router.push(path);
};
</script>
<style scoped> <style scoped>
.left-nav { .left-nav {
@ -45,6 +57,10 @@
margin-right: 20px; margin-right: 20px;
margin-left: 100px; margin-left: 100px;
height: 90%; height: 90%;
position: fixed;
left: 0;
top: 70px;
z-index: 9999;
} }
.nav-title { .nav-title {
@ -62,6 +78,7 @@
margin: 5px 10px; margin: 5px 10px;
border-radius: 8px; border-radius: 8px;
font-size: 24px; font-size: 24px;
color: #333;
} }
.nav-item.active { .nav-item.active {
@ -73,4 +90,14 @@
.nav-item:hover { .nav-item:hover {
background: rgba(156, 136, 255, 0.1); background: rgba(156, 136, 255, 0.1);
} }
.center-message
{
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
font-size: 32px;
color:#9c88ff;
}
</style> </style>

@ -9,6 +9,10 @@ import PostManager from '@/views/PostManagement.vue';
import Curriculum from '@/views/Curriculum.vue'; import Curriculum from '@/views/Curriculum.vue';
import DirectMessage from '@/views/DirectMessage.vue'; import DirectMessage from '@/views/DirectMessage.vue';
import AIManager from '@/views/AiManager.vue' import AIManager from '@/views/AiManager.vue'
import MessageNav from '@/components/MessageNav.vue'
import Comments from '@/views/Comments.vue'
import Goods from '@/views/Goods.vue'
import SystemNotifications from '@/views/System-notifications.vue'
import SearchResult from "@/views/SearchResult.vue"; import SearchResult from "@/views/SearchResult.vue";
const routes: Array<RouteRecordRaw> = [ const routes: Array<RouteRecordRaw> = [
@ -58,11 +62,6 @@ const routes: Array<RouteRecordRaw> = [
} }
] ]
}, },
{
path: '/message',
name: 'DirectMessage',
component: DirectMessage,
},
{ {
path:'/uniLifeHome', path:'/uniLifeHome',
name: 'ForumHome', name: 'ForumHome',
@ -82,17 +81,37 @@ const routes: Array<RouteRecordRaw> = [
} }
}, },
{ {
path:'/directMessage', path:'/messageNav',
name:'DirectMessage', name:'MessageNav',
component:() => import('@/views/DirectMessage.vue'), component:MessageNav,
children: [
{
path: 'directMessage',
name: 'DirectMessage',
component: DirectMessage,
},
{
path: 'comments',
name: 'Comments',
component: Comments,
},
{
path: 'goods',
name: 'Goods',
component: Goods,
},
{
path: 'system-notification',
name: 'System-notification',
component: SystemNotifications,
}
]
}, },
{ {
path: '/search', path: '/search',
name: 'SearchResult', name: 'SearchResult',
component: SearchResult, component: SearchResult,
}, }
]; ];
const router = createRouter({ const router = createRouter({

@ -0,0 +1,312 @@
<script lang="ts">
import { defineComponent, ref, computed } from 'vue';
interface Message {
id: number;
content: string;
time: string;
detail: string;
}
export default defineComponent({
setup() {
const messages = ref<Message[]>([
{ id: 1, content: "这是第一条消息内容,点击查看更多", detail:"哈哈哈哈", time: "2025-05-31 10:30" },
{ id: 2, content: "这是第二条消息内容,点击查看更多", detail:"哈哈哈哈", time: "2025-05-31 11:15" },
{ id: 3, content: "这是第三条消息内容,点击查看更多", detail:"哈哈哈哈", time: "2025-05-31 12:00" },
{ id: 4, content: "这是第四条消息内容,点击查看更多", detail:"哈哈哈哈", time: "2025-05-31 12:45" },
{ id: 5, content: "这是第五条消息内容,点击查看更多", detail:"哈哈哈哈", time: "2025-05-31 13:30" },
{ id: 6, content: "这是第六条消息内容,点击查看更多", detail:"哈哈哈哈", time: "2025-05-31 14:15" },
{ id: 7, content: "这是第七条消息内容,点击查看更多", detail:"哈哈哈哈", time: "2025-05-31 15:00" },
//
]);
const currentPage = ref<number>(1);
const messagesPerPage = ref<number>(5);
const isModalOpen = ref<boolean>(false);
const selectedMessage = ref<Message | null>(null);
const totalPages = computed((): number => {
return Math.ceil(messages.value.length / messagesPerPage.value);
});
const currentPageMessages = computed((): Message[] => {
const startIndex = (currentPage.value - 1) * messagesPerPage.value;
const endIndex = startIndex + messagesPerPage.value;
return messages.value.slice(startIndex, endIndex);
});
const changePage = (pageNumber: number): void => {
if (pageNumber >= 1 && pageNumber <= totalPages.value) {
currentPage.value = pageNumber;
}
};
const openModal = (message : Message) :void => {
selectedMessage.value = message;
isModalOpen.value = true;
document.body.style.overflow="hidden";
}
const closeModal = () :void => {
selectedMessage.value = null;
isModalOpen.value = false;
document.body.style.overflow='';
}
return {
messages,
currentPage,
messagesPerPage,
totalPages,
currentPageMessages,
changePage,
isModalOpen,
selectedMessage,
openModal,
closeModal,
};
}
});
</script>
<template>
<div class="message-center">
<!-- 右侧主要内容区域 -->
<div class="main-content">
<!-- 顶部标题区域 -->
<div class="content-header">
<span class="header-title">评论回复</span>
</div>
<!-- 消息框区域 - 现在是垂直排列 -->
<div class="message-container">
<div v-for="(message, index) in currentPageMessages"
:key="index"
class="message-box"
@click="openModal(message)">
<div class="message-content">{{ message.content }}</div>
<div class="message-time">{{ message.time }}</div>
</div>
</div>
<!-- 分页控制区域 -->
<div class="pagination-controls" v-if="totalPages > 1">
<button
class="page-button"
:disabled="currentPage === 1"
@click="changePage(currentPage - 1)"
>
上一页
</button>
<span class="page-indicator">{{ currentPage }} / {{ totalPages }}</span>
<button
class="page-button"
:disabled="currentPage === totalPages"
@click="changePage(currentPage + 1)"
>
下一页
</button>
</div>
</div>
<div v-if="isModalOpen" class="modal-overlay">
<div class="modal-content">
<div class="modal-header">
<h3>消息详情</h3>
</div>
<div class="modal-body">
<p>{{ selectedMessage?.detail }}</p>
</div>
<div class="modal-footer">
<div class="message-time">{{ selectedMessage?.time }}</div>
<button class="confirm-button" @click="closeModal"></button>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.message-center {
display: flex;
width: calc(100% - 100px); /* 减去侧边栏宽度 */
height: calc(100vh - 120px);
margin: 130px 20px 20px 350px; /* 左侧margin增加到120px为侧边栏留出空间 */
padding: 0;
border-radius: 10px;
}
/* 主要内容区域样式 */
.main-content {
display: flex;
flex-direction: column;
flex: 1;
height: 100%;
}
/* 顶部标题区域样式 */
.content-header {
height: 70px;
width:1267px;
background: rgba(255, 255, 255, 0.5);
backdrop-filter: blur(10px);
border: 2px solid rgba(133, 88, 207, 0.5);
border-radius: 10px;
margin-bottom: 10px;
display: flex;
align-items: center;
padding: 0 20px;
}
.header-title {
font-size: 30px;
font-weight: bold;
color: #7e7e7e;
}
/* 消息框容器样式 - 修改为垂直排列 */
.message-container {
display: flex;
flex-direction: column; /* 改为垂直排列 */
gap: 15px; /* 消息框之间的间距 */
margin-bottom: 20px;
overflow-y: auto; /* 如果内容过多可以滚动 */
}
/* 单个消息框样式 */
.message-box {
width: 1275px; /* 宽度占满容器 */
min-height: 80px; /* 减小高度使垂直排列更紧凑 */
background: rgba(255, 255, 255, 0.7);
backdrop-filter: blur(5px);
border: 1px solid rgba(133, 88, 207, 0.3);
border-radius: 8px;
padding: 15px;
display: flex;
flex-direction: column;
justify-content: space-between;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
transition: transform 0.2s, box-shadow 0.2s;
}
.message-box:hover{
transform: translateY(-3px);
box-shadow: 0 20px 10px rgba(0, 0, 0, 0.1);
}
.message-content{
font-size: 24px;
color:#333;
margin-bottom: 10px;
flex-grow: 1;
}
.message-time{
font-size: 18px;
color:#888;
text-align: right;
}
.pagination-controls{
display: flex;
justify-content: center;
align-items: center;
margin-top: 20px;
}
.page-button{
background: rgba(133, 88, 207, 0.7);
color: white;
border: none;
border-radius: 5px;
padding: 8px 15px;
cursor: pointer;
margin: 0 10px;
transition:background 0.2s;
position: relative;
right: 200px;
}
.page-button:hover:not(:disabled){
background: rgba(133, 88, 207, 0.9);
}
.page-button:disabled{
background: rgba(133, 88, 207, 0.3);
cursor: not-allowed;
}
.page-indicator{
font-size: 14px;
color: #666;
position: relative;
right: 200px;
}
.modal-overlay{
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(255, 255, 255, 0.7);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.modal-content{
background: #fff;
width: 600px;
border-radius: 10px;
box-shadow: 0 5px 30px rgba(0, 0, 0, 0.3);
display: flex;
flex-direction: column;
height: 800px;
font-size: 28px;
}
.modal-header{
padding: 15px 20px;
border-bottom: 1px solid #eee;
display: flex;
justify-content: space-between;
align-items: center;
}
.modal-header h3{
margin: 0;
color: #333;
}
.modal-body{
padding: 20px;
overflow-y: visible;
flex-grow: 1;
line-height: 1.6;
}
.modal-footer{
padding: 15px 20px;
border-top: 1px solid #eee;
display: flex;
justify-content: space-between;
align-items: center;
}
.confirm-button{
background: rgba(133, 88, 207, 0.7);
color: white;
border: none;
border-radius: 5px;
padding: 8px 20px;
cursor: pointer;
transition: background 0.2s;
}
.confirm-button:hover{
background: rgba(133, 88, 207, 0.9);
}
</style>

@ -1,8 +1,5 @@
<template> <template>
<div class="message-center"> <div class="message-center">
<!-- 使用导航组件 -->
<MessageNav @nav-change="handleNavChange" />
<!-- 右侧主要内容区域 --> <!-- 右侧主要内容区域 -->
<div class="main-content"> <div class="main-content">
<!-- 顶部标题区域 --> <!-- 顶部标题区域 -->
@ -78,7 +75,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; import { ref } from 'vue';
import MessageNav from '@/components/MessageNav.vue';
// //
interface Message { interface Message {
@ -139,11 +135,6 @@ const sendMessage = () => {
message.value = ''; message.value = '';
}; };
//
const handleNavChange = (index: number) => {
//
console.log('导航切换到:', index);
};
</script> </script>
<style scoped> <style scoped>

@ -1,387 +0,0 @@
<template>
<div class="message-center">
<!-- 左侧导航 -->
<div class="left-nav">
<div class="nav-title">消息中心</div>
<ul class="nav-list">
<li class="nav-item active">
<span>私信消息</span>
</li>
<li class="nav-item">
<span>评论回复</span>
</li>
<li class="nav-item">
<span>收到的赞</span>
</li>
<li class="nav-item">
<span>系统通知</span>
</li>
</ul>
</div>
<!-- 右侧主要内容区域 -->
<div class="main-content">
<!-- 顶部标题区域 -->
<div class="content-header">
<span class="header-title">私信消息</span>
</div>
<!-- 下方内容区域 -->
<div class="content-body">
<!-- 中间消息列表使用 AiManager 的样式 -->
<aside class="sidebar">
<h2 class="sidebar-title">近期消息</h2>
<ul class="history-list">
<li class="history-item"
v-for="conversation in conversations"
:key="conversation.id"
@click="selectConversation(conversation)">
<span class="history-text">{{ conversation.title }}</span>
</li>
</ul>
</aside>
<!-- 右侧聊天区域使用 AiManager 的样式 -->
<main class="chat-area">
<div class="chat-content">
<!-- 对话消息 -->
<template v-if="currentConversation">
<div v-for="message in currentConversation.messages"
:key="message.id"
:class="message.isUser ? 'user-message' : 'bot-message'">
<template v-if="message.isUser">
<div class="message-text">{{ message.text }}</div>
<div class="user-avatar">
<img src="@/assets/images/aiRobot.png" alt="用户头像" />
</div>
</template>
<template v-else>
<div class="bot-avatar">
<img src="@/assets/images/aiRobot.png" alt="对方头像" />
</div>
<div class="message-text">{{ message.text }}</div>
</template>
</div>
</template>
</div>
<!-- 输入区域 -->
<div class="input-area">
<div class="input-container">
<textarea
class="message-input"
placeholder="输入消息..."
v-model="message"
></textarea>
<button class="send-button" @click="sendMessage"></button>
</div>
</div>
</main>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
//
interface Message {
id: number;
text: string;
isUser: boolean;
timestamp: number;
}
//
interface Conversation {
id: number;
title: string;
messages: Message[];
timestamp: number;
}
//
const conversations = ref<Conversation[]>([
{
id: 1,
title: '用户A',
messages: [
{
id: 1,
text: '你好!',
isUser: false,
timestamp: Date.now() - 1000
}
],
timestamp: Date.now()
}
]);
//
const currentConversation = ref<Conversation | null>(null);
//
const message = ref('');
//
const selectConversation = (conversation: Conversation) => {
currentConversation.value = conversation;
};
//
const sendMessage = () => {
if (!currentConversation.value || !message.value.trim()) return;
const newMessage: Message = {
id: Date.now(),
text: message.value.trim(),
isUser: true,
timestamp: Date.now()
};
currentConversation.value.messages.push(newMessage);
message.value = '';
};
</script>
<style scoped>
/* 修改消息中心的样式 */
.message-center {
display: flex;
width: calc(100% - 100px); /* 减去侧边栏宽度 */
height: calc(100vh - 120px);
margin: 130px 20px 20px 350px; /* 左侧margin增加到120px为侧边栏留出空间 */
padding: 0;
border-radius: 10px;
}
/* 左侧导航样式 */
.left-nav {
width: 15%; /* 调整为百分比宽度 */
background: rgba(255, 255, 255, 0.5);
backdrop-filter: blur(10px);
border: 2px solid rgba(133, 88, 207, 0.5);
border-radius: 10px;
padding: 20px 0;
margin-right: 20px; /* 只保留右侧间距 */
height: 90%; /* 修改为100%填充 */
}
.nav-title {
font-size: 24px;
font-weight: bold;
padding: 0 20px;
margin-bottom: 20px;
color: #333;
}
.nav-item {
padding: 15px 20px;
cursor: pointer;
transition: all 0.3s;
margin: 5px 10px;
border-radius: 8px;
}
.nav-item.active {
background: rgba(156, 136, 255, 0.2);
color: #9c88ff;
}
.nav-item:hover {
background: rgba(156, 136, 255, 0.1);
}
/* 主要内容区域样式 */
.main-content {
display: flex;
flex-direction: column;
flex: 1;
height: 100%;
}
/* 顶部标题区域样式 */
.content-header {
height: 60px;
width:1400px;
background: rgba(255, 255, 255, 0.5);
backdrop-filter: blur(10px);
border: 2px solid rgba(133, 88, 207, 0.5);
border-radius: 10px;
margin-bottom: 20px;
display: flex;
align-items: center;
padding: 0 20px;
}
.header-title {
font-size: 20px;
font-weight: bold;
color: #333;
}
/* 下方内容区域样式 */
.content-body {
display: flex;
flex: 1;
gap: 20px;
}
/* 消息列表样式 */
.sidebar {
width: 15%; /* 调整为百分比宽度 */
background: rgba(255, 255, 255, 0.5);
backdrop-filter: blur(10px);
border: 2px solid rgba(133, 88, 207, 0.5);
border-radius: 10px;
margin-right: 20px; /* 只保留右侧间距 */
height: calc(100% - 80px); /* 减去顶部区域的高度和间距 */
}
.sidebar-title {
padding: 20px;
font-size: 20px;
border-bottom: 1px solid rgba(133, 88, 207, 0.2);
color: #333;
}
.history-list {
list-style: none;
padding: 0;
margin: 0;
}
.history-item {
padding: 15px 20px;
cursor: pointer;
border-bottom: 1px solid rgba(133, 88, 207, 0.2);
transition: all 0.3s;
}
.history-item:hover {
background: rgba(156, 136, 255, 0.1);
}
.history-text {
color: #333;
}
/* 聊天区域样式 */
.chat-area {
width: 50%; /* 设置固定宽度比例 */
flex: none; /* 移除 flex: 1避免自动扩展 */
display: flex;
flex-direction: column;
background: rgba(255, 255, 255, 0.5);
backdrop-filter: blur(10px);
border: 2px solid rgba(133, 88, 207, 0.5);
border-radius: 10px;
height: calc(100% - 80px); /* 减去顶部区域的高度和间距 */
}
.chat-content {
flex: 1;
padding: 20px;
overflow-y: auto;
}
.user-message {
display: flex;
justify-content: flex-end;
margin-bottom: 10px;
}
.bot-message {
display: flex;
justify-content: flex-start;
margin-bottom: 10px;
}
.message-text {
max-width: 70%;
padding: 12px 16px;
border-radius: 12px;
background: rgba(255, 255, 255, 0.9);
margin: 0 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.user-message .message-text {
background: rgba(156, 136, 255, 0.9);
color: white;
}
.bot-avatar,
.user-avatar {
width: 40px;
height: 40px;
border-radius: 50%;
overflow: hidden;
}
.input-area {
padding: 20px;
border-top: 1px solid rgba(133, 88, 207, 0.2);
background: rgba(255, 255, 255, 0.3);
border-radius: 0 0 10px 10px;
}
.input-container {
display: flex;
align-items: center;
}
.message-input {
flex: 1;
height: 100px;
padding: 12px;
border: 1px solid rgba(133, 88, 207, 0.3);
border-radius: 8px;
resize: none;
margin-right: 12px;
font-size: 16px;
background: rgba(255, 255, 255, 0.9);
transition: all 0.3s;
}
.message-input:focus {
border-color: #9c88ff;
outline: none;
}
.send-button {
padding: 8px 24px;
background: linear-gradient(45deg, #9c88ff, #ff6b9d);
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
font-size: 16px;
transition: all 0.3s;
}
.send-button:hover {
transform: translateY(-2px);
box-shadow: 0 4px 15px rgba(156, 136, 255, 0.3);
}
/* 自定义滚动条 */
::-webkit-scrollbar {
width: 6px;
}
::-webkit-scrollbar-track {
background: rgba(200, 180, 255, 0.1);
border-radius: 3px;
}
::-webkit-scrollbar-thumb {
background: rgba(156, 136, 255, 0.3);
border-radius: 3px;
}
::-webkit-scrollbar-thumb:hover {
background: rgba(156, 136, 255, 0.5);
}
</style>

@ -0,0 +1,312 @@
<script lang="ts">
import { defineComponent, ref, computed } from 'vue';
interface Message {
id: number;
content: string;
time: string;
detail: string;
}
export default defineComponent({
setup() {
const messages = ref<Message[]>([
{ id: 1, content: "这是第一条消息内容,点击查看更多", detail:"哈哈哈哈", time: "2025-05-31 10:30" },
{ id: 2, content: "这是第二条消息内容,点击查看更多", detail:"哈哈哈哈", time: "2025-05-31 11:15" },
{ id: 3, content: "这是第三条消息内容,点击查看更多", detail:"哈哈哈哈", time: "2025-05-31 12:00" },
{ id: 4, content: "这是第四条消息内容,点击查看更多", detail:"哈哈哈哈", time: "2025-05-31 12:45" },
{ id: 5, content: "这是第五条消息内容,点击查看更多", detail:"哈哈哈哈", time: "2025-05-31 13:30" },
{ id: 6, content: "这是第六条消息内容,点击查看更多", detail:"哈哈哈哈", time: "2025-05-31 14:15" },
{ id: 7, content: "这是第七条消息内容,点击查看更多", detail:"哈哈哈哈", time: "2025-05-31 15:00" },
//
]);
const currentPage = ref<number>(1);
const messagesPerPage = ref<number>(5);
const isModalOpen = ref<boolean>(false);
const selectedMessage = ref<Message | null>(null);
const totalPages = computed((): number => {
return Math.ceil(messages.value.length / messagesPerPage.value);
});
const currentPageMessages = computed((): Message[] => {
const startIndex = (currentPage.value - 1) * messagesPerPage.value;
const endIndex = startIndex + messagesPerPage.value;
return messages.value.slice(startIndex, endIndex);
});
const changePage = (pageNumber: number): void => {
if (pageNumber >= 1 && pageNumber <= totalPages.value) {
currentPage.value = pageNumber;
}
};
const openModal = (message : Message) :void => {
selectedMessage.value = message;
isModalOpen.value = true;
document.body.style.overflow="hidden";
}
const closeModal = () :void => {
selectedMessage.value = null;
isModalOpen.value = false;
document.body.style.overflow='';
}
return {
messages,
currentPage,
messagesPerPage,
totalPages,
currentPageMessages,
changePage,
isModalOpen,
selectedMessage,
openModal,
closeModal,
};
}
});
</script>
<template>
<div class="message-center">
<!-- 右侧主要内容区域 -->
<div class="main-content">
<!-- 顶部标题区域 -->
<div class="content-header">
<span class="header-title">评论回复</span>
</div>
<!-- 消息框区域 - 现在是垂直排列 -->
<div class="message-container">
<div v-for="(message, index) in currentPageMessages"
:key="index"
class="message-box"
@click="openModal(message)">
<div class="message-content">{{ message.content }}</div>
<div class="message-time">{{ message.time }}</div>
</div>
</div>
<!-- 分页控制区域 -->
<div class="pagination-controls" v-if="totalPages > 1">
<button
class="page-button"
:disabled="currentPage === 1"
@click="changePage(currentPage - 1)"
>
上一页
</button>
<span class="page-indicator">{{ currentPage }} / {{ totalPages }}</span>
<button
class="page-button"
:disabled="currentPage === totalPages"
@click="changePage(currentPage + 1)"
>
下一页
</button>
</div>
</div>
<div v-if="isModalOpen" class="modal-overlay">
<div class="modal-content">
<div class="modal-header">
<h3>消息详情</h3>
</div>
<div class="modal-body">
<p>{{ selectedMessage?.detail }}</p>
</div>
<div class="modal-footer">
<div class="message-time">{{ selectedMessage?.time }}</div>
<button class="confirm-button" @click="closeModal"></button>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.message-center {
display: flex;
width: calc(100% - 100px); /* 减去侧边栏宽度 */
height: calc(100vh - 120px);
margin: 130px 20px 20px 350px; /* 左侧margin增加到120px为侧边栏留出空间 */
padding: 0;
border-radius: 10px;
}
/* 主要内容区域样式 */
.main-content {
display: flex;
flex-direction: column;
flex: 1;
height: 100%;
}
/* 顶部标题区域样式 */
.content-header {
height: 70px;
width:1267px;
background: rgba(255, 255, 255, 0.5);
backdrop-filter: blur(10px);
border: 2px solid rgba(133, 88, 207, 0.5);
border-radius: 10px;
margin-bottom: 10px;
display: flex;
align-items: center;
padding: 0 20px;
}
.header-title {
font-size: 30px;
font-weight: bold;
color: #7e7e7e;
}
/* 消息框容器样式 - 修改为垂直排列 */
.message-container {
display: flex;
flex-direction: column; /* 改为垂直排列 */
gap: 15px; /* 消息框之间的间距 */
margin-bottom: 20px;
overflow-y: auto; /* 如果内容过多可以滚动 */
}
/* 单个消息框样式 */
.message-box {
width: 1275px; /* 宽度占满容器 */
min-height: 80px; /* 减小高度使垂直排列更紧凑 */
background: rgba(255, 255, 255, 0.7);
backdrop-filter: blur(5px);
border: 1px solid rgba(133, 88, 207, 0.3);
border-radius: 8px;
padding: 15px;
display: flex;
flex-direction: column;
justify-content: space-between;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
transition: transform 0.2s, box-shadow 0.2s;
}
.message-box:hover{
transform: translateY(-3px);
box-shadow: 0 20px 10px rgba(0, 0, 0, 0.1);
}
.message-content{
font-size: 24px;
color:#333;
margin-bottom: 10px;
flex-grow: 1;
}
.message-time{
font-size: 18px;
color:#888;
text-align: right;
}
.pagination-controls{
display: flex;
justify-content: center;
align-items: center;
margin-top: 20px;
}
.page-button{
background: rgba(133, 88, 207, 0.7);
color: white;
border: none;
border-radius: 5px;
padding: 8px 15px;
cursor: pointer;
margin: 0 10px;
transition:background 0.2s;
position: relative;
right: 200px;
}
.page-button:hover:not(:disabled){
background: rgba(133, 88, 207, 0.9);
}
.page-button:disabled{
background: rgba(133, 88, 207, 0.3);
cursor: not-allowed;
}
.page-indicator{
font-size: 14px;
color: #666;
position: relative;
right: 200px;
}
.modal-overlay{
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(255, 255, 255, 0.7);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.modal-content{
background: #fff;
width: 600px;
border-radius: 10px;
box-shadow: 0 5px 30px rgba(0, 0, 0, 0.3);
display: flex;
flex-direction: column;
height: 800px;
font-size: 28px;
}
.modal-header{
padding: 15px 20px;
border-bottom: 1px solid #eee;
display: flex;
justify-content: space-between;
align-items: center;
}
.modal-header h3{
margin: 0;
color: #333;
}
.modal-body{
padding: 20px;
overflow-y: visible;
flex-grow: 1;
line-height: 1.6;
}
.modal-footer{
padding: 15px 20px;
border-top: 1px solid #eee;
display: flex;
justify-content: space-between;
align-items: center;
}
.confirm-button{
background: rgba(133, 88, 207, 0.7);
color: white;
border: none;
border-radius: 5px;
padding: 8px 20px;
cursor: pointer;
transition: background 0.2s;
}
.confirm-button:hover{
background: rgba(133, 88, 207, 0.9);
}
</style>

@ -0,0 +1,312 @@
<script lang="ts">
import { defineComponent, ref, computed } from 'vue';
interface Message {
id: number;
content: string;
time: string;
detail: string;
}
export default defineComponent({
setup() {
const messages = ref<Message[]>([
{ id: 1, content: "这是第一条消息内容,点击查看更多", detail:"哈哈哈哈", time: "2025-05-31 10:30" },
{ id: 2, content: "这是第二条消息内容,点击查看更多", detail:"哈哈哈哈", time: "2025-05-31 11:15" },
{ id: 3, content: "这是第三条消息内容,点击查看更多", detail:"哈哈哈哈", time: "2025-05-31 12:00" },
{ id: 4, content: "这是第四条消息内容,点击查看更多", detail:"哈哈哈哈", time: "2025-05-31 12:45" },
{ id: 5, content: "这是第五条消息内容,点击查看更多", detail:"哈哈哈哈", time: "2025-05-31 13:30" },
{ id: 6, content: "这是第六条消息内容,点击查看更多", detail:"哈哈哈哈", time: "2025-05-31 14:15" },
{ id: 7, content: "这是第七条消息内容,点击查看更多", detail:"哈哈哈哈", time: "2025-05-31 15:00" },
//
]);
const currentPage = ref<number>(1);
const messagesPerPage = ref<number>(5);
const isModalOpen = ref<boolean>(false);
const selectedMessage = ref<Message | null>(null);
const totalPages = computed((): number => {
return Math.ceil(messages.value.length / messagesPerPage.value);
});
const currentPageMessages = computed((): Message[] => {
const startIndex = (currentPage.value - 1) * messagesPerPage.value;
const endIndex = startIndex + messagesPerPage.value;
return messages.value.slice(startIndex, endIndex);
});
const changePage = (pageNumber: number): void => {
if (pageNumber >= 1 && pageNumber <= totalPages.value) {
currentPage.value = pageNumber;
}
};
const openModal = (message : Message) :void => {
selectedMessage.value = message;
isModalOpen.value = true;
document.body.style.overflow="hidden";
}
const closeModal = () :void => {
selectedMessage.value = null;
isModalOpen.value = false;
document.body.style.overflow='';
}
return {
messages,
currentPage,
messagesPerPage,
totalPages,
currentPageMessages,
changePage,
isModalOpen,
selectedMessage,
openModal,
closeModal,
};
}
});
</script>
<template>
<div class="message-center">
<!-- 右侧主要内容区域 -->
<div class="main-content">
<!-- 顶部标题区域 -->
<div class="content-header">
<span class="header-title">评论回复</span>
</div>
<!-- 消息框区域 - 现在是垂直排列 -->
<div class="message-container">
<div v-for="(message, index) in currentPageMessages"
:key="index"
class="message-box"
@click="openModal(message)">
<div class="message-content">{{ message.content }}</div>
<div class="message-time">{{ message.time }}</div>
</div>
</div>
<!-- 分页控制区域 -->
<div class="pagination-controls" v-if="totalPages > 1">
<button
class="page-button"
:disabled="currentPage === 1"
@click="changePage(currentPage - 1)"
>
上一页
</button>
<span class="page-indicator">{{ currentPage }} / {{ totalPages }}</span>
<button
class="page-button"
:disabled="currentPage === totalPages"
@click="changePage(currentPage + 1)"
>
下一页
</button>
</div>
</div>
<div v-if="isModalOpen" class="modal-overlay">
<div class="modal-content">
<div class="modal-header">
<h3>消息详情</h3>
</div>
<div class="modal-body">
<p>{{ selectedMessage?.detail }}</p>
</div>
<div class="modal-footer">
<div class="message-time">{{ selectedMessage?.time }}</div>
<button class="confirm-button" @click="closeModal"></button>
</div>
</div>
</div>
</div>
</template>
<style scoped>
.message-center {
display: flex;
width: calc(100% - 100px); /* 减去侧边栏宽度 */
height: calc(100vh - 120px);
margin: 130px 20px 20px 350px; /* 左侧margin增加到120px为侧边栏留出空间 */
padding: 0;
border-radius: 10px;
}
/* 主要内容区域样式 */
.main-content {
display: flex;
flex-direction: column;
flex: 1;
height: 100%;
}
/* 顶部标题区域样式 */
.content-header {
height: 70px;
width:1267px;
background: rgba(255, 255, 255, 0.5);
backdrop-filter: blur(10px);
border: 2px solid rgba(133, 88, 207, 0.5);
border-radius: 10px;
margin-bottom: 10px;
display: flex;
align-items: center;
padding: 0 20px;
}
.header-title {
font-size: 30px;
font-weight: bold;
color: #7e7e7e;
}
/* 消息框容器样式 - 修改为垂直排列 */
.message-container {
display: flex;
flex-direction: column; /* 改为垂直排列 */
gap: 15px; /* 消息框之间的间距 */
margin-bottom: 20px;
overflow-y: auto; /* 如果内容过多可以滚动 */
}
/* 单个消息框样式 */
.message-box {
width: 1275px; /* 宽度占满容器 */
min-height: 80px; /* 减小高度使垂直排列更紧凑 */
background: rgba(255, 255, 255, 0.7);
backdrop-filter: blur(5px);
border: 1px solid rgba(133, 88, 207, 0.3);
border-radius: 8px;
padding: 15px;
display: flex;
flex-direction: column;
justify-content: space-between;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
transition: transform 0.2s, box-shadow 0.2s;
}
.message-box:hover{
transform: translateY(-3px);
box-shadow: 0 20px 10px rgba(0, 0, 0, 0.1);
}
.message-content{
font-size: 24px;
color:#333;
margin-bottom: 10px;
flex-grow: 1;
}
.message-time{
font-size: 18px;
color:#888;
text-align: right;
}
.pagination-controls{
display: flex;
justify-content: center;
align-items: center;
margin-top: 20px;
}
.page-button{
background: rgba(133, 88, 207, 0.7);
color: white;
border: none;
border-radius: 5px;
padding: 8px 15px;
cursor: pointer;
margin: 0 10px;
transition:background 0.2s;
position: relative;
right: 200px;
}
.page-button:hover:not(:disabled){
background: rgba(133, 88, 207, 0.9);
}
.page-button:disabled{
background: rgba(133, 88, 207, 0.3);
cursor: not-allowed;
}
.page-indicator{
font-size: 14px;
color: #666;
position: relative;
right: 200px;
}
.modal-overlay{
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(255, 255, 255, 0.7);
display: flex;
justify-content: center;
align-items: center;
z-index: 1000;
}
.modal-content{
background: #fff;
width: 600px;
border-radius: 10px;
box-shadow: 0 5px 30px rgba(0, 0, 0, 0.3);
display: flex;
flex-direction: column;
height: 800px;
font-size: 28px;
}
.modal-header{
padding: 15px 20px;
border-bottom: 1px solid #eee;
display: flex;
justify-content: space-between;
align-items: center;
}
.modal-header h3{
margin: 0;
color: #333;
}
.modal-body{
padding: 20px;
overflow-y: visible;
flex-grow: 1;
line-height: 1.6;
}
.modal-footer{
padding: 15px 20px;
border-top: 1px solid #eee;
display: flex;
justify-content: space-between;
align-items: center;
}
.confirm-button{
background: rgba(133, 88, 207, 0.7);
color: white;
border: none;
border-radius: 5px;
padding: 8px 20px;
cursor: pointer;
transition: background 0.2s;
}
.confirm-button:hover{
background: rgba(133, 88, 207, 0.9);
}
</style>
Loading…
Cancel
Save