'更新站内消息'

develoop
fwb 3 months ago
parent 0cf6e42287
commit 2caf79f6e4
  1. 4
      .env.development
  2. 29
      index.html
  3. 17530
      pnpm-lock.yaml
  4. BIN
      public/newslogo.jpg
  5. 19
      src/api/user/messag.js
  6. 7
      src/api/user/send.js
  7. 37
      src/permission.ts
  8. 80
      src/router/routers.ts
  9. 80
      src/views/message/components/indexContentList.vue
  10. 204
      src/views/message/components/messageContent.vue
  11. 267
      src/views/message/components/sendMessage.vue
  12. 80
      src/views/message/components/sendMessageList.vue
  13. 268
      src/views/message/index.vue
  14. 59
      src/views/news/index.vue
  15. 40
      vite.config.ts.timestamp-1723526592229-30b7000bab01c.mjs

@ -1,5 +1,5 @@
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
NODE_ENV = 'development'
VITE_APP_TITLE = '无糖运营平台'
VITE_APP_BASE_API = 'http://127.0.0.1:8080'
# VITE_APP_BASE_API = 'http://39.106.16.162:8080'
# VITE_APP_BASE_API = 'http://127.0.0.1:8080'
VITE_APP_BASE_API = 'http://39.106.16.162:8080'

@ -1,15 +1,18 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>教学一体化后师生后台</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r134/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.globe.min.js"></script>
</body>
</html>
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>教学一体化后师生后台</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r134/three.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vanta@latest/dist/vanta.globe.min.js"></script>
</body>
</html>

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

@ -0,0 +1,19 @@
import request from '@/utils/request'
// 获取发件箱信息列表
export const getSendMessagesListApi = (params) => {
return request.get('/user-inbox/page/sendmessages', {
params,
})
}
// 获取收件箱信息列表
export const getMessagesListApi = (params) => {
return request.get('/user-inbox/page/receivemessages', {
params,
})
}
//删除收件箱
export const deleteSendMessageApi = (params) => {
return request.delete('/user-inbox/deletereceivemessage', {
params,
})
}

@ -0,0 +1,7 @@
import request from '@/utils/request'
//发送消息
export const sendMessagesApi = (params) => {
return request.post('/messages/addmessage', {
params,
})
}

