From 47f0dd437ac25b5c7af3f954ed15ed44385541bb Mon Sep 17 00:00:00 2001 From: zhuangtianxiang <2913129173@qq.com> Date: Sat, 16 Nov 2024 12:17:07 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=AC=E5=91=8A=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../zsc/edu/gateway/FirstTimeInitializer.java | 58 ++++++ .../zsc/edu/gateway/common/enums/IState.java | 36 ++++ .../notice/controller/BulletinController.java | 174 ++++++++++++++++++ .../controller/UserMessageController.java | 164 +++++++++++++++++ .../dto/BulletinAttachmentCreateDto.java | 17 ++ .../notice/dto/BulletinAttachmentDto.java | 18 ++ .../modules/notice/dto/BulletinDto.java | 44 +++++ .../modules/notice/dto/UserMessageDto.java | 65 +++++++ .../modules/notice/entity/Bulletin.java | 122 ++++++++++++ .../notice/entity/BulletinAttachment.java | 23 +++ .../modules/notice/entity/BulletinUser.java | 31 ++++ .../modules/notice/entity/Message.java | 65 +++++++ .../modules/notice/entity/MessagePayload.java | 39 ++++ .../modules/notice/entity/MessageSetting.java | 53 ++++++ .../modules/notice/entity/MessageType.java | 11 ++ .../modules/notice/entity/UserMessage.java | 48 +++++ .../mapper/BulletinAttachmentMapper.java | 15 ++ .../modules/notice/mapper/BulletinMapper.java | 14 ++ .../notice/mapper/BulletinUserMapper.java | 11 ++ .../modules/notice/query/BulletinQuery.java | 55 ++++++ .../modules/notice/query/MessageQuery.java | 26 +++ .../notice/query/UserMessageQuery.java | 75 ++++++++ .../repo/BulletinAttachmentRepository.java | 8 + .../notice/repo/BulletinRepository.java | 20 ++ .../notice/repo/BulletinUserRepository.java | 19 ++ .../notice/repo/MessageRepository.java | 14 ++ .../notice/repo/MessageSettingRepository.java | 14 ++ .../notice/repo/UserMessageRepository.java | 13 ++ .../service/BulletinAttachmentService.java | 12 ++ .../notice/service/BulletinService.java | 33 ++++ .../notice/service/BulletinUserService.java | 16 ++ .../notice/service/UserMessageService.java | 15 ++ .../impl/BulletinAttachmentServiceImpl.java | 18 ++ .../service/impl/BulletinServiceImpl.java | 165 +++++++++++++++++ .../service/impl/BulletinUserServiceImpl.java | 52 ++++++ .../service/impl/UserMessageServiceImpl.java | 168 +++++++++++++++++ .../mappers/noticeMappers/BulletinMapper.xml | 45 +++++ .../edu/gateway/domain/BulletinBuilder.java | 35 ++++ .../gateway/service/BulletinServiceTest.java | 89 +++++++++ 39 files changed, 1900 insertions(+) create mode 100644 src/main/java/com/zsc/edu/gateway/FirstTimeInitializer.java create mode 100644 src/main/java/com/zsc/edu/gateway/common/enums/IState.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/controller/BulletinController.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/controller/UserMessageController.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/dto/BulletinAttachmentCreateDto.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/dto/BulletinAttachmentDto.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/dto/BulletinDto.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/dto/UserMessageDto.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/entity/Bulletin.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/entity/BulletinAttachment.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/entity/BulletinUser.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/entity/Message.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/entity/MessagePayload.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/entity/MessageSetting.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/entity/MessageType.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/entity/UserMessage.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/mapper/BulletinAttachmentMapper.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/mapper/BulletinMapper.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/mapper/BulletinUserMapper.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/query/BulletinQuery.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/query/MessageQuery.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/query/UserMessageQuery.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/repo/BulletinAttachmentRepository.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/repo/BulletinRepository.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/repo/BulletinUserRepository.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/repo/MessageRepository.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/repo/MessageSettingRepository.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/repo/UserMessageRepository.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/service/BulletinAttachmentService.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/service/BulletinService.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/service/BulletinUserService.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/service/UserMessageService.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/service/impl/BulletinAttachmentServiceImpl.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/service/impl/BulletinServiceImpl.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/service/impl/BulletinUserServiceImpl.java create mode 100644 src/main/java/com/zsc/edu/gateway/modules/notice/service/impl/UserMessageServiceImpl.java create mode 100644 src/main/resources/mappers/noticeMappers/BulletinMapper.xml create mode 100644 src/test/java/com/zsc/edu/gateway/domain/BulletinBuilder.java create mode 100644 src/test/java/com/zsc/edu/gateway/service/BulletinServiceTest.java diff --git a/src/main/java/com/zsc/edu/gateway/FirstTimeInitializer.java b/src/main/java/com/zsc/edu/gateway/FirstTimeInitializer.java new file mode 100644 index 0000000..f23ae1e --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/FirstTimeInitializer.java @@ -0,0 +1,58 @@ +package com.zsc.edu.gateway; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.zsc.edu.gateway.modules.system.dto.RoleDto; +import com.zsc.edu.gateway.modules.system.entity.*; +import com.zsc.edu.gateway.modules.system.repo.DeptRepository; +import com.zsc.edu.gateway.modules.system.repo.RoleRepository; +import com.zsc.edu.gateway.modules.system.repo.UserRepository; +import com.zsc.edu.gateway.modules.system.repo.UserRolesRepository; +import com.zsc.edu.gateway.modules.system.service.RoleService; +import lombok.RequiredArgsConstructor; +import org.springframework.boot.CommandLineRunner; +import org.springframework.context.annotation.Profile; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Component; + +@RequiredArgsConstructor +@Component +@Profile("!test") +public class FirstTimeInitializer implements CommandLineRunner { + + private final DeptRepository deptRepo; + private final RoleRepository roleRepo; + private final RoleService roleService; + private final UserRolesRepository userRolesRepo; + private final UserRepository userRepo; + + private final PasswordEncoder passwordEncoder; + + + + @Override + public void run(String... args) throws Exception { + Dept dept1 = new Dept(); + Role role = new Role(); + if (deptRepo.selectCount(new QueryWrapper<>()) == 0) { + dept1.setName("管理部门"); + deptRepo.insert(dept1); + } + if (roleRepo.selectCount(new QueryWrapper<>()) == 0) { + RoleDto dto = new RoleDto(); + dto.setName("超级管理员"); +// dto.setAuthorities(new HashSet<>(Arrays.asList(Authority.values()))); + role = roleService.create(dto); + } + if (userRepo.selectCount(new QueryWrapper<>()) == 0) { + User user = new User(); + user.setUsername("管理员"); + user.setPassword(passwordEncoder.encode("123456")); + user.setEnableState(true); + user.setPhone("13827993921"); + user.setEmail("123@qq.com"); + user.setDeptId(dept1.getId()); + user.setRoleId(role.getId()); + userRepo.insert(user); + } + } +} diff --git a/src/main/java/com/zsc/edu/gateway/common/enums/IState.java b/src/main/java/com/zsc/edu/gateway/common/enums/IState.java new file mode 100644 index 0000000..7d63a58 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/common/enums/IState.java @@ -0,0 +1,36 @@ +package com.zsc.edu.gateway.common.enums; + + +import com.zsc.edu.gateway.exception.StateException; + +import java.util.EnumSet; + +/** + * @author harry_yao + */ +public interface IState> { + + /** + * 用于检查对象当前状态是否等于correctStatus + * + * @param correctState 正确状态 + */ + default void checkStatus(T correctState) { + if (this != correctState) { + throw new StateException(correctState.getClass(), this, correctState); + } + } + + /** + * 用于检查对象当前状态是否在集合correctStates中 + * + * @param correctStates 正确状态集合 + */ + @SuppressWarnings("SuspiciousMethodCalls") + default void checkStatus(EnumSet correctStates) { + if (!correctStates.contains(this)) { + throw new StateException(this.getClass(), this, correctStates); + } + } + +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/controller/BulletinController.java b/src/main/java/com/zsc/edu/gateway/modules/notice/controller/BulletinController.java new file mode 100644 index 0000000..c6b6a24 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/controller/BulletinController.java @@ -0,0 +1,174 @@ +package com.zsc.edu.gateway.modules.notice.controller; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.zsc.edu.gateway.framework.security.UserDetailsImpl; +import com.zsc.edu.gateway.modules.notice.dto.BulletinDto; +import com.zsc.edu.gateway.modules.notice.entity.Bulletin; +import com.zsc.edu.gateway.modules.notice.query.BulletinQuery; +import com.zsc.edu.gateway.modules.notice.service.BulletinService; +import com.zsc.edu.gateway.modules.notice.service.BulletinUserService; +import lombok.AllArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.*; + +import java.util.Set; + +/** + * 公告Controller + * + * @author harry_yao + */ +@AllArgsConstructor +@RestController +@RequestMapping("/api/rest/bulletin") +public class BulletinController { + + private final BulletinService service; + private final BulletinUserService bulletinUserService; + + /** + * 普通用户查看公告详情 + * + * @param id ID + * @return 公告 + */ + @GetMapping("/self/{id}") + public Bulletin selfDetail(@AuthenticationPrincipal UserDetailsImpl userDetails,@PathVariable("id") Long id) { + return service.detail(userDetails,id, Bulletin.State.publish); + } + + /** + * 普通用户分页查询公告 + * + * @param query 查询表单 + * @param page 分页参数 + * @return 分页数据 + */ + @GetMapping("/self") + public Page query(BulletinQuery query, Page page) { + query.state = Bulletin.State.publish; + return service.page(page,query.wrapper()); + } + /** + * 管理查询公告详情 + * + * @param id ID + * @return 公告 + */ + @GetMapping("/{id}") + @PreAuthorize("hasAuthority('BULLETIN_QUERY')") + public Bulletin detail(@AuthenticationPrincipal UserDetailsImpl userDetails,@PathVariable("id") Long id) { + return service.detail(userDetails,id, null); + } + + /** + * 管理员分页查询公告 + * + * @param query 查询参数 + * @param page 分页参数 + * @return 分页数据 + */ + @GetMapping + @PreAuthorize("hasAuthority('BULLETIN_QUERY')") + public Page page(BulletinQuery query, Page page) { + return service.page(page, query.wrapper()); + } + + /** + * 创建公告 + * + * @param userDetails 操作用户 + * @param dto 表单数据 + * @return 公告 + */ + @PostMapping + @PreAuthorize("hasAuthority('BULLETIN_CREATE')") + public Bulletin create(@AuthenticationPrincipal UserDetailsImpl userDetails, @RequestBody BulletinDto dto) { + return service.create(userDetails, dto); + } + + /** + * 更新公告,只能修改"编辑中"或"已发布"的公告,"已发布"的公告修改后会改为"编辑中" + * + * @param userDetails 操作用户 + * @param dto 表单数据 + * @param id ID + * @return 公告 + */ + @PatchMapping("/{id}") + @PreAuthorize("hasAuthority('BULLETIN_UPDATE')") + public Boolean update(@AuthenticationPrincipal UserDetailsImpl userDetails, @RequestBody BulletinDto dto, @PathVariable("id") Long id) { + return service.update(userDetails, dto, id); + } + + /** + * 切换公告置顶状态 + * + * @param id ID + * @return 公告 + */ + @PatchMapping("/{id}/toggle-top") + @PreAuthorize("hasAuthority('BULLETIN_UPDATE')") + public Boolean toggleTop(@PathVariable("id") Long id) { + return service.toggleTop(id); + } + + /** + * 发布公告,只能发布"编辑中"的公告 + * + * @param userDetails 操作用户 + * @param id ID + * @return 公告 + */ + @PatchMapping("/{id}/publish") + @PreAuthorize("hasAuthority('BULLETIN_PUBLISH')") + public Boolean publish(@AuthenticationPrincipal UserDetailsImpl userDetails,@PathVariable("id") Long id) { + return service.publish(userDetails, id); + } + + /** + * 关闭公告,只能关闭"已发布"的公告 + * + * @param userDetails 操作用户 + * @param id ID + * @return 公告 + */ + @PatchMapping("/{id}/close") + @PreAuthorize("hasAuthority('BULLETIN_CLOSE')") + public Boolean close(@AuthenticationPrincipal UserDetailsImpl userDetails, @PathVariable("id") Long id) { + return service.close(userDetails, id); + } + + /** + * 开启公告切换到”编辑中“ + * + * @param id id + * @return true + */ + @PatchMapping("/{id}/open") + @PreAuthorize("hasAuthority('BULLETIN_CLOSE')") + public Boolean open(@PathVariable("id") Long id){ + return service.open(id); + } + /** + * 删除公告,只能删除"编辑中"的公告 + * + * @param id ID + * @return 公 + */ + @DeleteMapping("/{id}") + @PreAuthorize("hasAuthority('BULLETIN_DELETE')") + public Boolean delete(@PathVariable("id") Long id) { + return service.removeById(id); + } + + /** + *为公告添加附件 + */ + @PostMapping("/{id}/add") + @PreAuthorize("hasAuthority('BULLETIN_CREATE')") + public Boolean insertInto(@PathVariable Long id,@RequestBody Set attachments){ + return service.insertInto(id, attachments); + } +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/controller/UserMessageController.java b/src/main/java/com/zsc/edu/gateway/modules/notice/controller/UserMessageController.java new file mode 100644 index 0000000..6c77bdd --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/controller/UserMessageController.java @@ -0,0 +1,164 @@ +//package com.zsc.edu.gateway.modules.notice.controller; +// +//import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +//import com.zsc.edu.gateway.framework.security.UserDetailsImpl; +//import com.zsc.edu.gateway.modules.notice.entity.MessageSetting; +//import com.zsc.edu.gateway.modules.notice.entity.UserMessage; +//import com.zsc.edu.gateway.modules.notice.query.MessageQuery; +//import com.zsc.edu.gateway.modules.notice.query.UserMessageQuery; +//import com.zsc.edu.gateway.modules.notice.service.UserMessageService; +//import lombok.AllArgsConstructor; +//import org.springframework.data.domain.Pageable; +//import org.springframework.data.domain.Sort; +//import org.springframework.data.web.PageableDefault; +//import org.springframework.security.access.prepost.PreAuthorize; +//import org.springframework.security.core.annotation.AuthenticationPrincipal; +//import org.springframework.web.bind.annotation.*; +// +//import java.util.List; +//import java.util.Set; +// +///** +// * 用户消息Controller +// * +// * @author harry_yao +// */ +//@AllArgsConstructor +//@RestController +//@RequestMapping("api/rest/message") +//public class UserMessageController { +// +// private final UserMessageService service; +// +// /** +// * 普通用户查看消息详情 +// * +// * @param userDetails 操作用户 +// * @param messageId 消息ID +// * @return 用户消息详情 +// */ +// @GetMapping("/self/{message-id}") +// public UserMessage selfDetail(@AuthenticationPrincipal UserDetailsImpl userDetails, @PathVariable("message-id") Long messageId) { +// UserMessage.Id id = new UserMessage.Id(userDetails.id, messageId); +// return service.detail(id); +// } +// +// /** +// * 普通用户分页查询消息,不能设置查询参数userId和username +// * +// * @param userDetails 操作用户 +// * @param query 查询参数 +// * @param page 分页参数 +// * @return 分页数据 +// */ +// @GetMapping("/self") +// public Page selfPage(@AuthenticationPrincipal UserDetailsImpl userDetails, UserMessageQuery query, Page page) { +// query.userId = userDetails.id; +// query.name = null; +// return service.page(page, query.wrapper()); +// } +// +// /** +// * 普通用户统计自己未读消息数量 +// * +// * @param userDetails 操作用户 +// * @return 数据 +// */ +// @GetMapping("/count-unread") +// public int countUnread( +// @AuthenticationPrincipal UserDetailsImpl userDetails) { +// return service.countUnread(userDetails); +// } +// +// /** +// * 普通用户确认消息已读,如果提交的已读消息ID集合为空,则将所有未读消息设为已读 +// * +// * @param userDetails 操作用户 +// * @param messageIds 已读消息ID集合 +// * @return 确认已读数量 +// */ +// @PatchMapping("/read") +// public int acknowledge( +// @AuthenticationPrincipal UserDetailsImpl userDetails, +// @RequestBody MessageQuery messageQuery +//// @RequestBody Set messageIds +// ) { +// return service.markAsRead(userDetails, messageQuery.getMessageIds()); +// } +// +// /** +// * 管理查询消息详情 +// * +// * @param userId 用户ID +// * @param messageId 消息ID +// * @return 用户消息详情 +// */ +// @GetMapping("/{user-id}/{message-id}") +// @PreAuthorize("hasAuthority('MESSAGE_QUERY')") +// public UserMessage detail( +// @PathVariable("user-id") Long userId, +// @PathVariable("message-id") Long messageId +// ) { +// UserMessage.Id id = new UserMessage.Id(userId, messageId); +// return service.detail(id); +// } +// +// /** +// * 管理员分页查询消息 +// * +// * @param query 查询参数 +// * @param pageable 分页参数 +// * @return 分页数据 +// */ +// @GetMapping +// @PreAuthorize("hasAuthority('MESSAGE_QUERY')") +// public Page page( +// UserMessageQuery query, +// @PageableDefault( +// sort = {"message.createAt"}, +// direction = Sort.Direction.DESC +// ) Pageable pageable +// ) { +// return service.page(query, pageable); +// } +// +// /** +// * 管理员手动创建消息 +// * +// * @param dto 表单数据 +// * @return 消息列表 +// */ +// @PostMapping +// @PreAuthorize("hasAuthority('MESSAGE_CREATE')") +// public boolean create( +// @RequestBody com.zsc.gateway.module.notice.dto.UserMessageDto dto +// ) { +// return service.createByAdmin(dto); +// } +// +// /** +// * 获取消息推送方式 +// * +// * @return 消息推送方式列表 +// */ +// @GetMapping("/setting") +// @PreAuthorize("hasAuthority('MESSAGE_SETTING')") +// public List getSetting() { +// return service.getSetting(); +// } +// +// /** +// * 设置消息推送方式 +// * +// * @param settings 表单数据 +// * @return 消息设置 +// */ +// @PatchMapping("/setting") +// @PreAuthorize("hasAuthority('MESSAGE_SETTING')") +// public List saveSetting( +// @RequestBody Set settings +// ) { +// return service.saveSetting(settings); +// } +// +//} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/dto/BulletinAttachmentCreateDto.java b/src/main/java/com/zsc/edu/gateway/modules/notice/dto/BulletinAttachmentCreateDto.java new file mode 100644 index 0000000..b076527 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/dto/BulletinAttachmentCreateDto.java @@ -0,0 +1,17 @@ +//package com.zsc.edu.gateway.modules.notice.dto; +// +//import lombok.AllArgsConstructor; +//import lombok.Data; +//import lombok.NoArgsConstructor; +// +//import java.util.Set; +///** +// * @author zhuang +// */ +//@Data +//@AllArgsConstructor +//@NoArgsConstructor +//public class BulletinAttachmentCreateDto { +// +// private String attachmentIds; +//} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/dto/BulletinAttachmentDto.java b/src/main/java/com/zsc/edu/gateway/modules/notice/dto/BulletinAttachmentDto.java new file mode 100644 index 0000000..b3872d8 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/dto/BulletinAttachmentDto.java @@ -0,0 +1,18 @@ +package com.zsc.edu.gateway.modules.notice.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * @author zhuang + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class BulletinAttachmentDto { + + private Long bulletinId; + + private String attachmentId; +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/dto/BulletinDto.java b/src/main/java/com/zsc/edu/gateway/modules/notice/dto/BulletinDto.java new file mode 100644 index 0000000..d09db8c --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/dto/BulletinDto.java @@ -0,0 +1,44 @@ +package com.zsc.edu.gateway.modules.notice.dto; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import jakarta.validation.constraints.NotBlank; + +import java.util.List; + +/** + * @author harry_yao + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class BulletinDto { + + /** + * 标题 + */ + @NotBlank(message = "接收用户不能为空") + public String title; + + /** + * 是否置顶 + */ + public boolean top; + + /** + * 内容 + */ + @NotBlank(message = "消息内容不能为空") + public String content; + /** + * 备注 + */ + public String remark; +// +// /** +// * 附件ID集合 +// */ +// private List attachmentIds; +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/dto/UserMessageDto.java b/src/main/java/com/zsc/edu/gateway/modules/notice/dto/UserMessageDto.java new file mode 100644 index 0000000..6239643 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/dto/UserMessageDto.java @@ -0,0 +1,65 @@ +package com.zsc.edu.gateway.modules.notice.dto; + +import com.zsc.edu.gateway.modules.notice.entity.MessageType; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; +import java.util.Set; + +/** + * @author harry_yao + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class UserMessageDto { + + /** + * 用户ID集合 + */ + @NotEmpty(message = "接收用户不能为空") + public Set userIds; + + /** + * 消息类型 + */ + @NotNull(message = "消息类型不能为空") + public MessageType type; + + /** + * 是否需要发送邮件 + */ + public boolean email; + + /** + * 是否需要发送短信 + */ + public boolean sms; + + /** + * 消息内容是否富文本,True则以富文本形式发送 + */ + public boolean html; + + /** + * 消息标题 + */ + @NotBlank(message = "消息标题不能为空") + public String title; + + /** + * 消息内容 + */ + @NotBlank(message = "消息内容不能为空") + public String content; + + /** + * 附件ID集合 + */ + public Set attachmentIds; + +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/entity/Bulletin.java b/src/main/java/com/zsc/edu/gateway/modules/notice/entity/Bulletin.java new file mode 100644 index 0000000..d95b1bf --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/entity/Bulletin.java @@ -0,0 +1,122 @@ +package com.zsc.edu.gateway.modules.notice.entity; + +import com.baomidou.mybatisplus.annotation.IEnum; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableName; +import com.zsc.edu.gateway.common.enums.IState; +import com.zsc.edu.gateway.modules.system.entity.BaseEntity; +import com.zsc.edu.gateway.modules.attachment.entity.Attachment; +import lombok.*; +import org.springframework.data.mongodb.core.aggregation.ArrayOperators; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * 系统公告Domain + * + * @author zhuang + */ +@Setter +@Getter +@NoArgsConstructor +@AllArgsConstructor +@TableName("sys_bulletin") +public class Bulletin extends BaseEntity { + + /** + * 标题 + */ + public String title; + + /** + * 状态 + */ + public State state = State.edit; + + /** + * 是否置顶 + */ + public boolean top; + + /** + * 编辑者ID + */ + public Long editUserId; + + /** + * 编辑者 + */ + @TableField(exist = false) + public String editUsername; + + /** + * 编辑时间 + */ + public LocalDateTime editTime; + + /** + * 审核发布者ID + */ + public Long publishUserId; + + /** + * 审核发布者 + */ + @TableField(exist = false) + public String publishUsername; + + /** + * 审核发布时间 + */ + public LocalDateTime publishTime; + + /** + * 关闭者ID + */ + public Long closeUserId; + + /** + * 关闭者 + */ + @TableField(exist = false) + public String closeUsername; + + /** + * 关闭时间 + */ + public LocalDateTime closeTime; + + /** + * 内容 + */ + public String content; + + /** + * 附件列表 + */ + @TableField(exist = false) + public List attachments; + + public enum State implements IEnum, IState { + edit(1,"编辑中"), + publish(2,"已发布"), + close(3,"已关闭"); + + private final Integer value; + private final String name; + + State(int value, String name) { + this.value=value; + this.name = name; + } + @Override + public Integer getValue() { + return this.value; + } + @Override + public String toString() { + return this.name; + } + } +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/entity/BulletinAttachment.java b/src/main/java/com/zsc/edu/gateway/modules/notice/entity/BulletinAttachment.java new file mode 100644 index 0000000..7f01864 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/entity/BulletinAttachment.java @@ -0,0 +1,23 @@ +package com.zsc.edu.gateway.modules.notice.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +/** + * @author zhuang + */ +@Setter +@Getter +@NoArgsConstructor +@AllArgsConstructor +@TableName("sys_bulletin_attach") +public class BulletinAttachment { + + private Long bulletinId; + + private String attachmentId; + +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/entity/BulletinUser.java b/src/main/java/com/zsc/edu/gateway/modules/notice/entity/BulletinUser.java new file mode 100644 index 0000000..160508a --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/entity/BulletinUser.java @@ -0,0 +1,31 @@ +package com.zsc.edu.gateway.modules.notice.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +/** + * @author zhuang + */ +@Setter +@Getter +@NoArgsConstructor +@AllArgsConstructor +@TableName("sys_bulletin_user") +public class BulletinUser { + + /** + * 公告ID + */ + public Long bulletinId; + /** + * 用户ID + */ + public Long userId; + /** + * 是否已读 + */ + public Boolean isRead=true; +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/entity/Message.java b/src/main/java/com/zsc/edu/gateway/modules/notice/entity/Message.java new file mode 100644 index 0000000..242a2f4 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/entity/Message.java @@ -0,0 +1,65 @@ +package com.zsc.edu.gateway.modules.notice.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import com.zsc.edu.gateway.modules.system.entity.BaseEntity; +import com.zsc.edu.gateway.modules.attachment.entity.Attachment; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.util.List; + +/** + * 消息 + * + * @author harry_yao + */ +@Setter +@Getter +@NoArgsConstructor +@AllArgsConstructor +@TableName("sys_message") +public class Message extends BaseEntity { + + /** + * 消息类型 + */ + public com.zsc.edu.gateway.modules.notice.entity.MessageType type = MessageType.其他; + + /** + * 是否系统生成 + */ + public boolean system; + + /** + * 是否需要发送邮件 + */ + public boolean email; + + /** + * 是否需要发送短信 + */ + public boolean sms; + + /** + * 消息内容是否富文本,True则以富文本形式发送 + */ + public boolean html; + + /** + * 标题 + */ + public String title; + + /** + * 消息内容 + */ + public String content; + + /** + * 附件 + */ + public List attachments; + +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/entity/MessagePayload.java b/src/main/java/com/zsc/edu/gateway/modules/notice/entity/MessagePayload.java new file mode 100644 index 0000000..392269a --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/entity/MessagePayload.java @@ -0,0 +1,39 @@ +package com.zsc.edu.gateway.modules.notice.entity; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +/** + * 消息内容 + * + * @author harry_yao + */ +public abstract class MessagePayload { + + public MessageType type; + public String content; + public boolean html; + + public static class Other extends MessagePayload { + public Other(String content) { + this.content = content; + this.type = MessageType.其他; + } + } + + public static class ResetPassword extends MessagePayload { + public String username; + public String password; + public LocalDateTime resetTime; + + public ResetPassword(String username, String password, LocalDateTime resetTime) { + this.username = username; + this.password = password; + this.resetTime = resetTime; + this.type =MessageType.重置密码; + this.content = String.format("尊敬的用户%s,您的密码已于%s被管理员重置,新密码为%s," + + "请及时登录系统修改密码!", username, resetTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")), password); + } + } + +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/entity/MessageSetting.java b/src/main/java/com/zsc/edu/gateway/modules/notice/entity/MessageSetting.java new file mode 100644 index 0000000..833978f --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/entity/MessageSetting.java @@ -0,0 +1,53 @@ +package com.zsc.edu.gateway.modules.notice.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + + +/** + * 消息设置 + * + * @author harry_yao + */ +@Setter +@Getter +@NoArgsConstructor +@AllArgsConstructor +@TableName("sys_message_setting") +public class MessageSetting { + + /** + * 消息类型 + */ + @TableId + public Long id; + + /** + * 是否发送邮件 + */ + public boolean email; + + /** + * 是否发送短信 + */ + public boolean sms; + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + MessageSetting that = (MessageSetting) o; + + return id == that.id; + } + + @Override + public int hashCode() { + return id.hashCode(); + } +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/entity/MessageType.java b/src/main/java/com/zsc/edu/gateway/modules/notice/entity/MessageType.java new file mode 100644 index 0000000..064d99c --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/entity/MessageType.java @@ -0,0 +1,11 @@ +package com.zsc.edu.gateway.modules.notice.entity; + +/** + * 消息类型 + * + * @author harry_yao + */ +public enum MessageType { + 其他, + 重置密码 +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/entity/UserMessage.java b/src/main/java/com/zsc/edu/gateway/modules/notice/entity/UserMessage.java new file mode 100644 index 0000000..7205139 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/entity/UserMessage.java @@ -0,0 +1,48 @@ +package com.zsc.edu.gateway.modules.notice.entity; + +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import com.zsc.edu.gateway.modules.system.entity.User; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.io.Serializable; +import java.time.LocalDateTime; + +/** + * 用户消息 + * + * @author harry_yao + */ +@Setter +@Getter +@NoArgsConstructor +@AllArgsConstructor +@TableName("sys_user_message") +public class UserMessage implements Serializable { + + @TableId + private Long id; + /** + * 用户 + */ + public User user; + + /** + * 消息 + */ + public Message message; + + /** + * 是否已读 + */ + public boolean read; + + /** + * 阅读时间 + */ + public LocalDateTime readTime; + +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/mapper/BulletinAttachmentMapper.java b/src/main/java/com/zsc/edu/gateway/modules/notice/mapper/BulletinAttachmentMapper.java new file mode 100644 index 0000000..e3b4d0e --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/mapper/BulletinAttachmentMapper.java @@ -0,0 +1,15 @@ +package com.zsc.edu.gateway.modules.notice.mapper; + +import com.zsc.edu.gateway.common.mapstruct.BaseMapper; +import com.zsc.edu.gateway.modules.notice.dto.BulletinAttachmentDto; +import com.zsc.edu.gateway.modules.notice.entity.BulletinAttachment; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** + * @author zhuang + */ +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface BulletinAttachmentMapper extends BaseMapper { + +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/mapper/BulletinMapper.java b/src/main/java/com/zsc/edu/gateway/modules/notice/mapper/BulletinMapper.java new file mode 100644 index 0000000..e1e6390 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/mapper/BulletinMapper.java @@ -0,0 +1,14 @@ +package com.zsc.edu.gateway.modules.notice.mapper; + +import com.zsc.edu.gateway.common.mapstruct.BaseMapper; +import com.zsc.edu.gateway.modules.notice.dto.BulletinDto; +import com.zsc.edu.gateway.modules.notice.entity.Bulletin; +import org.mapstruct.Mapper; +import org.mapstruct.ReportingPolicy; + +/** + * @author zhuang + */ +@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) +public interface BulletinMapper extends BaseMapper { +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/mapper/BulletinUserMapper.java b/src/main/java/com/zsc/edu/gateway/modules/notice/mapper/BulletinUserMapper.java new file mode 100644 index 0000000..b546a8d --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/mapper/BulletinUserMapper.java @@ -0,0 +1,11 @@ +//package com.zsc.edu.gateway.modules.notice.mapper; +// +//import org.mapstruct.Mapper; +//import org.mapstruct.ReportingPolicy; +// +///** +// * @author zhuang +// */ +//@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE) +//public interface BulletinUserMapper extends BaseMapper<>{ +//} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/query/BulletinQuery.java b/src/main/java/com/zsc/edu/gateway/modules/notice/query/BulletinQuery.java new file mode 100644 index 0000000..18cd7cb --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/query/BulletinQuery.java @@ -0,0 +1,55 @@ +package com.zsc.edu.gateway.modules.notice.query; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.zsc.edu.gateway.modules.notice.entity.Bulletin; +import com.zsc.edu.gateway.modules.system.entity.Authority; +import com.zsc.edu.gateway.modules.system.entity.User; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.util.StringUtils; + +import java.time.LocalDateTime; +import java.util.Objects; + +/** + * 系统公告Query + * + * @author harry_yao + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class BulletinQuery { + + /** + * 标题,模糊查询 + */ + public String title; + + /** + * 状态,只用于管理员查询 + */ + public Bulletin.State state; + + /** + * 公告发布时间区间起始 + */ + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) + public LocalDateTime publishTimeBegin; + + /** + * 公告发布时间区间终止 + */ + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) + public LocalDateTime publishTimeEnd; + + + public LambdaQueryWrapper wrapper() { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.like(StringUtils.hasText(this.title), Bulletin::getTitle, this.title); + queryWrapper.eq(Objects.nonNull(this.state), Bulletin::getState, this.state); + return queryWrapper; + } +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/query/MessageQuery.java b/src/main/java/com/zsc/edu/gateway/modules/notice/query/MessageQuery.java new file mode 100644 index 0000000..63d3adc --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/query/MessageQuery.java @@ -0,0 +1,26 @@ +package com.zsc.edu.gateway.modules.notice.query; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.zsc.edu.gateway.modules.notice.entity.Message; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.util.StringUtils; + +import java.util.Set; + +/** + * @author zhuang + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class MessageQuery { + Set messageIds; + + public LambdaQueryWrapper wrapper() { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + queryWrapper.eq(StringUtils.hasText((CharSequence) this.messageIds), Message::getId, this.messageIds); + return queryWrapper; + } +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/query/UserMessageQuery.java b/src/main/java/com/zsc/edu/gateway/modules/notice/query/UserMessageQuery.java new file mode 100644 index 0000000..dc9d621 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/query/UserMessageQuery.java @@ -0,0 +1,75 @@ +package com.zsc.edu.gateway.modules.notice.query; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.zsc.edu.gateway.modules.notice.entity.Bulletin; +import com.zsc.edu.gateway.modules.notice.entity.MessageType; +import com.zsc.edu.gateway.modules.notice.entity.UserMessage; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import org.springframework.format.annotation.DateTimeFormat; +import org.springframework.util.StringUtils; + +import java.time.LocalDateTime; +import java.util.Set; + +/** + * 用户消息Query + * + * @author harry_yao + */ +@Data +@AllArgsConstructor +@NoArgsConstructor +public class UserMessageQuery { + + /** + * 用户ID + */ + public Long userId; + + /** + * 标题,模糊查询 + */ + public String title; + + /** + * 消息类型 + */ + public Set types; + + /** + * 用户名或真实姓名,用户名准确查询,姓名模糊查询 + */ + public String name; + + /** + * 是否系统自动生成 + */ + public Boolean system; + + /** + * 是否已读 + */ + public Boolean read; + + /** + * 消息创建时间区间起始 + */ + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) + public LocalDateTime createAtBegin; + + /** + * 消息创建时间区间终止 + */ + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME) + public LocalDateTime createAtEnd; + + +// public LambdaQueryWrapper wrapper() { +// LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); +// queryWrapper.like(StringUtils.hasText(this.title), UserMessage::getTitle, this.title); +// queryWrapper.eq(StringUtils.hasText((CharSequence) this.states), UserMessage::getState, this.states); +// return queryWrapper; +// } +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/repo/BulletinAttachmentRepository.java b/src/main/java/com/zsc/edu/gateway/modules/notice/repo/BulletinAttachmentRepository.java new file mode 100644 index 0000000..27e9c24 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/repo/BulletinAttachmentRepository.java @@ -0,0 +1,8 @@ +package com.zsc.edu.gateway.modules.notice.repo; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zsc.edu.gateway.modules.notice.entity.BulletinAttachment; + +public interface BulletinAttachmentRepository extends BaseMapper { + +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/repo/BulletinRepository.java b/src/main/java/com/zsc/edu/gateway/modules/notice/repo/BulletinRepository.java new file mode 100644 index 0000000..e5b292e --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/repo/BulletinRepository.java @@ -0,0 +1,20 @@ +package com.zsc.edu.gateway.modules.notice.repo; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zsc.edu.gateway.modules.notice.entity.Bulletin; +import org.apache.ibatis.annotations.Param; + +/** + * 公告Repo + * + * @author harry_yao + */ +public interface BulletinRepository extends BaseMapper { + + + Bulletin selectByBulletinId(@Param("bulletinId") Long bulletinId); + + + Bulletin selectAll(); +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/repo/BulletinUserRepository.java b/src/main/java/com/zsc/edu/gateway/modules/notice/repo/BulletinUserRepository.java new file mode 100644 index 0000000..42c918e --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/repo/BulletinUserRepository.java @@ -0,0 +1,19 @@ +package com.zsc.edu.gateway.modules.notice.repo; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zsc.edu.gateway.modules.notice.entity.BulletinUser; +import org.apache.ibatis.annotations.Param; +import org.apache.ibatis.annotations.Select; + +/** + * @author zhuang + */ +public interface BulletinUserRepository extends BaseMapper { + + @Select("select * from sys_bulletin_user sbu where sbu.bulletin_id=#{bulletinId} and sbu.user_id=#{userId}") + Boolean selectByBulletinIdAndUserId(@Param("bulletinId") Long bulletinId, @Param("userId") Long userId); + + @Select("select * from sys_bulletin_user sbu where sbu.bulletin_id=#{bulletinId}") + BulletinUser selectReadByBulletinId(@Param("bulletinId") Long bulletinId); +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/repo/MessageRepository.java b/src/main/java/com/zsc/edu/gateway/modules/notice/repo/MessageRepository.java new file mode 100644 index 0000000..7282637 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/repo/MessageRepository.java @@ -0,0 +1,14 @@ +package com.zsc.edu.gateway.modules.notice.repo; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zsc.edu.gateway.modules.notice.entity.Message; + +/** + * 消息Repo + * + * @author harry_yao + */ +public interface MessageRepository extends BaseMapper { + +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/repo/MessageSettingRepository.java b/src/main/java/com/zsc/edu/gateway/modules/notice/repo/MessageSettingRepository.java new file mode 100644 index 0000000..b0192c2 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/repo/MessageSettingRepository.java @@ -0,0 +1,14 @@ +package com.zsc.edu.gateway.modules.notice.repo; + + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zsc.edu.gateway.modules.notice.entity.MessageSetting; + +/** + * 消息设置Repo + * + * @author harry_yao + */ +public interface MessageSettingRepository extends BaseMapper { + +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/repo/UserMessageRepository.java b/src/main/java/com/zsc/edu/gateway/modules/notice/repo/UserMessageRepository.java new file mode 100644 index 0000000..18420b3 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/repo/UserMessageRepository.java @@ -0,0 +1,13 @@ +package com.zsc.edu.gateway.modules.notice.repo; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.zsc.edu.gateway.modules.notice.entity.UserMessage; + +/** + * 用户消息Repo + * + * @author harry_yao + */ +public interface UserMessageRepository extends BaseMapper { + +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/service/BulletinAttachmentService.java b/src/main/java/com/zsc/edu/gateway/modules/notice/service/BulletinAttachmentService.java new file mode 100644 index 0000000..296a59c --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/service/BulletinAttachmentService.java @@ -0,0 +1,12 @@ +package com.zsc.edu.gateway.modules.notice.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.zsc.edu.gateway.modules.notice.entity.BulletinAttachment; + + + +/** + * @author zhuang + */ +public interface BulletinAttachmentService extends IService { +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/service/BulletinService.java b/src/main/java/com/zsc/edu/gateway/modules/notice/service/BulletinService.java new file mode 100644 index 0000000..d13b94f --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/service/BulletinService.java @@ -0,0 +1,33 @@ +package com.zsc.edu.gateway.modules.notice.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.zsc.edu.gateway.framework.security.UserDetailsImpl; +import com.zsc.edu.gateway.modules.notice.dto.BulletinDto; +import com.zsc.edu.gateway.modules.notice.entity.Bulletin; + +import java.util.Set; + +/** + * 系统公告Service + * + * @author harry_yao + */ + +public interface BulletinService extends IService { + + Bulletin detail(UserDetailsImpl userDetails,Long id, Bulletin.State state); + + Bulletin create(UserDetailsImpl userDetails, BulletinDto dto); + + Boolean update(UserDetailsImpl userDetails, BulletinDto dto, Long id); + + Boolean open(Long id); + + Boolean toggleTop(Long id); + + Boolean publish(UserDetailsImpl userDetails,Long id); + + Boolean close(UserDetailsImpl userDetails,Long id); + + Boolean insertInto(Long bulletinId, Set attachmentIds); +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/service/BulletinUserService.java b/src/main/java/com/zsc/edu/gateway/modules/notice/service/BulletinUserService.java new file mode 100644 index 0000000..23a6996 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/service/BulletinUserService.java @@ -0,0 +1,16 @@ +package com.zsc.edu.gateway.modules.notice.service; + + +import com.baomidou.mybatisplus.extension.service.IService; +import com.zsc.edu.gateway.framework.security.UserDetailsImpl; +import com.zsc.edu.gateway.modules.notice.entity.BulletinUser; + +/** + * @author zhuang + */ +public interface BulletinUserService extends IService { + + Boolean isRead(UserDetailsImpl userDetails, Long id); + + void toggleIsRead(Long id); +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/service/UserMessageService.java b/src/main/java/com/zsc/edu/gateway/modules/notice/service/UserMessageService.java new file mode 100644 index 0000000..2da727f --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/service/UserMessageService.java @@ -0,0 +1,15 @@ +package com.zsc.edu.gateway.modules.notice.service; + +import com.baomidou.mybatisplus.extension.service.IService; +import com.zsc.edu.gateway.modules.notice.dto.UserMessageDto; +import org.springframework.transaction.annotation.Transactional; + +/** + * 用户消息Service + * + * @author harry_yao + */ +public interface UserMessageService extends IService { + + Boolean createByAdmin(UserMessageDto dto); +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/service/impl/BulletinAttachmentServiceImpl.java b/src/main/java/com/zsc/edu/gateway/modules/notice/service/impl/BulletinAttachmentServiceImpl.java new file mode 100644 index 0000000..bd4f326 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/service/impl/BulletinAttachmentServiceImpl.java @@ -0,0 +1,18 @@ +package com.zsc.edu.gateway.modules.notice.service.impl; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.zsc.edu.gateway.modules.notice.entity.BulletinAttachment; +import com.zsc.edu.gateway.modules.notice.repo.BulletinAttachmentRepository; +import com.zsc.edu.gateway.modules.notice.service.BulletinAttachmentService; +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Service; + + +/** + * @author zhuang + */ +@AllArgsConstructor +@Service +public class BulletinAttachmentServiceImpl extends ServiceImpl implements BulletinAttachmentService { + +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/service/impl/BulletinServiceImpl.java b/src/main/java/com/zsc/edu/gateway/modules/notice/service/impl/BulletinServiceImpl.java new file mode 100644 index 0000000..5a51527 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/service/impl/BulletinServiceImpl.java @@ -0,0 +1,165 @@ +package com.zsc.edu.gateway.modules.notice.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.zsc.edu.gateway.exception.ConstraintException; +import com.zsc.edu.gateway.framework.security.UserDetailsImpl; +import com.zsc.edu.gateway.modules.notice.dto.BulletinDto; +import com.zsc.edu.gateway.modules.notice.entity.Bulletin; +import com.zsc.edu.gateway.modules.notice.entity.BulletinAttachment; +import com.zsc.edu.gateway.modules.notice.repo.BulletinRepository; +import com.zsc.edu.gateway.modules.notice.service.BulletinAttachmentService; +import com.zsc.edu.gateway.modules.notice.service.BulletinService; +import com.zsc.edu.gateway.modules.notice.service.BulletinUserService; +import lombok.AllArgsConstructor; +import org.springframework.beans.BeanUtils; +import org.springframework.stereotype.Service; + +import java.time.LocalDateTime; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + +import static com.zsc.edu.gateway.modules.notice.entity.Bulletin.State.*; + +/** + * 系统公告Service + * + * @author harry_yao + */ +@AllArgsConstructor +@Service +public class BulletinServiceImpl extends ServiceImpl implements BulletinService { + + private final BulletinRepository repo; + private final BulletinAttachmentService bulletinAttachmentService; + private final BulletinUserService bulletinUserService; + /** + * 查询公告详情 + * + * @param id ID + * @param state 公告状态 + * @return 公告详情 + */ + @Override + public Bulletin detail(UserDetailsImpl userDetails,Long id, Bulletin.State state) { + Bulletin bulletin = repo.selectByBulletinId(id); + if (state != null) { + bulletin.state.checkStatus(state); + } + bulletinUserService.isRead(userDetails, id); + return bulletin; + } + /** + * 新建公告 + * + * @param userDetails 操作用户 + * @param dto 表单数据 + * @return 新建的公告 + */ + @Override + public Bulletin create(UserDetailsImpl userDetails, BulletinDto dto) { + boolean existsByName=count(new LambdaQueryWrapper().eq(Bulletin::getTitle,dto.getTitle())) > 0; + if(existsByName){ + throw new ConstraintException("title", dto.title, "标题已存在"); + } + Bulletin bulletin=new Bulletin(); + BeanUtils.copyProperties(dto,bulletin); + bulletin.setCreateTime(LocalDateTime.now()); + bulletin.setCreateBy(userDetails.getName()); + bulletin.setEditUserId(userDetails.getId()); + save(bulletin); + return bulletin; + } + /** + * 修改公告,只能修改"编辑中"或"已发布"的公告 + * + * @param userDetails 操作用户 + * @param dto 表单数据 + * @return 已修改的公告 + */ + @Override + public Boolean update(UserDetailsImpl userDetails,BulletinDto dto, Long id) { + Bulletin bulletin = getById(id); + bulletin.state.checkStatus(EnumSet.of(edit, publish)); + BeanUtils.copyProperties(dto, bulletin); + bulletin.setCreateBy(userDetails.getName()); + bulletin.setCreateTime(LocalDateTime.now()); + bulletin.state = edit; + bulletinUserService.toggleIsRead(id); + return updateById(bulletin); + } + /** + * 发布公告,只能发布"编辑中"的公告 + * + * @param userDetails 操作用户 + * @param id ID + * @return 已发布的公告 + */ + @Override + public Boolean publish(UserDetailsImpl userDetails, Long id) { + Bulletin bulletin = getById(id); + bulletin.state.checkStatus(edit); + bulletin.state = publish; + bulletin.setPublishUserId(userDetails.getId()); + bulletin.setPublishTime(LocalDateTime.now()); + return updateById(bulletin); + } + + /** + * 关闭公告,只能关闭"已发布"的公告 + * + * @param userDetails 操作用户 + * @param id ID + * @return 已关闭的公告 + */ + @Override + public Boolean close(UserDetailsImpl userDetails, Long id) { + Bulletin bulletin = getById(id); + bulletin.top = false; + bulletin.state.checkStatus(publish); + bulletin.state = close; + bulletin.setCloseUserId(userDetails.getId()); + bulletin.setCloseTime(LocalDateTime.now()); + return updateById(bulletin); + } + /** + * 开启公告,只能开启“已关闭“的公告,变成编辑中 + * + * + */ + @Override + public Boolean open(Long id){ + Bulletin bulletin = getById(id); + bulletin.top = false; + bulletin.state.checkStatus(close); + bulletin.state = edit; + return updateById(bulletin); + } + /** + * 切换公告置顶状态 + * + * @param id ID + * @return 被更新的公告 + */ + @Override + public Boolean toggleTop(Long id) { + Bulletin bulletin = getById(id); + bulletin.top = !bulletin.top; + return updateById(bulletin); + } + + /** + *为公告添加附件 + * + * @param bulletinId bulletinId + * @param attachments attachments + * @return true + */ + @Override + public Boolean insertInto(Long bulletinId, Set attachments) { + List bulletinAttachments=attachments.stream().map(bulletinAttachment->new BulletinAttachment(bulletinId, attachments.toString())).toList(); + return bulletinAttachmentService.saveBatch(bulletinAttachments); + } + +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/service/impl/BulletinUserServiceImpl.java b/src/main/java/com/zsc/edu/gateway/modules/notice/service/impl/BulletinUserServiceImpl.java new file mode 100644 index 0000000..bf1bf46 --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/service/impl/BulletinUserServiceImpl.java @@ -0,0 +1,52 @@ +package com.zsc.edu.gateway.modules.notice.service.impl; + +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.zsc.edu.gateway.framework.security.UserDetailsImpl; +import com.zsc.edu.gateway.modules.notice.entity.BulletinUser; +import com.zsc.edu.gateway.modules.notice.repo.BulletinUserRepository; +import com.zsc.edu.gateway.modules.notice.service.BulletinUserService; +import lombok.AllArgsConstructor; +import org.springframework.stereotype.Service; + + +/** + * @author zhuang + */ +@AllArgsConstructor +@Service +public class BulletinUserServiceImpl extends ServiceImpl implements BulletinUserService { + + private BulletinUserRepository bulletinUserRepository; + /** + * 已读公告,每次已读自动获取用户id与公告id加入联表 + * + * @param userDetails userDetails + * @param id id + * return true + */ + @Override + public Boolean isRead(UserDetailsImpl userDetails,Long id) { + BulletinUser bulletinUser = new BulletinUser(); + bulletinUser.setBulletinId(id); + bulletinUser.setUserId(userDetails.getId()); + bulletinUser.isRead=false; + if(!bulletinUserRepository.selectByBulletinIdAndUserId(id,userDetails.getId())){ + return save(bulletinUser); + }else{ + return false; + } + } + + /** + * 更新公告后修改已读状态 + * + * @param id id + */ + @Override + public void toggleIsRead(Long id) { + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("bulletin_id",id).set("is_read",true); + } + +} diff --git a/src/main/java/com/zsc/edu/gateway/modules/notice/service/impl/UserMessageServiceImpl.java b/src/main/java/com/zsc/edu/gateway/modules/notice/service/impl/UserMessageServiceImpl.java new file mode 100644 index 0000000..9863fde --- /dev/null +++ b/src/main/java/com/zsc/edu/gateway/modules/notice/service/impl/UserMessageServiceImpl.java @@ -0,0 +1,168 @@ +//package com.zsc.edu.gateway.modules.notice.service.impl; +// +//import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +//import com.zsc.edu.gateway.modules.attachment.entity.Attachment; +//import com.zsc.edu.gateway.modules.attachment.service.AttachmentService; +//import com.zsc.edu.gateway.modules.notice.dto.UserMessageDto; +//import com.zsc.edu.gateway.modules.notice.entity.Message; +//import com.zsc.edu.gateway.modules.notice.entity.MessagePayload; +//import com.zsc.edu.gateway.modules.notice.entity.UserMessage; +//import com.zsc.edu.gateway.modules.notice.repo.MessageRepository; +//import com.zsc.edu.gateway.modules.notice.repo.MessageSettingRepository; +//import com.zsc.edu.gateway.modules.notice.repo.UserMessageRepository; +//import com.zsc.edu.gateway.modules.notice.service.UserMessageService; +//import com.zsc.edu.gateway.modules.system.entity.User; +//import com.zsc.edu.gateway.modules.system.service.UserService; +//import lombok.AllArgsConstructor; +//import org.springframework.scheduling.annotation.Async; +//import org.springframework.stereotype.Service; +//import org.springframework.transaction.annotation.Transactional; +// +//import java.util.List; +//import java.util.Optional; +//import java.util.Set; +//import java.util.concurrent.atomic.AtomicBoolean; +//import java.util.stream.Collectors; +// +///** +// * 用户消息Service +// * +// * @author harry_yao +// */ +//@AllArgsConstructor +//@Service +//public class UserMessageServiceImpl extends ServiceImpl implements UserMessageService { +// +// private final MessageRepository messageRepo; +// private final MessageSettingRepository messageSettingRepo; +// private final UserService userService; +// private final AttachmentService attachmentService; +//// private final EmailSender emailSender; +//// private final SmsSender smsSender; +// +// +// /** +// * 查询用户消息详情 +// * +// * @param id ID +// * @return 用户消息详情 +// */ +// public UserMessage detail(Long id) { +// return getById(id); +// } +// +// /** +// * 分页查询用户消息 +// * +// * @param query 查询表单 +// * @param pageable 分页参数 +// * @return 页面数据 +// */ +//// public Page page(UserMessageQuery query, Pageable pageable) { +//// return this.page(query, pageable); +//// } +// +// /** +// * 管理员手动创建用户消息并发送 +// * +// * @param dto 表单数据 +// * @return 创建的用户消息列表 +// */ +// @Transactional +// @Override +// public Boolean createByAdmin(UserMessageDto dto) { +// Set users = dto.userIds.stream().map(userService::getById).collect(Collectors.toSet()); +// List attachments = attachmentService.listByIds(dto.attachmentIds); +// Message message = new Message(dto.type, false, dto.email, dto.sms, dto.html, +// dto.title, dto.content, attachments); +// messageRepo.insert(message); +// Set userMessages = users.stream().map(user -> +// new UserMessage(null, user, message, false, null)).collect(Collectors.toSet()); +// send(users, message); +// return saveBatch(userMessages); +// } +// +// /** +// * 系统自动创建用户消息并发送 +// * +// * @param receivers 接收者 +// * @param payload 消息内容 +// */ +// @Transactional +// public boolean createBySystem(Set receivers, MessagePayload payload) { +// AtomicBoolean email = new AtomicBoolean(false); +// AtomicBoolean sms = new AtomicBoolean(false); +// Optional.of(messageSettingRepo.selectById(payload.type)).ifPresent(messageSetting -> { +// email.set(messageSetting.email); +// sms.set(messageSetting.sms); +// }); +// Message message = new Message(payload.type, true, email.get(), sms.get(), +// payload.html, payload.type.name(), payload.content, null); +// messageRepo.insert(message); +// Set userMessages = receivers.stream().map(user -> +// new UserMessage(null, user, message, false, null)).collect(Collectors.toSet()); +//// List list = saveBatch(userMessages); +// send(receivers, message); +// return saveBatch(userMessages); +// } +// +// /** +// * 统计用户未读消息数量 +// * +// * @param userDetails 操作用户 +// * @return 未读消息数量 +// */ +//// public int countUnread(UserDetailsImpl userDetails) { +//// return repo.countByUserIdAndRead(userDetails.id, false); +//// } +// +// /** +// * 设为已读 +// * +// * @param userDetails 操作用户 +// * @param messageIds 消息ID集合,如为空,则将该用户的所有未读消息设为已读 +// * @return 修改记录数量 +// */ +//// public int markAsRead(UserDetailsImpl userDetails, Set messageIds) { +//// if (CollectionUtils.isEmpty(messageIds)) { +//// return repo.markAsRead(userDetails.id, LocalDateTime.now()); +//// } +//// return repo.markAsRead(userDetails.id, messageIds, LocalDateTime.now()); +//// } +// +// /** +// * 获取所有消息推送方式 +// * +// * @return 消息设置列表 +// */ +//// public List getSetting() { +//// return messageSettingRepo.findAll(); +//// } +// +// /** +// * 设置消息推送方式 +// * +// * @param settings 消息设置集合 +// * @return 消息设置列表 +// */ +//// public List saveSetting(Set settings) { +//// return messageSettingRepo.saveAll(settings); +//// } +// +// /** +// * 以邮件、短信等形式发送消息,只有非html格式的消息才能以短信方式发送 +// * +// * @param users 接收者 +// * @param message 消息 +// */ +// @Async +// void send(Set users, Message message) { +// if (message.email) { +// emailSender.send(users.stream().map(User::getEmail).collect(Collectors.toSet()), message); +// } +// if (message.sms && !message.html) { +// smsSender.send(users.stream().map(User::getPhone).collect(Collectors.toSet()), message.content); +// } +// } +// +//} diff --git a/src/main/resources/mappers/noticeMappers/BulletinMapper.xml b/src/main/resources/mappers/noticeMappers/BulletinMapper.xml new file mode 100644 index 0000000..5873905 --- /dev/null +++ b/src/main/resources/mappers/noticeMappers/BulletinMapper.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/java/com/zsc/edu/gateway/domain/BulletinBuilder.java b/src/test/java/com/zsc/edu/gateway/domain/BulletinBuilder.java new file mode 100644 index 0000000..9a48d6d --- /dev/null +++ b/src/test/java/com/zsc/edu/gateway/domain/BulletinBuilder.java @@ -0,0 +1,35 @@ +package com.zsc.edu.gateway.domain; + +import com.zsc.edu.gateway.modules.notice.entity.Bulletin; + +public class BulletinBuilder extends BaseEntityBuilder{ + private String title; + private String content; + private Boolean top; + + public static BulletinBuilder bBulletin(){return new BulletinBuilder();} + + public BulletinBuilder title(String title){ + this.title = title; + return this; + } + + public BulletinBuilder content(String content){ + this.content = content; + return this; + } + + + public BulletinBuilder top(Boolean top){ + this.top = top; + return this; + } + + public Bulletin build(){ + Bulletin bulletin = new Bulletin(); + bulletin.setTitle(title); + bulletin.setContent(content); + bulletin.setTop(top); + return bulletin; + } +} diff --git a/src/test/java/com/zsc/edu/gateway/service/BulletinServiceTest.java b/src/test/java/com/zsc/edu/gateway/service/BulletinServiceTest.java new file mode 100644 index 0000000..586b04b --- /dev/null +++ b/src/test/java/com/zsc/edu/gateway/service/BulletinServiceTest.java @@ -0,0 +1,89 @@ +package com.zsc.edu.gateway.service; + +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.zsc.edu.gateway.domain.BulletinBuilder; +import com.zsc.edu.gateway.exception.ConstraintException; +import com.zsc.edu.gateway.framework.security.UserDetailsImpl; +import com.zsc.edu.gateway.modules.notice.dto.BulletinDto; +import com.zsc.edu.gateway.modules.notice.entity.Bulletin; +import com.zsc.edu.gateway.modules.notice.repo.BulletinRepository; +import com.zsc.edu.gateway.modules.notice.service.BulletinService; +import jakarta.annotation.Resource; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.*; + +public class BulletinServiceTest { + @Resource + private BulletinService service; + @Resource + private BulletinRepository repo; + + Bulletin bulletin1; + Bulletin bulletin2; + + @BeforeEach + void setUp() { + bulletin1 = BulletinBuilder.bBulletin().title("测试1").build(); + repo.insert(bulletin1); + bulletin2 = BulletinBuilder.bBulletin().title("测试2").build(); + repo.insert(bulletin2); + } + + @Test + void list() { + LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); + assertEquals(2, service.list(queryWrapper.like(Bulletin::getTitle, "测试")).size()); + assertEquals(1, service.list(queryWrapper.eq(Bulletin::getTitle, bulletin1.getTitle())).size()); + assertEquals(2, service.list().size()); + } + + @Test + void createBulletin() { + BulletinDto dto = new BulletinDto(); + dto.setTitle("测试"); + dto.setTop(true); + dto.setContent("测试测试"); + dto.setRemark("测试公告增加"); + BulletinDto dto2 = new BulletinDto(); + dto2.setTitle(bulletin2.getTitle()); + dto2.setTop(bulletin2.isTop()); + dto2.setRemark(bulletin2.getRemark()); + UserDetailsImpl userDetails = new UserDetailsImpl(); + userDetails.setUsername("admin"); + Bulletin bulletin=service.create(userDetails,dto); + assertNotNull(bulletin.getId()); + List list = service.list(); + assertEquals(3, list.size()); + // 不能创建其他已存在标题公告 + assertThrows(ConstraintException.class, () -> service.create(userDetails,dto2)); + } + + @Test + void updateBulletin() { + BulletinDto dto = new BulletinDto(); + dto.setTitle("测试3"); + dto.setContent("测试测"); + dto.setTop(true); + dto.setRemark("测试公告更新"); + UserDetailsImpl userDetails = new UserDetailsImpl(); + userDetails.setUsername("admin"); + assertTrue(service.update(userDetails,dto, bulletin2.id)); + Bulletin bulletin = service.getOne(new LambdaQueryWrapper().eq(Bulletin::getTitle, dto.getTitle())); + assertEquals(bulletin.getTitle(), dto.getTitle()); + assertEquals(bulletin.getId(), bulletin2.id); + // 不能改为其他已存在的同名同代码部门 + assertThrows(ConstraintException.class, + () -> service.update(userDetails,new BulletinDto(bulletin1.getTitle(),true,null,null), bulletin2.id)); + } + + @AfterEach + void tearDown() { + repo.delete(new QueryWrapper<>()); + } +}