completepage: 🍻 消息功能完成
This commit is contained in:
parent
a6eaa41226
commit
56534cdf67
|
@ -3,7 +3,7 @@
|
||||||
*/
|
*/
|
||||||
(async function requestPath() {
|
(async function requestPath() {
|
||||||
// 获取基础paths对象
|
// 获取基础paths对象
|
||||||
const response = await fetch('http://localhost:7070/v3/api-docs/admin%E7%AE%A1%E7%90%86%E5%91%98%E6%8E%A5%E5%8F%A3%E8%AF%B7%E6%B1%82', { method: 'GET' });
|
const response = await fetch('http://localhost:7070/v3/api-docs/%E9%BB%98%E8%AE%A4%E8%AF%B7%E6%B1%82%E6%8E%A5%E5%8F%A3', { method: 'GET' });
|
||||||
const json = await response.json();
|
const json = await response.json();
|
||||||
const paths = json.paths;
|
const paths = json.paths;
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
// 获取所有键
|
// 获取所有键
|
||||||
Object.keys(paths)
|
Object.keys(paths)
|
||||||
.filter(item => !item.includes('noAuth'))
|
.filter(item => !item.includes('noAuth') && !item.includes('noManage'))
|
||||||
.forEach(key => {
|
.forEach(key => {
|
||||||
const pathKey = paths[key];
|
const pathKey = paths[key];
|
||||||
const { tags, description } = pathKey[Object.keys(pathKey)[0]];
|
const { tags, description } = pathKey[Object.keys(pathKey)[0]];
|
||||||
|
@ -76,7 +76,7 @@ async function add(data) {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
token:
|
token:
|
||||||
'eyJhbGciOiJIUzI1NiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAA_yWLywrCMBAA_2XPjeSxZEtP4s2L_7DpbqBCorUGLMV_N-BtGGYO2FqCCS6t1h0G0M8TJkfBhtFbHwdom76u0t0fb1y05yxlqed1Pc2P0q_7e-lS3JwUkQxhDgZzFMPZkUmWhTX6EYnh-wMBQi1DcgAAAA.II3lcc1R1pX8G6eaEVkCxxDXkscN4c6p89zn7FzFhaU',
|
'eyJhbGciOiJIUzI1NiIsInppcCI6IkdaSVAifQ.H4sIAAAAAAAA_yWLywqFIBQA_-WsE9Sjt2xXuz7jmAYGWfiAIu6_X-HuhmHmhVwtjDDXGB_owN8XjKJH3iMayTuo2afFNffHSIdv-eSOEEMuicqZ2raX0Kx22g4ciRkUyBRpw6yxgq1S0SBXubnPBt8fEjhnWnMAAAA.YwSm-NO_6Kg1k1GRwucIt50Y70FbPHoldsdTPVHK_Y4',
|
||||||
},
|
},
|
||||||
body: JSON.stringify(data),
|
body: JSON.stringify(data),
|
||||||
});
|
});
|
||||||
|
|
|
@ -23,6 +23,11 @@ export const fetchAssignRolesToRouter = (data: any) => {
|
||||||
return http.request<BaseResult<any>>('post', `routerRole/assignRolesToRouter`, { data });
|
return http.request<BaseResult<any>>('post', `routerRole/assignRolesToRouter`, { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** 菜单管理-批量为菜单添加角色 */
|
||||||
|
export const fetchAssignAddBatchRolesToRouter = (data: any) => {
|
||||||
|
return http.request<BaseResult<any>>('post', `routerRole/assignAddBatchRolesToRouter`, { data });
|
||||||
|
};
|
||||||
|
|
||||||
/** 菜单管理-清除选中菜单所有角色 */
|
/** 菜单管理-清除选中菜单所有角色 */
|
||||||
export const fetchClearAllRolesSelect = (data: any) => {
|
export const fetchClearAllRolesSelect = (data: any) => {
|
||||||
return http.request<BaseResult<any>>('delete', `routerRole/clearAllRolesSelect`, { data });
|
return http.request<BaseResult<any>>('delete', `routerRole/clearAllRolesSelect`, { data });
|
||||||
|
|
|
@ -1,26 +1,16 @@
|
||||||
import { http } from '@/api/service/request';
|
import { http } from '@/api/service/request';
|
||||||
import type { BaseResult, ResultTable } from '@/api/service/types';
|
import type { BaseResult, ResultTable } from '@/api/service/types';
|
||||||
|
|
||||||
/** 系统消息---获取系统消息列表 */
|
/** 系统消息---获取系统管理消息列表 */
|
||||||
export const fetchGetMessageList = (data: any) => {
|
export const fetchGetMessageList = (data: any) => {
|
||||||
return http.request<BaseResult<ResultTable>>('get', `message/getMessageList/${data.currentPage}/${data.pageSize}`, { params: data });
|
return http.request<BaseResult<ResultTable>>('get', `message/getMessageList/${data.currentPage}/${data.pageSize}`, { params: data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 系统消息---获取系统消息列表 */
|
|
||||||
export const fetchGetUserMessageList = (data: any) => {
|
|
||||||
return http.request<BaseResult<ResultTable>>('get', `message/noManage/getUserMessageList/${data.currentPage}/${data.pageSize}`, { params: data });
|
|
||||||
};
|
|
||||||
|
|
||||||
/** 系统消息---根据消息id获取接收人信息 */
|
/** 系统消息---根据消息id获取接收人信息 */
|
||||||
export const fetchGetReceivedUserinfoByMessageId = (data: any) => {
|
export const fetchGetReceivedUserinfoByMessageId = (data: any) => {
|
||||||
return http.request<BaseResult<any>>('get', `messageReceived/noManage/getReceivedUserinfoByMessageId`, { params: data });
|
return http.request<BaseResult<any>>('get', `messageReceived/noManage/getReceivedUserinfoByMessageId`, { params: data });
|
||||||
};
|
};
|
||||||
|
|
||||||
/** 系统消息---根据消息id查询消息详情 */
|
|
||||||
export const fetchGetMessageDetailById = (data: any) => {
|
|
||||||
return http.request<BaseResult<any>>('get', `message/noManage/getMessageDetailById`, { params: data });
|
|
||||||
};
|
|
||||||
|
|
||||||
/** 系统消息---添加系统消息 */
|
/** 系统消息---添加系统消息 */
|
||||||
export const fetchAddMessage = (data: any) => {
|
export const fetchAddMessage = (data: any) => {
|
||||||
return http.request<BaseResult<object>>('post', 'message/addMessage', { data });
|
return http.request<BaseResult<object>>('post', 'message/addMessage', { data });
|
||||||
|
@ -35,3 +25,23 @@ export const fetchUpdateMessage = (data: any) => {
|
||||||
export const fetchDeleteMessage = (data: any) => {
|
export const fetchDeleteMessage = (data: any) => {
|
||||||
return http.request<BaseResult<object>>('delete', 'message/deleteMessage', { data });
|
return http.request<BaseResult<object>>('delete', 'message/deleteMessage', { data });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** 用户系统消息---根据消息id查询消息详情 */
|
||||||
|
export const fetchGetMessageDetailById = (data: any) => {
|
||||||
|
return http.request<BaseResult<any>>('get', `message/noManage/getMessageDetailById`, { params: data });
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 用户系统消息---用户获取系统消息列表 */
|
||||||
|
export const fetchGetUserMessageList = (data: any) => {
|
||||||
|
return http.request<BaseResult<ResultTable>>('get', `message/noManage/getUserMessageList/${data.currentPage}/${data.pageSize}`, { params: data });
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 系统消息---用户将消息标为已读 */
|
||||||
|
export const fetchUpdateUserMarkAsRead = (data: any) => {
|
||||||
|
return http.request<BaseResult<object>>('put', 'message/noManage/updateUserMarkAsRead', { data });
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 系统消息---用户删除系统消息 */
|
||||||
|
export const fetchDeleteUserMessageByIds = (data: any) => {
|
||||||
|
return http.request<BaseResult<object>>('delete', 'message/noManage/deleteUserMessageByIds', { data });
|
||||||
|
};
|
||||||
|
|
|
@ -35,8 +35,9 @@ export const enabledOrNotStatus = [
|
||||||
|
|
||||||
/** 是否已读 */
|
/** 是否已读 */
|
||||||
export const isReadStatus = [
|
export const isReadStatus = [
|
||||||
{ value: true, label: $t('readAlready') },
|
{ value: '', label: $t('all') },
|
||||||
{ value: false, label: $t('unread') },
|
{ value: 'true', label: $t('readAlready') },
|
||||||
|
{ value: 'false', label: $t('unread') },
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { $t } from '@/plugins/i18n';
|
||||||
import { computed, ref } from 'vue';
|
import { computed, ref } from 'vue';
|
||||||
import { fetchGetUserMessageList } from '@/api/v1/message';
|
import { fetchGetUserMessageList } from '@/api/v1/message';
|
||||||
import { throttle } from '@pureadmin/utils';
|
import { throttle } from '@pureadmin/utils';
|
||||||
|
import { useWebNotification } from '@vueuse/core';
|
||||||
|
|
||||||
export interface ListItem {
|
export interface ListItem {
|
||||||
messageId: string;
|
messageId: string;
|
||||||
|
@ -27,6 +28,13 @@ const form = { status: false, currentPage: 1, pageSize: 100 };
|
||||||
// 响应内容
|
// 响应内容
|
||||||
export const noticesData = ref<TabItem[]>([]);
|
export const noticesData = ref<TabItem[]>([]);
|
||||||
|
|
||||||
|
// 通知消息数据
|
||||||
|
export const noticesNum = ref(0);
|
||||||
|
export const notices = ref(noticesData);
|
||||||
|
// 选择的消息栏目
|
||||||
|
export const activeKey = ref(noticesData.value[0]?.key);
|
||||||
|
export const getLabel = computed(() => item => item.name + (item.list.length > 0 ? `(${item.list.length})` : ''));
|
||||||
|
|
||||||
/** 获取所有消息 */
|
/** 获取所有消息 */
|
||||||
export const getAllMessageList = async () => {
|
export const getAllMessageList = async () => {
|
||||||
const baseResult = await fetchGetUserMessageList(form);
|
const baseResult = await fetchGetUserMessageList(form);
|
||||||
|
@ -82,14 +90,21 @@ export const getAllMessageList = async () => {
|
||||||
{ key: '2', name: $t('status.pureMessage'), list: notify, emptyText: $t('status.pureNoMessage') },
|
{ key: '2', name: $t('status.pureMessage'), list: notify, emptyText: $t('status.pureNoMessage') },
|
||||||
{ key: '3', name: $t('status.systemMessage'), list: system, emptyText: $t('status.systemMessage') },
|
{ key: '3', name: $t('status.systemMessage'), list: system, emptyText: $t('status.systemMessage') },
|
||||||
];
|
];
|
||||||
};
|
|
||||||
|
|
||||||
// 通知消息数据
|
// 调用浏览器系统通知
|
||||||
export const noticesNum = ref(0);
|
const { isSupported, show, close } = useWebNotification({
|
||||||
export const notices = ref(noticesData);
|
title: system[0]?.title,
|
||||||
// 选择的消息栏目
|
dir: 'auto',
|
||||||
export const activeKey = ref(noticesData.value[0]?.key);
|
lang: 'zh',
|
||||||
export const getLabel = computed(() => item => item.name + (item.list.length > 0 ? `(${item.list.length})` : ''));
|
renotify: true,
|
||||||
|
tag: system[0]?.extra,
|
||||||
|
});
|
||||||
|
if (system.length <= 0 || !isSupported.value) {
|
||||||
|
close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
await show();
|
||||||
|
};
|
||||||
|
|
||||||
/** 计算消息数量 */
|
/** 计算消息数量 */
|
||||||
export const computedNoticesNum = throttle(async () => {
|
export const computedNoticesNum = throttle(async () => {
|
||||||
|
|
|
@ -4,17 +4,24 @@ import { onMounted } from 'vue';
|
||||||
import { activeKey, computedNoticesNum, getLabel, notices, noticesNum } from './data';
|
import { activeKey, computedNoticesNum, getLabel, notices, noticesNum } from './data';
|
||||||
import NoticeList from './components/NoticeList.vue';
|
import NoticeList from './components/NoticeList.vue';
|
||||||
import BellIcon from '@iconify-icons/ep/bell';
|
import BellIcon from '@iconify-icons/ep/bell';
|
||||||
|
import { useMessageTypeStore } from '@/store/message/messageType';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const messageTypeStore = useMessageTypeStore();
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
|
messageTypeStore.getAllMessageTypeList();
|
||||||
computedNoticesNum();
|
computedNoticesNum();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<el-dropdown placement="bottom-end" trigger="click">
|
<el-dropdown placement="bottom-end" trigger="click">
|
||||||
<span :class="['dropdown-badge', 'navbar-bg-hover', 'select-none', Number(noticesNum) !== 0 && 'mr-[10px]']" @click="computedNoticesNum">
|
<span
|
||||||
|
:class="['dropdown-badge', 'navbar-bg-hover', 'select-none', Number(noticesNum) !== 0 && 'mr-[10px]']"
|
||||||
|
@click="computedNoticesNum"
|
||||||
|
@dblclick="$router.push(`/message-detail/${messageTypeStore?.allMessageTypeList[0]?.messageType}`)"
|
||||||
|
>
|
||||||
<el-badge :max="99" :value="Number(noticesNum) === 0 ? '' : noticesNum">
|
<el-badge :max="99" :value="Number(noticesNum) === 0 ? '' : noticesNum">
|
||||||
<span class="header-notice-icon">
|
<span class="header-notice-icon">
|
||||||
<IconifyIconOffline :icon="BellIcon" />
|
<IconifyIconOffline :icon="BellIcon" />
|
||||||
|
|
|
@ -0,0 +1,65 @@
|
||||||
|
import { defineStore } from 'pinia';
|
||||||
|
import { fetchDeleteUserMessageByIds, fetchGetUserMessageList, fetchUpdateUserMarkAsRead } from '@/api/v1/message';
|
||||||
|
import { pageSizes } from '@/enums/baseConstant';
|
||||||
|
import { storePagination } from '@/store/useStorePagination';
|
||||||
|
import { storeMessage } from '@/utils/message';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统消息 Store
|
||||||
|
*/
|
||||||
|
export const useMessageUserStore = defineStore('messageUserStore', {
|
||||||
|
state() {
|
||||||
|
return {
|
||||||
|
// 系统消息列表
|
||||||
|
datalist: [],
|
||||||
|
// 查询表单
|
||||||
|
form: {
|
||||||
|
// 消息标题
|
||||||
|
title: undefined,
|
||||||
|
// 0:未读 1:已读
|
||||||
|
status: '',
|
||||||
|
// 消息类型
|
||||||
|
messageType: undefined,
|
||||||
|
},
|
||||||
|
// 分页查询结果
|
||||||
|
pagination: {
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 150,
|
||||||
|
total: 100,
|
||||||
|
pageSizes,
|
||||||
|
},
|
||||||
|
// 加载
|
||||||
|
loading: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
getters: {},
|
||||||
|
actions: {
|
||||||
|
/** 获取系统消息 */
|
||||||
|
async getMessageList() {
|
||||||
|
// 整理请求参数
|
||||||
|
const data = { ...this.pagination, ...this.form };
|
||||||
|
delete data.pageSizes;
|
||||||
|
delete data.total;
|
||||||
|
delete data.background;
|
||||||
|
|
||||||
|
// 获取系统消息列表
|
||||||
|
const result = await fetchGetUserMessageList(data);
|
||||||
|
|
||||||
|
// 公共页面函数hook
|
||||||
|
const pagination = storePagination.bind(this);
|
||||||
|
return pagination(result);
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 用户将消息标为已读 */
|
||||||
|
async updateUserMarkAsRead(data: any) {
|
||||||
|
const result = await fetchUpdateUserMarkAsRead(data);
|
||||||
|
return storeMessage(result);
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 用户删除系统消息 */
|
||||||
|
async deleteUserMessageByIds(data: any) {
|
||||||
|
const result = await fetchDeleteUserMessageByIds(data);
|
||||||
|
return storeMessage(result);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
|
@ -3,6 +3,7 @@ import { storeMessage } from '@/utils/message';
|
||||||
import { handleTree } from '@/utils/tree';
|
import { handleTree } from '@/utils/tree';
|
||||||
import {
|
import {
|
||||||
fetchAddMenu,
|
fetchAddMenu,
|
||||||
|
fetchAssignAddBatchRolesToRouter,
|
||||||
fetchAssignRolesToRouter,
|
fetchAssignRolesToRouter,
|
||||||
fetchClearAllRolesSelect,
|
fetchClearAllRolesSelect,
|
||||||
fetchDeletedMenuByIds,
|
fetchDeletedMenuByIds,
|
||||||
|
@ -76,6 +77,12 @@ export const userMenuStore = defineStore('menuStore', {
|
||||||
return storeMessage(result);
|
return storeMessage(result);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** 批量为菜单添加角色 */
|
||||||
|
async assignAddBatchRolesToRouter(data: any) {
|
||||||
|
const result = await fetchAssignAddBatchRolesToRouter(data);
|
||||||
|
return storeMessage(result);
|
||||||
|
},
|
||||||
|
|
||||||
/** 清除选中菜单所有角色 */
|
/** 清除选中菜单所有角色 */
|
||||||
async clearAllRolesSelect(data: any) {
|
async clearAllRolesSelect(data: any) {
|
||||||
const result = await fetchClearAllRolesSelect(data);
|
const result = await fetchClearAllRolesSelect(data);
|
||||||
|
|
|
@ -1,37 +1,117 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { useRoute } from 'vue-router';
|
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
import { PlusCheckCardGroup } from 'plus-pro-components';
|
import { columns } from '@/views/message-management/message-detail/utils/columns';
|
||||||
import 'plus-pro-components/es/components/check-card-group/style/css';
|
import PureTableBar from '@/components/TableBar/src/bar';
|
||||||
|
import PureTable from '@pureadmin/table';
|
||||||
|
import { markAsAllRead, markAsRead, onDelete, onSearch, selectids } from '@/views/message-management/message-detail/utils/hooks';
|
||||||
|
import Delete from '@iconify-icons/ep/delete';
|
||||||
|
import { $t } from '@/plugins/i18n';
|
||||||
|
import { Message, MessageBox } from '@element-plus/icons-vue';
|
||||||
|
import { useRenderIcon } from '@/components/CommonIcon/src/hooks';
|
||||||
|
import { isReadStatus } from '@/enums/baseConstant';
|
||||||
|
import { useMessageUserStore } from '@/store/message/messageUser';
|
||||||
|
import { useMessageTypeStore } from '@/store/message/messageType';
|
||||||
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
|
||||||
|
const tableRef = ref();
|
||||||
|
const formRef = ref();
|
||||||
|
const messageTypeStore = useMessageTypeStore();
|
||||||
|
const messageUserStore = useMessageUserStore();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
/** 获取消息详情 */
|
/** 当前页改变时 */
|
||||||
const getMessageDetail = () => {
|
const onCurrentPageChange = (value: number) => {
|
||||||
const messageId = route.params.messageId;
|
messageUserStore.pagination.currentPage = value;
|
||||||
|
onSearch(route.params.messageType);
|
||||||
};
|
};
|
||||||
const options = [
|
|
||||||
{
|
/**
|
||||||
title: '标题一',
|
* * 当分页发生变化
|
||||||
value: '0',
|
* @param value
|
||||||
description: '坚持梦想,成就不凡的自己',
|
*/
|
||||||
avatar: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg',
|
const onPageSizeChange = (value: number) => {
|
||||||
},
|
messageUserStore.pagination.pageSize = value;
|
||||||
{
|
onSearch(route.params.messageType);
|
||||||
title: '标题二',
|
};
|
||||||
value: '1',
|
|
||||||
description: '每一次努力,都是成长的契机',
|
/**
|
||||||
avatar: 'https://fuss10.elemecdn.com/1/34/19aa98b1fcb2781c4fba33d850549jpeg.jpeg',
|
* * 选择多行
|
||||||
},
|
* @param rows
|
||||||
];
|
*/
|
||||||
const size = ref('default');
|
const onSelectionChange = (rows: Array<any>) => {
|
||||||
const dynamicSize = ref();
|
selectids.value = rows.map((row: any) => row.id);
|
||||||
const list = ref('0');
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
getMessageDetail();
|
onSearch(route.params.messageType);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<PlusCheckCardGroup v-model="list" :disabled="size === 'disabled'" :options="options" :size="dynamicSize" />
|
<div class="main">
|
||||||
|
<PureTableBar :columns="columns" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch(route.params.messageType)">
|
||||||
|
<template #title>
|
||||||
|
<el-segmented v-model="messageUserStore.form.status" :options="isReadStatus" @change="onSearch(route.params.messageType)" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #buttons>
|
||||||
|
<!-- 删除按钮 -->
|
||||||
|
<el-button :disabled="!(selectids.length > 0)" :icon="useRenderIcon(Delete)" type="danger" @click="onDelete">
|
||||||
|
{{ $t('delete') }}
|
||||||
|
</el-button>
|
||||||
|
|
||||||
|
<!-- 标为已读 -->
|
||||||
|
<el-button :disabled="!(selectids.length > 0)" :icon="useRenderIcon('octicon:read-24')" type="primary" @click="markAsRead">
|
||||||
|
{{ $t('markAsRead') }}
|
||||||
|
</el-button>
|
||||||
|
|
||||||
|
<!-- 全部标为已读 -->
|
||||||
|
<el-button :icon="useRenderIcon('octicon:read-24')" type="primary" @click="markAsAllRead">
|
||||||
|
{{ $t('allMarkAsRead') }}
|
||||||
|
</el-button>
|
||||||
|
|
||||||
|
<!-- 标题搜索 -->
|
||||||
|
<el-input v-model="messageUserStore.form.title" :placeholder="`${$t('input')}${$t('title')}`" class="!w-[180px] ml-3" clearable @input="onSearch(route.params.messageType)" />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-slot="{ size, dynamicColumns }">
|
||||||
|
<pure-table
|
||||||
|
ref="tableRef"
|
||||||
|
:adaptiveConfig="{ offsetBottom: 96 }"
|
||||||
|
:columns="dynamicColumns"
|
||||||
|
:data="messageUserStore.datalist"
|
||||||
|
:header-cell-style="{ background: 'var(--el-fill-color-light)', color: 'var(--el-text-color-primary)' }"
|
||||||
|
:loading="messageUserStore.loading"
|
||||||
|
:pagination="messageUserStore.pagination"
|
||||||
|
:size="size"
|
||||||
|
adaptive
|
||||||
|
highlight-current-row
|
||||||
|
row-key="id"
|
||||||
|
showOverflowTooltip
|
||||||
|
table-layout="auto"
|
||||||
|
@page-size-change="onPageSizeChange"
|
||||||
|
@selection-change="onSelectionChange"
|
||||||
|
@page-current-change="onCurrentPageChange"
|
||||||
|
>
|
||||||
|
<template #title="{ row }">
|
||||||
|
<el-link v-if="row.status" :icon="MessageBox" :underline="false" type="info" @click="router.push(`/message-detail/${messageTypeStore?.form?.messageType}/${row.id}`)">
|
||||||
|
{{ row.title }}
|
||||||
|
</el-link>
|
||||||
|
<el-link v-else :icon="Message" :underline="false" type="primary" @click="router.push(`/message-detail/${messageTypeStore?.form?.messageType}/${row.id}`)">
|
||||||
|
{{ row.title }}
|
||||||
|
</el-link>
|
||||||
|
</template>
|
||||||
|
</pure-table>
|
||||||
|
</template>
|
||||||
|
</PureTableBar>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.el-link {
|
||||||
|
:deep(.el-icon) {
|
||||||
|
margin: 0 5px 0 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
|
@ -6,26 +6,27 @@ import { useDataThemeChange } from '@/layout/hooks/useDataThemeChange';
|
||||||
import leftLine from '@iconify-icons/ri/arrow-left-s-line';
|
import leftLine from '@iconify-icons/ri/arrow-left-s-line';
|
||||||
import { $t } from '@/plugins/i18n';
|
import { $t } from '@/plugins/i18n';
|
||||||
import { useMessageTypeStore } from '@/store/message/messageType';
|
import { useMessageTypeStore } from '@/store/message/messageType';
|
||||||
|
import { onSearch } from '@/views/message-management/message-detail/utils/hooks';
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
const isOpen = ref(!deviceDetection());
|
const isOpen = ref(!deviceDetection());
|
||||||
const { $storage } = useGlobal<GlobalPropertiesApi>();
|
const { $storage } = useGlobal<GlobalPropertiesApi>();
|
||||||
const witchPane = ref('profile');
|
const router = useRouter();
|
||||||
const messageTypeStore = useMessageTypeStore();
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const routerMessageType = ref('');
|
const messageTypeStore = useMessageTypeStore();
|
||||||
|
|
||||||
/** 点击菜单时 */
|
/** 点击菜单时 */
|
||||||
const onMenuClick = (item: any) => {
|
const onMenuClick = (item: any) => {
|
||||||
const messageType = item.messageType;
|
messageTypeStore.form.messageType = item.messageType;
|
||||||
const messageId = item.messageId;
|
|
||||||
routerMessageType.value = messageType;
|
|
||||||
router.push({ path: `/message-detail/${item.messageType}` });
|
router.push({ path: `/message-detail/${item.messageType}` });
|
||||||
|
onSearch(item.messageType);
|
||||||
};
|
};
|
||||||
|
|
||||||
onBeforeMount(() => {
|
onBeforeMount(() => {
|
||||||
|
// 获取所有消息类型
|
||||||
messageTypeStore.getAllMessageTypeList();
|
messageTypeStore.getAllMessageTypeList();
|
||||||
routerMessageType.value = route.params.messageType as string;
|
|
||||||
|
// 设置路由消息类型
|
||||||
|
messageTypeStore.form.messageType = route.params.messageType as string;
|
||||||
useDataThemeChange().dataThemeChange($storage.layout?.overallStyle);
|
useDataThemeChange().dataThemeChange($storage.layout?.overallStyle);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -34,25 +35,31 @@ onBeforeMount(() => {
|
||||||
<el-container class="h-full">
|
<el-container class="h-full">
|
||||||
<el-aside
|
<el-aside
|
||||||
v-if="isOpen"
|
v-if="isOpen"
|
||||||
:width="deviceDetection() ? '180px' : '240px'"
|
:width="deviceDetection() ? '180 px' : '240px'"
|
||||||
class="pure-account-settings overflow-hidden px-2 dark:!bg-[var(--el-bg-color)] border-r-[1px] border-[var(--pure-border-color)]"
|
class="pure-account-settings overflow-hidden px-2 dark:!bg-[var(--el-bg-color)] border-r-[1px] border-[var(--pure-border-color)]"
|
||||||
>
|
>
|
||||||
<el-menu :default-active="witchPane" class="pure-account-settings-menu">
|
<el-menu :default-active="messageTypeStore.form.messageType" class="pure-account-settings-menu">
|
||||||
<!--<el-menu-item class="hover:!transition-all hover:!duration-200 hover:!text-base !h-[50px]" @click="router.go(-1)">-->
|
<el-menu-item class="!h-[50px]" @click="$router.go(-1)">
|
||||||
<el-menu-item class="hover:!transition-all hover:!duration-200 hover:!text-base !h-[50px]" @click="router.push('/')">
|
<div class="flex items-center hover:!transition-all hover:!duration-200 hover:!text-base">
|
||||||
<div class="flex items-center">
|
|
||||||
<IconifyIconOffline :icon="leftLine" />
|
<IconifyIconOffline :icon="leftLine" />
|
||||||
<span class="ml-2">{{ $t('back') }}</span>
|
<span>{{ $t('back') }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
<el-button class="ml-2" link type="primary" @click="$router.push('/')">{{ $t('returnToHomepage') }} </el-button>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
<el-menu-item v-for="item in messageTypeStore.allMessageTypeList" :key="item.id" :class="routerMessageType === item.messageType ? 'is-active' : ''" :index="item.id" @click="onMenuClick(item)">
|
<el-menu-item
|
||||||
|
v-for="item in messageTypeStore.allMessageTypeList"
|
||||||
|
:key="item.id"
|
||||||
|
:class="messageTypeStore.form.messageType === item.messageType ? 'is-active' : ''"
|
||||||
|
:index="item.id"
|
||||||
|
@click="onMenuClick(item)"
|
||||||
|
>
|
||||||
<div class="flex items-center z-10">
|
<div class="flex items-center z-10">
|
||||||
<span>{{ item.messageName }}</span>
|
<span>{{ item.messageName }}</span>
|
||||||
</div>
|
</div>
|
||||||
</el-menu-item>
|
</el-menu-item>
|
||||||
</el-menu>
|
</el-menu>
|
||||||
</el-aside>
|
</el-aside>
|
||||||
<el-main>
|
<el-main class="w-[100%]">
|
||||||
<RouterView />
|
<RouterView />
|
||||||
</el-main>
|
</el-main>
|
||||||
</el-container>
|
</el-container>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
import { $t } from '@/plugins/i18n';
|
||||||
|
|
||||||
|
// 表格列
|
||||||
|
export const columns: TableColumnList = [
|
||||||
|
{ type: 'selection', align: 'left' },
|
||||||
|
{ label: $t('title'), prop: 'title', slot: 'title' },
|
||||||
|
{ label: $t('table.acceptanceTime'), prop: 'acceptanceTime', sortable: true },
|
||||||
|
{ label: $t('extra'), prop: 'extra' },
|
||||||
|
];
|
|
@ -0,0 +1,72 @@
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { messageBox } from '@/utils/message';
|
||||||
|
import { $t } from '@/plugins/i18n';
|
||||||
|
import { useMessageUserStore } from '@/store/message/messageUser';
|
||||||
|
|
||||||
|
// 删除ids
|
||||||
|
export const selectids = ref([]);
|
||||||
|
const messageUserStore = useMessageUserStore();
|
||||||
|
|
||||||
|
/** 搜索初始化系统消息 */
|
||||||
|
export const onSearch = async (messageType?: string) => {
|
||||||
|
messageUserStore.loading = true;
|
||||||
|
if (messageType) {
|
||||||
|
messageUserStore.form.messageType = messageType;
|
||||||
|
}
|
||||||
|
await messageUserStore.getMessageList();
|
||||||
|
messageUserStore.loading = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 删除系统消息 */
|
||||||
|
export const onDelete = async () => {
|
||||||
|
const ids = selectids.value;
|
||||||
|
|
||||||
|
// 是否确认删除
|
||||||
|
const result = await messageBox({
|
||||||
|
title: $t('confirmDelete'),
|
||||||
|
showMessage: false,
|
||||||
|
confirmMessage: undefined,
|
||||||
|
cancelMessage: $t('cancel_delete'),
|
||||||
|
});
|
||||||
|
if (!result) return;
|
||||||
|
|
||||||
|
// 删除数据
|
||||||
|
await messageUserStore.deleteUserMessageByIds(ids);
|
||||||
|
await onSearch();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 标为已读 */
|
||||||
|
export const markAsRead = async () => {
|
||||||
|
const ids = selectids.value;
|
||||||
|
|
||||||
|
// 是否确认标为已读
|
||||||
|
const result = await messageBox({
|
||||||
|
title: $t('markAsRead'),
|
||||||
|
showMessage: false,
|
||||||
|
confirmMessage: undefined,
|
||||||
|
cancelMessage: $t('cancel'),
|
||||||
|
});
|
||||||
|
if (!result) return;
|
||||||
|
|
||||||
|
// 标为已读
|
||||||
|
await messageUserStore.updateUserMarkAsRead(ids);
|
||||||
|
await onSearch();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 全部标为已读 */
|
||||||
|
export const markAsAllRead = async () => {
|
||||||
|
const ids = messageUserStore.datalist.map(message => message.id);
|
||||||
|
|
||||||
|
// 是否确认标为已读
|
||||||
|
const result = await messageBox({
|
||||||
|
title: $t('allMarkAsRead'),
|
||||||
|
showMessage: false,
|
||||||
|
confirmMessage: undefined,
|
||||||
|
cancelMessage: $t('cancel'),
|
||||||
|
});
|
||||||
|
if (!result) return;
|
||||||
|
|
||||||
|
// 标为已读
|
||||||
|
await messageUserStore.updateUserMarkAsRead(ids);
|
||||||
|
await onSearch();
|
||||||
|
};
|
|
@ -0,0 +1,26 @@
|
||||||
|
// 添加或者修改表单元素
|
||||||
|
export interface FormItemProps {
|
||||||
|
// 消息标题
|
||||||
|
title: string;
|
||||||
|
// 接收人用户ID
|
||||||
|
receivedUserIds: string[];
|
||||||
|
// 发送人用户ID
|
||||||
|
sendUserId: string;
|
||||||
|
// 消息类型
|
||||||
|
messageType: string;
|
||||||
|
// 消息内容
|
||||||
|
content: string;
|
||||||
|
// 消息等级
|
||||||
|
level: string;
|
||||||
|
// 消息等级类型
|
||||||
|
extra: string;
|
||||||
|
// 编辑器类型
|
||||||
|
editorType: string;
|
||||||
|
// 0:未读 1:已读
|
||||||
|
status: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加或修改表单Props
|
||||||
|
export interface FormProps {
|
||||||
|
formInline: FormItemProps;
|
||||||
|
}
|
|
@ -1,8 +1,8 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
import { FormInstance, genFileId, UploadProps, UploadRawFile } from 'element-plus';
|
import { FormInstance, genFileId, UploadProps, UploadRawFile } from 'element-plus';
|
||||||
import { addRules, uploadRules } from '@/views/monitor/files/utils/columns';
|
import { addRules, uploadRules } from '@/views/system/files/utils/columns';
|
||||||
import { FormProps } from '@/views/monitor/files/utils/types';
|
import { FormProps } from '@/views/system/files/utils/types';
|
||||||
import { $t } from '@/plugins/i18n';
|
import { $t } from '@/plugins/i18n';
|
||||||
import { useFilesStore } from '@/store/monitor/files';
|
import { useFilesStore } from '@/store/monitor/files';
|
||||||
import { UploadFilled } from '@element-plus/icons-vue';
|
import { UploadFilled } from '@element-plus/icons-vue';
|
|
@ -1,10 +1,10 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, ref } from 'vue';
|
import { onMounted, ref } from 'vue';
|
||||||
import { columns } from '@/views/monitor/files/utils/columns';
|
import { columns } from '@/views/system/files/utils/columns';
|
||||||
import PureTableBar from '@/components/TableBar/src/bar';
|
import PureTableBar from '@/components/TableBar/src/bar';
|
||||||
import AddFill from '@iconify-icons/ri/add-circle-line';
|
import AddFill from '@iconify-icons/ri/add-circle-line';
|
||||||
import PureTable from '@pureadmin/table';
|
import PureTable from '@pureadmin/table';
|
||||||
import { onAdd, onDelete, onDeleteBatch, onDownload, onDownloadBatch, onSearch, onUpdate, selectRows } from '@/views/monitor/files/utils/hooks';
|
import { onAdd, onDelete, onDeleteBatch, onDownload, onDownloadBatch, onSearch, onUpdate, selectRows } from '@/views/system/files/utils/hooks';
|
||||||
import Delete from '@iconify-icons/ep/delete';
|
import Delete from '@iconify-icons/ep/delete';
|
||||||
import Download from '@iconify-icons/ep/download';
|
import Download from '@iconify-icons/ep/download';
|
||||||
import EditPen from '@iconify-icons/ep/edit-pen';
|
import EditPen from '@iconify-icons/ep/edit-pen';
|
|
@ -1,9 +1,9 @@
|
||||||
import { addDialog } from '@/components/BaseDialog/index';
|
import { addDialog } from '@/components/BaseDialog/index';
|
||||||
import FilesDialog from '@/views/monitor/files/files-dialog.vue';
|
import FilesDialog from '@/views/system/files/files-dialog.vue';
|
||||||
import { useFilesStore } from '@/store/monitor/files';
|
import { useFilesStore } from '@/store/monitor/files';
|
||||||
import { h, ref } from 'vue';
|
import { h, ref } from 'vue';
|
||||||
import { message, messageBox } from '@/utils/message';
|
import { message, messageBox } from '@/utils/message';
|
||||||
import type { FormItemProps } from '@/views/monitor/files/utils/types';
|
import type { FormItemProps } from '@/views/system/files/utils/types';
|
||||||
import { $t } from '@/plugins/i18n';
|
import { $t } from '@/plugins/i18n';
|
||||||
import { downloadFilesByFileId, downloadFilesByFilepath } from '@/api/v1/files';
|
import { downloadFilesByFileId, downloadFilesByFilepath } from '@/api/v1/files';
|
||||||
import { download } from '@/utils/sso';
|
import { download } from '@/utils/sso';
|
|
@ -235,7 +235,7 @@ export const assignBatchRolesToRouter = () => {
|
||||||
draggable: true,
|
draggable: true,
|
||||||
closeOnClickModal: false,
|
closeOnClickModal: false,
|
||||||
fullscreenIcon: true,
|
fullscreenIcon: true,
|
||||||
props: { warning: $t('assignBatchRolesToRouterTip') },
|
// props: { warning: $t('assignBatchRolesToRouterTip') },
|
||||||
contentRenderer: () => <AssignRouterToRole ref={assignRouterToRolesRef} />,
|
contentRenderer: () => <AssignRouterToRole ref={assignRouterToRolesRef} />,
|
||||||
beforeSure: async (done: any) => {
|
beforeSure: async (done: any) => {
|
||||||
// 表格功能
|
// 表格功能
|
||||||
|
@ -243,7 +243,7 @@ export const assignBatchRolesToRouter = () => {
|
||||||
|
|
||||||
// 分配用户角色
|
// 分配用户角色
|
||||||
const data = { routerIds: selectIds.value, roleIds: assignRouterToRolesRef.value.assignRoles };
|
const data = { routerIds: selectIds.value, roleIds: assignRouterToRolesRef.value.assignRoles };
|
||||||
const result = await menuStore.assignRolesToRouter(data);
|
const result = await menuStore.assignAddBatchRolesToRouter(data);
|
||||||
|
|
||||||
// 更新成功关闭弹窗
|
// 更新成功关闭弹窗
|
||||||
if (!result) return;
|
if (!result) return;
|
||||||
|
|
Loading…
Reference in New Issue