Commit 452ca69b by Ren Ping

消息模块开发

1 parent 5d92eccb
package com.dituhui.pea.order.controller;
import cn.hutool.core.date.DateUtil;
import com.dituhui.pea.common.PageResult;
import com.dituhui.pea.common.Result;
import com.dituhui.pea.order.dto.MsgDTO;
import com.dituhui.pea.order.dto.MsgGroupResp;
import com.dituhui.pea.order.dto.MsgResp;
import com.dituhui.pea.order.service.MsgService;
import com.dituhui.pea.order.utils.AssertUtil;
import com.dituhui.pea.order.utils.CommonUtil;
import com.dituhui.pea.pojo.RoleInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import java.util.Objects;
/**
* 消息相关接口
*
* @author RenPing
* @date 2023/10/24
*/
@RestController
@RequestMapping("/pea-order/msg")
public class MsgController {
@Autowired
private MsgService msgService;
/**
* 消息列表
*
* @param userId 用户标识
* @param request 请求
* @return {@link Result }<{@link PageResult }<{@link MsgResp }>>
* @author RenPing
* @date 2023/10/24
*/
@GetMapping("/list")
public Result<PageResult<MsgGroupResp>> list(@RequestHeader(name = "userId", required = true) String userId,
MsgDTO.Request request) {
CommonUtil.setNullValue(request);
request.setUserId(userId);
if (!"is_read".equalsIgnoreCase(request.getSort())) {
request.setSort("create_time");
}
if (!"asc".equalsIgnoreCase(request.getSortType())) {
request.setSortType("desc");
}
if (Objects.nonNull(request.getEndDate())) {
request.setEndDate(CommonUtil.addDays(request.getEndDate(), 1));
}
return Result.success(msgService.list(request));
}
/**
* 删除消息
*
* @param userId 用户标识
* @param deleteDto
* @return {@link Result }<{@link Boolean }>
* @author RenPing
* @date 2023/10/24
*/
@RequestMapping(value = "/delete", method = RequestMethod.POST)
public Result<Boolean> delete(@RequestHeader(name = "userId", required = true) String userId, @RequestBody @Valid MsgDTO.DeleteDto deleteDto) {
AssertUtil.isNotEmpty(userId, "用户ID不能为空");
msgService.delete(deleteDto.getId(), userId);
return Result.success(true);
}
}
package com.dituhui.pea.order.dao;
import com.dituhui.pea.order.dto.MsgDTO;
import com.dituhui.pea.order.dto.MsgGroupResp;
import com.dituhui.pea.order.dto.MsgResp;
import com.dituhui.pea.order.entity.MsgEntity;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
import java.util.Map;
import java.util.Objects;
public interface MsgDao extends JpaRepository<MsgEntity, Long> {
@Query(value = "select t.cluster_id,t.branch_id,t.group_id" +
" from (" +
" select tt.cluster_id,tt.branch_id,tt.group_id,min(tt.create_time) create_time,min(r.is_read) is_read" +
" from zzz_msg tt join zzz_msg_receiver r on r.msg_id=tt.id and r.user_id=:#{#req.userId}" +
" where IF(:#{#req.startDate} is not null, tt.create_time>=:#{#req.startDate}, 1=1)" +
" and IF(:#{#req.endDate} is not null, tt.create_time<:#{#req.endDate}, 1=1)" +
" and IF(:#{#req.keyWord} is not null, tt.content like concat('%',:#{#req.keyWord},'%'), 1=1)" +
"group by tt.cluster_id,tt.branch_id,tt.group_id" +
") t"
//, countProjection = "t.id" //用于分页计数
, nativeQuery = true // 开启原生sql
)
Page<Map<String, Objects>> getGroupList(@Param("req") MsgDTO.Request req, Pageable pageable);
@Query(value = "select t.* from (select tt.*,r.is_read" +
" from zzz_msg tt join zzz_msg_receiver r on r.msg_id=tt.id and r.user_id=:#{#req.userId}" +
" where IF(:#{#msgGroupResp.clusterId} is not null, tt.cluster_id=:#{#msgGroupResp.clusterId}, tt.cluster_id is null)" +
" and IF(:#{#msgGroupResp.branchId} is not null, tt.branch_id=:#{#msgGroupResp.branchId}, tt.branch_id is null)" +
" and IF(:#{#msgGroupResp.groupId} is not null, tt.group_id=:#{#msgGroupResp.groupId}, tt.group_id is null)" +
" and IF(:#{#req.startDate} is not null, tt.create_time>=:#{#req.startDate}, 1=1)" +
" and IF(:#{#req.endDate} is not null, tt.create_time<:#{#req.endDate}, 1=1)" +
" and IF(:#{#req.keyWord} is not null, tt.content like concat('%',:#{#req.keyWord},'%'), 1=1)" +
") t"
, nativeQuery = true // 开启原生sql
)
List<Map<String, Objects>> getList(@Param("req") MsgDTO.Request req, @Param("msgGroupResp") MsgGroupResp msgGroupResp, Pageable pageable);
}
package com.dituhui.pea.order.dao;
import com.dituhui.pea.order.entity.MsgReceiverEntity;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
public interface MsgReceiverDao extends JpaRepository<MsgReceiverEntity, Long> {
@Modifying
@Query("delete from MsgReceiverEntity a where a.msgId=?1 and a.userId=?2")
void delete(Integer msgId, String userId);
}
package com.dituhui.pea.order.dto;
import com.dituhui.pea.pojo.PageRequest;
import org.springframework.format.annotation.DateTimeFormat;
import javax.validation.constraints.NotNull;
import java.time.LocalDate;
import java.util.Date;
import static com.dituhui.pea.order.config.OrderConfig.DEFAULT_PAGE_SIZE;
public class MsgDTO {
@lombok.Data
public static class Request {
/**
* 每页大小
*/
private Integer size = DEFAULT_PAGE_SIZE;
/**
* 页码
*/
private Integer page = 1;
/**
* 当前用户Id,前端将userId放在header中
*/
private String userId;
/**
* 排序字段:create_time、is_read
*/
private String sort;
/**
* 排序类型:asc、desc
*/
private String sortType;
/**
* 开始日期
*/
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date startDate;
/**
* 结束日期
*/
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date endDate;
/**
* 关键词模糊查询
*/
private String keyWord;
}
@lombok.Data
public static class DeleteDto {
@NotNull(message = "消息ID不能为空")
private Integer id;
}
@lombok.Data
public static class addDto {
/**
* 大区ID
*/
private String clusterId;
/**
* 分部ID
*/
private String branchId;
/**
* 小组ID
*/
private String groupId;
/**
* 消息类型,0:派工类,1:服务类,2:容量类
*/
private Integer type;
/**
* 消息内容
*/
private String content;
/**
* 单号集合,以顿号连接
*/
private String orderIds;
/**
* 标签类型,0:紧急,1:正常
*/
private Integer tag;
}
}
\ No newline at end of file
package com.dituhui.pea.order.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
* 消息分组
*
* @author RenPing
* @date 2023/10/24
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MsgGroupResp {
/**
* 大区ID
*/
private String clusterId;
/**
* 分部ID
*/
private String branchId;
/**
* 小组ID
*/
private String groupId;
/**
* 分组名称
*/
private String groupName;
/**
* 未读消息数量
*/
private Integer unReadNum;
/**
* 总消息数量
*/
private Integer sumNum;
/**
* 消息列表
*/
private List<MsgResp> msgRespList;
}
package com.dituhui.pea.order.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class MsgResp {
private Integer id;
/**
* 大区ID
*/
private String clusterId;
/**
* 分部ID
*/
private String branchId;
/**
* 小组ID
*/
private String groupId;
/**
* 消息类型,0:派工类,1:服务类,2:容量类
*/
private Integer type;
/**
* 消息类型名称
*/
private String typeName;
/**
* 消息内容
*/
private String content;
/**
* 单号集合,以顿号连接
*/
private String orderIds;
/**
* 标签类型,0:紧急,1:正常
*/
private Integer tag;
/**
* 标签类型名称
*/
private String tagName;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm", timezone = "GMT+8")
private Date createTime;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm", timezone = "GMT+8")
private Date updateTime;
/**
* 是否已读,0:未读,1:已读
*/
private Integer isRead;
}
package com.dituhui.pea.order.entity;
import lombok.Data;
import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.Date;
/**
* 消息实体
*
* @author RenPing
* @date 2023/10/23
*/
@Entity
@Data
@Table(name = "zzz_msg")
public class MsgEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
/**
* 大区ID
*/
@Column(name = "cluster_id")
private String clusterId;
/**
* 分部ID
*/
@Column(name = "branch_id")
private String branchId;
/**
* 小组ID
*/
@Column(name = "group_id")
private String groupId;
/**
* 消息类型,0:派工类,1:服务类,2:容量类
*/
@Column(name = "type")
private Integer type;
/**
* 消息内容
*/
@Column(name = "content")
private String content;
/**
* 单号集合,以逗号连接
*/
@Column(name = "order_ids")
private String orderIds;
/**
* 标签类型,0:紧急,1:正常
*/
@Column(name = "tag")
private Integer tag;
@Column(name = "create_time", nullable = false, columnDefinition = "datetime default current_timestamp")
private Date createTime;
@Column(name = "update_time", nullable = false, columnDefinition = "datetime default current_timestamp")
private Date updateTime;
}
package com.dituhui.pea.order.entity;
import lombok.Data;
import lombok.experimental.Accessors;
import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.Date;
/**
* 消息接收人实体
*
* @author RenPing
* @date 2023/10/23
*/
@Entity
@Data
@Table(name = "zzz_msg_receiver")
@Accessors(chain = true)
public class MsgReceiverEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
/**
* 消息ID
*/
@Column(name = "msg_id")
private Integer msgId;
/**
* 用户ID
*/
@Column(name = "user_id")
private String userId;
/**
* 是否已读,0:未读,1:已读
*/
@Column(name = "is_read")
private Integer isRead;
@Column(name = "create_time", nullable = false, columnDefinition = "datetime default current_timestamp")
private Date createTime;
@Column(name = "update_time", nullable = false, columnDefinition = "datetime default current_timestamp")
private Date updateTime;
}
package com.dituhui.pea.order.enums;
import cn.hutool.core.util.ObjectUtil;
import java.util.Objects;
/**
* 消息标签枚举
* 标签类型,0:紧急,1:正常
*
* @author RenPing
* @date 2023/10/24
*/
public enum MsgTagEnum {
URGENT(0, "紧急"),
NORMAL(1, "正常");
private Integer code;
private String name;
private MsgTagEnum(Integer code, String name) {
this.code = code;
this.name = name;
}
public Integer getCode() {
return code;
}
public String getName() {
return name;
}
public static String getNameByValue(Integer value) {
if (Objects.isNull(value)) {
return null;
}
for (MsgTagEnum enums : MsgTagEnum.values()) {
if (ObjectUtil.equal(enums.getCode(), value)) {
return enums.getName();
}
}
return null;
}
}
package com.dituhui.pea.order.enums;
import cn.hutool.core.util.ObjectUtil;
import java.util.Objects;
/**
* 消息类型枚举
* 消息类型,0:派工类,1:服务类,2:容量类
*
* @author RenPing
* @date 2023/10/24
*/
public enum MsgTypeEnum {
DISPATCH(0, "派工类"),
SERVICE(1, "服务类"),
CAPACITY(2, "容量类");
private Integer code;
private String name;
private MsgTypeEnum(Integer code, String name) {
this.code = code;
this.name = name;
}
public Integer getCode() {
return code;
}
public String getName() {
return name;
}
public static String getNameByValue(Integer value) {
if (Objects.isNull(value)) {
return null;
}
for (MsgTypeEnum enums : MsgTypeEnum.values()) {
if (ObjectUtil.equal(enums.getCode(), value)) {
return enums.getName();
}
}
return null;
}
}
package com.dituhui.pea.order.service;
import com.dituhui.pea.common.PageResult;
import com.dituhui.pea.order.dto.MsgDTO;
import com.dituhui.pea.order.dto.MsgGroupResp;
public interface MsgService {
/**
* 消息分页查询
*
* @param request 请求
* @return {@link PageResult }<{@link MsgGroupResp }>
* @author RenPing
* @date 2023/10/23
*/
PageResult<MsgGroupResp> list(MsgDTO.Request request);
/**
* 删除
*
* @param msgId 消息标识
* @param userId 用户标识
* @author RenPing
* @date 2023/10/24
*/
void delete(Integer msgId, String userId);
}
package com.dituhui.pea.order.service.impl;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.dituhui.pea.common.PageResult;
import com.dituhui.pea.order.dao.*;
import com.dituhui.pea.order.dto.MsgDTO;
import com.dituhui.pea.order.dto.MsgGroupResp;
import com.dituhui.pea.order.dto.MsgResp;
import com.dituhui.pea.order.entity.MsgReceiverEntity;
import com.dituhui.pea.order.enums.MsgTagEnum;
import com.dituhui.pea.order.enums.MsgTypeEnum;
import com.dituhui.pea.order.service.MsgService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
@Service
@Slf4j
public class MsgServiceImpl implements MsgService {
@Autowired
private MsgDao msgDao;
@Autowired
private MsgReceiverDao msgReceiverDao;
@Autowired
private OrgClusterDao clusterDao;
@Autowired
private OrgBranchDao branchDao;
@Autowired
private OrgGroupDao groupDao;
@Override
public PageResult<MsgGroupResp> list(MsgDTO.Request request) {
Sort sort = Sort.by("asc".equalsIgnoreCase(request.getSortType()) ? Sort.Direction.ASC : Sort.Direction.DESC, request.getSort());
Pageable pageable = PageRequest.of(request.getPage() - 1, request.getSize(), sort);
Page<Map<String, Objects>> page = msgDao.getGroupList(request, pageable);
List<MsgGroupResp> list = page.getContent().stream().map(msg -> {
MsgGroupResp msgGroupResp = JSONObject.parseObject(JSONObject.toJSONString(msg), MsgGroupResp.class);
if (ObjectUtil.isNotEmpty(msgGroupResp.getGroupId())) {
msgGroupResp.setGroupName(groupDao.getByGroupId(msgGroupResp.getGroupId()).getGroupName());
} else if (ObjectUtil.isNotEmpty(msgGroupResp.getBranchId())) {
msgGroupResp.setGroupName(branchDao.getByBranchId(msgGroupResp.getBranchId()).getBranchName());
} else if (ObjectUtil.isNotEmpty(msgGroupResp.getClusterId())) {
msgGroupResp.setGroupName(clusterDao.getByClusterId(msgGroupResp.getBranchId()).getName());
}
Sort sort2 = Sort.by("asc".equalsIgnoreCase(request.getSortType()) ? Sort.Direction.ASC : Sort.Direction.DESC, request.getSort());
Pageable pageable2 = PageRequest.of(0, Integer.MAX_VALUE, sort2);
List<Map<String, Objects>> msgMapList = msgDao.getList(request, msgGroupResp, pageable2);
List<MsgResp> msgList = msgMapList.stream().map(msgMap -> {
MsgResp msgResp = JSONObject.parseObject(JSONObject.toJSONString(msgMap), MsgResp.class);
msgResp.setTypeName(MsgTypeEnum.getNameByValue(msgResp.getType()));
msgResp.setTagName(MsgTagEnum.getNameByValue(msgResp.getTag()));
return msgResp;
}).collect(Collectors.toList());
msgGroupResp.setSumNum(msgList.size());
msgGroupResp.setUnReadNum((int) msgList.stream().filter(msgResp -> msgResp.getIsRead() == 0).count());
msgGroupResp.setMsgRespList(msgList);
return msgGroupResp;
}).collect(Collectors.toList());
PageResult<MsgGroupResp> result = new PageResult<>();
result.setDataList(list);
result.setCurrPage(page.getNumber());
result.setRecordCount(page.getTotalElements());
result.setTotalPage(page.getTotalPages());
return result;
}
@Override
@Transactional(rollbackFor = Exception.class)
public void delete(Integer msgId, String userId) {
msgReceiverDao.delete(msgId, userId);
}
}
package com.dituhui.pea.order.utils;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.dituhui.pea.common.BusinessException;
import java.util.Objects;
/**
* 前提条件校验类 参考Guava Preconditions
*
* @Author: RenPing
* @Date: 2022/10/11 14:58
* @Version: 1.0
*/
public final class AssertUtil {
private AssertUtil() {
}
/**
* 断言表达式为真,否则抛出异常
*
* @param expression
* @param message
*/
public static void checkArgument(boolean expression, String message) {
if (!expression) {
throw new BusinessException(message);
}
}
/**
* 断言对象为空,否则抛出异常
*
* @param obj
* @param message
*/
public static void isNull(Object obj, String message) {
if (ObjectUtil.isNotNull(obj)) {
throw new BusinessException(message);
}
}
/**
* 断言对象为非空,否则抛出异常
*
* @param obj
* @param message
*/
public static void isNotNull(Object obj, String message) {
if (Objects.isNull(obj)) {
throw new BusinessException(message);
}
}
/**
* 断言对象1、2相等,否则抛出异常
*
* @param obj1
* @param obj2
* @param message
*/
public static void equal(Object obj1, Object obj2, String message) {
if (ObjectUtil.notEqual(obj1, obj2)) {
throw new BusinessException(message);
}
}
/**
* 断言对象1、2不等,否则抛出异常
*
* @param obj1
* @param obj2
* @param message
*/
public static void notEqual(Object obj1, Object obj2, String message) {
if (ObjectUtil.equal(obj1, obj2)) {
throw new BusinessException(message);
}
}
/**
* 断言对象为空,否则抛出异常
*
* @param obj
* @param message
*/
public static void isEmpty(Object obj, String message) {
if (ObjectUtil.isNotEmpty(obj)) {
throw new BusinessException(message);
}
}
/**
* 断言对象为非空,否则抛出异常
*
* @param obj
* @param message
*/
public static void isNotEmpty(Object obj, String message) {
if (ObjectUtil.isEmpty(obj)) {
throw new BusinessException(message);
}
}
/**
* 断言字符串空白,否则抛出异常
*
* @param str
* @param message
*/
public static void isBank(String str, String message) {
if (StrUtil.isNotBlank(str)) {
throw new BusinessException(message);
}
}
/**
* 断言字符串非空白,否则抛出异常
*
* @param str
* @param message
*/
public static void isNotBlank(String str, String message) {
if (StrUtil.isBlank(str)) {
throw new BusinessException(message);
}
}
}
package com.dituhui.pea.order.utils;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import java.util.*;
@Slf4j
public class CommonUtil {
/**
* 设置对象中空字符串为null
*
* @param source
* @param <T>
* @return
*/
public static <T> T setNullValue(T source) {
if (Objects.isNull(source)) {
return null;
}
Class cls = source.getClass();
Arrays.stream(cls.getDeclaredFields()).forEach(field -> {
if (field.getType().equals(String.class)) {
field.setAccessible(true); //设置可访问private变量值
try {
Object obj = field.get(source);
if (StrUtil.isBlank((String) obj)) {
field.set(source, null);
} else if (Objects.nonNull(obj)) {
field.set(source, obj.toString().trim());
}
} catch (IllegalAccessException e) {
log.error(e.getMessage(), e);
}
}
});
if (Objects.nonNull(cls.getSuperclass())) {
Arrays.stream(cls.getSuperclass().getDeclaredFields()).forEach(field -> {
if (field.getType().equals(String.class)) {
field.setAccessible(true);
try {
Object obj = field.get(source);
if (StrUtil.isBlank((String) obj)) {
field.set(source, null);
} else if (Objects.nonNull(obj)) {
field.set(source, obj.toString().trim());
}
} catch (IllegalAccessException e) {
log.error(e.getMessage(), e);
}
}
});
}
return source;
}
public static Date addDays(Date date, int days) {
Calendar calendar = new GregorianCalendar();
calendar.setTime(date);
calendar.add(Calendar.DATE, days);
return calendar.getTime();
}
}
......@@ -34,6 +34,17 @@ spring:
username: boxi
password: boxi_dev_0725
type: com.alibaba.druid.pool.DruidDataSource
redis:
database: 0
host: redis
port: 6379
password: 123456
jedis:
pool:
max-active: 32
min-idle: 0
max-idle: 8
max-wait: -1
seata:
application-id: ${spring.application.name}
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!