mirror of
				https://github.com/continew-org/continew-admin.git
				synced 2025-10-31 00:57:13 +08:00 
			
		
		
		
	fix: 修复消息管理部分格式及拼写错误
This commit is contained in:
		| @@ -3,7 +3,7 @@ | ||||
| <a href="https://github.com/Charles7c/continew-admin/blob/dev/LICENSE" target="_blank"> | ||||
| <img src="https://img.shields.io/badge/License-Apache--2.0-blue.svg" alt="License" /> | ||||
| </a> | ||||
| <a href="https://github.com/Charles7c/continew-admin/tree/1.0.x" target="_blank"> | ||||
| <a href="https://github.com/Charles7c/continew-admin" target="_blank"> | ||||
| <img src="https://img.shields.io/badge/SNAPSHOT-v1.3.0-%23ff3f59.svg" alt="Release" /> | ||||
| </a> | ||||
| <a href="https://github.com/Charles7c/continew-admin" target="_blank"> | ||||
| @@ -72,11 +72,12 @@ ContiNew Admin (Continue New Admin)中后台管理框架/脚手架,持续 | ||||
| > **Note** | ||||
| > 更多功能和优化正在赶来💦,最新项目计划和进展请关注 [GitHub Project](https://github.com/Charles7c/continew-admin/projects) 和 [CHANGELOG.md](https://github.com/Charles7c/continew-admin/blob/dev/CHANGELOG.md)。 | ||||
|  | ||||
| - 用户管理:提供用户的相关配置,新增用户后,默认密码为 123456,且支持第三方账号登录、邮箱登录,可在个人中心灵活修改 | ||||
| - 用户管理:提供用户的相关配置,新增用户后,默认密码为 123456,且支持第三方账号登录、邮箱登录、手机号登录,可在个人中心灵活配置 | ||||
| - 部门管理:可配置系统组织架构,树形表格展示 | ||||
| - 角色管理:对权限与菜单进行分配,可根据部门设置角色的数据权限 | ||||
| - 菜单管理:已实现菜单动态路由,后端可配置化,支持多级菜单 | ||||
| - 公告管理:提供公告的发布、查看和删除等功能。管理员可以在后台发布公告,并可以设置公告的生效时间、终止时间,以 markdown-it 为内核渲染 Markdown 格式内容显示 | ||||
| - 消息管理:提供消息中心功能,暂时仅支持系统消息管理 | ||||
| - 字典管理:提供对系统公用数据字典的维护,例如:公告类型,支持字典标签背景色和排序等配置 | ||||
| - 系统配置:提供修改系统标题、Logo、favicon 等基础配置功能,以方便用户系统与其自身品牌形象保持一致(暂未开放高级配置) | ||||
| - 代码生成:提供根据数据库表自动生成相应的前后端 CRUD 代码的功能 | ||||
| @@ -429,6 +430,7 @@ continew-admin | ||||
|     │  │    ├─ dept             # 部门管理 | ||||
|     │  │    ├─ dict             # 字典管理 | ||||
|     │  │    ├─ menu             # 菜单管理 | ||||
|     │  │    ├─ message          # 消息管理 | ||||
|     │  │    ├─ role             # 角色管理 | ||||
|     │  │    └─ user             # 用户模块 | ||||
|     │  │      └─ center           # 个人中心 | ||||
|   | ||||
| @@ -1,19 +1,18 @@ | ||||
| import axios from 'axios'; | ||||
| import qs from 'query-string'; | ||||
| import { DataRecord } from "@/api/system/dict"; | ||||
|  | ||||
| const BASE_URL = '/system/message'; | ||||
|  | ||||
| export interface MessageRecord { | ||||
|   id?: number; | ||||
|   type?: string; | ||||
|   title?: string; | ||||
|   subTitle?: string; | ||||
|   avatar?: string; | ||||
|   content?: string; | ||||
|   createTime?: string; | ||||
|   readStatus?: 0 | 1; | ||||
|   messageType?: number; | ||||
|   id: number; | ||||
|   title: string; | ||||
|   content: string; | ||||
|   type: string; | ||||
|   createUserString: string; | ||||
|   createTime: string; | ||||
|   subTitle: string; | ||||
|   readStatus: boolean; | ||||
|   readTime: string; | ||||
| } | ||||
|  | ||||
| export interface ChatRecord { | ||||
| @@ -30,12 +29,12 @@ export interface ListParam { | ||||
|   type?: string; | ||||
|   page?: number; | ||||
|   size?: number; | ||||
|   uid?:number | ||||
|   uid?: number; | ||||
|   sort?: Array<string>; | ||||
| } | ||||
|  | ||||
| export interface PageRes { | ||||
|   list: DataRecord[]; | ||||
|   list: MessageRecord[]; | ||||
|   total: number; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -52,8 +52,6 @@ | ||||
|       list({ sort: ['createTime,desc'] }).then((res) => { | ||||
|         messageData.messageList = res.data; | ||||
|       }); | ||||
|     } catch (err) { | ||||
|       // you can report use errorHandler or other | ||||
|     } finally { | ||||
|       setLoading(false); | ||||
|     } | ||||
| @@ -67,16 +65,16 @@ | ||||
|   async function readMessage(data: MessageListType) { | ||||
|     const ids = data.map((item) => item.id); | ||||
|     await read(ids); | ||||
|     fetchSourceData(); | ||||
|     await fetchSourceData(); | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * 每个消息类型下的消息列表 | ||||
|    */ | ||||
|   const renderList = computed(() => { | ||||
|     return messageData.messageList.filter( | ||||
|       (item) => item.type === messageType.value && !item.readStatus | ||||
|     ).splice(0,3); | ||||
|     return messageData.messageList | ||||
|       .filter((item) => item.type === messageType.value && !item.readStatus) | ||||
|       .splice(0, 3); | ||||
|   }); | ||||
|  | ||||
|   /** | ||||
| @@ -115,15 +113,6 @@ | ||||
|   const handleItemClick = (items: MessageListType) => { | ||||
|     if (renderList.value.length) readMessage([...items]); | ||||
|   }; | ||||
|  | ||||
|   /** | ||||
|    * 清空消息 | ||||
|    */ | ||||
|   const emptyList = () => { | ||||
|     read([]).then((res) => { | ||||
|       messageData.messageList = []; | ||||
|     }); | ||||
|   }; | ||||
|   fetchSourceData(); | ||||
| </script> | ||||
|  | ||||
|   | ||||
| @@ -5,17 +5,11 @@ | ||||
|       :key="item.id" | ||||
|       action-layout="vertical" | ||||
|       :style="{ | ||||
|         opacity: item.readStatus == 1 ? 0.5 : 1, | ||||
|         opacity: item.readStatus ? 0.5 : 1, | ||||
|       }" | ||||
|     > | ||||
|       <div class="item-wrap" @click="onItemClick(item)"> | ||||
|         <a-list-item-meta> | ||||
|           <template v-if="item.avatar" #avatar> | ||||
|             <a-avatar shape="circle"> | ||||
|               <img v-if="item.avatar" :src="item.avatar" /> | ||||
|               <icon-desktop v-else /> | ||||
|             </a-avatar> | ||||
|           </template> | ||||
|           <template #title> | ||||
|             <a-space :size="4"> | ||||
|               <span>{{ item.title }}</span> | ||||
| @@ -92,7 +86,7 @@ | ||||
|    */ | ||||
|   const toList = () => { | ||||
|     router.push({ | ||||
|       path: '/system/message', | ||||
|       name: 'Message', | ||||
|     }); | ||||
|   }; | ||||
|  | ||||
| @@ -149,6 +143,9 @@ | ||||
|     } | ||||
|     .footer-wrap { | ||||
|       text-align: center; | ||||
|       .arco-link { | ||||
|         padding: 1px 10px; | ||||
|       } | ||||
|     } | ||||
|     .arco-typography { | ||||
|       margin-bottom: 0; | ||||
|   | ||||
| @@ -227,7 +227,7 @@ | ||||
|  | ||||
|   const unReadMessageCount = ref(0); | ||||
|   watchEffect(async () => { | ||||
|     const res = await list({ sort: ["createTime,desc"],readStatus:0 }); | ||||
|     const res = await list({ sort: ['createTime,desc'], readStatus: 0 }); | ||||
|     unReadMessageCount.value = res.data?.length ?? 0; | ||||
|   }); | ||||
|  | ||||
|   | ||||
| @@ -39,6 +39,15 @@ const System: AppRouteRecordRaw = { | ||||
|         requiresAuth: true, | ||||
|       }, | ||||
|     }, | ||||
|     { | ||||
|       name: 'Menu', | ||||
|       path: '/system/menu', | ||||
|       component: () => import('@/views/system/menu/index.vue'), | ||||
|       meta: { | ||||
|         locale: 'menu.system.menu.list', | ||||
|         requiresAuth: true, | ||||
|       }, | ||||
|     }, | ||||
|     { | ||||
|       name: 'Announcement', | ||||
|       path: '/system/announcement', | ||||
| @@ -49,11 +58,11 @@ const System: AppRouteRecordRaw = { | ||||
|       }, | ||||
|     }, | ||||
|     { | ||||
|       name: 'Menu', | ||||
|       path: '/system/menu', | ||||
|       component: () => import('@/views/system/menu/index.vue'), | ||||
|       name: 'Message', | ||||
|       path: '/system/message', | ||||
|       component: () => import('@/views/system/message/index.vue'), | ||||
|       meta: { | ||||
|         locale: 'menu.system.menu.list', | ||||
|         locale: 'menu.system.message', | ||||
|         requiresAuth: true, | ||||
|       }, | ||||
|     }, | ||||
| @@ -75,15 +84,6 @@ const System: AppRouteRecordRaw = { | ||||
|         requiresAuth: true, | ||||
|       }, | ||||
|     }, | ||||
|     { | ||||
|       name: 'Message', | ||||
|       path: '/system/message', | ||||
|       component: () => import('@/views/system/message/index.vue'), | ||||
|       meta: { | ||||
|         locale: 'menu.system.message', | ||||
|         requiresAuth: true, | ||||
|       }, | ||||
|     }, | ||||
|   ], | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -27,7 +27,12 @@ | ||||
|             </a-form-item> | ||||
|  | ||||
|             <a-form-item field="type" hide-label> | ||||
|               <a-select :style="{width:'150px'}" placeholder="是否已读" allow-clear v-model="queryParams.readStatus"> | ||||
|               <a-select | ||||
|                 v-model="queryParams.readStatus" | ||||
|                 :style="{ width: '150px' }" | ||||
|                 placeholder="是否已读" | ||||
|                 allow-clear | ||||
|               > | ||||
|                 <a-option :value="true">是</a-option> | ||||
|                 <a-option :value="false">否</a-option> | ||||
|               </a-select> | ||||
| @@ -66,7 +71,7 @@ | ||||
|                   <template #icon><icon-check /></template>全部已读 | ||||
|                 </a-button> | ||||
|                 <a-button | ||||
|                   v-permission="['system:announcement:delete']" | ||||
|                   v-permission="['system:message:delete']" | ||||
|                   type="primary" | ||||
|                   status="danger" | ||||
|                   :disabled="multiple" | ||||
| @@ -136,7 +141,9 @@ | ||||
|           </a-table-column> | ||||
|           <a-table-column title="发送时间" data-index="createTime" /> | ||||
|           <a-table-column | ||||
|             v-if="checkPermission(['system:message:delete'])" | ||||
|             v-if=" | ||||
|               checkPermission(['system:message:delete']) | ||||
|             " | ||||
|             title="操作" | ||||
|             align="center" | ||||
|           > | ||||
| @@ -157,7 +164,7 @@ | ||||
|                 @ok="handleDelete([record.id])" | ||||
|               > | ||||
|                 <a-button | ||||
|                   v-permission="['system:announcement:delete']" | ||||
|                   v-permission="['system:message:delete']" | ||||
|                   type="text" | ||||
|                   size="small" | ||||
|                   title="删除" | ||||
| @@ -202,7 +209,9 @@ | ||||
|             <a-skeleton v-if="detailLoading" :animation="true"> | ||||
|               <a-skeleton-line :rows="1" /> | ||||
|             </a-skeleton> | ||||
|             <span v-else-if="dataDetail.createUserString">{{ dataDetail.createUserString }}</span> | ||||
|             <span v-else-if="dataDetail.createUserString">{{ | ||||
|               dataDetail.createUserString | ||||
|             }}</span> | ||||
|             <dict-tag | ||||
|               v-if="dataDetail.createUserString == null" | ||||
|               :value="dataDetail.type" | ||||
| @@ -221,9 +230,9 @@ | ||||
|             <a-skeleton v-if="detailLoading" :animation="true"> | ||||
|               <a-skeleton-line :rows="1" /> | ||||
|             </a-skeleton> | ||||
|             <span color="green" v-else> | ||||
|                <a-tag v-if="dataDetail.readStatus" color="green">已读</a-tag> | ||||
|                <a-tag v-else color="red">未读</a-tag> | ||||
|             <span v-else> | ||||
|               <a-tag v-if="dataDetail.readStatus" color="green">是</a-tag> | ||||
|               <a-tag v-else color="red">否</a-tag> | ||||
|             </span> | ||||
|           </a-descriptions-item> | ||||
|  | ||||
| @@ -262,7 +271,17 @@ | ||||
|   const { message_type } = proxy.useDict('message_type'); | ||||
|  | ||||
|   const dataList = ref<MessageRecord[]>([]); | ||||
|   const dataDetail = ref<MessageRecord>({}); | ||||
|   const dataDetail = ref<MessageRecord>({ | ||||
|     id: 0, | ||||
|     title: '', | ||||
|     content: '', | ||||
|     type: '', | ||||
|     createUserString: '', | ||||
|     createTime: '', | ||||
|     subTitle: '', | ||||
|     readStatus: false, | ||||
|     readTime: '', | ||||
|   }); | ||||
|   const total = ref(0); | ||||
|   const ids = ref<Array<number>>([]); | ||||
|   const single = ref(true); | ||||
| @@ -319,7 +338,6 @@ | ||||
|    */ | ||||
|   const handleDetailCancel = () => { | ||||
|     detailVisible.value = false; | ||||
|     dataDetail.value = {}; | ||||
|   }; | ||||
|  | ||||
|   /** | ||||
| @@ -394,11 +412,10 @@ | ||||
|     const unReadMessageList = dataList.value.filter( | ||||
|       (item) => rowKeys.indexOf(item.id) !== -1 && !item.readStatus | ||||
|     ); | ||||
|     readMultiple.value=!unReadMessageList.length | ||||
|     readMultiple.value = !unReadMessageList.length; | ||||
|     ids.value = rowKeys; | ||||
|     single.value = rowKeys.length !== 1; | ||||
|     multiple.value = !rowKeys.length; | ||||
|  | ||||
|   }; | ||||
|  | ||||
|   /** | ||||
| @@ -439,7 +456,7 @@ | ||||
|  | ||||
| <script lang="ts"> | ||||
|   export default { | ||||
|     name: 'Announcement', | ||||
|     name: 'Message', | ||||
|   }; | ||||
| </script> | ||||
|  | ||||
|   | ||||
| @@ -54,8 +54,8 @@ public class MessageController | ||||
|  | ||||
|     private final MessageUserService messageUserService; | ||||
|  | ||||
|     @Operation(description = "将消息标记已读", summary = "将消息标记已读") | ||||
|     @Parameter(name = "ids", description = "消息ID", example = "1,2", in = ParameterIn.PATH) | ||||
|     @Operation(description = "标记已读", summary = "将消息标记为已读状态") | ||||
|     @Parameter(name = "ids", description = "消息ID列表", example = "1,2", in = ParameterIn.QUERY) | ||||
|     @PatchMapping("/read") | ||||
|     public void readMessage(@RequestParam(required = false) List<Long> ids) { | ||||
|         messageUserService.readMessage(ids); | ||||
|   | ||||
| @@ -5,14 +5,14 @@ | ||||
| INSERT IGNORE INTO `sys_menu` | ||||
| (`id`, `title`, `parent_id`, `type`, `path`, `name`, `component`, `icon`, `is_external`, `is_cache`, `is_hidden`, `permission`, `sort`, `status`, `create_user`, `create_time`, `update_user`, `update_time`) | ||||
| VALUES | ||||
| (1060, '字典管理', 1000, 2, '/system/dict', 'Dict', 'system/dict/index', 'bookmark', b'0', b'0', b'0', 'system:dict:list', 6, 1, 1, NOW(), NULL, NULL), | ||||
| (1061, '字典新增', 1060, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:dict:add', 1, 1, 1, NOW(), NULL, NULL), | ||||
| (1062, '字典修改', 1060, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:dict:update', 2, 1, 1, NOW(), NULL, NULL), | ||||
| (1063, '字典删除', 1060, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:dict:delete', 3, 1, 1, NOW(), NULL, NULL), | ||||
| (1064, '字典导出', 1060, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:dict:export', 4, 1, 1, NOW(), NULL, NULL), | ||||
| (1070, '系统配置', 1000, 2, '/system/config', 'Config', 'system/config/index', 'desktop', b'0', b'0', b'0', 'system:config:list', 7, 1, 1, NOW(), NULL, NULL), | ||||
| (1071, '修改配置', 1070, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:config:update', 1, 1, 1, NOW(), NULL, NULL), | ||||
| (1072, '恢复默认', 1070, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:config:reset', 2, 1, 1, NOW(), NULL, NULL); | ||||
| (1070, '字典管理', 1000, 2, '/system/dict', 'Dict', 'system/dict/index', 'bookmark', b'0', b'0', b'0', 'system:dict:list', 7, 1, 1, NOW(), NULL, NULL), | ||||
| (1071, '字典新增', 1070, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:dict:add', 1, 1, 1, NOW(), NULL, NULL), | ||||
| (1072, '字典修改', 1070, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:dict:update', 2, 1, 1, NOW(), NULL, NULL), | ||||
| (1073, '字典删除', 1070, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:dict:delete', 3, 1, 1, NOW(), NULL, NULL), | ||||
| (1074, '字典导出', 1070, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:dict:export', 4, 1, 1, NOW(), NULL, NULL), | ||||
| (1080, '系统配置', 1000, 2, '/system/config', 'Config', 'system/config/index', 'desktop', b'0', b'0', b'0', 'system:config:list', 8, 1, 1, NOW(), NULL, NULL), | ||||
| (1081, '修改配置', 1080, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:config:update', 1, 1, 1, NOW(), NULL, NULL), | ||||
| (1082, '恢复默认', 1080, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:config:reset', 2, 1, 1, NOW(), NULL, NULL); | ||||
|  | ||||
| -- 初始化默认字典 | ||||
| INSERT IGNORE INTO `sys_dict` | ||||
| @@ -20,7 +20,6 @@ INSERT IGNORE INTO `sys_dict` | ||||
| VALUES | ||||
| (1, '公告类型', 'announcement_type', NULL, b'1', 1, NOW(), NULL, NULL); | ||||
|  | ||||
| -- 初始化默认字典项 | ||||
| INSERT IGNORE INTO `sys_dict_item` | ||||
| (`id`, `label`, `value`, `color`, `sort`, `description`, `dict_id`, `create_user`, `create_time`, `update_user`, `update_time`) | ||||
| VALUES | ||||
|   | ||||
| @@ -1,13 +1,19 @@ | ||||
| -- liquibase formatted sql | ||||
|  | ||||
| -- changeset BUSS_BCLS:1 | ||||
| -- 初始化默认菜单 | ||||
| INSERT IGNORE INTO `sys_menu` | ||||
| (`id`, `title`, `parent_id`, `type`, `path`, `name`, `component`, `icon`, `is_external`, `is_cache`, `is_hidden`, `permission`, `sort`, `status`, `create_user`, `create_time`, `update_user`, `update_time`) | ||||
| VALUES | ||||
| (1060, '消息管理', 1000, 2, '/system/message', 'Message', 'system/message/index', 'notification', b'0', b'0', b'0', 'system:message:list', 6, 1, 1, NOW(), NULL, NULL), | ||||
| (1061, '消息删除', 1060, 3, NULL, NULL, NULL, NULL, b'0', b'0', b'0', 'system:message:delete', 1, 1, 1, NOW(), NULL, NULL); | ||||
|  | ||||
| -- 初始化默认字典 | ||||
| INSERT IGNORE INTO `sys_dict` | ||||
| (`id`, `name`, `code`, `description`, `is_system`, `create_user`, `create_time`, `update_user`, `update_time`) | ||||
| VALUES | ||||
| (2, '消息类型', 'message_type', NULL, b'1', 1, NOW(), NULL, NULL); | ||||
|  | ||||
| -- 初始化默认字典项 | ||||
| INSERT IGNORE INTO `sys_dict_item` | ||||
| (`id`, `label`, `value`, `color`, `sort`, `description`, `dict_id`, `create_user`, `create_time`, `update_user`, `update_time`) | ||||
| VALUES | ||||
|   | ||||
		Reference in New Issue
	
	Block a user