diff --git a/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/constant/SysConsts.java b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/constant/SysConsts.java index 8fcb324e..704ec355 100644 --- a/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/constant/SysConsts.java +++ b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/constant/SysConsts.java @@ -67,9 +67,4 @@ public class SysConsts { * VO 描述类字段后缀 */ public static final String VO_DESCRIPTION_FIELD_SUFFIX = "String"; - - /** - * 系统消息类型 - */ - public static final String SYSTEM_MESSAGE_TYPE = "1"; } diff --git a/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/enums/MessageTypeEnum.java b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/enums/MessageTypeEnum.java new file mode 100644 index 00000000..1ed82043 --- /dev/null +++ b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/enums/MessageTypeEnum.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.charles7c.cnadmin.common.enums; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +import top.charles7c.cnadmin.common.base.IBaseEnum; +import top.charles7c.cnadmin.common.constant.UIConsts; + +/** + * 消息类型枚举 + * + * @author Charles7c + * @since 2023/11/2 20:08 + */ +@Getter +@RequiredArgsConstructor +public enum MessageTypeEnum implements IBaseEnum { + + /** 系统消息 */ + SYSTEM(1, "系统消息", UIConsts.COLOR_PRIMARY),; + + private final Integer value; + private final String description; + private final String color; +} diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/service/impl/LoginServiceImpl.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/service/impl/LoginServiceImpl.java index 3f2443f0..200243be 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/service/impl/LoginServiceImpl.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/auth/service/impl/LoginServiceImpl.java @@ -28,10 +28,10 @@ import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.lang.tree.Tree; import cn.hutool.core.lang.tree.TreeNodeConfig; -import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.RandomUtil; import cn.hutool.core.util.ReUtil; +import cn.hutool.core.util.StrUtil; import cn.hutool.json.JSONUtil; import top.charles7c.cnadmin.auth.model.vo.MetaVO; @@ -45,6 +45,7 @@ import top.charles7c.cnadmin.common.constant.SysConsts; import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum; import top.charles7c.cnadmin.common.enums.GenderEnum; import top.charles7c.cnadmin.common.enums.MenuTypeEnum; +import top.charles7c.cnadmin.common.enums.MessageTypeEnum; import top.charles7c.cnadmin.common.model.dto.LoginUser; import top.charles7c.cnadmin.common.util.SecureUtils; import top.charles7c.cnadmin.common.util.TreeUtils; @@ -71,6 +72,7 @@ import me.zhyd.oauth.model.AuthUser; @RequiredArgsConstructor public class LoginServiceImpl implements LoginService { + private final ProjectProperties projectProperties; private final UserService userService; private final DeptService deptService; private final RoleService roleService; @@ -79,7 +81,6 @@ public class LoginServiceImpl implements LoginService { private final UserRoleService userRoleService; private final UserSocialService userSocialService; private final MessageService messageService; - private final ProjectProperties projectProperties; @Override public String accountLogin(String username, String password) { @@ -137,7 +138,7 @@ public class LoginServiceImpl implements LoginService { userSocial.setUserId(userId); userSocial.setSource(source); userSocial.setOpenId(openId); - this.sendMsg(user); + this.sendSystemMsg(user); } else { user = BeanUtil.toBean(userService.get(userSocial.getUserId()), UserDO.class); } @@ -214,20 +215,17 @@ public class LoginServiceImpl implements LoginService { } /** - * 发送消息 + * 发送系统消息 * * @param user * 用户信息 */ - private void sendMsg(UserDO user) { + private void sendSystemMsg(UserDO user) { MessageRequest request = new MessageRequest(); MessageTemplateEnum socialRegister = MessageTemplateEnum.SOCIAL_REGISTER; - request.setTitle(socialRegister.getTitle()); - Map contentMap = MapUtil.newHashMap(2); - contentMap.put("nickname", user.getNickname()); - contentMap.put("projectName", projectProperties.getName()); - request.setContent(socialRegister.getContent(), contentMap); - request.setType(SysConsts.SYSTEM_MESSAGE_TYPE); + request.setTitle(StrUtil.format(socialRegister.getTitle(), projectProperties.getName())); + request.setContent(StrUtil.format(socialRegister.getContent(), user.getNickname())); + request.setType(MessageTypeEnum.SYSTEM); messageService.add(request, CollUtil.toList(user.getId())); } } diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/enums/MessageTemplateEnum.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/enums/MessageTemplateEnum.java index 067934fb..bb8acf09 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/enums/MessageTemplateEnum.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/enums/MessageTemplateEnum.java @@ -32,7 +32,7 @@ public enum MessageTemplateEnum { /** * 第三方登录 */ - SOCIAL_REGISTER("欢迎注册 {projectName}", "尊敬的 {nickname},欢迎注册使用,请及时配置您的密码。"); + SOCIAL_REGISTER("欢迎注册 {}", "尊敬的 {},欢迎注册使用,请及时配置您的密码。"); private final String title; private final String content; diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/mapper/MessageMapper.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/mapper/MessageMapper.java index f1b7bb09..0e8c00c6 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/mapper/MessageMapper.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/mapper/MessageMapper.java @@ -16,8 +16,6 @@ package top.charles7c.cnadmin.system.mapper; -import java.util.List; - import org.apache.ibatis.annotations.Param; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; @@ -35,24 +33,16 @@ import top.charles7c.cnadmin.system.model.vo.MessageVO; * @since 2023/10/15 19:05 */ public interface MessageMapper extends BaseMapper { + /** * 分页查询列表 * - * @param queryWrapper - * 查询条件 * @param page * 分页查询条件 + * @param queryWrapper + * 查询条件 * @return 分页信息 */ IPage selectVoPage(@Param("page") IPage page, @Param(Constants.WRAPPER) QueryWrapper queryWrapper); - - /** - * 查询列表 - * - * @param queryWrapper - * 查询条件 - * @return 列表信息 - */ - List selectVoList(@Param(Constants.WRAPPER) QueryWrapper queryWrapper); } \ No newline at end of file diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/mapper/MessageUserMapper.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/mapper/MessageUserMapper.java index 73663fc1..f20a7e20 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/mapper/MessageUserMapper.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/mapper/MessageUserMapper.java @@ -16,13 +16,27 @@ package top.charles7c.cnadmin.system.mapper; +import org.apache.ibatis.annotations.Param; + import top.charles7c.cnadmin.common.base.BaseMapper; import top.charles7c.cnadmin.system.model.entity.MessageUserDO; /** - * 消息和用户关联 Mapper + * 消息和用户 Mapper * * @author BULL_BCLS * @since 2023/10/15 20:25 */ -public interface MessageUserMapper extends BaseMapper {} \ No newline at end of file +public interface MessageUserMapper extends BaseMapper { + + /** + * 根据用户 ID 和消息类型查询未读消息数量 + * + * @param userId + * 用户 ID + * @param type + * 消息类型 + * @return 未读消息信息 + */ + Long selectUnreadCountByUserIdAndType(@Param("userId") Long userId, @Param("type") Integer type); +} \ No newline at end of file diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/MessageDO.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/MessageDO.java index c38bb0d7..21284bc4 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/MessageDO.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/MessageDO.java @@ -16,11 +16,17 @@ package top.charles7c.cnadmin.system.model.entity; +import java.io.Serializable; +import java.time.LocalDateTime; + import lombok.Data; +import com.baomidou.mybatisplus.annotation.FieldFill; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; -import top.charles7c.cnadmin.common.base.BaseDO; +import top.charles7c.cnadmin.common.enums.MessageTypeEnum; /** * 消息实体 @@ -30,17 +36,18 @@ import top.charles7c.cnadmin.common.base.BaseDO; */ @Data @TableName("sys_message") -public class MessageDO extends BaseDO { +public class MessageDO implements Serializable { private static final long serialVersionUID = 1L; /** - * 消息ID + * ID */ + @TableId private Long id; /** - * 主题 + * 标题 */ private String title; @@ -50,7 +57,18 @@ public class MessageDO extends BaseDO { private String content; /** - * 类型(取值于字典 message_type) + * 类型(1:系统消息) */ - private String type; + private MessageTypeEnum type; + + /** + * 创建人 + */ + private Long createUser; + + /** + * 创建时间 + */ + @TableField(fill = FieldFill.INSERT) + private LocalDateTime createTime; } \ No newline at end of file diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/MessageUserDO.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/MessageUserDO.java index ab960d64..f0e937b4 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/MessageUserDO.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/MessageUserDO.java @@ -16,14 +16,13 @@ package top.charles7c.cnadmin.system.model.entity; +import java.io.Serializable; import java.time.LocalDateTime; import lombok.Data; import com.baomidou.mybatisplus.annotation.TableName; -import top.charles7c.cnadmin.common.base.BaseDO; - /** * 消息和用户关联实体 * @@ -32,24 +31,24 @@ import top.charles7c.cnadmin.common.base.BaseDO; */ @Data @TableName("sys_message_user") -public class MessageUserDO extends BaseDO { +public class MessageUserDO implements Serializable { private static final long serialVersionUID = 1L; /** - * 消息ID + * 消息 ID */ private Long messageId; /** - * 用户ID + * 用户 ID */ private Long userId; /** - * 读取状态 (0未读 1已读) + * 是否已读 */ - private Boolean readStatus; + private Boolean isRead; /** * 读取时间 diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/query/MessageQuery.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/query/MessageQuery.java index c8f27879..aeec7d1f 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/query/MessageQuery.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/query/MessageQuery.java @@ -41,32 +41,32 @@ public class MessageQuery implements Serializable { * ID */ @Schema(description = "ID", example = "1") - @Query(type = QueryTypeEnum.EQUAL) + @Query private Long id; /** - * 类型(取值于字典 message_type) + * 标题 */ - @Schema(description = "类型(取值于字典 message_type)", example = "1") - @Query(type = QueryTypeEnum.EQUAL) - private String type; - - /** - * 主题 - */ - @Schema(description = "主题", example = "欢迎 xxx") + @Schema(description = "标题", example = "欢迎注册 xxx") @Query(type = QueryTypeEnum.INNER_LIKE) private String title; /** - * 用户ID + * 类型 */ - @Schema(description = "用户ID", example = "1") - private Long uid; + @Schema(description = "类型(1:系统消息)", example = "1") + @Query + private Integer type; /** * 是否已读 */ @Schema(description = "是否已读", example = "true") - private Boolean readStatus; + private Boolean isRead; + + /** + * 用户 ID + */ + @Schema(hidden = true) + private Long userId; } \ No newline at end of file diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/request/MessageRequest.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/request/MessageRequest.java index 7b681ed3..eec39c2d 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/request/MessageRequest.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/request/MessageRequest.java @@ -16,9 +16,8 @@ package top.charles7c.cnadmin.system.model.request; -import java.util.Map; - import javax.validation.constraints.NotBlank; +import javax.validation.constraints.NotNull; import lombok.Data; @@ -26,9 +25,8 @@ import io.swagger.v3.oas.annotations.media.Schema; import org.hibernate.validator.constraints.Length; -import cn.hutool.core.util.StrUtil; - import top.charles7c.cnadmin.common.base.BaseRequest; +import top.charles7c.cnadmin.common.enums.MessageTypeEnum; /** * 创建消息信息 @@ -36,37 +34,32 @@ import top.charles7c.cnadmin.common.base.BaseRequest; * @author BULL_BCLS * @since 2023/10/15 19:05 */ -@Schema(description = "创建消息信息") @Data +@Schema(description = "创建消息信息") public class MessageRequest extends BaseRequest { private static final long serialVersionUID = 1L; /** - * 主题 + * 标题 */ - @Schema(description = "主题", example = "欢迎 xxx") - @NotBlank(message = "主题不能为空") - @Length(max = 50, message = "主题长度不能超过 {max} 个字符") + @Schema(description = "标题", example = "欢迎注册 xxx") + @NotBlank(message = "标题不能为空") + @Length(max = 50, message = "标题长度不能超过 {max} 个字符") private String title; /** * 内容 */ - @Schema(description = "内容", example = "欢迎 xxx 来到 ContiNew Admin") + @Schema(description = "内容", example = "尊敬的 xx,欢迎注册使用,请及时配置您的密码。") @NotBlank(message = "内容不能为空") @Length(max = 255, message = "内容长度不能超过 {max} 个字符") private String content; /** - * 类型(取值于字典 message_type) + * 类型 */ - @Schema(description = "类型(取值于字典 message_type)", example = "1") - @NotBlank(message = "类型不能为空") - @Length(max = 30, message = "类型长度不能超过 {max} 个字符") - private String type; - - public void setContent(String content, Map contentMap) { - this.content = StrUtil.format(content, contentMap); - } + @Schema(description = "类型(1:系统消息)", example = "1") + @NotNull(message = "类型非法") + private MessageTypeEnum type; } \ No newline at end of file diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/MessageUserVO.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/MessageTypeUnreadVO.java similarity index 53% rename from continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/MessageUserVO.java rename to continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/MessageTypeUnreadVO.java index 6b28c682..dff7d29b 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/MessageUserVO.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/MessageTypeUnreadVO.java @@ -16,47 +16,35 @@ package top.charles7c.cnadmin.system.model.vo; -import java.time.LocalDateTime; +import java.io.Serializable; import lombok.Data; import io.swagger.v3.oas.annotations.media.Schema; -import top.charles7c.cnadmin.common.base.BaseVO; +import top.charles7c.cnadmin.common.enums.MessageTypeEnum; /** - * 消息和用户关联信息 + * 各类型未读消息信息 * - * @author BULL_BCLS - * @since 2023/10/15 20:25 + * @author Charles7c + * @since 2023/11/2 23:00 */ @Data -@Schema(description = "消息和用户关联信息") -public class MessageUserVO extends BaseVO { +@Schema(description = "各类型未读消息信息") +public class MessageTypeUnreadVO implements Serializable { private static final long serialVersionUID = 1L; /** - * 消息ID + * 类型 */ - @Schema(description = "消息ID", example = "1") - private Long messageId; + @Schema(description = "类型(1:系统消息)", example = "1") + private MessageTypeEnum type; /** - * 用户ID + * 数量 */ - @Schema(description = "用户ID", example = "1") - private Long userId; - - /** - * 是否已读 - */ - @Schema(description = "是否已读", example = "true") - private Boolean readStatus; - - /** - * 读取时间 - */ - @Schema(description = "读取时间", example = "2023-08-08 23:59:59", type = "string") - private LocalDateTime readTime; + @Schema(description = "数量", example = "10") + private Long count; } \ No newline at end of file diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/MessageUnreadVO.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/MessageUnreadVO.java new file mode 100644 index 00000000..e4565db6 --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/MessageUnreadVO.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2022-present Charles7c Authors. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package top.charles7c.cnadmin.system.model.vo; + +import java.io.Serializable; +import java.util.List; + +import lombok.Data; + +import io.swagger.v3.oas.annotations.media.Schema; + +import com.fasterxml.jackson.annotation.JsonInclude; + +/** + * 未读消息信息 + * + * @author Charles7c + * @since 2023/11/2 23:00 + */ +@Data +@Schema(description = "未读消息信息") +@JsonInclude(JsonInclude.Include.NON_EMPTY) +public class MessageUnreadVO implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * 未读消息数量 + */ + @Schema(description = "未读消息数量", example = "20") + private Long total; + + /** + * 各类型未读消息数量 + */ + @Schema(description = "各类型未读消息数量") + private List details; +} \ No newline at end of file diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/MessageVO.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/MessageVO.java index 9357c252..bf87d8d8 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/MessageVO.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/MessageVO.java @@ -16,13 +16,16 @@ package top.charles7c.cnadmin.system.model.vo; +import java.io.Serializable; import java.time.LocalDateTime; import lombok.Data; import io.swagger.v3.oas.annotations.media.Schema; -import top.charles7c.cnadmin.common.base.BaseVO; +import com.fasterxml.jackson.annotation.JsonIgnore; + +import top.charles7c.cnadmin.common.enums.MessageTypeEnum; /** * 消息信息 @@ -32,43 +35,61 @@ import top.charles7c.cnadmin.common.base.BaseVO; */ @Data @Schema(description = "消息信息") -public class MessageVO extends BaseVO { +public class MessageVO implements Serializable { private static final long serialVersionUID = 1L; /** - * 消息ID + * ID */ - @Schema(description = "消息ID", example = "1") + @Schema(description = "ID", example = "1") private Long id; /** - * 主题 + * 标题 */ - @Schema(description = "主题", example = "欢迎 xxx") + @Schema(description = "标题", example = "欢迎注册 xxx") private String title; /** * 内容 */ - @Schema(description = "内容", example = "欢迎 xxx") + @Schema(description = "内容", example = "尊敬的 xx,欢迎注册使用,请及时配置您的密码。") private String content; /** - * 类型(取值于字典 message_type) + * 类型 */ - @Schema(description = "类型(取值于字典 message_type)", example = "1") - private String type; + @Schema(description = "类型(1:系统消息)", example = "1") + private MessageTypeEnum type; /** * 是否已读 */ @Schema(description = "是否已读", example = "true") - private Boolean readStatus; + private Boolean isRead; /** * 读取时间 */ @Schema(description = "读取时间", example = "2023-08-08 23:59:59", type = "string") private LocalDateTime readTime; + + /** + * 创建人 + */ + @JsonIgnore + private Long createUser; + + /** + * 创建人 + */ + @Schema(description = "创建人", example = "超级管理员") + private String createUserString; + + /** + * 创建时间 + */ + @Schema(description = "创建时间", example = "2023-08-08 08:08:08", type = "string") + private LocalDateTime createTime; } \ No newline at end of file diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/MessageService.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/MessageService.java index f7f23c47..5fba48c5 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/MessageService.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/MessageService.java @@ -18,7 +18,8 @@ package top.charles7c.cnadmin.system.service; import java.util.List; -import top.charles7c.cnadmin.common.base.BaseService; +import top.charles7c.cnadmin.common.model.query.PageQuery; +import top.charles7c.cnadmin.common.model.vo.PageDataVO; import top.charles7c.cnadmin.system.model.query.MessageQuery; import top.charles7c.cnadmin.system.model.request.MessageRequest; import top.charles7c.cnadmin.system.model.vo.MessageVO; @@ -29,15 +30,34 @@ import top.charles7c.cnadmin.system.model.vo.MessageVO; * @author BULL_BCLS * @since 2023/10/15 19:05 */ -public interface MessageService extends BaseService { +public interface MessageService { /** - * 发送消息 + * 分页查询列表 + * + * @param query + * 查询条件 + * @param pageQuery + * 分页查询条件 + * @return 分页列表信息 + */ + PageDataVO page(MessageQuery query, PageQuery pageQuery); + + /** + * 新增 * * @param request * 消息 * @param userIdList - * 接收人 + * 接收人列表 */ void add(MessageRequest request, List userIdList); + + /** + * 删除 + * + * @param ids + * ID 列表 + */ + void delete(List ids); } \ No newline at end of file diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/MessageUserService.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/MessageUserService.java index a1fa5f94..164eaea6 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/MessageUserService.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/MessageUserService.java @@ -18,6 +18,8 @@ package top.charles7c.cnadmin.system.service; import java.util.List; +import top.charles7c.cnadmin.system.model.vo.MessageUnreadVO; + /** * 消息和用户关联业务接口 * @@ -27,12 +29,23 @@ import java.util.List; public interface MessageUserService { /** - * 发送消息 + * 根据用户 ID 查询未读消息数量 + * + * @param userId + * 用户 ID + * @param isDetail + * 是否查询详情 + * @return 未读消息信息 + */ + MessageUnreadVO countUnreadMessageByUserId(Long userId, Boolean isDetail); + + /** + * 新增 * * @param messageId - * 消息ID + * 消息 ID * @param userIdList - * 接收人 + * 用户 ID 列表 */ void add(Long messageId, List userIdList); @@ -45,10 +58,10 @@ public interface MessageUserService { void readMessage(List ids); /** - * 删除消息 + * 根据消息 ID 删除 * - * @param ids - * 消息ID + * @param messageIds + * 消息 ID 列表 */ - void delete(List ids); + void deleteByMessageIds(List messageIds); } \ No newline at end of file diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/MessageServiceImpl.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/MessageServiceImpl.java index f7fca496..83b31044 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/MessageServiceImpl.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/MessageServiceImpl.java @@ -16,7 +16,6 @@ package top.charles7c.cnadmin.system.service.impl; -import java.util.Collections; import java.util.List; import lombok.RequiredArgsConstructor; @@ -27,13 +26,14 @@ import org.springframework.transaction.annotation.Transactional; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.metadata.IPage; +import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; +import cn.hutool.extra.spring.SpringUtil; -import top.charles7c.cnadmin.common.base.BaseServiceImpl; import top.charles7c.cnadmin.common.model.query.PageQuery; -import top.charles7c.cnadmin.common.model.query.SortQuery; import top.charles7c.cnadmin.common.model.vo.PageDataVO; -import top.charles7c.cnadmin.common.util.helper.LoginHelper; +import top.charles7c.cnadmin.common.service.CommonUserService; +import top.charles7c.cnadmin.common.util.ExceptionUtils; import top.charles7c.cnadmin.common.util.helper.QueryHelper; import top.charles7c.cnadmin.common.util.validate.CheckUtils; import top.charles7c.cnadmin.system.mapper.MessageMapper; @@ -52,57 +52,48 @@ import top.charles7c.cnadmin.system.service.MessageUserService; */ @Service @RequiredArgsConstructor -public class MessageServiceImpl - extends BaseServiceImpl - implements MessageService { +public class MessageServiceImpl implements MessageService { + private final MessageMapper baseMapper; private final MessageUserService messageUserService; @Override public PageDataVO page(MessageQuery query, PageQuery pageQuery) { QueryWrapper queryWrapper = QueryHelper.build(query); - queryWrapper.apply(null != query.getUid(), "msgUser.user_id={0}", query.getUid()) - .apply(null != query.getReadStatus(), "msgUser.read_status={0}", query.getReadStatus()); + queryWrapper.apply(null != query.getUserId(), "t2.user_id={0}", query.getUserId()) + .apply(null != query.getIsRead(), "t2.is_read={0}", query.getIsRead()); IPage page = baseMapper.selectVoPage(pageQuery.toPage(), queryWrapper); page.getRecords().forEach(this::fill); return PageDataVO.build(page); } - @Override - public List list(MessageQuery query, SortQuery sortQuery) { - QueryWrapper queryWrapper = QueryHelper.build(query); - queryWrapper.apply("msgUser.user_id={0}", LoginHelper.getUserId()).apply(null != query.getReadStatus(), - "msgUser.read_status={0}", query.getReadStatus()); - // 设置排序 - this.sort(queryWrapper, sortQuery); - return baseMapper.selectVoList(queryWrapper); - } - - @Override - public MessageVO get(Long id) { - MessageQuery messageQuery = new MessageQuery(); - messageQuery.setId(id); - PageDataVO page = this.page(messageQuery, new PageQuery()); - List messageVOList = page.getList(); - if (CollUtil.isEmpty(messageVOList)) { - return new MessageVO(); - } - MessageVO messageVO = messageVOList.get(0); - messageUserService.readMessage(Collections.singletonList(messageVO.getId())); - return messageVO; - } - @Override public void add(MessageRequest request, List userIdList) { CheckUtils.throwIf(() -> CollUtil.isEmpty(userIdList), "消息接收人不能为空"); - Long messageId = super.add(request); - messageUserService.add(messageId, userIdList); + MessageDO message = BeanUtil.copyProperties(request, MessageDO.class); + baseMapper.insert(message); + messageUserService.add(message.getId(), userIdList); } @Override @Transactional(rollbackFor = Exception.class) public void delete(List ids) { - super.delete(ids); - messageUserService.delete(ids); + baseMapper.deleteBatchIds(ids); + messageUserService.deleteByMessageIds(ids); + } + + /** + * 填充数据 + * + * @param message + * 待填充信息 + */ + private void fill(MessageVO message) { + Long createUser = message.getCreateUser(); + if (null == createUser) { + return; + } + CommonUserService userService = SpringUtil.getBean(CommonUserService.class); + message.setCreateUserString(ExceptionUtils.exToNull(() -> userService.getNicknameById(createUser))); } } \ No newline at end of file diff --git a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/MessageUserServiceImpl.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/MessageUserServiceImpl.java index 90d90edc..870ebae2 100644 --- a/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/MessageUserServiceImpl.java +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/MessageUserServiceImpl.java @@ -17,6 +17,7 @@ package top.charles7c.cnadmin.system.service.impl; import java.time.LocalDateTime; +import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -24,13 +25,14 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; -import com.baomidou.mybatisplus.core.toolkit.Wrappers; - import cn.hutool.core.collection.CollUtil; +import top.charles7c.cnadmin.common.enums.MessageTypeEnum; import top.charles7c.cnadmin.common.util.validate.CheckUtils; import top.charles7c.cnadmin.system.mapper.MessageUserMapper; import top.charles7c.cnadmin.system.model.entity.MessageUserDO; +import top.charles7c.cnadmin.system.model.vo.MessageTypeUnreadVO; +import top.charles7c.cnadmin.system.model.vo.MessageUnreadVO; import top.charles7c.cnadmin.system.service.MessageUserService; /** @@ -43,32 +45,52 @@ import top.charles7c.cnadmin.system.service.MessageUserService; @RequiredArgsConstructor public class MessageUserServiceImpl implements MessageUserService { - private final MessageUserMapper messageUserMapper; + private final MessageUserMapper baseMapper; + + @Override + public MessageUnreadVO countUnreadMessageByUserId(Long userId, Boolean isDetail) { + MessageUnreadVO result = new MessageUnreadVO(); + Long total = 0L; + if (Boolean.TRUE.equals(isDetail)) { + List detailList = new ArrayList<>(); + for (MessageTypeEnum messageType : MessageTypeEnum.values()) { + MessageTypeUnreadVO vo = new MessageTypeUnreadVO(); + vo.setType(messageType); + Long count = baseMapper.selectUnreadCountByUserIdAndType(userId, messageType.getValue()); + vo.setCount(count); + detailList.add(vo); + total += count; + } + result.setDetails(detailList); + } else { + total = baseMapper.selectUnreadCountByUserIdAndType(userId, null); + } + result.setTotal(total); + return result; + } @Override public void add(Long messageId, List userIdList) { - CheckUtils.throwIf(() -> CollUtil.isEmpty(userIdList), "消息接收人不能为空"); - List messageUserDOList = userIdList.stream().map(userId -> { - MessageUserDO messageUserDO = new MessageUserDO(); - messageUserDO.setUserId(userId); - messageUserDO.setMessageId(messageId); - messageUserDO.setReadStatus(false); - return messageUserDO; + CheckUtils.throwIfEmpty(userIdList, "消息接收人不能为空"); + List messageUserList = userIdList.stream().map(userId -> { + MessageUserDO messageUser = new MessageUserDO(); + messageUser.setUserId(userId); + messageUser.setMessageId(messageId); + messageUser.setIsRead(false); + return messageUser; }).collect(Collectors.toList()); - messageUserMapper.insertBatch(messageUserDOList); + baseMapper.insertBatch(messageUserList); } @Override public void readMessage(List ids) { - messageUserMapper.lambdaUpdate().set(MessageUserDO::getReadStatus, true) - .set(MessageUserDO::getReadTime, LocalDateTime.now()).eq(MessageUserDO::getReadStatus, false) + baseMapper.lambdaUpdate().set(MessageUserDO::getIsRead, true) + .set(MessageUserDO::getReadTime, LocalDateTime.now()).eq(MessageUserDO::getIsRead, false) .in(CollUtil.isNotEmpty(ids), MessageUserDO::getMessageId, ids).update(); } @Override - public void delete(List ids) { - if (CollUtil.isNotEmpty(ids)) { - messageUserMapper.delete(Wrappers.lambdaQuery().in(MessageUserDO::getMessageId, ids)); - } + public void deleteByMessageIds(List messageIds) { + baseMapper.lambdaUpdate().in(MessageUserDO::getMessageId, messageIds).remove(); } } \ No newline at end of file diff --git a/continew-admin-system/src/main/resources/mapper/MessageMapper.xml b/continew-admin-system/src/main/resources/mapper/MessageMapper.xml index e10ba359..76b96b0b 100644 --- a/continew-admin-system/src/main/resources/mapper/MessageMapper.xml +++ b/continew-admin-system/src/main/resources/mapper/MessageMapper.xml @@ -2,31 +2,13 @@ "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > - diff --git a/continew-admin-system/src/main/resources/mapper/MessageUserMapper.xml b/continew-admin-system/src/main/resources/mapper/MessageUserMapper.xml new file mode 100644 index 00000000..75c22de6 --- /dev/null +++ b/continew-admin-system/src/main/resources/mapper/MessageUserMapper.xml @@ -0,0 +1,14 @@ + + + + + \ No newline at end of file diff --git a/continew-admin-ui/src/api/system/message.ts b/continew-admin-ui/src/api/system/message.ts index 8fd22bbd..352a59fd 100644 --- a/continew-admin-ui/src/api/system/message.ts +++ b/continew-admin-ui/src/api/system/message.ts @@ -3,45 +3,33 @@ import qs from 'query-string'; const BASE_URL = '/system/message'; -export interface MessageRecord { +export interface DataRecord { id: number; title: string; content: string; - type: string; - createUserString: string; + type: number; + createUserString?: string; createTime: string; - subTitle: string; - readStatus: boolean; + isRead: boolean; readTime: string; } -export interface ChatRecord { - id: number; - username: string; - content: string; - time: string; - isCollect: boolean; -} - export interface ListParam { title?: string; - readStatus?: 0 | 1; - type?: string; + type?: number; + isRead?: boolean; page?: number; size?: number; - uid?: number; sort?: Array; } -export interface PageRes { - list: MessageRecord[]; +export interface ListRes { + list: DataRecord[]; total: number; } -export type MessageListType = MessageRecord[]; - -export function page(params?: ListParam) { - return axios.get(`${BASE_URL}`, { +export function list(params: ListParam) { + return axios.get(`${BASE_URL}`, { params, paramsSerializer: (obj) => { return qs.stringify(obj); @@ -49,27 +37,24 @@ export function page(params?: ListParam) { }); } -export function list(params?: ListParam) { - return axios.get(`${BASE_URL}/list`, { - params, - paramsSerializer: (obj) => { - return qs.stringify(obj); - }, - }); -} - -export function get(id: number) { - return axios.get(`${BASE_URL}/${id}`); -} - export function del(ids: number | Array) { return axios.delete(`${BASE_URL}/${ids}`); } -export function read(data: Array) { - return axios.patch(`${BASE_URL}/read?ids=${data}`); +export function read(ids: Array) { + return axios.patch(`${BASE_URL}/read?ids=${ids}`); } -export function queryChatList() { - return axios.get('/api/chat/list'); +export interface MessageTypeUnreadRes { + type: number; + count: number; +} + +export interface MessageUnreadRes { + total: number; + details: MessageTypeUnreadRes[]; +} + +export function countUnread(detail: boolean) { + return axios.get(`${BASE_URL}/unread?detail=${detail}`); } diff --git a/continew-admin-ui/src/components/message-box/index.vue b/continew-admin-ui/src/components/message-box/index.vue index f4c36278..ead9ac04 100644 --- a/continew-admin-ui/src/components/message-box/index.vue +++ b/continew-admin-ui/src/components/message-box/index.vue @@ -1,56 +1,68 @@ + diff --git a/continew-admin-webapi/src/main/java/top/charles7c/cnadmin/webapi/controller/system/MessageController.java b/continew-admin-webapi/src/main/java/top/charles7c/cnadmin/webapi/controller/system/MessageController.java index 0daff216..ee31ab88 100644 --- a/continew-admin-webapi/src/main/java/top/charles7c/cnadmin/webapi/controller/system/MessageController.java +++ b/continew-admin-webapi/src/main/java/top/charles7c/cnadmin/webapi/controller/system/MessageController.java @@ -16,8 +16,6 @@ package top.charles7c.cnadmin.webapi.controller.system; -import static top.charles7c.cnadmin.common.annotation.CrudRequestMapping.Api; - import java.util.List; import lombok.RequiredArgsConstructor; @@ -27,14 +25,16 @@ import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.enums.ParameterIn; import io.swagger.v3.oas.annotations.tags.Tag; -import org.springframework.web.bind.annotation.PatchMapping; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; -import top.charles7c.cnadmin.common.annotation.CrudRequestMapping; -import top.charles7c.cnadmin.common.base.BaseController; +import top.charles7c.cnadmin.common.model.query.PageQuery; +import top.charles7c.cnadmin.common.model.vo.PageDataVO; +import top.charles7c.cnadmin.common.model.vo.R; +import top.charles7c.cnadmin.common.util.helper.LoginHelper; +import top.charles7c.cnadmin.monitor.annotation.Log; import top.charles7c.cnadmin.system.model.query.MessageQuery; -import top.charles7c.cnadmin.system.model.request.MessageRequest; +import top.charles7c.cnadmin.system.model.vo.MessageUnreadVO; import top.charles7c.cnadmin.system.model.vo.MessageVO; import top.charles7c.cnadmin.system.service.MessageService; import top.charles7c.cnadmin.system.service.MessageUserService; @@ -48,16 +48,39 @@ import top.charles7c.cnadmin.system.service.MessageUserService; @Tag(name = "消息管理 API") @RestController @RequiredArgsConstructor -@CrudRequestMapping(value = "/system/message", api = {Api.PAGE, Api.GET, Api.DELETE, Api.LIST}) -public class MessageController - extends BaseController { +@RequestMapping("/system/message") +public class MessageController { + private final MessageService baseService; private final MessageUserService messageUserService; + @Operation(summary = "分页查询列表", description = "分页查询列表") + @GetMapping + public PageDataVO page(MessageQuery query, @Validated PageQuery pageQuery) { + query.setUserId(LoginHelper.getUserId()); + return baseService.page(query, pageQuery); + } + + @Operation(summary = "删除数据", description = "删除数据") + @Parameter(name = "ids", description = "ID 列表", example = "1,2", in = ParameterIn.PATH) + @DeleteMapping("/{ids}") + public R delete(@PathVariable List ids) { + baseService.delete(ids); + return R.ok("删除成功"); + } + @Operation(description = "标记已读", summary = "将消息标记为已读状态") @Parameter(name = "ids", description = "消息ID列表", example = "1,2", in = ParameterIn.QUERY) @PatchMapping("/read") public void readMessage(@RequestParam(required = false) List ids) { messageUserService.readMessage(ids); } + + @Log(ignore = true) + @Operation(description = "查询未读消息数量", summary = "查询当前用户的未读消息数量") + @Parameter(name = "isDetail", description = "是否查询详情", example = "true", in = ParameterIn.QUERY) + @GetMapping("/unread") + public MessageUnreadVO countUnreadMessage(@RequestParam(required = false) Boolean detail) { + return messageUserService.countUnreadMessageByUserId(LoginHelper.getUserId(), detail); + } } \ No newline at end of file diff --git a/continew-admin-webapi/src/main/resources/db/changelog/v1.3.0/continew-admin_data.sql b/continew-admin-webapi/src/main/resources/db/changelog/v1.3.0/continew-admin_data.sql index 365808a1..a109ed7a 100644 --- a/continew-admin-webapi/src/main/resources/db/changelog/v1.3.0/continew-admin_data.sql +++ b/continew-admin-webapi/src/main/resources/db/changelog/v1.3.0/continew-admin_data.sql @@ -7,14 +7,3 @@ INSERT IGNORE INTO `sys_menu` 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 -(3, '系统消息', '1', 'blue', 1, NULL, 2, 1, NOW(), NULL, NULL); diff --git a/continew-admin-webapi/src/main/resources/db/changelog/v1.3.0/continew-admin_table.sql b/continew-admin-webapi/src/main/resources/db/changelog/v1.3.0/continew-admin_table.sql index 84d6693c..23d91a7d 100644 --- a/continew-admin-webapi/src/main/resources/db/changelog/v1.3.0/continew-admin_table.sql +++ b/continew-admin-webapi/src/main/resources/db/changelog/v1.3.0/continew-admin_table.sql @@ -13,19 +13,19 @@ CREATE TABLE IF NOT EXISTS `sys_user_social` ( -- changeset BUSS_BCLS:2 CREATE TABLE IF NOT EXISTS `sys_message` ( - `id` bigint(20) AUTO_INCREMENT COMMENT 'ID', - `title` varchar(50) NOT NULL COMMENT '主题', - `content` varchar(255) DEFAULT NULL COMMENT '内容', - `type` varchar(30) NOT NULL COMMENT '类型', - `create_user` bigint(20) DEFAULT NULL COMMENT '创建人', - `create_time` datetime NOT NULL COMMENT '创建时间', + `id` bigint(20) AUTO_INCREMENT COMMENT 'ID', + `title` varchar(50) NOT NULL COMMENT '标题', + `content` varchar(255) DEFAULT NULL COMMENT '内容', + `type` tinyint(1) UNSIGNED NOT NULL DEFAULT 1 COMMENT '类型(1:系统消息)', + `create_user` bigint(20) DEFAULT NULL COMMENT '创建人', + `create_time` datetime NOT NULL COMMENT '创建时间', PRIMARY KEY (`id`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='消息表'; CREATE TABLE IF NOT EXISTS `sys_message_user` ( - `message_id` bigint(20) NOT NULL COMMENT '消息ID', - `user_id` bigint(11) NOT NULL COMMENT '用户ID', - `read_status` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否已读', - `read_time` datetime DEFAULT NULL COMMENT '读取时间', + `message_id` bigint(20) NOT NULL COMMENT '消息ID', + `user_id` bigint(11) NOT NULL COMMENT '用户ID', + `is_read` bit(1) NOT NULL DEFAULT b'0' COMMENT '是否已读', + `read_time` datetime DEFAULT NULL COMMENT '读取时间', PRIMARY KEY (`message_id`,`user_id`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='消息和用户关联表'; \ No newline at end of file