【类 型】:feat

【原  因】:需要管理员能够发布公告信息,方便向管理员及时传达重要通知。
【过  程】:增加公告管理模块,支持指定管理员用户发布公告。管理员登录时自动弹出公告列表框。
【影  响】:新增公告功能模块,涉及管理员界面和通知弹窗逻辑,不影响其他业务功能。
This commit is contained in:
air 2025-06-12 19:31:17 +08:00
parent 651f02be2c
commit 04e64c5a21
7 changed files with 128 additions and 46 deletions

View File

@ -310,6 +310,17 @@ const routes = [
tapName: 'admin',
hidden: true
}
},
{
path: '/admin/message',
component: () => import('@/views/layout/components/main/admin/message'),
meta: {
title: '发布公告',
icon: 'el-icon-microphone',
roles: ['admin', 'editor'],
tapName: 'admin',
hidden: true
}
}
]
},

View File

@ -5,7 +5,7 @@ import app from './modules/app'
import settings from './modules/settings'
import user from './modules/user'
import api from '@/utils/api'
import { Message, MessageBox } from 'element-ui'
import { Message, MessageBox, Notification } from 'element-ui'
// 把vuex作为插件引入到Vue示例中 ps:注册
Vue.use(Vuex)
@ -23,6 +23,7 @@ const store = new Vuex.Store({
skuList: [], // 商品sku列表
paidOrderList: [], // 已付款 和已退款但是发货状态为 已发货 订单列表
logList: [], // 操作日志列表
messageList: [], // 管理员公告列表
crosFrequency: null// 对频macadd
},
mutations: {
@ -102,6 +103,13 @@ const store = new Vuex.Store({
insertNewLog (state, logData) {
state.logList.push(logData)
},
/**
* @description: 向管理员公告列表最后插入新的信息
* @param {*} list
*/
setMessageList (state, list) {
state.messageList = list
},
/**
* @description: 登记对频信息
*/
@ -980,6 +988,34 @@ const store = new Vuex.Store({
}
return res
},
/**
* @description: 异步获取管理员消息列表 成功获取之后 弹出通知框 显示列表
*/
async fetchMessageList ({ commit }) {
const res = await api.get('getMessageList', 'Admin')
if (res.data.status === 1) {
const list = res.data.messageList || []
commit('setMessageList', list)
// 每条通知之间延迟 800ms显示时间为 8000ms
list.forEach((item, index) => {
setTimeout(() => {
Notification({
title: item.tit || '通知',
message: item.message || '',
duration: 8000, // 显示时间 8 秒
type: 'info' // 可选类型: success / warning / error / info
})
}, index * 800)
})
} else {
Message.error(res.data.msg || '获取消息失败')
commit('setMessageList', [])
}
return res
},
/**
* @description: 向操作日志插入信息 并在积攒多条之后 向服务器提交
* @param {logData} content 日志内容 logData.color 时间

View File

@ -5,7 +5,10 @@ const state = {
isWideScreen: window.innerWidth < 480, // 屏幕宽度是否小于480
defaultLonLat: null, // 地图默认经纬度
defaultZoom: null, // 地图默认缩放
orderSerch: null// 订单列表页搜索条件
orderSerch: null, // 订单列表页搜索条件
/* 页面临时传参 */
toMessageIdArr: [] // 用户管理 发布公告页面 id临时传参
}
const mutations = {
@ -50,6 +53,11 @@ const mutations = {
// 存储到 localStorage
localStorage.setItem('orderSerch', JSON.stringify(state.orderSerch))
},
/* 临时传参 */
setToMessageIdArr (state, idArr) {
state.toMessageIdArr = idArr
}
}

View File

@ -143,3 +143,21 @@ export async function addLog (log) {
const res = await api.post('addLog', params)
return res
}
/**
* @description: 向管理员用户发布公告
* @param {*} tit 公告标题
* @param {*} message 公告内容
* @param {*} idArr 接收公告的管理员ID数组
* @param {*} endTime 公告截至时间时间戳
*/
export async function pubMessage (tit, message, idArr, endTime) {
const params = new URLSearchParams()
params.append('tit', tit)
params.append('message', message)
params.append('idArr', idArr.join(',')) // 后端只收字符串
params.append('endTime', endTime)
const res = await api.post('pubMessage', params, 'Admin') // 模块名根据你实际配置来
return res
}

View File

@ -6,6 +6,7 @@
<el-button type="danger" icon="el-icon-delete" @click="deleteAdmin(countSelIdArr($refs.myTable.selection))">删除
</el-button>
<el-button type="warning" icon="el-icon-edit" @click="toEditPage()">编辑</el-button>
<el-button type="success" icon="el-icon-microphone" @click="toMessagePage(countSelIdArr($refs.myTable.selection))">发布公告</el-button>
</el-button-group>
<!-- 用户select选项 -->
<el-button-group class="m-l-20">
@ -32,12 +33,13 @@
{{ scope.row.addtime | parseTime('{y}-{m}-{d}') }}
</template>
</el-table-column>
<el-table-column prop="controler" label="操作" width="200" min-width="200">
<el-table-column prop="controler" label="操作" width="350" min-width="350">
<template slot-scope="scope">
<el-button-group>
<el-button type="warning" icon="el-icon-edit"
@click="$router.replace(`/admin/edit/${scope.row.id}`)">编辑</el-button>
<el-button type="danger" icon="el-icon-delete" @click="deleteAdmin([scope.row.id])">删除</el-button>
<el-button type="success" icon="el-icon-microphone" @click="toMessagePage([scope.row.id])">发布公告</el-button>
</el-button-group>
</template>
</el-table-column>
@ -101,6 +103,17 @@ export default {
this.$message.error('只能选择一条记录')
}
},
/**
* @description: 跳转到发布公告页面
*/
toMessagePage (selIdArr) {
if (selIdArr.length === 0) {
this.$message.error('请选择至少一个用户')
} else {
this.$store.commit('app/setToMessageIdArr', selIdArr)//
this.$router.push('/admin/message/')
}
},
/**
* @description: 删除用户
*/

View File

@ -11,30 +11,19 @@
</el-header>
<el-main class="border p-20">
<el-form label-width="120px">
<el-form-item label="信息公告">
<el-input
v-model="form.message"
type="textarea"
placeholder="请输入公告内容"
:rows="5"
/>
<el-form-item label="公告标题">
<el-input v-model="form.tit" placeholder="请输入公告标题" maxlength="50" show-word-limit />
</el-form-item>
<el-form-item label="公告信息">
<el-input v-model="form.message" type="textarea" placeholder="请输入公告内容" :rows="5" maxlength="80"
show-word-limit />
</el-form-item>
<el-form-item label="显示截止日期">
<el-date-picker
v-model="form.date"
type="date"
placeholder="选择日期"
format="yyyy 年 MM 月 dd 日"
value-format="timestamp"
/>
<el-date-picker v-model="form.date" type="date" placeholder="选择日期" format="yyyy 年 MM 月 dd 日"
value-format="timestamp" />
</el-form-item>
<el-form-item>
<el-button
type="primary"
icon="el-icon-edit"
:loading="loading"
@click="pubMessage"
>
<el-button type="primary" icon="el-icon-edit" :loading="loading" @click="pubMessage()">
发布公告
</el-button>
</el-form-item>
@ -55,7 +44,8 @@ export default {
return {
form: {
date: '',
message: ''
message: '',
tit: ''
},
loading: false
}
@ -66,37 +56,42 @@ export default {
return this.$store.state.app.toMessageIdArr
}
},
created () {
},
methods: {
async pubMessage () {
//
if (!this.form.message.trim()) {
// idArr
if (!this.idArr || this.idArr.length === 0) {
this.$message.warning('接收用户为空,请重新操作')
this.$router.push('/admin/index')
return
}
if (!this.form.tit) {
this.$message.error('请输入公告标题')
return
}
if (!this.form.message) {
this.$message.error('请输入公告内容')
return
}
if (!this.form.date) {
this.$message.error('请选择显示截止日期')
return
}
if (!this.ids.length) {
this.$message.error('接收用户为空,请重新操作')
this.$message.error('请选择截止日期')
return
}
this.loading = true
try {
const res = await pubMessage(this.form.message, this.ids, this.form.date)
if (res.status === 1) {
this.$message.success(res.msg || '公告发布成功')
this.form.message = ''
this.form.date = ''
} else {
this.$message.error(res.msg || '公告发布失败')
}
} catch (error) {
this.$message.error('接口请求失败')
console.error(error)
} finally {
this.loading = false
const endTime = Math.floor(new Date(this.form.date).getTime() / 1000 + 86400)
const res = await pubMessage(this.form.tit, this.form.message, this.idArr, endTime)
if (res.data.status === 1) {
this.$message.success(res.data.msg)
this.form.message = ''
this.form.date = ''
this.form.tit = ''
//
this.$router.push('/admin/index')
} else {
this.$message.error(res.data.msg || '公告发布失败')
}
}
}

View File

@ -69,6 +69,7 @@ export default {
this.$store.dispatch('fetchSpuList')// spu
this.$store.dispatch('fetchSkuList')// sku
this.$store.dispatch('fetchPaidOrderList')//
this.$store.dispatch('fetchMessageList')//
},
watch: {
/**