Compare commits

...

3 Commits

49 changed files with 1176 additions and 619 deletions

View File

@ -0,0 +1,10 @@
package com.zsc.edu.gateway.exception;
/**
* @author zhuang
*/
public class EmptyIdsException extends RuntimeException {
public EmptyIdsException(String message) {
super(message);
}
}

View File

@ -0,0 +1,13 @@
package com.zsc.edu.gateway.exception;
/**
* @author zhuang
*/
public class PublishFailedException extends RuntimeException {
public PublishFailedException(String message) {
super(message);
}
}

View File

@ -0,0 +1,17 @@
package com.zsc.edu.gateway.framework;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestClient;
/**
* @author zhuang
*/
@Configuration
public class AppConfig {
@Bean
public RestClient restClient() {
return RestClient.builder().build();
}
}

View File

@ -0,0 +1,15 @@
package com.zsc.edu.gateway.framework.message.email;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @author harry_yao
*/
@Data
@ConfigurationProperties("spring.mail")
@Configuration
public class EmailProperties {
public String username;
}

View File

@ -0,0 +1,108 @@
package com.zsc.edu.gateway.framework.message.email;
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.entity.Message;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import jakarta.annotation.Resource;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.AddressException;
import jakarta.mail.internet.InternetAddress;
import jakarta.mail.internet.MimeMessage;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Objects;
import java.util.Set;
/**
* @author pegnzheng
*/
@AllArgsConstructor
@Component
public class EmailSender {
private final static String TEMPLATE = "message.ftl";
private final EmailProperties config;
private final Configuration freemarkerConfig;
@Resource
private final JavaMailSender sender;
private final AttachmentService attachmentService;
@Async
public void send(String email, Message message) {
if (StringUtils.hasText(email)) {
return;
}
InternetAddress to;
try {
to = new InternetAddress(email);
to.validate();
} catch (AddressException e) {
return;
}
send(new InternetAddress[]{to}, message);
}
@Async
public void send(Set<String> emails, Message message) {
InternetAddress[] to = emails.stream().filter(Objects::nonNull).map(email ->
{
try {
return new InternetAddress(email);
} catch (AddressException e) {
return null;
}
}).filter(Objects::nonNull).filter(internetAddress -> {
try {
internetAddress.validate();
} catch (AddressException e) {
return false;
}
return true;
}).toArray(InternetAddress[]::new);
if (to.length == 0) {
return;
}
send(to, message);
}
private void send(InternetAddress[] to, Message message) {
try {
MimeMessage mimeMessage = sender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
helper.setTo(to);
helper.setFrom(config.username);
helper.setSubject(message.getTitle());
if (message.html) {
StringWriter sw = new StringWriter();
Template tp = freemarkerConfig.getTemplate(TEMPLATE, "UTF-8");
tp.process(message, sw);
helper.setText(sw.toString(), true);
} else {
helper.setText(message.content);
}
if (Objects.nonNull(message.attachments)) {
for (Attachment attachment : message.attachments) {
helper.addAttachment(attachment.fileName, attachmentService.loadAsResource(attachment.id), attachment.mimeType);
}
}
sender.send(mimeMessage);
} catch (MessagingException | IOException | TemplateException e) {
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,17 @@
package com.zsc.edu.gateway.framework.message.sms;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @author harry_yao
*/
@Data
@ConfigurationProperties("sms")
@Configuration
public class SmsProperties {
public String apiKey = "4d8de516324886549d0ba3ddc4bf6f47";
public String singleSendUrl = "https://sms.yunpian.com/v2/sms/single_send.json";
public String batchSendUrl = "https://sms.yunpian.com/v2/sms/batch_send.json";
}

View File

@ -0,0 +1,47 @@
package com.zsc.edu.gateway.framework.message.sms;
import jakarta.annotation.Resource;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestClient;
import java.util.Set;
import java.util.stream.Collectors;
/**
* @author pegnzheng
*/
@AllArgsConstructor
@Component
public class SmsSender {
private final SmsProperties properties;
@Resource
private final RestClient restClient;
@Async
public void send(String mobile, String text) {
MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
params.add("apikey", properties.apiKey);
params.add("mobile", mobile);
params.add("text", text);
restClient.post().uri(properties.singleSendUrl).body(params);
}
@Async
public void send(Set<String> mobiles, String text) {
MultiValueMap<String, Object> params = new LinkedMultiValueMap<>();
params.add("apikey", properties.apiKey);
params.add("mobile", mobiles.stream().filter(StringUtils::hasText).collect(Collectors.joining(",")));
params.add("text", text);
restClient.post().uri(properties.batchSendUrl).body(params);
}
}

View File

@ -4,10 +4,7 @@ import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.*;
import org.springframework.core.io.FileSystemResource;
import java.io.Serializable;
@ -18,9 +15,9 @@ import java.time.LocalDateTime;
*
* @author harry_yao
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@TableName(value ="attachment")
public class Attachment implements Serializable {

View File

@ -2,19 +2,22 @@ package com.zsc.edu.gateway.modules.attachment.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zsc.edu.gateway.modules.attachment.entity.Attachment;
import org.springframework.core.io.Resource;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
/**
* @author fantianzhi
* @description 针对表attach_file(票据附件表)的数据库操作Service
* @createDate 2024-01-28 19:48:22
* &#064;description 针对表attach_file(票据附件表)的数据库操作Service
* &#064;createDate 2024-01-28 19:48:22
*/
public interface AttachmentService extends IService<Attachment> {
Attachment store(Attachment.Type type, MultipartFile file) throws IOException;
Attachment stores(Attachment.Type type, MultipartFile file)throws IOException;
Resource loadAsResource(String id);
Attachment.Wrapper loadAsWrapper(String id);
}

View File

@ -142,6 +142,7 @@ public class AttachmentServiceImpl extends ServiceImpl<AttachmentRepository, Att
return save(file, sha1, filename, mimeType, type);
}
@Override
public Resource loadAsResource(String id) {
Path file = attachmentPath.resolve(id);
FileSystemResource resource = new FileSystemResource(file);
@ -152,6 +153,7 @@ public class AttachmentServiceImpl extends ServiceImpl<AttachmentRepository, Att
}
}
@Override
public Attachment.Wrapper loadAsWrapper(String id) {
Path file = attachmentPath.resolve(id);
FileSystemResource resource = new FileSystemResource(file);

View File

@ -7,7 +7,6 @@ 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.BulletinVoService;
import com.zsc.edu.gateway.modules.notice.vo.BulletinVo;
import lombok.AllArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
@ -28,8 +27,6 @@ import java.util.Set;
public class BulletinController {
private final BulletinService service;
private final BulletinVoService bulletinVoService;
/**
* 普通用户查看公告详情
*
@ -37,7 +34,7 @@ public class BulletinController {
* @return 公告
*/
@GetMapping("/self/{id}")
public BulletinVo selfDetail(@AuthenticationPrincipal UserDetailsImpl userDetails,@PathVariable("id") Long id) {
public List<BulletinVo> selfDetail(@AuthenticationPrincipal UserDetailsImpl userDetails, @PathVariable("id") Long id) {
return service.detail(userDetails,id, Bulletin.State.publish);
}
@ -47,11 +44,11 @@ public class BulletinController {
* @param query 查询表单
* @return 分页数据
*/
@GetMapping("/query")
@GetMapping("/self")
public IPage<BulletinVo> getBulletins( BulletinQuery query) {
query.setState(Bulletin.State.publish);
Page<BulletinVo> page = new Page<>(query.getPageNum(), query.getPageSize());
return bulletinVoService.selectPageByConditions(page, query);
return service.selectPageByConditions(page, query);
}
/**
@ -62,7 +59,7 @@ public class BulletinController {
*/
@GetMapping("/{id}")
@PreAuthorize("hasAuthority('BULLETIN_QUERY')")
public BulletinVo detail(@AuthenticationPrincipal UserDetailsImpl userDetails, @PathVariable("id") Long id) {
public List<BulletinVo> detail(@AuthenticationPrincipal UserDetailsImpl userDetails, @PathVariable("id") Long id) {
return service.detail(userDetails,id, null);
}
@ -76,7 +73,7 @@ public class BulletinController {
@PreAuthorize("hasAuthority('BULLETIN_QUERY')")
public IPage<BulletinVo> query( BulletinQuery query) {
Page<BulletinVo> page = new Page<>(query.getPageNum(), query.getPageSize());
return bulletinVoService.selectPageByConditions(page, query);
return service.selectPageByConditions(page, query);
}
/**

View File

@ -1,164 +1,157 @@
//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 = new UserMessage.Id(userDetails.id, messageId);
// return service.detail(id);
// }
//
// /**
// * 普通用户分页查询消息不能设置查询参数userId和username
// *
// * @param userDetails 操作用户
// * @param query 查询参数
// * @param page 分页参数
// * @return 分页数据
// */
// @GetMapping("/self")
// public Page<UserMessage> selfPage(@AuthenticationPrincipal UserDetailsImpl userDetails, UserMessageQuery query, Page<UserMessage> 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<Long> 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<UserMessage> 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<MessageSetting> getSetting() {
// return service.getSetting();
// }
//
// /**
// * 设置消息推送方式
// *
// * @param settings 表单数据
// * @return 消息设置
// */
// @PatchMapping("/setting")
// @PreAuthorize("hasAuthority('MESSAGE_SETTING')")
// public List<MessageSetting> saveSetting(
// @RequestBody Set<MessageSetting> settings
// ) {
// return service.saveSetting(settings);
// }
//
//}
package com.zsc.edu.gateway.modules.notice.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zsc.edu.gateway.framework.security.UserDetailsImpl;
import com.zsc.edu.gateway.modules.notice.dto.UserMessageDto;
import com.zsc.edu.gateway.modules.notice.entity.MessagePayload;
import com.zsc.edu.gateway.modules.notice.entity.MessageSetting;
import com.zsc.edu.gateway.modules.notice.query.UserMessageQuery;
import com.zsc.edu.gateway.modules.notice.service.UserMessageService;
import com.zsc.edu.gateway.modules.notice.vo.UserMessageVo;
import com.zsc.edu.gateway.modules.system.entity.User;
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.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/{messageId}")
public UserMessageVo selfDetail(@AuthenticationPrincipal UserDetailsImpl userDetails, @PathVariable("messageId") Long messageId) {
return service.detail(messageId, userDetails.getId());
}
/**
* 普通用户分页查询消息不能设置查询参数userId和username
*
* @param userDetails 操作用户
* @param query 查询参数
* @return 分页数据
*/
@GetMapping("/self")
public IPage<UserMessageVo> selfPage(@AuthenticationPrincipal UserDetailsImpl userDetails, UserMessageQuery query) {
query.userId = userDetails.id;
query.name = null;
Page<UserMessageVo> page = new Page<>(query.getPageNum(), query.getPageSize());
return service.page(page, query);
}
/**
* 普通用户统计自己未读消息数量
*
* @param userDetails 操作用户
* @return 数据
*/
@GetMapping("/countUnread")
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 List<Long> messageIds) {
return service.markAsRead(userDetails, messageIds);
}
/**
* 管理查询消息详情
*
* @param userId 用户ID
* @param messageId 消息ID
* @return 用户消息详情
*/
@GetMapping("/{userId}/{messageId}")
@PreAuthorize("hasAuthority('MESSAGE_QUERY')")
public UserMessageVo detail(@PathVariable("userId") Long userId, @PathVariable("messageId") Long messageId) {
return service.detail(messageId, userId);
}
/**
* 管理员分页查询消息
*
* @param query 查询参数
* @return 分页数据
*/
@GetMapping
@PreAuthorize("hasAuthority('MESSAGE_QUERY')")
public IPage<UserMessageVo> page(UserMessageQuery query) {
Page<UserMessageVo> page = new Page<>(query.getPageNum(), query.getPageSize());
return service.page(page, query);
}
/**
* 管理员手动创建消息
*
* @param dto 表单数据
* @return 消息列表
*/
@PostMapping
@PreAuthorize("hasAuthority('MESSAGE_CREATE')")
public Boolean create(@RequestBody UserMessageDto dto) {
return service.createByAdmin(dto);
}
/**
* 管理员为消息添加附件
*
* @param messageId 消息ID
* @param attachmentIds 附件ID集合
* @return 消息列表
*/
@PostMapping("/attachment/{messageId}")
@PreAuthorize("hasAuthority('MESSAGE_CREATE')")
public Boolean insertInto(@PathVariable("messageId") Long messageId, @RequestBody List<String> attachmentIds) {
return service.insertInto(messageId, attachmentIds);
}
/**
* 获取消息推送方式
*
* @return 消息推送方式列表
*/
@GetMapping("/setting")
@PreAuthorize("hasAuthority('MESSAGE_SETTING')")
public List<MessageSetting> getSetting() {
return service.getSetting();
}
/**
* 设置消息推送方式
*
* @param settings 表单数据
* @return 消息设置
*/
@PatchMapping("/setting")
@PreAuthorize("hasAuthority('MESSAGE_SETTING')")
public List<MessageSetting> saveSetting(@RequestBody List<MessageSetting> settings) {
return service.saveSetting(settings);
}
}

View File

@ -1,17 +0,0 @@
//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;
//}

View File

@ -0,0 +1,24 @@
package com.zsc.edu.gateway.modules.notice.dto;
import lombok.Data;
import java.util.List;
/**
* @author zhuang
*/
@Data
public class PageDto<T> {
/**
* 总条数
*/
private Long total;
/**
* 总页数
*/
private Integer pages;
/**
* 集合
*/
private List<T> list;
}

View File

@ -33,17 +33,17 @@ public class UserMessageDto {
/**
* 是否需要发送邮件
*/
public boolean email;
public Boolean email;
/**
* 是否需要发送短信
*/
public boolean sms;
public Boolean sms;
/**
* 消息内容是否富文本True则以富文本形式发送
*/
public boolean html;
public Boolean html;
/**
* 消息标题
@ -57,9 +57,5 @@ public class UserMessageDto {
@NotBlank(message = "消息内容不能为空")
public String content;
/**
* 附件ID集合
*/
public Set<String> attachmentIds;
}

View File

@ -30,22 +30,22 @@ public class Message extends BaseEntity {
/**
* 是否系统生成
*/
public boolean system;
public Boolean system;
/**
* 是否需要发送邮件
*/
public boolean email;
public Boolean email;
/**
* 是否需要发送短信
*/
public boolean sms;
public Boolean sms;
/**
* 消息内容是否富文本True则以富文本形式发送
*/
public boolean html;
public Boolean html;
/**
* 标题

View File

@ -13,19 +13,10 @@ import lombok.Setter;
@Getter
@NoArgsConstructor
@AllArgsConstructor
@TableName("sys_bulletin_user")
public class BulletinUser {
@TableName("sys_message_attachment")
public class MessageAttachment {
/**
* 公告ID
*/
public Long bulletinId;
/**
* 用户ID
*/
public Long userId;
/**
* 是否已读
*/
public Boolean isRead=true;
private Long messageId;
private String attachmentId;
}

View File

@ -12,7 +12,7 @@ public abstract class MessagePayload {
public MessageType type;
public String content;
public boolean html;
public Boolean html;
public static class Other extends MessagePayload {
public Other(String content) {

View File

@ -7,6 +7,8 @@ import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import java.util.Objects;
/**
* 消息设置
@ -29,21 +31,23 @@ public class MessageSetting {
/**
* 是否发送邮件
*/
public boolean email;
public Boolean email;
/**
* 是否发送短信
*/
public boolean sms;
public Boolean sms;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
MessageSetting that = (MessageSetting) o;
return id == that.id;
return Objects.equals(id, that.id);
}
@Override

View File

@ -1,12 +1,10 @@
package com.zsc.edu.gateway.modules.notice.entity;
import com.baomidou.mybatisplus.annotation.TableField;
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 lombok.*;
import java.io.Serializable;
import java.time.LocalDateTime;
@ -16,8 +14,7 @@ import java.time.LocalDateTime;
*
* @author harry_yao
*/
@Setter
@Getter
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("sys_user_message")
@ -25,20 +22,23 @@ public class UserMessage implements Serializable {
@TableId
private Long id;
/**
* 用户
*/
public User user;
/**
* 消息
* 用户ID
*/
public Message message;
public Long userId;
/**
* 消息ID
*/
public Long messageId;
/**
* 是否已读
*/
public boolean read;
public Boolean isRead;
/**
* 阅读时间

View File

@ -1,11 +0,0 @@
//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<>{
//}

View File

@ -27,17 +27,8 @@ public class BulletinQuery {
private Integer pageSize = 10;
private String title;
private Bulletin.State state;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime publishTimeBegin;
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private LocalDateTime publishTimeEnd;
private Boolean isRead;
public LambdaQueryWrapper<BulletinVo> wrapper() {
LambdaQueryWrapper<BulletinVo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.like(StringUtils.hasText(this.title), BulletinVo::getTitle, this.title);
queryWrapper.eq(Objects.nonNull(this.state), BulletinVo::getState, this.state);
if(Objects.nonNull(this.publishTimeBegin)&&Objects.nonNull(this.publishTimeEnd)) {
queryWrapper.between(BulletinVo::getPublishTime,publishTimeBegin,publishTimeEnd);
}
queryWrapper.eq(Objects.nonNull(this.isRead), BulletinVo::getIsRead, this.isRead);
return queryWrapper;
}
}

View File

@ -52,7 +52,7 @@ public class UserMessageQuery {
/**
* 是否已读
*/
public Boolean read;
public Boolean isRead;
/**
* 消息创建时间区间起始
@ -66,12 +66,7 @@ public class UserMessageQuery {
@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)
public LocalDateTime createAtEnd;
private Integer pageNum = 1;
private Integer pageSize = 10;
public LambdaQueryWrapper<UserMessage> wrapper() {
LambdaQueryWrapper<UserMessage> queryWrapper = new LambdaQueryWrapper<>();
LambdaQueryWrapper<Message> messageQueryWrapper = new LambdaQueryWrapper<>();
messageQueryWrapper.like(StringUtils.hasText(this.title), Message::getTitle, this.title);
// messageQueryWrapper.eq(Objects::nonNull(this.type) Message::getType, this.type);
return queryWrapper;
}
}

View File

@ -3,6 +3,9 @@ package com.zsc.edu.gateway.modules.notice.repo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zsc.edu.gateway.modules.notice.entity.BulletinAttachment;
/**
* @author zhuang
*/
public interface BulletinAttachmentRepository extends BaseMapper<BulletinAttachment> {
}

View File

@ -4,13 +4,14 @@ package com.zsc.edu.gateway.modules.notice.repo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zsc.edu.gateway.modules.notice.dto.PageDto;
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.vo.BulletinVo;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* 公告Repo
@ -20,6 +21,7 @@ import org.apache.ibatis.annotations.Select;
public interface BulletinRepository extends BaseMapper<Bulletin> {
BulletinVo selectByBulletinId(@Param("bulletinId") Long bulletinId);
List<BulletinVo> selectByBulletinId(@Param("bulletinId") Long bulletinId);
IPage<BulletinVo> selectPageByConditions(Page<BulletinVo> page, @Param("query") BulletinQuery query);
}

View File

@ -1,16 +0,0 @@
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<BulletinUser> {
// @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);
}

View File

@ -3,6 +3,9 @@ package com.zsc.edu.gateway.modules.notice.repo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zsc.edu.gateway.modules.notice.entity.MessageSetting;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* 消息设置Repo
@ -10,5 +13,6 @@ import com.zsc.edu.gateway.modules.notice.entity.MessageSetting;
* @author harry_yao
*/
public interface MessageSettingRepository extends BaseMapper<MessageSetting> {
@Select("select * from sys_message_setting")
List<MessageSetting> findAll();
}

View File

@ -1,7 +1,14 @@
package com.zsc.edu.gateway.modules.notice.repo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zsc.edu.gateway.modules.notice.entity.UserMessage;
import com.zsc.edu.gateway.modules.notice.query.BulletinQuery;
import com.zsc.edu.gateway.modules.notice.query.UserMessageQuery;
import com.zsc.edu.gateway.modules.notice.vo.BulletinVo;
import com.zsc.edu.gateway.modules.notice.vo.UserMessageVo;
import org.apache.ibatis.annotations.Param;
/**
* 用户消息Repo
@ -9,5 +16,7 @@ import com.zsc.edu.gateway.modules.notice.entity.UserMessage;
* @author harry_yao
*/
public interface UserMessageRepository extends BaseMapper<UserMessage> {
UserMessageVo selectByMessageIdAndUserId(@Param("messageId") Long messageId, @Param("userId") Long userId);
IPage<UserMessageVo> query(Page<UserMessageVo> page, @Param("query") UserMessageQuery query);
}

View File

@ -1,5 +1,6 @@
package com.zsc.edu.gateway.modules.notice.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zsc.edu.gateway.framework.security.UserDetailsImpl;
@ -20,7 +21,7 @@ import java.util.Set;
public interface BulletinService extends IService<Bulletin> {
BulletinVo detail(UserDetailsImpl userDetails, Long id, Bulletin.State state);
List<BulletinVo> detail(UserDetailsImpl userDetails, Long id, Bulletin.State state);
Bulletin create(UserDetailsImpl userDetails, BulletinDto dto);
@ -34,4 +35,5 @@ public interface BulletinService extends IService<Bulletin> {
Boolean insertInto(Long bulletinId, Set<String> attachmentIds);
IPage<BulletinVo> selectPageByConditions(Page<BulletinVo> page, BulletinQuery query);
}

View File

@ -1,16 +0,0 @@
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<BulletinUser> {
Boolean isRead(UserDetailsImpl userDetails, Long id);
void toggleIsRead(Long id);
}

View File

@ -1,12 +1,21 @@
package com.zsc.edu.gateway.modules.notice.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zsc.edu.gateway.framework.security.UserDetailsImpl;
import com.zsc.edu.gateway.modules.notice.dto.UserMessageDto;
import com.zsc.edu.gateway.modules.notice.entity.MessagePayload;
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.BulletinQuery;
import com.zsc.edu.gateway.modules.notice.query.UserMessageQuery;
import com.zsc.edu.gateway.modules.notice.vo.BulletinVo;
import com.zsc.edu.gateway.modules.notice.vo.UserMessageVo;
import com.zsc.edu.gateway.modules.system.entity.User;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Set;
/**
@ -14,11 +23,23 @@ import java.util.Set;
*
* @author harry_yao
*/
public interface UserMessageService extends IService<UserMessageService> {
public interface UserMessageService extends IService<UserMessage> {
Boolean createByAdmin(UserMessageDto dto);
public UserMessage detail(Long id);
UserMessageVo detail(Long messageId, Long userId);
Boolean insertInto(Long messageId, List<String> attachmentIds);
List<MessageSetting> getSetting();
IPage<UserMessageVo> page(Page<UserMessageVo> page, UserMessageQuery query);
Integer countUnread(UserDetailsImpl userDetails);
Integer markAsRead(UserDetailsImpl userDetails, List<Long> messageIds);
@Transactional
List<MessageSetting> saveSetting(List<MessageSetting> settings);
public boolean createBySystem(Set<User> receivers, MessagePayload payload);
}

View File

@ -1,6 +1,7 @@
package com.zsc.edu.gateway.modules.notice.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zsc.edu.gateway.exception.ConstraintException;
@ -14,7 +15,6 @@ import com.zsc.edu.gateway.modules.notice.query.BulletinQuery;
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 com.zsc.edu.gateway.modules.notice.vo.BulletinVo;
import com.zsc.edu.gateway.modules.system.repo.UserRepository;
import lombok.AllArgsConstructor;
@ -38,7 +38,6 @@ public class BulletinServiceImpl extends ServiceImpl<BulletinRepository, Bulleti
private final BulletinRepository repo;
private final BulletinAttachmentService bulletinAttachmentService;
private final BulletinUserService bulletinUserService;
private final UserRepository userRepository;
/**
* 查询公告详情
@ -48,16 +47,21 @@ public class BulletinServiceImpl extends ServiceImpl<BulletinRepository, Bulleti
* @return 公告详情
*/
@Override
public BulletinVo detail(UserDetailsImpl userDetails, Long id, Bulletin.State state) {
BulletinVo bulletin = repo.selectByBulletinId(id);
public List<BulletinVo> detail(UserDetailsImpl userDetails, Long id, Bulletin.State state) {
List<BulletinVo> bulletins = repo.selectByBulletinId(id);
if (bulletins.isEmpty()) {
return Collections.emptyList();
}
for (BulletinVo bulletin : bulletins) {
if (state != null) {
bulletin.getState().checkStatus(state);
}
bulletin.setEditUsername(userRepository.selectNameById(bulletin.getEditUserId()));
bulletin.setPublishUsername(userRepository.selectNameById(bulletin.getPublishUserId()));
bulletin.setCloseUsername(userRepository.selectNameById(bulletin.getCloseUserId()));
bulletinUserService.isRead(userDetails, id);
return bulletin;
}
return bulletins;
}
/**
* 新建公告
@ -95,7 +99,6 @@ public class BulletinServiceImpl extends ServiceImpl<BulletinRepository, Bulleti
bulletin.setCreateBy(userDetails.getName());
bulletin.setCreateTime(LocalDateTime.now());
bulletin.state = edit;
bulletinUserService.toggleIsRead(id);
return updateById(bulletin);
}
/**
@ -177,12 +180,14 @@ public class BulletinServiceImpl extends ServiceImpl<BulletinRepository, Bulleti
*为公告添加附件
*
* @param bulletinId bulletinId
* @param attachments attachments
* @param attachmentIds attachments
* @return true
*/
@Override
public Boolean insertInto(Long bulletinId, Set<String> attachments) {
List<BulletinAttachment> bulletinAttachments=attachments.stream().map(bulletinAttachment->new BulletinAttachment(bulletinId, attachments.toString())).toList();
public Boolean insertInto(Long bulletinId, Set<String> attachmentIds) {
List<BulletinAttachment> bulletinAttachments = attachmentIds.stream()
.map(attachmentId -> new BulletinAttachment(bulletinId, attachmentId))
.collect(Collectors.toList());
return bulletinAttachmentService.saveBatch(bulletinAttachments);
}
@ -195,4 +200,9 @@ public class BulletinServiceImpl extends ServiceImpl<BulletinRepository, Bulleti
queryWrapper.in(Bulletin::getId, ids);
return repo.selectList(queryWrapper);
}
@Override
public IPage<BulletinVo> selectPageByConditions(Page<BulletinVo> page, BulletinQuery query) {
return baseMapper.selectPageByConditions(page, query);
}
}

View File

@ -1,60 +0,0 @@
package com.zsc.edu.gateway.modules.notice.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
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<BulletinUserRepository, BulletinUser> implements BulletinUserService {
/**
* 已读公告每次已读自动获取用户id与公告id加入联表
*
* @param userDetails userDetails
* @param id id
* return true
*/
@Override
public Boolean isRead(UserDetailsImpl userDetails,Long id) {
if (id == null || userDetails.getId() == null) {
throw new IllegalArgumentException("Bulletin ID and User ID cannot be null");
}
QueryWrapper<BulletinUser> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("bulletin_id", id)
.eq("user_id", userDetails.getId());
BulletinUser existingUser = getOne(queryWrapper);
if (existingUser == null) {
BulletinUser newUser = new BulletinUser();
newUser.setBulletinId(id);
newUser.setUserId(userDetails.getId());
newUser.setIsRead(false);
save(newUser);
} else {
UpdateWrapper<BulletinUser> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("bulletin_id", id).eq("user_id", userDetails.getId()).set("is_read",false);
}
return true;
}
/**
* 更新公告后修改已读状态
*
* @param id id
*/
@Override
public void toggleIsRead(Long id) {
UpdateWrapper<BulletinUser> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("bulletin_id",id).set("is_read",true);
}
}

View File

@ -1,170 +1,226 @@
//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<UserMessageRepository, UserMessage> 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 用户消息详情
// */
// @Override
// public UserMessage detail(Long id) {
// return getById(id);
// }
//
// /**
// * 分页查询用户消息
// *
// * @param query 查询表单
// * @param pageable 分页参数
// * @return 页面数据
// */
//// public Page<UserMessage> page(UserMessageQuery query, Pageable pageable) {
//// return this.page(query, pageable);
//// }
//
// /**
// * 管理员手动创建用户消息并发送
// *
// * @param dto 表单数据
// * @return 创建的用户消息列表
// */
// @Transactional
// @Override
// public Boolean createByAdmin(UserMessageDto dto) {
// Set<User> users = dto.userIds.stream().map(userService::getById).collect(Collectors.toSet());
// List<Attachment> 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<UserMessage> 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
// @Override
// public boolean createBySystem(Set<User> 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<UserMessage> userMessages = receivers.stream().map(user ->
// new UserMessage(null, user, message, false, null)).collect(Collectors.toSet());
//// List<UserMessage> 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<Long> messageIds) {
//// if (CollectionUtils.isEmpty(messageIds)) {
//// return repo.markAsRead(userDetails.id, LocalDateTime.now());
//// }
//// return repo.markAsRead(userDetails.id, messageIds, LocalDateTime.now());
//// }
//
// /**
// * 获取所有消息推送方式
// *
// * @return 消息设置列表
// */
//// public List<MessageSetting> getSetting() {
//// return messageSettingRepo.findAll();
//// }
//
// /**
// * 设置消息推送方式
// *
// * @param settings 消息设置集合
// * @return 消息设置列表
// */
//// public List<MessageSetting> saveSetting(Set<MessageSetting> settings) {
//// return messageSettingRepo.saveAll(settings);
//// }
//
// /**
// * 以邮件短信等形式发送消息只有非html格式的消息才能以短信方式发送
// *
// * @param users 接收者
// * @param message 消息
// */
// @Async
// void send(Set<User> 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);
// }
// }
//
//}
package com.zsc.edu.gateway.modules.notice.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zsc.edu.gateway.framework.message.email.EmailSender;
import com.zsc.edu.gateway.framework.message.sms.SmsSender;
import com.zsc.edu.gateway.framework.security.UserDetailsImpl;
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.*;
import com.zsc.edu.gateway.modules.notice.query.UserMessageQuery;
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.MessageAttachmentService;
import com.zsc.edu.gateway.modules.notice.service.UserMessageService;
import com.zsc.edu.gateway.modules.notice.vo.UserMessageVo;
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.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
/**
* 用户消息Service
*
* @author harry_yao
*/
@AllArgsConstructor
@Service
public class UserMessageServiceImpl extends ServiceImpl<UserMessageRepository, UserMessage> 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;
private final UserMessageRepository userMessageRepository;
private final MessageAttachmentService messageAttachmentService;
/**
* 查询消息详情
*
* @param messageId 消息ID
* @param userId 用户ID
* @return 查询详情
*/
@Override
public UserMessageVo detail(Long messageId, Long userId) {
return userMessageRepository.selectByMessageIdAndUserId(messageId, userId);
}
/**
* 分页查询用户消息
*
* @param query 查询表单
* @param page 分页参数
* @return 页面数据
*/
@Override
public IPage<UserMessageVo> page(Page<UserMessageVo> page, UserMessageQuery query) {
return userMessageRepository.query(page, query);
}
/**
* 统计用户未读消息数量
*
* @param userDetails 操作用户
* @return 未读消息数量
*/
@Override
public Integer countUnread(UserDetailsImpl userDetails) {
QueryWrapper<UserMessage> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("user_id", userDetails.getId()).eq("is_read", true);
return Math.toIntExact(userMessageRepository.selectCount(queryWrapper));
}
/**
* 设为已读
*
* @param userDetails 操作用户
* @param messageIds 消息ID集合如为空则将该用户的所有未读消息设为已读
* @return 修改记录数量
*/
@Override
public Integer markAsRead(UserDetailsImpl userDetails, List<Long> messageIds) {
if (CollectionUtils.isEmpty(messageIds)) {
throw new RuntimeException("messageIds is NULL!");
}
UpdateWrapper<UserMessage> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("user_id", userDetails.getId()).in("message_id", messageIds);
updateWrapper.set("is_read", false);
updateWrapper.set("read_time", LocalDateTime.now());
return userMessageRepository.update(updateWrapper);
}
/**
* 管理员手动创建用户消息并发送
*
* @param dto 表单数据
* @return 创建的用户消息列表
*/
@Transactional
@Override
public Boolean createByAdmin(UserMessageDto dto) {
Set<User> users = dto.userIds.stream()
.map(userService::getById)
.filter(Objects::nonNull)
.collect(Collectors.toSet());
if (users.isEmpty()) {
throw new RuntimeException("No valid users found for the provided userIds.");
}
Message message = new Message(dto.type, false, dto.email, dto.sms, dto.html,
dto.title, dto.content, null);
messageRepo.insert(message);
Set<UserMessage> userMessages = users.stream()
.map(user -> new UserMessage(null, user.getId(), message.getId(), false, null))
.collect(Collectors.toSet());
send(users, message);
return saveBatch(userMessages);
}
/**
* 将附件关联信息插入数据库
*
* @param messageId 消息ID用于关联消息和附件
* @param attachmentIds 附件ID列表表示需要插入的附件
* @return 返回一个布尔值表示批量插入是否成功
*/
@Override
public Boolean insertInto(Long messageId, List<String> attachmentIds) {
List<MessageAttachment> messageAttachments = attachmentIds.stream()
.map(attachmentId -> new MessageAttachment(messageId, attachmentId))
.collect(Collectors.toList());
return messageAttachmentService.saveBatch(messageAttachments);
}
/**
* 获取所有消息推送方式
*
* @return 消息设置列表
*/
@Override
public List<MessageSetting> getSetting() {
return messageSettingRepo.findAll();
}
/**
* 设置消息推送方式
*
* @param settings 消息设置集合
* @return 消息设置列表
*/
@Transactional
@Override
public List<MessageSetting> saveSetting(List<MessageSetting> settings) {
if (CollectionUtils.isEmpty(settings)) {
throw new RuntimeException("settings is NULL!");
}
for (MessageSetting setting : settings) {
try {
messageSettingRepo.insert(setting);
} catch (Exception e) {
throw new RuntimeException("设置失败" + e.getMessage());
}
}
return settings;
}
/**
* 以邮件短信等形式发送消息只有非html格式的消息才能以短信方式发送
*
* @param users 接收者
* @param message 消息
*/
@Async
void send(Set<User> 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);
}
}
/**
* 系统自动创建用户消息并发送
*
* @param receivers 接收者
* @param payload 消息内容
*/
@Transactional
public Boolean createBySystem(Set<User> 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<UserMessage> userMessages = receivers.stream().map(user ->
new UserMessage(null, user.getId(), message.getId(), false, null)).collect(Collectors.toSet());
send(receivers, message);
return saveBatch(userMessages);
}
}

View File

@ -0,0 +1,45 @@
package com.zsc.edu.gateway.modules.notice.vo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.zsc.edu.gateway.modules.attachment.entity.Attachment;
import com.zsc.edu.gateway.modules.attachment.vo.AttachmentVo;
import com.zsc.edu.gateway.modules.notice.entity.Bulletin;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
import java.util.List;
/**
* @author zhuang
*/
@Data
public class BulletinVo {
private Long id;
private String title;
private Bulletin.State state = Bulletin.State.edit;
private Boolean top;
private Long editUserId;
private String editUsername;
private LocalDateTime editTime;
private Long publishUserId;
private String publishUsername;
private LocalDateTime publishTime;
private Long closeUserId;
private String closeUsername;
private LocalDateTime closeTime;
private String content;
@TableField(value = "create_time", fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(value = "create_by", fill = FieldFill.INSERT)
private String createBy;
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
@TableField(value = "update_by", fill = FieldFill.INSERT_UPDATE)
private String updateBy;
List<AttachmentVo> attachmentVos;
}

View File

@ -0,0 +1,51 @@
package com.zsc.edu.gateway.modules.notice.vo;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.zsc.edu.gateway.modules.attachment.entity.Attachment;
import com.zsc.edu.gateway.modules.notice.entity.Message;
import com.zsc.edu.gateway.modules.notice.entity.MessageType;
import com.zsc.edu.gateway.modules.system.entity.User;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
/**
* @author zhuang
*/
@Data
public class UserMessageVo {
private Long id;
public Long userId;
public User user;
public Long messageId;
public Message message;
public Boolean isRead;
public LocalDateTime readTime;
public String username;
public String name;
public String avatar;
public String address;
public MessageType type = MessageType.other;
public Boolean system;
public Boolean email;
public Boolean sms;
public Boolean html;
public String title;
public String content;
private String remark;
@TableField(value = "create_time", fill = FieldFill.INSERT)
private LocalDateTime createTime;
@TableField(value = "create_by", fill = FieldFill.INSERT)
private String createBy;
@TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE)
private LocalDateTime updateTime;
@TableField(value = "update_by", fill = FieldFill.INSERT_UPDATE)
private String updateBy;
public List<Attachment> attachments;
}

View File

@ -9,10 +9,13 @@ import com.zsc.edu.gateway.modules.system.entity.User;
import com.zsc.edu.gateway.modules.system.query.DeptQuery;
import com.zsc.edu.gateway.modules.system.service.DeptService;
import com.zsc.edu.gateway.modules.system.service.UserService;
import com.zsc.edu.gateway.modules.system.vo.DeptTree;
import lombok.AllArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 部门Controller
*
@ -29,13 +32,11 @@ public class DeptController {
/**
* 返回管理部门列表 hasAuthority('DEPT_QUERY')
*
* @param query 查询表单
* @return 部门列表
*/
@GetMapping
@PreAuthorize("hasAuthority('DEPT_QUERY')")
public Page<Dept> query(DeptQuery query, Page<Dept> page) {
return service.page(page, query.wrapper());
@GetMapping()
public List<DeptTree> getDeptTree() {
return service.getDeptTree();
}
/**

View File

@ -40,7 +40,6 @@ public class UserController {
private final RoleService roleService;
private final DeptService deptService;
private final RoleAuthService roleAuthService;
private final AuthorityService authorityService;
/**

View File

@ -5,7 +5,9 @@ import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Getter;
import lombok.Setter;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
@ -45,6 +47,9 @@ public class Dept extends BaseEntity {
private Boolean enabled = true;
@TableField(exist = false)
public Set<Dept> children = new HashSet<>(0);
public List<Dept> children = new ArrayList<>(0);
@TableField(exist = false)
public List<User> members = new ArrayList<>(0);
}

View File

@ -2,6 +2,13 @@ package com.zsc.edu.gateway.modules.system.repo;
import com.zsc.edu.gateway.modules.system.entity.Dept;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.zsc.edu.gateway.modules.system.entity.User;
import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* <p>
@ -12,5 +19,6 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
* @since 2023-04-06
*/
public interface DeptRepository extends BaseMapper<Dept> {
@Select("SELECT d.*, u.* FROM sys_dept d LEFT JOIN sys_user u ON d.id = u.dept_id")
List<Dept> selectAllWithMembers();
}

View File

@ -3,6 +3,9 @@ package com.zsc.edu.gateway.modules.system.service;
import com.zsc.edu.gateway.modules.system.dto.DeptDto;
import com.zsc.edu.gateway.modules.system.entity.Dept;
import com.baomidou.mybatisplus.extension.service.IService;
import com.zsc.edu.gateway.modules.system.vo.DeptTree;
import java.util.List;
/**
* <p>
@ -28,11 +31,13 @@ public interface DeptService extends IService<Dept> {
Boolean edit(DeptDto dto, Long id);
Boolean toggle(Long id);
//
// /**
// * 生成部门树结构
// * @param id
// * @return
// */
//// Dept listTree(Long id);
/**
* 生成部门树结构
* @param id
* @return
*/
// Dept listTree(Long id);
List<DeptTree> getDeptTree();
}

View File

@ -2,15 +2,24 @@ package com.zsc.edu.gateway.modules.system.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zsc.edu.gateway.exception.ConstraintException;
import com.zsc.edu.gateway.framework.DeptTreeUtil;
import com.zsc.edu.gateway.modules.system.dto.DeptDto;
import com.zsc.edu.gateway.modules.system.entity.Dept;
import com.zsc.edu.gateway.modules.system.entity.User;
import com.zsc.edu.gateway.modules.system.mapper.DeptMapper;
import com.zsc.edu.gateway.modules.system.repo.DeptRepository;
import com.zsc.edu.gateway.modules.system.repo.UserRepository;
import com.zsc.edu.gateway.modules.system.service.DeptService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zsc.edu.gateway.modules.system.vo.DeptTree;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* <p>
* 部门 服务实现类
@ -24,6 +33,8 @@ import org.springframework.stereotype.Service;
public class DeptServiceImpl extends ServiceImpl<DeptRepository, Dept> implements DeptService {
private final DeptMapper mapper;
private final DeptRepository repo;
private final UserRepository userRepository;
@Override
public Dept create(DeptDto dto) {
@ -52,15 +63,15 @@ public class DeptServiceImpl extends ServiceImpl<DeptRepository, Dept> implement
return updateById(dept);
}
// @Override
// public Dept listTree(Long deptId) {
// Dept rootDept;
// List<Dept> all = list(null);
// HashSet<Dept> deptList = new HashSet<>(all);
// rootDept = DeptTreeUtil.initTree(deptList);
// if (deptId != null) {
// return rootDept.id.equals(deptId) ? rootDept : DeptTreeUtil.getChildNode(rootDept.children, deptId);
// }
// return rootDept;
// }
@Override
public List<DeptTree> getDeptTree() {
List<Dept> depots = repo.selectList(null);
List<User> users = userRepository.selectList(null);
Map<Long, List<User>> userMap = new HashMap<>();
for (User user : users) {
userMap.computeIfAbsent(user.getDeptId(), k -> new ArrayList<>()).add(user);
}
return DeptTreeUtil.buildDeptTree(depots, userMap);
}
}

View File

@ -35,6 +35,9 @@ spring:
properties:
mail:
smtp:
auth: true
starttls:
enable: true
socketFactoryClass: javax.net.ssl.SSLSocketFactory
#表示开启 DEBUG 模式,这样,邮件发送过程的日志会在控制台打印出来,方便排查错误
debug: true

View File

@ -145,9 +145,7 @@ create index inx_pid
create table sys_message
(
id integer not null
constraint sys_message_pk
primary key,
id SERIAL PRIMARY KEY,
type integer not null,
system boolean not null,
email boolean not null,
@ -156,9 +154,9 @@ create table sys_message
title varchar,
content varchar,
remark varchar,
create_time time,
create_time timestamp,
create_by varchar,
update_time time,
update_time timestamp,
update_by varchar
);
comment on table sys_message is '消息';
@ -177,6 +175,7 @@ comment on column sys_message.update_by is '更新人';
alter table sys_message
owner to postgres;
create table sys_message_attach
(
message_id bigint not null,
@ -297,16 +296,16 @@ create table sys_user_message
id bigint not null
constraint sys_user_message_pk
primary key,
"user" sys_user not null,
message sys_message not null,
read boolean not null,
read_time time
user_id bigint not null,
message_id bigint not null,
is_read boolean not null,
read_time timestamp
);
comment on table sys_user_message is '用户消息';
comment on column sys_user_message.id is '主键';
comment on column sys_user_message."user" is '用户';
comment on column sys_user_message.message is '消息';
comment on column sys_user_message.read is '是否已读';
comment on column sys_user_message.user_id is '用户';
comment on column sys_user_message.message_id is '消息';
comment on column sys_user_message.is_read is '是否已读';
comment on column sys_user_message.read_time is '阅读时间';
alter table sys_user_message
owner to postgres;
@ -398,14 +397,80 @@ INSERT INTO "sys_user" VALUES (1, 210, 50, 'admin', '{bcrypt}$2a$10$lwEbMpGYMIcV
INSERT INTO "sys_user" VALUES (2, 215, 51, 'user', '{bcrypt}$2a$10$lwEbMpGYMIcVpuVXIWBSlOO7d085buqONGjTuY4tg3rz84y/xFQXe', '12324352313', 'zsc3456@qq.com', '帐篷', '35bd7d32843a413f3cd2486114318d6ccd5f9d62', '电子科技大学四川',NULL, NULL, '2024-01-11 09:57:48', '2024-01-11 18:31:29', NULL, b'1');
INSERT INTO "sys_user" VALUES (3, 218, 54, 'auditor', '{bcrypt}$2a$10$lwEbMpGYMIcVpuVXIWBSlOO7d085buqONGjTuY4tg3rz84y/xFQXe', '12345678901', 'zsc3456@qq.com', '王超', '35bd7d32843a413f3cd2486114318d6ccd5f9d62', '电子科技大学中山',NULL, NULL, '2024-01-11 09:57:48', '2024-01-11 18:31:29', NULL, b'1');
INSERT INTO "attachment" VALUES ('195bd3517bfcd9915906957730bdd6fef7fa5a86', 'Snipaste_2024-02-08_09-26-22.jpg', 'image/jpeg','2024-03-21 15:20:03');
INSERT INTO "attachment" VALUES ('1f744e54c23c388d890a6a3822a87eae32617f29', '6.25-07.jpg', 'image/jpeg','2024-03-07 07:59:34');
INSERT INTO "attachment" VALUES ('35bd7d32843a413f3cd2486114318d6ccd5f9d62', 'Snipaste_2024-03-22_08-11-52.jpg', 'image/jpeg','2024-03-22 00:12:05');
INSERT INTO "attachment" VALUES ('5440f9aa9266589413f015fa673f2f372a86c74e', '各组织活动申报表模板.png', 'image/png','2024-02-11 17:37:44');
INSERT INTO "attachment" VALUES ('5ad6601fd1cf58aa66b25b4f12a83d63b61a681e', '申请表1模板计算机学院素质拓展活动申请表.doc', 'application/msword','2024-02-05 14:37:10');
INSERT INTO "attachment" VALUES ('6853fd7cf5b0621678377227d299d86d6f90cc97', 'logo02.png', 'image/png','2024-03-07 07:59:11');
INSERT INTO "attachment" VALUES ('84fa4f586f190886ea8708c49e8645f5a9a1ea04', '屏幕截图(1).png', 'image/png','2024-03-21 16:12:46');
INSERT INTO "attachment"
VALUES ('195bd3517bfcd9915906957730bdd6fef7fa5a86', 'Snipaste_2024-02-08_09-26-22.jpg', '1', 'image/jpeg',
'2024-03-21 15:20:03');
INSERT INTO "attachment"
VALUES ('1f744e54c23c388d890a6a3822a87eae32617f29', '6.25-07.jpg', '1', 'image/jpeg', '2024-03-07 07:59:34');
INSERT INTO "attachment"
VALUES ('35bd7d32843a413f3cd2486114318d6ccd5f9d62', 'Snipaste_2024-03-22_08-11-52.jpg', '1', 'image/jpeg',
'2024-03-22 00:12:05');
INSERT INTO "attachment"
VALUES ('5440f9aa9266589413f015fa673f2f372a86c74e', '各组织活动申报表模板.png', '1', 'image/png',
'2024-02-11 17:37:44');
INSERT INTO "attachment"
VALUES ('5ad6601fd1cf58aa66b25b4f12a83d63b61a681e', '申请表1模板计算机学院素质拓展活动申请表.doc', '1',
'application/msword', '2024-02-05 14:37:10');
INSERT INTO "attachment"
VALUES ('6853fd7cf5b0621678377227d299d86d6f90cc97', 'logo02.png', '1', 'image/png', '2024-03-07 07:59:11');
INSERT INTO "attachment"
VALUES ('84fa4f586f190886ea8708c49e8645f5a9a1ea04', '屏幕截图(1).png', '1', 'image/png', '2024-03-21 16:12:46');
INSERT INTO "sys_bulletin" VALUES (1,'测试测试测试测试测试测试测试',1,true,50,'2024-03-21 15:20:03',51,'2024-03-21 15:20:03',54,'2024-03-21 15:20:03','测试测试测试数据',null,null,null,null);
INSERT INTO "sys_bulletin_attach" VALUES (1,'195bd3517bfcd9915906957730bdd6fef7fa5a86')
INSERT INTO "sys_bulletin_attach"
VALUES (1, '195bd3517bfcd9915906957730bdd6fef7fa5a86');
INSERT INTO sys_message (id, type, system, email, sms, html, title, content, remark, create_time, create_by,
update_time, update_by)
VALUES (1, 1, TRUE, FALSE, TRUE, FALSE, '系统通知', '系统维护通知', '例行维护', NOW(), 'admin', NOW(), 'admin'),
(2, 1, FALSE, TRUE, FALSE, TRUE, '用户注册', '欢迎注册我们的平台', '感谢您的注册', NOW() - INTERVAL '1 day',
'user1', NOW() - INTERVAL '1 day', 'user1'),
(3, 1, TRUE, TRUE, FALSE, FALSE, '密码重置', '您的密码已重置', '请尽快登录并修改密码', NOW() - INTERVAL '2 days',
'admin', NOW() - INTERVAL '2 days', 'admin'),
(4, 1, FALSE, FALSE, TRUE, TRUE, '订单确认', '您的订单已确认', '订单号123456789', NOW() - INTERVAL '3 days',
'user2', NOW() - INTERVAL '3 days', 'user2'),
(5, 1, TRUE, FALSE, TRUE, FALSE, '系统更新', '系统已更新到最新版本', '新功能介绍', NOW() - INTERVAL '4 days',
'admin', NOW() - INTERVAL '4 days', 'admin'),
(6, 1, FALSE, TRUE, FALSE, TRUE, '活动邀请', '您被邀请参加我们的活动', '活动详情见附件',
NOW() - INTERVAL '5 days', 'user3', NOW() - INTERVAL '5 days', 'user3'),
(7, 1, TRUE, TRUE, FALSE, FALSE, '账户激活', '您的账户已激活', '您可以开始使用了', NOW() - INTERVAL '6 days',
'admin', NOW() - INTERVAL '6 days', 'admin'),
(8, 1, FALSE, FALSE, TRUE, TRUE, '支付成功', '您的支付已成功', '感谢您的支持', NOW() - INTERVAL '7 days',
'user4', NOW() - INTERVAL '7 days', 'user4'),
(9, 1, TRUE, FALSE, TRUE, FALSE, '安全提醒', '请检查您的账户安全设置', '安全提示', NOW() - INTERVAL '8 days',
'admin', NOW() - INTERVAL '8 days', 'admin'),
(10, 1, FALSE, TRUE, FALSE, TRUE, '反馈回复', '感谢您的反馈', '我们会尽快处理', NOW() - INTERVAL '9 days',
'user5', NOW() - INTERVAL '9 days', 'user5');
INSERT INTO sys_message_setting (id, email, sms)
VALUES (1, TRUE, FALSE),
(2, FALSE, TRUE),
(3, TRUE, TRUE),
(4, FALSE, FALSE),
(5, TRUE, FALSE),
(6, FALSE, TRUE),
(7, TRUE, TRUE),
(8, FALSE, FALSE),
(9, TRUE, FALSE),
(10, FALSE, TRUE);
INSERT INTO attachment (id, file_name, mime_type, url, upload_time)
VALUES ('8', 'document1.pdf', 'application/pdf', 'http://example.com/files/document1.pdf',
CURRENT_TIMESTAMP - INTERVAL '1 day'),
('9', 'image1.jpg', 'image/jpeg', 'http://example.com/files/image1.jpg', CURRENT_TIMESTAMP - INTERVAL '2 days'),
('10', 'presentation.pptx', 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'http://example.com/files/presentation.pptx', CURRENT_TIMESTAMP - INTERVAL '3 days'),
('11', 'spreadsheet.xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'http://example.com/files/spreadsheet.xlsx', CURRENT_TIMESTAMP - INTERVAL '4 days'),
('12', 'audio1.mp3', 'audio/mpeg', 'http://example.com/files/audio1.mp3', CURRENT_TIMESTAMP - INTERVAL '5 days'),
('13', 'video1.mp4', 'video/mp4', 'http://example.com/files/video1.mp4', CURRENT_TIMESTAMP - INTERVAL '6 days'),
('14', 'archive.zip', 'application/zip', 'http://example.com/files/archive.zip',
CURRENT_TIMESTAMP - INTERVAL '7 days'),
('15', 'textfile.txt', 'text/plain', 'http://example.com/files/textfile.txt',
CURRENT_TIMESTAMP - INTERVAL '8 days'),
('16', 'image2.png', 'image/png', 'http://example.com/files/image2.png', CURRENT_TIMESTAMP - INTERVAL '9 days'),
('17', 'document2.docx', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'http://example.com/files/document2.docx', CURRENT_TIMESTAMP - INTERVAL '10 days');

View File

@ -18,21 +18,73 @@
<result column="edit_user_name" jdbcType="VARCHAR" property="editUsername"/>
<result column="publish_user_name" jdbcType="VARCHAR" property="publishUsername"/>
<result column="close_user_name" jdbcType="VARCHAR" property="closeUsername"/>
<collection property="attachmentVos" ofType="com.zsc.edu.gateway.modules.attachment.vo.AttachmentVo">
<result column="file_name" jdbcType="VARCHAR" property="fileName"/>
<result column="mime_type" jdbcType="VARCHAR" property="mimeType"/>
<result column="upload_time" jdbcType="TIMESTAMP" property="uploadTime"/>
<result column="url" jdbcType="VARCHAR" property="url"/>
<result column="is_read" jdbcType="BOOLEAN" property="isRead"/>
</collection>
</resultMap>
<select id="selectByBulletinId" resultMap="BulletinMap">
select sb.*,a.id as attachment_id,a.file_name as attachment_file_name,a.mime_type as attachment_mime_type,a.url as attachment_url,a.upload_time as attachment_upload_time,sbu.is_read
from sys_bulletin sb
left join sys_bulletin_attach sba on sb.id=sba.bulletin_id
left join attachment a on a.id=sba.attachment_id
left join sys_bulletin_user sbu on sb.id=sbu.bulletin_id
left join sys_user su on sbu.user_id=su.id
where sb.id=#{bulletinId}
order by sb.top DESC, sb.create_time DESC;
SELECT sb.id AS id,
sb.state AS state,
sb.content AS content,
sb.title AS title,
sb.top AS top,
sb.remark AS remark,
sb.close_time AS close_time,
sb.close_user_id AS close_user_id,
sb.create_by AS create_by,
sb.create_time AS create_time,
sb.edit_user_id AS edit_user_id,
sb.publish_time AS publish_time,
sb.publish_user_id AS publish_user_id,
sb.update_by AS update_by,
sb.update_time AS update_time,
a.file_name AS file_name,
a.url AS url
FROM sys_bulletin sb
LEFT JOIN
sys_bulletin_attach sba ON sb.id = sba.bulletin_id
LEFT JOIN
attachment a ON a.id = sba.attachment_id
WHERE sb.id = #{bulletinId}
</select>
<select id="selectPageByConditions" resultType="com.zsc.edu.gateway.modules.notice.vo.BulletinVo">
SELECT
sb.id AS id,
sb.state AS state,
sb.content AS content,
sb.title AS title,
sb.top AS top,
sb.remark AS remark,
sb.close_time AS close_time,
sb.close_user_id AS close_user_id,
sb.create_by AS create_by,
sb.create_time AS create_time,
sb.edit_user_id AS edit_user_id,
sb.publish_time AS publish_time,
sb.publish_user_id AS publish_user_id,
sb.update_by AS update_by,
sb.update_time AS update_time,
a.file_name AS file_name,
a.url AS url
FROM
sys_bulletin sb
LEFT JOIN
sys_bulletin_attach sba ON sb.id = sba.bulletin_id
LEFT JOIN
attachment a ON a.id = sba.attachment_id
where 1=1
<if test="query.title != null and query.title != ''">
AND sb.title LIKE CONCAT('%', #{query.title}, '%')
</if>
<if test="query.state != null">
AND sb.state = #{query.state}
</if>
<if test="query.publishTimeBegin != null and query.publishTimeEnd != null">
AND sb.publish_time BETWEEN #{query.publishTimeBegin} AND #{query.publishTimeEnd}
</if>
order by sb.top DESC,sb.publish_time DESC,sb.create_time DESC
</select>
</mapper>

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zsc.edu.gateway.modules.notice.repo.MessageRepository">
<select id="selectById" resultType="com.zsc.edu.gateway.modules.notice.entity.Message">
select *
from sys_message sm
left join sys_message_attachment sma on sm.id = sma.message_id
left join attachment a on sma.attachment_id = a.id
where sm.id = #{messageId}
</select>
</mapper>

View File

@ -0,0 +1,87 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zsc.edu.gateway.modules.notice.repo.UserMessageRepository">
<resultMap id="userMessageMap" type="com.zsc.edu.gateway.modules.notice.vo.UserMessageVo">
<id column="id" jdbcType="BIGINT" property="id"/>
<result column="is_read" jdbcType="BOOLEAN" property="isRead"/>
<result column="read_time" jdbcType="TIMESTAMP" property="readTime"/>
<result column="username" jdbcType="VARCHAR" property="username"/>
<result column="address" jdbcType="VARCHAR" property="address"/>
<result column="avatar" jdbcType="VARCHAR" property="avatar"/>
<result column="name" jdbcType="VARCHAR" property="name"/>
<result column="email" jdbcType="VARCHAR" property="email"/>
<result column="type" jdbcType="INTEGER" property="type"/>
<result column="system" jdbcType="BOOLEAN" property="system"/>
<result column="email" jdbcType="BOOLEAN" property="email"/>
<result column="sms" jdbcType="BOOLEAN" property="sms"/>
<result column="html" jdbcType="BOOLEAN" property="html"/>
<result column="title" jdbcType="VARCHAR" property="title"/>
<result column="content" jdbcType="VARCHAR" property="content"/>
<result column="create_by" jdbcType="VARCHAR" property="createBy"/>
<result column="update_by" jdbcType="VARCHAR" property="updateBy"/>
<result column="create_time" jdbcType="DATE" property="createTime"/>
<result column="update_time" jdbcType="DATE" property="updateTime"/>
<result column="remark" jdbcType="VARCHAR" property="remark"/>
<collection property="attachments" ofType="com.zsc.edu.gateway.modules.attachment.entity.Attachment">
<id column="id" jdbcType="VARCHAR" property="id"/>
<result column="file_name" jdbcType="VARCHAR" property="fileName"/>
<result column="mime_type" jdbcType="VARCHAR" property="mimeType"/>
<result column="upload_time" jdbcType="TIMESTAMP" property="uploadTime"/>
<result column="url" jdbcType="VARCHAR" property="url"/>
</collection>
</resultMap>
<select id="selectByMessageIdAndUserId" resultType="com.zsc.edu.gateway.modules.notice.vo.UserMessageVo"
resultMap="userMessageMap">
select sum.id as user_message_id,sum.user_id as user_message_user_id,sum.message_id as
user_message_message_id,sum.is_read as user_message_is_read,sum.read_time as user_message_read_time,su.id as
user_id,su.username as user_username,su.address as user_address,su.avatar as user_avatar,su.name as
user_name,su.phone as user_phone,sm.*,sm.email as message_email,a.*
from sys_user_message sum
left join sys_user su on sum.id=su.id
left join sys_message sm on sm.id=sum.id
left join sys_message_attachment sma on sm.id=sma.message_id
left join attachment a on sma.attachment_id=a.id
<where>
sm.id=#{messageId}
and su.id=#{userId}
</where>
</select>
<select id="query" resultType="com.zsc.edu.gateway.modules.notice.vo.UserMessageVo" resultMap="userMessageMap">
select sum.id as user_message_id,sum.user_id as user_message_user_id,sum.message_id as
user_message_message_id,sum.is_read as user_message_is_read,sum.read_time as user_message_read_time,su.id as
user_id,su.username as user_username,su.address as user_address,su.avatar as user_avatar,su.name as
user_name,su.email as user_email,su.phone as user_phone,sm.*,sm.email as message_email,a.*
from sys_user_message sum
left join sys_user su on sum.id=su.id
left join sys_message sm on sm.id=sum.id
left join sys_message_attachment sma on sm.id=sma.message_id
left join attachment a on sma.attachment_id=a.id
where 1=1
<if test="query.userId != null">
AND sum.user_id = #{query.userId}
</if>
<if test="query.title != null and query.title != ''">
AND sm.title LIKE CONCAT('%', #{query.title}, '%')
</if>
<if test="query.type != null">
AND sm.type = #{query.type}
</if>
<if test="query.name != null and query.name != ''">
AND su.username LIKE CONCAT('%', #{query.name}, '%')
</if>
<if test="query.system != null">
AND sm.system = #{query.system}
</if>
<if test="query.isRead != null">
AND sum.is_read = #{query.isRead}
</if>
<if test="query.createAtBegin != null and query.createAtEnd != null">
AND sm.create_time BETWEEN #{query.createAtBegin} AND #{query.createAtEnd}
</if>
ORDER BY
sm.create_time DESC
</select>
</mapper>

View File

@ -1,5 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zsc.edu.gateway.modules.system.repo.DeptRepository">
<select id="selectAllWithMembers" resultType="com.zsc.edu.gateway.modules.system.entity.Dept">
SELECT d.*, u.*
FROM sys_dept d
LEFT JOIN sys_user u ON d.id = u.dept_id
</select>
</mapper>

View File

@ -3,6 +3,7 @@ package com.zsc.edu.gateway.domain;
import com.zsc.edu.gateway.modules.system.entity.Dept;
import java.util.HashSet;
import java.util.List;
public class DeptBuilder extends BaseEntityBuilder {
@ -43,7 +44,7 @@ public class DeptBuilder extends BaseEntityBuilder {
Dept dept = new Dept();
dept.setName(name);
dept.setPid(pid);
dept.setChildren(children);
dept.setChildren((List<Dept>) children);
return dept;
}