diff --git a/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/base/BaseServiceImpl.java b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/base/BaseServiceImpl.java index 1d71956a..dcd8f3af 100644 --- a/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/base/BaseServiceImpl.java +++ b/continew-admin-common/src/main/java/top/charles7c/cnadmin/common/base/BaseServiceImpl.java @@ -149,14 +149,26 @@ public abstract class BaseServiceImpl, T extends BaseDO, protected List list(Q query, SortQuery sortQuery, Class targetClass) { QueryWrapper queryWrapper = QueryHelper.build(query); // 设置排序 + this.sort(queryWrapper, sortQuery); + List entityList = baseMapper.selectList(queryWrapper); + return BeanUtil.copyToList(entityList, targetClass); + } + + /** + * 设置排序 + * + * @param queryWrapper + * 查询 Wrapper + * @param sortQuery + * 排序查询条件 + */ + protected void sort(QueryWrapper queryWrapper, SortQuery sortQuery) { Sort sort = Opt.ofNullable(sortQuery).orElseGet(SortQuery::new).getSort(); for (Sort.Order order : sort) { if (null != order) { queryWrapper.orderBy(true, order.isAscending(), StrUtil.toUnderlineCase(order.getProperty())); } } - List entityList = baseMapper.selectList(queryWrapper); - return BeanUtil.copyToList(entityList, targetClass); } @Override 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 704ec355..8fcb324e 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,4 +67,9 @@ 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-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 22fcf8a4..3f2443f0 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,6 +28,7 @@ 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; @@ -38,6 +39,7 @@ import top.charles7c.cnadmin.auth.model.vo.RouteVO; import top.charles7c.cnadmin.auth.service.LoginService; import top.charles7c.cnadmin.auth.service.PermissionService; import top.charles7c.cnadmin.common.annotation.TreeField; +import top.charles7c.cnadmin.common.config.properties.ProjectProperties; import top.charles7c.cnadmin.common.constant.RegexConsts; import top.charles7c.cnadmin.common.constant.SysConsts; import top.charles7c.cnadmin.common.enums.DisEnableStatusEnum; @@ -48,9 +50,11 @@ import top.charles7c.cnadmin.common.util.SecureUtils; import top.charles7c.cnadmin.common.util.TreeUtils; import top.charles7c.cnadmin.common.util.helper.LoginHelper; import top.charles7c.cnadmin.common.util.validate.CheckUtils; +import top.charles7c.cnadmin.system.enums.MessageTemplateEnum; import top.charles7c.cnadmin.system.model.entity.RoleDO; import top.charles7c.cnadmin.system.model.entity.UserDO; import top.charles7c.cnadmin.system.model.entity.UserSocialDO; +import top.charles7c.cnadmin.system.model.request.MessageRequest; import top.charles7c.cnadmin.system.model.vo.DeptDetailVO; import top.charles7c.cnadmin.system.model.vo.MenuVO; import top.charles7c.cnadmin.system.service.*; @@ -74,6 +78,8 @@ public class LoginServiceImpl implements LoginService { private final PermissionService permissionService; private final UserRoleService userRoleService; private final UserSocialService userSocialService; + private final MessageService messageService; + private final ProjectProperties projectProperties; @Override public String accountLogin(String username, String password) { @@ -131,6 +137,7 @@ public class LoginServiceImpl implements LoginService { userSocial.setUserId(userId); userSocial.setSource(source); userSocial.setOpenId(openId); + this.sendMsg(user); } else { user = BeanUtil.toBean(userService.get(userSocial.getUserId()), UserDO.class); } @@ -180,7 +187,7 @@ public class LoginServiceImpl implements LoginService { /** * 登录并缓存用户信息 - * + * * @param user * 用户信息 * @return 令牌 @@ -205,4 +212,22 @@ public class LoginServiceImpl implements LoginService { DeptDetailVO deptDetailVO = deptService.get(user.getDeptId()); CheckUtils.throwIfEqual(DisEnableStatusEnum.DISABLE, deptDetailVO.getStatus(), "此账号所属部门已被禁用,如有疑问,请联系管理员"); } + + /** + * 发送消息 + * + * @param user + * 用户信息 + */ + private void sendMsg(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); + 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 new file mode 100644 index 00000000..067934fb --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/enums/MessageTemplateEnum.java @@ -0,0 +1,39 @@ +/* + * 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.enums; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +/** + * 消息模板枚举 + * + * @author BULL_BCLS + * @since 2023/10/15 19:51 + */ +@Getter +@RequiredArgsConstructor +public enum MessageTemplateEnum { + + /** + * 第三方登录 + */ + SOCIAL_REGISTER("欢迎注册 {projectName}", "尊敬的 {nickname},欢迎注册使用,请及时配置您的密码。"); + + 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 new file mode 100644 index 00000000..f1b7bb09 --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/mapper/MessageMapper.java @@ -0,0 +1,58 @@ +/* + * 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.mapper; + +import java.util.List; + +import org.apache.ibatis.annotations.Param; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.core.metadata.IPage; +import com.baomidou.mybatisplus.core.toolkit.Constants; + +import top.charles7c.cnadmin.common.base.BaseMapper; +import top.charles7c.cnadmin.system.model.entity.MessageDO; +import top.charles7c.cnadmin.system.model.vo.MessageVO; + +/** + * 消息 Mapper + * + * @author BULL_BCLS + * @since 2023/10/15 19:05 + */ +public interface MessageMapper extends BaseMapper { + /** + * 分页查询列表 + * + * @param queryWrapper + * 查询条件 + * @param page + * 分页查询条件 + * @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 new file mode 100644 index 00000000..73663fc1 --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/mapper/MessageUserMapper.java @@ -0,0 +1,28 @@ +/* + * 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.mapper; + +import top.charles7c.cnadmin.common.base.BaseMapper; +import top.charles7c.cnadmin.system.model.entity.MessageUserDO; + +/** + * 消息和用户关联 Mapper + * + * @author BULL_BCLS + * @since 2023/10/15 20:25 + */ +public interface MessageUserMapper extends BaseMapper {} \ 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 new file mode 100644 index 00000000..c38bb0d7 --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/MessageDO.java @@ -0,0 +1,56 @@ +/* + * 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.entity; + +import lombok.Data; + +import com.baomidou.mybatisplus.annotation.TableName; + +import top.charles7c.cnadmin.common.base.BaseDO; + +/** + * 消息实体 + * + * @author BULL_BCLS + * @since 2023/10/15 19:05 + */ +@Data +@TableName("sys_message") +public class MessageDO extends BaseDO { + + private static final long serialVersionUID = 1L; + + /** + * 消息ID + */ + private Long id; + + /** + * 主题 + */ + private String title; + + /** + * 内容 + */ + private String content; + + /** + * 类型(取值于字典 message_type) + */ + private String type; +} \ 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 new file mode 100644 index 00000000..ab960d64 --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/entity/MessageUserDO.java @@ -0,0 +1,58 @@ +/* + * 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.entity; + +import java.time.LocalDateTime; + +import lombok.Data; + +import com.baomidou.mybatisplus.annotation.TableName; + +import top.charles7c.cnadmin.common.base.BaseDO; + +/** + * 消息和用户关联实体 + * + * @author BULL_BCLS + * @since 2023/10/15 20:25 + */ +@Data +@TableName("sys_message_user") +public class MessageUserDO extends BaseDO { + + private static final long serialVersionUID = 1L; + + /** + * 消息ID + */ + private Long messageId; + + /** + * 用户ID + */ + private Long userId; + + /** + * 读取状态 (0未读 1已读) + */ + private Boolean readStatus; + + /** + * 读取时间 + */ + private LocalDateTime readTime; +} \ No newline at end of file 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 new file mode 100644 index 00000000..c8f27879 --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/query/MessageQuery.java @@ -0,0 +1,72 @@ +/* + * 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.query; + +import java.io.Serializable; + +import lombok.Data; + +import io.swagger.v3.oas.annotations.media.Schema; + +import top.charles7c.cnadmin.common.annotation.Query; +import top.charles7c.cnadmin.common.enums.QueryTypeEnum; + +/** + * 消息查询条件 + * + * @author BULL_BCLS + * @since 2023/10/15 19:05 + */ +@Data +@Schema(description = "消息查询条件") +public class MessageQuery implements Serializable { + + private static final long serialVersionUID = 1L; + + /** + * ID + */ + @Schema(description = "ID", example = "1") + @Query(type = QueryTypeEnum.EQUAL) + private Long id; + + /** + * 类型(取值于字典 message_type) + */ + @Schema(description = "类型(取值于字典 message_type)", example = "1") + @Query(type = QueryTypeEnum.EQUAL) + private String type; + + /** + * 主题 + */ + @Schema(description = "主题", example = "欢迎 xxx") + @Query(type = QueryTypeEnum.INNER_LIKE) + private String title; + + /** + * 用户ID + */ + @Schema(description = "用户ID", example = "1") + private Long uid; + + /** + * 是否已读 + */ + @Schema(description = "是否已读", example = "true") + private Boolean readStatus; +} \ 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 new file mode 100644 index 00000000..7b681ed3 --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/request/MessageRequest.java @@ -0,0 +1,72 @@ +/* + * 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.request; + +import java.util.Map; + +import javax.validation.constraints.NotBlank; + +import lombok.Data; + +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; + +/** + * 创建消息信息 + * + * @author BULL_BCLS + * @since 2023/10/15 19:05 + */ +@Schema(description = "创建消息信息") +@Data +public class MessageRequest extends BaseRequest { + + private static final long serialVersionUID = 1L; + + /** + * 主题 + */ + @Schema(description = "主题", example = "欢迎 xxx") + @NotBlank(message = "主题不能为空") + @Length(max = 50, message = "主题长度不能超过 {max} 个字符") + private String title; + + /** + * 内容 + */ + @Schema(description = "内容", example = "欢迎 xxx 来到 ContiNew Admin") + @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); + } +} \ 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/MessageUserVO.java new file mode 100644 index 00000000..6b28c682 --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/MessageUserVO.java @@ -0,0 +1,62 @@ +/* + * 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.time.LocalDateTime; + +import lombok.Data; + +import io.swagger.v3.oas.annotations.media.Schema; + +import top.charles7c.cnadmin.common.base.BaseVO; + +/** + * 消息和用户关联信息 + * + * @author BULL_BCLS + * @since 2023/10/15 20:25 + */ +@Data +@Schema(description = "消息和用户关联信息") +public class MessageUserVO extends BaseVO { + + private static final long serialVersionUID = 1L; + + /** + * 消息ID + */ + @Schema(description = "消息ID", example = "1") + private Long messageId; + + /** + * 用户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; +} \ 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 new file mode 100644 index 00000000..9357c252 --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/model/vo/MessageVO.java @@ -0,0 +1,74 @@ +/* + * 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.time.LocalDateTime; + +import lombok.Data; + +import io.swagger.v3.oas.annotations.media.Schema; + +import top.charles7c.cnadmin.common.base.BaseVO; + +/** + * 消息信息 + * + * @author BULL_BCLS + * @since 2023/10/15 19:05 + */ +@Data +@Schema(description = "消息信息") +public class MessageVO extends BaseVO { + + private static final long serialVersionUID = 1L; + + /** + * 消息ID + */ + @Schema(description = "消息ID", example = "1") + private Long id; + + /** + * 主题 + */ + @Schema(description = "主题", example = "欢迎 xxx") + private String title; + + /** + * 内容 + */ + @Schema(description = "内容", example = "欢迎 xxx") + private String content; + + /** + * 类型(取值于字典 message_type) + */ + @Schema(description = "类型(取值于字典 message_type)", example = "1") + private String type; + + /** + * 是否已读 + */ + @Schema(description = "是否已读", example = "true") + private Boolean readStatus; + + /** + * 读取时间 + */ + @Schema(description = "读取时间", example = "2023-08-08 23:59:59", type = "string") + private LocalDateTime readTime; +} \ 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 new file mode 100644 index 00000000..f7f23c47 --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/MessageService.java @@ -0,0 +1,43 @@ +/* + * 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.service; + +import java.util.List; + +import top.charles7c.cnadmin.common.base.BaseService; +import top.charles7c.cnadmin.system.model.query.MessageQuery; +import top.charles7c.cnadmin.system.model.request.MessageRequest; +import top.charles7c.cnadmin.system.model.vo.MessageVO; + +/** + * 消息业务接口 + * + * @author BULL_BCLS + * @since 2023/10/15 19:05 + */ +public interface MessageService extends BaseService { + + /** + * 发送消息 + * + * @param request + * 消息 + * @param userIdList + * 接收人 + */ + void add(MessageRequest request, List userIdList); +} \ 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 new file mode 100644 index 00000000..a1fa5f94 --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/MessageUserService.java @@ -0,0 +1,54 @@ +/* + * 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.service; + +import java.util.List; + +/** + * 消息和用户关联业务接口 + * + * @author BULL_BCLS + * @since 2023/10/15 19:05 + */ +public interface MessageUserService { + + /** + * 发送消息 + * + * @param messageId + * 消息ID + * @param userIdList + * 接收人 + */ + void add(Long messageId, List userIdList); + + /** + * 将消息标记已读 + * + * @param ids + * 消息ID(为空则将所有消息标记已读) + */ + void readMessage(List ids); + + /** + * 删除消息 + * + * @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/impl/MessageServiceImpl.java b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/MessageServiceImpl.java new file mode 100644 index 00000000..50eb66c1 --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/MessageServiceImpl.java @@ -0,0 +1,108 @@ +/* + * 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.service.impl; + +import java.util.Collections; +import java.util.List; + +import lombok.RequiredArgsConstructor; + +import org.springframework.stereotype.Service; +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.collection.CollUtil; + +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.util.helper.QueryHelper; +import top.charles7c.cnadmin.common.util.validate.CheckUtils; +import top.charles7c.cnadmin.system.mapper.MessageMapper; +import top.charles7c.cnadmin.system.model.entity.MessageDO; +import top.charles7c.cnadmin.system.model.query.MessageQuery; +import top.charles7c.cnadmin.system.model.request.MessageRequest; +import top.charles7c.cnadmin.system.model.vo.MessageVO; +import top.charles7c.cnadmin.system.service.MessageService; +import top.charles7c.cnadmin.system.service.MessageUserService; + +/** + * 消息业务实现 + * + * @author BULL_BCLS + * @since 2023/10/15 19:05 + */ +@Service +@RequiredArgsConstructor +public class MessageServiceImpl + extends BaseServiceImpl + implements MessageService { + + 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()); + queryWrapper.apply(null != query.getReadStatus(), "msgUser.read_status={0}", query.getReadStatus()); + 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()); + queryWrapper.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); + } + + @Transactional(rollbackFor = Exception.class) + @Override + public void delete(List ids) { + super.delete(ids); + messageUserService.delete(ids); + } +} \ 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 new file mode 100644 index 00000000..90d90edc --- /dev/null +++ b/continew-admin-system/src/main/java/top/charles7c/cnadmin/system/service/impl/MessageUserServiceImpl.java @@ -0,0 +1,74 @@ +/* + * 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.service.impl; + +import java.time.LocalDateTime; +import java.util.List; +import java.util.stream.Collectors; + +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.util.validate.CheckUtils; +import top.charles7c.cnadmin.system.mapper.MessageUserMapper; +import top.charles7c.cnadmin.system.model.entity.MessageUserDO; +import top.charles7c.cnadmin.system.service.MessageUserService; + +/** + * 消息和用户关联业务实现 + * + * @author BULL_BCLS + * @since 2023/10/15 19:05 + */ +@Service +@RequiredArgsConstructor +public class MessageUserServiceImpl implements MessageUserService { + + private final MessageUserMapper messageUserMapper; + + @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; + }).collect(Collectors.toList()); + messageUserMapper.insertBatch(messageUserDOList); + } + + @Override + public void readMessage(List ids) { + messageUserMapper.lambdaUpdate().set(MessageUserDO::getReadStatus, true) + .set(MessageUserDO::getReadTime, LocalDateTime.now()).eq(MessageUserDO::getReadStatus, 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)); + } + } +} \ 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 new file mode 100644 index 00000000..e10ba359 --- /dev/null +++ b/continew-admin-system/src/main/resources/mapper/MessageMapper.xml @@ -0,0 +1,32 @@ + + + + + diff --git a/continew-admin-ui/src/api/system/message.ts b/continew-admin-ui/src/api/system/message.ts new file mode 100644 index 00000000..64ec5a94 --- /dev/null +++ b/continew-admin-ui/src/api/system/message.ts @@ -0,0 +1,76 @@ +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; +} + +export interface ChatRecord { + id: number; + username: string; + content: string; + time: string; + isCollect: boolean; +} + +export interface ListParam { + title?: string; + readStatus?: 0 | 1; + type?: string; + page?: number; + size?: number; + uid?:number + sort?: Array; +} + +export interface PageRes { + list: DataRecord[]; + total: number; +} + +export type MessageListType = MessageRecord[]; + +export function page(params?: ListParam) { + return axios.get(`${BASE_URL}`, { + params, + paramsSerializer: (obj) => { + return qs.stringify(obj); + }, + }); +} + +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 queryChatList() { + return axios.get('/api/chat/list'); +} diff --git a/continew-admin-ui/src/components/message-box/index.vue b/continew-admin-ui/src/components/message-box/index.vue index e3dbf27a..615ea5a3 100644 --- a/continew-admin-ui/src/components/message-box/index.vue +++ b/continew-admin-ui/src/components/message-box/index.vue @@ -1,9 +1,9 @@ diff --git a/continew-admin-ui/src/components/message-box/list.vue b/continew-admin-ui/src/components/message-box/list.vue index 4f2ff361..d9890d4a 100644 --- a/continew-admin-ui/src/components/message-box/list.vue +++ b/continew-admin-ui/src/components/message-box/list.vue @@ -5,15 +5,9 @@ :key="item.id" action-layout="vertical" :style="{ - opacity: item.status ? 0.5 : 1, + opacity: item.readStatus == 1 ? 0.5 : 1, }" > -
@@ -59,7 +50,7 @@ {{ $t('messageBox.allRead') }}
@@ -72,7 +63,10 @@ + + + + diff --git a/continew-admin-ui/src/views/system/message/locale/en-US.ts b/continew-admin-ui/src/views/system/message/locale/en-US.ts new file mode 100644 index 00000000..1af2926b --- /dev/null +++ b/continew-admin-ui/src/views/system/message/locale/en-US.ts @@ -0,0 +1,3 @@ +export default { + 'menu.system.message.list': 'Message management', +}; diff --git a/continew-admin-ui/src/views/system/message/locale/zh-CN.ts b/continew-admin-ui/src/views/system/message/locale/zh-CN.ts new file mode 100644 index 00000000..6e4fbd6e --- /dev/null +++ b/continew-admin-ui/src/views/system/message/locale/zh-CN.ts @@ -0,0 +1,3 @@ +export default { + 'menu.system.message.list': '消息管理', +}; 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 new file mode 100644 index 00000000..9770bc5e --- /dev/null +++ b/continew-admin-webapi/src/main/java/top/charles7c/cnadmin/webapi/controller/system/MessageController.java @@ -0,0 +1,63 @@ +/* + * 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.webapi.controller.system; + +import static top.charles7c.cnadmin.common.annotation.CrudRequestMapping.Api; + +import java.util.List; + +import lombok.RequiredArgsConstructor; + +import io.swagger.v3.oas.annotations.Operation; +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 top.charles7c.cnadmin.common.annotation.CrudRequestMapping; +import top.charles7c.cnadmin.common.base.BaseController; +import top.charles7c.cnadmin.system.model.query.MessageQuery; +import top.charles7c.cnadmin.system.model.request.MessageRequest; +import top.charles7c.cnadmin.system.model.vo.MessageVO; +import top.charles7c.cnadmin.system.service.MessageService; +import top.charles7c.cnadmin.system.service.MessageUserService; + +/** + * 消息管理 API + * + * @author BULL_BCLS + * @since 2023/10/15 19:05 + */ +@Tag(name = "消息管理 API") +@RestController +@RequiredArgsConstructor +@CrudRequestMapping(value = "/system/message", api = {Api.PAGE, Api.GET, Api.DELETE, Api.LIST}) +public class MessageController + extends BaseController { + + private final MessageUserService messageUserService; + + @Operation(description = "将消息标记已读", summary = "将消息标记已读") + @Parameter(name = "ids", description = "消息ID", example = "1,2", in = ParameterIn.PATH) + @PatchMapping("/read") + public void readMessage(@RequestParam(required = false) List ids) { + messageUserService.readMessage(ids); + } +} \ 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 874085b8..f7427e0f 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 @@ -1,2 +1,14 @@ -- liquibase formatted sql +-- changeset BUSS_BCLS:1 +-- 初始化默认字典 +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 8b24fb4e..84d6693c 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 @@ -9,4 +9,23 @@ CREATE TABLE IF NOT EXISTS `sys_user_social` ( `last_login_time` datetime DEFAULT NULL COMMENT '最后登录时间', `create_time` datetime NOT NULL COMMENT '创建时间', UNIQUE INDEX `uk_source_open_id`(`source`, `open_id`) USING BTREE -) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户社会化关联表'; \ No newline at end of file +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户社会化关联表'; + +-- 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 '创建时间', + 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 '读取时间', + PRIMARY KEY (`message_id`,`user_id`) USING BTREE +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='消息和用户关联表'; \ No newline at end of file