@ -27,24 +27,25 @@ router.beforeEach(async (to, form, next) => {
// 没有获取到用户信息 就获取用户信息 然后放行
await userStore.getUserInfo()
// 获取筛选到的路由
const asyncRouter = await usePermissionStore.getAsyncRoutes(
userStore.routes,
)
// 遍历筛选出来的路由通过addRoute添加到路由表
asyncRouter.forEach((item: any) => {
router.addRoute(item)
})
// 在最后向路由表添加一个404规则
// 切记不要写到路由表内 否者刷新页面会跳转到404页面
router.addRoute({
path: '/:pathMatch(.*)*',
component: () => import('@/views/404/index.vue'),
name: 'Any',
meta: {
title: '任意',
hidden: true,
},
})
// const asyncRouter = await usePermissionStore.getAsyncRoutes(
// userStore.routes,
// )
// // 遍历筛选出来的路由通过addRoute添加到路由表
// asyncRouter.forEach((item: any) => {
// router.addRoute(item)
// })
// // 在最后向路由表添加一个404规则
// // 切记不要写到路由表内 否者刷新页面会跳转到404页面
// router.addRoute({
// path: '/:pathMatch(.*)*',
// component: () => import('@/views/404/index.vue'),
// name: 'Any',
// meta: {
// title: '任意',
// hidden: true,
// },
// })
next({ ...to, replace: true }) // 这里相当于push到一个页面 不在进入路由拦截
} catch (error) {
// 如果获取用户信息失败了则执行登出操作让重新登录

@ -1,3 +1,6 @@
import component from 'element-plus/es/components/tree-select/src/tree-select-option.mjs';
import { pa } from 'element-plus/es/locales.mjs';
export const constantRoute: any = [
{
path: '/',
@ -163,28 +166,89 @@ export const constantRoute: any = [
// ],
// },
{
path: '/mssageManagement',
path: '/messageManagement',
component: () => import('@/layout/index.vue'),
name: 'MssageManagement',
name: 'MessageManagement',
meta: {
title: '',
title: '消息',
hidden: false,
icon: 'HomeFilled', // 菜单图标
icon: 'ChatLineRound', // 菜单图标
},
children: [
{
path: '/mssageManagement/message',
path: '/messageManagement/message',
component: () => import('@/views/message/index.vue'),
name: 'Message',
meta: {
title: '消息',
title: '消息详情',
hidden: false,
icon: 'ChatDotSquare',
},
}
},
{
path: '/messageManagement/sendMessage',
component: ()=>import('@/views/message/components/sendMessage.vue'),
name:'SendMessage',
meta: {
title: '个人发出',
hidden: true,
icon: '',
}
},
{
path: '/messageContentList',
component:()=>import('@/views/message/components/indexContentList.vue'),
name:'MessageContentList',
meta: {
title: '收到信息详情',
hidden: true,
icon: ''
}
},
{
path: '/sendMessageList',
component:()=>import('@/views/message/components/sendMessageList.vue'),
name:'SendMessageList',
meta: {
title: '发送信息详情',
hidden: true,
icon: ''
}
},
],
},
{
path: '/messageContent',
component: () => import('@/views/message/components/messageContent.vue'),
name: 'MessageContent',
meta:{
title: '写栈内信函',
hidden: true,
icon: 'EditPen',
}
},
{
path: '/news',
component: () => import('@/layout/index.vue'),
name:'NewsManagement',
meta: {
title: '新闻',
hidden: false,
icon: 'BellFilled'
},
children: [
{
path: '/news/newsContent',
component:()=>import('@/views/news/index.vue'),
name:'NewsContent',
meta: {
title: '新闻内容',
hidden: false,
icon: 'BellFilled'
}
},
]
},
{
path: '/myCourseStudyManagement',
component: () => import('@/layout/index.vue'),

@ -0,0 +1,80 @@
<template>
<div class="common-layout">
<el-container>
<el-header class="header">
<p>收到信息详情</p>
</el-header>
<el-main >
<el-card>
<template #header>
<div class="card-header">
<el-button type="primary" style="width: 80px" @click="back" round plain>返回</el-button>
</div>
</template>
<div class="container">
<div class="header_content">
<span class="sender">发送人{{ Message.senderName }}</span>
<span class="time">发送时间{{ Message.sendTime }}</span>
<span class="read-status">是否阅读{{Message.isRead}}</span>
</div>
<div class="recipient">标题{{ Message.title }}</div>
<div class="content">
内容{{ Message.content }}
</div>
</div>
<!-- <template #footer>Footer content</template>-->
</el-card>
</el-main>
</el-container>
</div>
</template>
<script setup lang="ts">
import {useRouter,useRoute} from "vue-router";
const router = useRouter()
const route = useRoute()
//
if(!Object.keys(route.query).length){
router.go(-1)
}
//
const back = ()=>{
router.push('/messageManagement/message')
}
import {ref} from "vue";
//
const Message = ref(route.query)
</script>
<style scoped>
.header{
background: #7f98cb;
height: 50px;
font-size: 20px;
text-align: center;
padding: 15px;
}
.container {
padding: 10px; /* 容器内边距 */
margin-top: 10px; /* 容器上边距 */
height: 65vh;
}
.header_content {
margin-bottom: 10px; /* 与下面的收件人信息保持一定间距 */
}
.header_content span {
margin-right: 50px; /* 发件人和时间之间的间距 */
}
.header_content .read-status {
margin-right: 0; /* 已读状态右侧不需要间距 */
}
.recipient, .content {
font-size: 20px;
color: #333;
margin-top: 10px;
margin-bottom: 20px;
}
</style>

@ -0,0 +1,204 @@
<template>
<div class="common-layout">
<el-container>
<el-header class="header">
<p>写栈内信函</p>
</el-header>
<el-main class="mainContainer">
<el-card>
<template #header>
<div class="card-header">
<span>写栈内信函</span>
<div>
<el-button style="width: 100px;text-align: center" type="primary" round @click="back" plain>返回</el-button>
<el-button style="width: 100px;text-align: center" type="primary" round>发送</el-button>
</div>
</div>
</template>
<!-- 输入框内容-->
<el-input
v-model="inputPerson"
size="large"
placeholder="收件人:"
>
<template #append>
<el-button @click="addPerson = true">
<el-icon><CirclePlus /></el-icon>
</el-button>
</template>
</el-input>
<el-input
v-model="inputText"
size="large"
placeholder="标题:"
>
</el-input>
<el-input
v-model="textarea"
:rows="15"
type="textarea"
placeholder="内容:"
/>
<!--添加收件人信息-->
<el-dialog class="dialogType" v-model="addPerson" title="选择收件人">
<el-divider/>
<div class="content-container">
<div class="left-panel" style="flex: 1; display: flex; align-items: center; justify-content: center;">
<!-- <el-input-->
<!-- v-model="inputSearch"-->
<!-- style="max-width: 300px;-->
<!-- margin-bottom: 20px"-->
<!-- placeholder="搜索"-->
<!-- >-->
<!-- <template #append>-->
<!-- <el-button :icon="Search" @click="editSearch"/>-->
<!-- </template>-->
<!-- </el-input>-->
<!-- 组织架构-->
<div>
组织框架:
<el-tree-select
v-model="inputPerson"
:data="data"
multiple
:render-after-expand="false"
show-checkbox
style="width: 240px"
/>
</div>
</div>
<div class="right-panel" style="flex: 1;">
<p>已选人:</p>
<el-divider/>
<li v-for="item in inputPerson" :key="item.lable">
<p>{{item}}</p>
</li>
</div>
</div>
<el-divider/>
<div style="text-align: right">
<el-button type="primary" plain round>取消</el-button>
<el-button type="primary" @click="confirm" round>确定</el-button>
</div>
</el-dialog>
<template #footer>
<p>发送此站内信函即表示您已阅读并接受<el-link href="https://element-plus.org/zh-CN/component/overview.html" type="primary">用户协议</el-link></p>
</template>
</el-card>
</el-main>
</el-container>
</div>
</template>
<script setup lang="ts">
import { ref,onMounted} from 'vue'
import { Search } from '@element-plus/icons-vue'
import { useRouter } from 'vue-router';
const inputPerson = ref([])
const inputText = ref('')
const textarea = ref('')
const inputSearch = ref('')
const addPerson = ref(false)
const router = useRouter()
//
const back= ()=>{
router.push('/messageManagement/message')
}
//
const confirm = ()=>{
addPerson.value = false
}
//
const editSearch=()=>{
}
//
const data = ref([
{
value: '计算机学院',
label: '计算机学院',
children: [
{
value: '软件技术专业',
label: '软件技术专业',
children: [
{
value: '彭于晏',
label: '彭于晏',
},
],
},
],
},
{
value: '艺术学院',
label: '艺术学院',
children: [
{
value: '编导专业',
label: '编导专业',
children: [
{
value: '刘亦菲',
label: '刘亦菲',
},
],
},
{
value: '动画专业',
label: '动画专业',
children: [
{
value: '辛芷蕾',
label: '辛芷蕾',
},
],
},
],
},
])
</script>
<style scoped>
.header{
background: steelblue;
text-align: center;
font-size: 18px;
line-height: 45px;
height: 45px;
width: 100%;
margin-bottom: 30px;
}
.header p{
color: gainsboro;
}
li{
list-style: none;
}
.mainContainer{
width: 80%;
margin: auto;
}
.card-header{
display: flex; /* 启用Flexbox布局 */
justify-content: space-between; /* 在主轴上分布项目,这里让h2和button分布在两端 */
align-items: center; /* 在交叉轴上居中项目,这里是垂直居中 */
height: 30px; /* 示例高度,根据实际需求调整 */
padding: 0 20px; /* 添加一些内边距以避免内容紧贴边缘 */
}
.el-input{
margin-bottom: 30px;
}
.content-container {
display: flex;
height: 100%; /* 根据需要调整高度 */
}
.left-panel, .right-panel {
display: flex;
flex-direction: column;
justify-content: center; /* 垂直居中内容 */
align-items: center; /* 水平居中内容 */
}
</style>

@ -0,0 +1,267 @@
<template>
<el-card>
<template #header>
<div class="card-header">
<el-button type="primary" @click="back" round plain>返回</el-button>
<el-button type="primary" @click="sendContent" round>写栈内信函</el-button>
</div>
</template>
<div class="container">
<div class="checkboxHeader">
<input type="checkbox" class="custom-checkbox" @change="toggleAll" :checked="allSelected" />
<p class="selected-count">已选 {{ selectedCount }} 条记录</p>
</div>
<li v-for="item in sendMessage"
:key="item.title"
class="message-list-item"
>
<!--添加悬浮删除按钮-->
<!-- <div class="message-list" @mouseover="hoveringOver = item.id" @mouseleave="hoveringOver = null">-->
<div class="message-list">
<!-- 添加勾选框 -->
<div class="message-check">
<input type="checkbox" class="custom-checkbox" :value="item.id" @change="toggleSelection(item.id)" :checked="isSelected(item.id)"/>
</div>
<div class="message-icon">
<el-icon><Comment /></el-icon>
</div>
<div class="message-content" @click="handleClick(item)">
<h2 class="message-title">{{item.title}}</h2>
<div class="message-details">
<span class="sender">发送人:{{item.senderName}}</span>
<span class="read-status">阅读人数{{item.readUserNum}}</span>
</div>
<div class="message-time">{{item.sendTime}}</div>
</div>
<!-- 删除按钮默认不显示hover时显示 -->
<!-- <el-button v-if="hoveringOver === item.id" class="delete-btn" @click="deleteSendMessage(item.id)" type="danger" round >删除</el-button>-->
</div>
<el-divider/>
</li>
</div>
<template #footer>
<!-- 分页-->
<el-pagination
v-model:current-page="params.pageNo"
v-model:page-size="params.pageSize"
:page-sizes="[2,3, 5, 7, 10]"
:background="true"
layout="jumper,total, sizes, prev, pager, next "
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
style="margin-top: 10px; justify-content: center"
/>
</template>
</el-card>
</template>
<script setup lang="ts">
import { ref,computed,onMounted} from 'vue';
import { useRouter } from 'vue-router';
import useUserStore from "@/store/modules/user";
import {getSendMessagesListApi,deleteSendMessageApi} from "@/api/user/messag";
import { ElMessageBox, ElMessage } from 'element-plus'
const userStore = useUserStore()
//
const params = ref({
userId: userStore.userInfo.id,
// userId: 4,
isAsc:true,
isDelete:0,
isRead:'',
isSend:1,
// messageId:false,
pageNo:1,
pageSize:3,
sortBy:false,//
})
const total = ref(0)
const sendMessage = ref([])
const loading = ref(false)
// const hoveringOver = ref(null)
//
const selectedIds = ref([]); // ID
const allSelected = computed(() => {
// true
return sendMessage.value.length > 0 && sendMessage.value.every(item => selectedIds.value.includes(item.id));
});
const selectedCount = computed(() => {
//
return selectedIds.value.length;
});
function toggleAll(event) {
//
const target = event.target;
if (target.checked) {
// IDselectedIds
selectedIds.value = sendMessage.value.map(item => item.id);
} else {
// selectedIds
selectedIds.value = [];
}
}
function toggleSelection(id: number) {
//
const index = selectedIds.value.indexOf(id);
if (index > -1) {
selectedIds.value.splice(index, 1);
} else {
selectedIds.value.push(id);
}
}
function isSelected(id) {
return selectedIds.value.includes(id);
}
//
const getSendMessageList = async () => {
loading.value = true
const res = await getSendMessagesListApi(params.value)
sendMessage.value = res.data.list
total.value = res.data.total
loading.value = false
}
//
onMounted(() => {
getSendMessageList()
})
//
// const deleteSendMessage = async (id: any) => {
// await ElMessageBox.confirm('', '', {
// confirmButtonText: '',
// cancelButtonText: '',
// type: 'warning',
// })
// await deleteSendMessageApi({
// messageIds:id,
// userId:userStore.userInfo.id
// })
// .then(() => {
// console.log(id, 'id')
// getSendMessageList() //
// ElMessage.success('')
// // console.log(res)
// })
// .catch((err: any) => {
// console.log(id, 'id')
// ElMessage.error(err.response.data.message)
// })
//
// await getSendMessageList()
// }
//
const handleSizeChange = (size: any) => {
// loading.value = true
// console.log(size)
params.value.pageNo = 1
params.value.pageSize = size
//
getSendMessageList()
}
const handleCurrentChange = (page: any) => {
console.log(page)
params.value.pageNo = page
//
getSendMessageList()
}
const userId = userStore.userInfo.id
const router = useRouter()
//
const back =()=>{
router.push('/messageManagement/message')
}
//
const sendContent = ()=>{
router.push('/messageContent')
}
//
const handleClick = (item)=> {
//
router.push({ path: '/sendMessageList', query: item })
}
</script>
<style scoped>
.container{
margin: auto;
width: 95%;
padding: 15px;
}
.checkboxHeader {
width: 100%;
padding: 10px;
height: 50px;
display: flex; /* 使用Flex布局使子元素在同一行显示 */
align-items: center; /* 垂直居中对齐子元素 */
gap: 10px; /* 设置子元素之间的间距 */
}
.custom-checkbox {
transform: scale(1.5); /* 将勾选框放大1.5倍 */
}
.selected-count {
}
.message-check{
margin-right: 20px;
}
.message-list {
display: flex;
align-items: center; /* 垂直居中 */
height: 80px;
/*background-color: #f2f2f2;*/
padding: 0 10px;
box-sizing: border-box;
}
.message-icon {
margin-right: 30px; /* 图标右侧间距 */
font-size: 34px; /* 图标大小 */
}
li{
list-style: none;
}
.message-content {
display: flex;
flex-direction: column;
justify-content: center; /* 标题和详情内容垂直居中 */
flex: 1; /* 填充剩余空间 */
}
.message-title {
line-height: 30px;
font-size: 20px;
}
.message-details {
display: flex;
align-items: center; /* 细节内容水平居中 */
margin-top: 10px; /* 与标题的间距 */
}
.sender {
margin-right: 88px; /* 发件人和已读状态的间距 */
}
.read-status {
color: #888; /* 已读状态的颜色 */
}
.message-time {
margin-left: auto; /* 发送时间靠右显示 */
font-size: 15px; /* 发送时间字体大小 */
color: #666; /* 发送时间颜色 */
}
.message-list-item {
cursor: pointer; /* 鼠标悬停时显示手指形状,表示可点击 */
}
.message-list-item:hover{
background-image: linear-gradient(60deg,powderblue,darkgrey,snow);
}
</style>

@ -0,0 +1,80 @@
<template>
<div class="common-layout">
<el-container>
<el-header class="header">
<p>收到信息详情</p>
</el-header>
<el-main >
<el-card>
<template #header>
<div class="card-header">
<el-button type="primary" style="width: 80px" @click="back" round plain>返回</el-button>
</div>
</template>
<div class="container">
<div class="header_content">
<span class="sender">发送人{{ sendMessage.senderName }}</span>
<span class="time">发送时间{{ sendMessage.sendTime }}</span>
<span class="read-status">是否阅读{{sendMessage.isRead}}</span>
</div>
<div class="recipient">标题{{ sendMessage.title }}</div>
<div class="content">
内容{{ sendMessage.content }}
</div>
</div>
<!-- <template #footer>Footer content</template>-->
</el-card>
</el-main>
</el-container>
</div>
</template>
<script setup lang="ts">
import {useRouter,useRoute} from "vue-router";
const router = useRouter()
const route = useRoute()
//
if(!Object.keys(route.query).length){
router.go(-1)
}
//
const back = ()=>{
router.push('/messageManagement/sendMessage')
}
import {ref} from "vue";
//
const sendMessage = ref(route.query)
</script>
<style scoped>
.header{
background: #7f98cb;
height: 50px;
font-size: 20px;
text-align: center;
padding: 15px;
}
.container {
padding: 10px; /* 容器内边距 */
margin-top: 10px; /* 容器上边距 */
height: 65vh;
}
.header_content {
margin-bottom: 10px; /* 与下面的收件人信息保持一定间距 */
}
.header_content span {
margin-right: 50px; /* 发件人和时间之间的间距 */
}
.header_content .read-status {
margin-right: 0; /* 已读状态右侧不需要间距 */
}
.recipient, .content {
font-size: 20px;
color: #333;
margin-top: 10px;
margin-bottom: 20px;
}
</style>

@ -1,5 +1,269 @@
<template>
<div>消息</div>
<el-card>
<template #header>
<div class="card-header">
<el-button type="primary" @click="editContent" round>写栈内信函</el-button>
<el-button type="primary" @click="sendContent" round>个人发出</el-button>
</div>
</template>
<div class="container">
<div class="checkboxHeader">
<input type="checkbox" class="custom-checkbox" @change="toggleAll" :checked="allSelected" />
<p class="selected-count">已选 {{ selectedCount }} 条记录</p>
</div>
<li v-for="item in Message"
:key="item.title"
class="message-list-item"
>
<!--添加悬浮删除按钮-->
<div class="message-list" @mouseover="hoveringOver = item.id" @mouseleave="hoveringOver = null">
<!-- 添加勾选框 -->
<div class="messageCheck">
<input type="checkbox" class="custom-checkbox" :value="item.id" @change="toggleSelection(item.id)" :checked="isSelected(item.id)"/>
</div>
<!-- 图标 -->
<div class="message-icon">
<el-icon><Comment /></el-icon>
</div>
<div class="message-content" @click="handleClick(item)">
<h2 class="message-title">{{item.title}}</h2>
<div class="message-details">
<span class="sender">发件人{{item.sendPerson}}</span>
<span class="read-status">已读状态{{item.isRead}}</span>
</div>
<div class="message-time">发送时间{{item.sendTime}}</div>
</div>
<!-- 删除按钮默认不显示hover时显示 -->
<el-button v-if="hoveringOver === item.id" class="delete-btn" @click="deleteMessage(item.id)" type="danger" round>删除</el-button>
</div>
<el-divider/>
</li>
</div>
<template #footer>
<el-pagination
v-model:current-page="params.pageNo"
v-model:page-size="params.pageSize"
:page-sizes="[2,4, 5, 7, 10]"
:background="true"
layout="jumper,total, sizes, prev, pager, next "
:total="total"
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
style="margin-top: 10px; justify-content: center"
/>
</template>
</el-card>
</template>
<script setup lang="ts">
import { ref,computed,onMounted} from 'vue';
import { useRouter } from 'vue-router';
import useUserStore from "@/store/modules/user";
import {getMessagesListApi,deleteSendMessageApi} from "@/api/user/messag";
import { ElMessageBox, ElMessage } from 'element-plus'
const userStore = useUserStore()
const params = ref({
userId: userStore.userInfo.id,
// userId: 4,
isAsc:true,
isDelete:0,
isRead:'',
isSend:1,
// messageId:false,
pageNo:1,
pageSize:4,
sortBy:false,//
})
const total = ref(0)
const Message = ref([])
const loading = ref(false)
const hoveringOver = ref(null)
//
const selectedIds = ref([]); // ID
const allSelected = computed(() => {
// true
return Message.value.length > 0 && Message.value.every(item => selectedIds.value.includes(item.id));
});
<script></script>
const selectedCount = computed(() => {
//
return selectedIds.value.length;
});
function toggleAll(event) {
//
const target = event.target;
if (target.checked) {
// IDselectedIds
selectedIds.value = Message.value.map(item => item.id);
} else {
// selectedIds
selectedIds.value = [];
}
}
function toggleSelection(id: number) {
//
const index = selectedIds.value.indexOf(id);
if (index > -1) {
selectedIds.value.splice(index, 1);
} else {
selectedIds.value.push(id);
}
}
function isSelected(id) {
return selectedIds.value.includes(id);
}
//
const getMessageList = async () => {
loading.value = true
const res = await getMessagesListApi(params.value)
Message.value = res.data.list
total.value = res.data.total
loading.value = false
}
//
onMounted(() => {
getMessageList()
})
//
const deleteMessage = async (id: any) => {
await ElMessageBox.confirm('您确定删除这条课程信息吗', '温馨提示', {
confirmButtonText: '确认',
cancelButtonText: '取消',
type: 'warning',
})
await deleteSendMessageApi({
messageIds:id,
userId:userStore.userInfo.id
})
.then(() => {
console.log(id, '删除id')
getMessageList() //
ElMessage.success('删除成功')
// console.log(res)
})
.catch((err: any) => {
console.log(id, 'id')
ElMessage.error(err.response.data.message)
})
await getMessageList()
}
//
const handleSizeChange = (size: any) => {
// loading.value = true
// console.log(size)
params.value.pageNo = 1
params.value.pageSize = size
//
getMessageList()
}
const handleCurrentChange = (page: any) => {
console.log(page)
params.value.pageNo = page
//
getMessageList()
}
const router = useRouter()
//
const editContent =()=>{
router.push('/messageContent')
}
//
const sendContent = ()=>{
router.push('/messageManagement/sendMessage')
}
//
const handleClick = (item)=> {
// console.log(item)
//
router.push({ path: '/messageContentList', query: item })
}
</script>
<style scoped>
.container{
/*background: darkgray;*/
margin: auto;
width: 95%;
padding: 15px;
}
.checkboxHeader {
/*background: lightgrey;*/
width: 100%;
padding: 10px;
height: 50px;
display: flex; /* 使用Flex布局使子元素在同一行显示 */
align-items: center; /* 垂直居中对齐子元素 */
gap: 10px; /* 设置子元素之间的间距 */
}
.custom-checkbox {
transform: scale(1.5); /* 将勾选框放大1.5倍 */
}
.selected-count {
}
.messageCheck{
margin-right: 20px;
}
.message-list {
display: flex;
align-items: center; /* 垂直居中 */
height: 80px;
/*background-color: #f2f2f2;*/
padding: 0 10px;
box-sizing: border-box;
}
.message-icon {
margin-right: 30px; /* 图标右侧间距 */
font-size: 34px; /* 图标大小 */
}
li{
list-style: none;
}
.message-content {
display: flex;
flex-direction: column;
justify-content: center; /* 标题和详情内容垂直居中 */
flex: 1; /* 填充剩余空间 */
}
.message-title {
line-height: 30px;
font-size: 20px;
}
.message-details {
display: flex;
align-items: center; /* 细节内容水平居中 */
margin-top: 10px; /* 与标题的间距 */
}
.sender {
margin-right: 88px; /* 发件人和已读状态的间距 */
}
.read-status {
color: #888; /* 已读状态的颜色 */
}
.message-time {
margin-left: auto; /* 发送时间靠右显示 */
font-size: 15px; /* 发送时间字体大小 */
color: #666; /* 发送时间颜色 */
}
.message-list-item {
cursor: pointer; /* 鼠标悬停时显示手指形状,表示可点击 */
}
.message-list-item:hover{
background-image: linear-gradient(60deg,powderblue,darkgrey,snow);
}
</style>

@ -0,0 +1,59 @@
<template>
<div style="margin: 10px">
<img src="C:\project\Teaching_integration_platform_admin_template\public\newslogo.jpg">
</div>
<div>
<el-card shadow="always">
<el-dropdown placement="bottom">
<el-button> bottom </el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>The Action 1st</el-dropdown-item>
<el-dropdown-item>The Action 2st</el-dropdown-item>
<el-dropdown-item>The Action 3st</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<el-dropdown placement="bottom">
<el-button> bottom </el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>The Action 1st</el-dropdown-item>
<el-dropdown-item>The Action 2st</el-dropdown-item>
<el-dropdown-item>The Action 3st</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
<el-dropdown placement="bottom">
<el-button> bottom </el-button>
<template #dropdown>
<el-dropdown-menu>
<el-dropdown-item>The Action 1st</el-dropdown-item>
<el-dropdown-item>The Action 2st</el-dropdown-item>
<el-dropdown-item>The Action 3st</el-dropdown-item>
</el-dropdown-menu>
</template>
</el-dropdown>
</el-card>
</div>
<el-card class="container">
<template #header>
<div class="card-header">
<span>Card name</span>
<el-card shadow="hover">Hover</el-card>
</div>
</template>
<p v-for="o in 4" :key="o" class="text item">{{ 'List item ' + o }}</p>
<template #footer>Footer content</template>
</el-card>
</template>
<script setup lang="ts">
</script>
<style scoped>
.container{
height: 65vh;
}
</style>

@ -0,0 +1,40 @@
// vite.config.ts
import vue from "file:///C:/project/Teaching_integration_platform_admin_template/node_modules/.pnpm/@vitejs+plugin-vue@5.1.2_vite@5.4.0_@types+node@22.2.0_sass@1.77.8__vue@3.4.37_typescript@5.5.4_/node_modules/@vitejs/plugin-vue/dist/index.mjs";
import path from "path";
import { viteMockServe } from "file:///C:/project/Teaching_integration_platform_admin_template/node_modules/.pnpm/vite-plugin-mock@3.0.2_esbuild@0.21.5_mockjs@1.1.0_vite@5.4.0_@types+node@22.2.0_sass@1.77.8_/node_modules/vite-plugin-mock/dist/index.mjs";
import { createSvgIconsPlugin } from "file:///C:/project/Teaching_integration_platform_admin_template/node_modules/.pnpm/vite-plugin-svg-icons@2.0.1_vite@5.4.0_@types+node@22.2.0_sass@1.77.8_/node_modules/vite-plugin-svg-icons/dist/index.mjs";
var vite_config_default = ({ command }) => {
return {
plugins: [
vue(),
viteMockServe({
enable: command === "serve"
}),
createSvgIconsPlugin({
// Specify the icon folder to be cached
iconDirs: [path.resolve(process.cwd(), "src/assets/icons")],
// Specify symbolId format
symbolId: "icon-[dir]-[name]"
})
],
resolve: {
alias: {
"@": path.resolve("./src")
// 相对路径别名配置,使用 @ 代替 src
}
},
// 配置scss
css: {
preprocessorOptions: {
scss: {
javascriptEnabled: true,
additionalData: '@import "./src/styles/variable.scss";'
}
}
}
};
};
export {
vite_config_default as default
};
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJDOlxcXFxwcm9qZWN0XFxcXFRlYWNoaW5nX2ludGVncmF0aW9uX3BsYXRmb3JtX2FkbWluX3RlbXBsYXRlXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ZpbGVuYW1lID0gXCJDOlxcXFxwcm9qZWN0XFxcXFRlYWNoaW5nX2ludGVncmF0aW9uX3BsYXRmb3JtX2FkbWluX3RlbXBsYXRlXFxcXHZpdGUuY29uZmlnLnRzXCI7Y29uc3QgX192aXRlX2luamVjdGVkX29yaWdpbmFsX2ltcG9ydF9tZXRhX3VybCA9IFwiZmlsZTovLy9DOi9wcm9qZWN0L1RlYWNoaW5nX2ludGVncmF0aW9uX3BsYXRmb3JtX2FkbWluX3RlbXBsYXRlL3ZpdGUuY29uZmlnLnRzXCI7aW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAndml0ZSdcclxuaW1wb3J0IHZ1ZSBmcm9tICdAdml0ZWpzL3BsdWdpbi12dWUnXHJcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnXHJcbi8vIFx1NUJGQ1x1NTE2NW1vY2tcdTYzRDJcdTRFRjZcclxuaW1wb3J0IHsgdml0ZU1vY2tTZXJ2ZSB9IGZyb20gJ3ZpdGUtcGx1Z2luLW1vY2snXHJcbi8vIFx1NUJGQ1x1NTE2NXN2Z1x1OTE0RFx1N0Y2RVx1NjNEMlx1NEVGNlxyXG5pbXBvcnQgeyBjcmVhdGVTdmdJY29uc1BsdWdpbiB9IGZyb20gJ3ZpdGUtcGx1Z2luLXN2Zy1pY29ucydcclxuLy8gaHR0cHM6Ly92aXRlanMuZGV2L2NvbmZpZy9cclxuZXhwb3J0IGRlZmF1bHQgKHsgY29tbWFuZCB9OiBhbnkpID0+IHtcclxuICByZXR1cm4ge1xyXG4gICAgcGx1Z2luczogW1xyXG4gICAgICB2dWUoKSxcclxuICAgICAgdml0ZU1vY2tTZXJ2ZSh7XHJcbiAgICAgICAgZW5hYmxlOiBjb21tYW5kID09PSAnc2VydmUnLFxyXG4gICAgICB9KSxcclxuICAgICAgY3JlYXRlU3ZnSWNvbnNQbHVnaW4oe1xyXG4gICAgICAgIC8vIFNwZWNpZnkgdGhlIGljb24gZm9sZGVyIHRvIGJlIGNhY2hlZFxyXG4gICAgICAgIGljb25EaXJzOiBbcGF0aC5yZXNvbHZlKHByb2Nlc3MuY3dkKCksICdzcmMvYXNzZXRzL2ljb25zJyldLFxyXG4gICAgICAgIC8vIFNwZWNpZnkgc3ltYm9sSWQgZm9ybWF0XHJcbiAgICAgICAgc3ltYm9sSWQ6ICdpY29uLVtkaXJdLVtuYW1lXScsXHJcbiAgICAgIH0pLFxyXG4gICAgXSxcclxuICAgIHJlc29sdmU6IHtcclxuICAgICAgYWxpYXM6IHtcclxuICAgICAgICAnQCc6IHBhdGgucmVzb2x2ZSgnLi9zcmMnKSwgLy8gXHU3NkY4XHU1QkY5XHU4REVGXHU1Rjg0XHU1MjJCXHU1NDBEXHU5MTREXHU3RjZFXHVGRjBDXHU0RjdGXHU3NTI4IEAgXHU0RUUzXHU2NkZGIHNyY1xyXG4gICAgICB9LFxyXG4gICAgfSxcclxuICAgIC8vIFx1OTE0RFx1N0Y2RXNjc3NcclxuICAgIGNzczoge1xyXG4gICAgICBwcmVwcm9jZXNzb3JPcHRpb25zOiB7XHJcbiAgICAgICAgc2Nzczoge1xyXG4gICAgICAgICAgamF2YXNjcmlwdEVuYWJsZWQ6IHRydWUsXHJcbiAgICAgICAgICBhZGRpdGlvbmFsRGF0YTogJ0BpbXBvcnQgXCIuL3NyYy9zdHlsZXMvdmFyaWFibGUuc2Nzc1wiOycsXHJcbiAgICAgICAgfSxcclxuICAgICAgfSxcclxuICAgIH0sXHJcbiAgfVxyXG59XHJcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFDQSxPQUFPLFNBQVM7QUFDaEIsT0FBTyxVQUFVO0FBRWpCLFNBQVMscUJBQXFCO0FBRTlCLFNBQVMsNEJBQTRCO0FBRXJDLElBQU8sc0JBQVEsQ0FBQyxFQUFFLFFBQVEsTUFBVztBQUNuQyxTQUFPO0FBQUEsSUFDTCxTQUFTO0FBQUEsTUFDUCxJQUFJO0FBQUEsTUFDSixjQUFjO0FBQUEsUUFDWixRQUFRLFlBQVk7QUFBQSxNQUN0QixDQUFDO0FBQUEsTUFDRCxxQkFBcUI7QUFBQTtBQUFBLFFBRW5CLFVBQVUsQ0FBQyxLQUFLLFFBQVEsUUFBUSxJQUFJLEdBQUcsa0JBQWtCLENBQUM7QUFBQTtBQUFBLFFBRTFELFVBQVU7QUFBQSxNQUNaLENBQUM7QUFBQSxJQUNIO0FBQUEsSUFDQSxTQUFTO0FBQUEsTUFDUCxPQUFPO0FBQUEsUUFDTCxLQUFLLEtBQUssUUFBUSxPQUFPO0FBQUE7QUFBQSxNQUMzQjtBQUFBLElBQ0Y7QUFBQTtBQUFBLElBRUEsS0FBSztBQUFBLE1BQ0gscUJBQXFCO0FBQUEsUUFDbkIsTUFBTTtBQUFBLFVBQ0osbUJBQW1CO0FBQUEsVUFDbkIsZ0JBQWdCO0FBQUEsUUFDbEI7QUFBQSxNQUNGO0FBQUEsSUFDRjtBQUFBLEVBQ0Y7QUFDRjsiLAogICJuYW1lcyI6IFtdCn0K
Loading…
Cancel
Save