需求
ERP的审批流,每个审批存在多个审批节点,每个节点下有N个领导的评论以及意见,针对每个审批评论的已读未读,需要设置
难点
貌似难点也不是很多,针对已读/未读的解决方案网上成熟的方案也不少
说明
点击查看评论: 审批的评论设置为已读
新增了一个评论:除评论人以外,所有人对该审批的评论标识都设置为未读
项目环境
3个服务一同运行,共享一个reids服务器
解决思路
利用redis对每个用户每个审批设置布尔值的key-value
核心代码
private RedisTemplate<String, Boolean> redisTemplate;
@WebLog(operationType = AdminOperationType.QUERY, operationName = "读某个审批的评论")
@GetMapping("get_audits")
public List<WaitApprovalGroupDto> getAudits() {
List<WaitApprovalGroupDto> audits = queryCommentList();
ValueOperations<String, Boolean> ops = redisTemplate.opsForValue();
audits.parallelStream().forEachOrdered(vo -> {
String key = StringUtils.join("audit::comment::" + vo.getUserId(), "_", vo.getAuditId());
Boolean flag = ops.get(key) == null ? true : ops.get(key);
vo.setHasNewComment(flag);
});
return audits;
}
@WebLog(operationType = AdminOperationType.QUERY, operationName = "读某个审批的评论")
@GetMapping("read_comment")
public void redisRead(@RequestParam(value = "user_id") Long userId, @RequestParam(value = "audit_id") Long auditId) {
String key = StringUtils.join("audit::comment::" + userId, "_", auditId);
ValueOperations<String, Boolean> ops = redisTemplate.opsForValue();
ops.set(key, false);
}
@WebLog(operationType = AdminOperationType.QUERY, operationName = "添加某个审批的评论")
@GetMapping("add_comment")
public void redisAdd(@RequestParam(value = "user_id") Long userId, @RequestParam(value = "audit_id") Long auditId) {
String key = StringUtils.join("audit::comment::" + userId, "_", auditId);
ValueOperations<String, Boolean> ops = redisTemplate.opsForValue();
// 更新当用户评论的缓存状态
ops.set(key, false);
// 将所有涉及的审批的用户已读缓存更新为未读
queryCommentList().stream()
.filter(vo -> !vo.getUserId().equals(userId))
.forEach(vo -> {
String userKey = StringUtils.join("audit::comment::" + vo.getUserId(), "_", auditId);
ops.set(userKey, true);
});
}
/**
* 模拟所有用户的审批评论信息查询
*/
private List<WaitApprovalGroupDto> queryCommentList() {
List<WaitApprovalGroupDto> lists = Lists.newArrayList();
WaitApprovalGroupDto dto = new WaitApprovalGroupDto();
dto.setId(1L);
dto.setAuditId(1L);
dto.setUserId(1L);
dto.setName("审批1");
WaitApprovalGroupDto dto2 = new WaitApprovalGroupDto();
dto2.setId(2L);
dto2.setUserId(2L);
dto2.setAuditId(2L);
dto2.setName("审批2");
WaitApprovalGroupDto dto3 = new WaitApprovalGroupDto();
dto3.setId(3L);
dto3.setUserId(3L);
dto3.setAuditId(3L);
dto3.setName("审批3");
WaitApprovalGroupDto dto4 = new WaitApprovalGroupDto();
BeanUtils.copyProperties(dto, dto4);
dto4.setAuditId(2L);
WaitApprovalGroupDto dto5 = new WaitApprovalGroupDto();
BeanUtils.copyProperties(dto, dto5);
dto5.setAuditId(3L);
WaitApprovalGroupDto dto6 = new WaitApprovalGroupDto();
BeanUtils.copyProperties(dto2, dto6);
dto6.setAuditId(2L);
WaitApprovalGroupDto dto7 = new WaitApprovalGroupDto();
BeanUtils.copyProperties(dto2, dto7);
dto7.setAuditId(3L);
WaitApprovalGroupDto dto8 = new WaitApprovalGroupDto();
BeanUtils.copyProperties(dto3, dto8);
dto8.setAuditId(2L);
WaitApprovalGroupDto dto9 = new WaitApprovalGroupDto();
BeanUtils.copyProperties(dto3, dto9);
dto9.setAuditId(3L);
lists.add(dto);
lists.add(dto2);
lists.add(dto3);
lists.add(dto4);
lists.add(dto5);
lists.add(dto6);
lists.add(dto7);
lists.add(dto8);
lists.add(dto9);
lists.sort(Comparator.comparing(WaitApprovalGroupDto::getUserId)
.thenComparing(WaitApprovalGroupDto::getAuditId));
return lists;
}
package com.micecs.erp.module.meeting.dto;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.micecs.erp.module.enums.ApprovalStageEnum;
import java.math.BigDecimal;
import java.util.Date;
/**
* @author simengyuan, [email protected]
* @version 1.0
*/
@Data
public class WaitApprovalGroupDto {
private Long id;
private String name;
private Long auditId;
private Boolean hasNewComment;
private Long userId;
}
过期时间记得加上,opts.expire(30, TimeUnit.Days);