站内信模块:整体功能实现
This commit is contained in:
parent
143035d798
commit
ae3ee95cdd
|
@ -1,7 +1,9 @@
|
||||||
package cn.iocoder.yudao.framework.mybatis.core.query;
|
package cn.iocoder.yudao.framework.mybatis.core.query;
|
||||||
|
|
||||||
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
|
import cn.iocoder.yudao.framework.common.util.collection.ArrayUtils;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.enums.SqlConstants;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
|
||||||
|
|
|
@ -146,19 +146,19 @@ public class QueryWrapperX<T> extends QueryWrapper<T> {
|
||||||
*
|
*
|
||||||
* @return this
|
* @return this
|
||||||
*/
|
*/
|
||||||
public QueryWrapperX<T> limit1() {
|
public QueryWrapperX<T> limitN(int n) {
|
||||||
Assert.notNull(SqlConstants.DB_TYPE, "获取不到数据库的类型");
|
Assert.notNull(SqlConstants.DB_TYPE, "获取不到数据库的类型");
|
||||||
switch (SqlConstants.DB_TYPE) {
|
switch (SqlConstants.DB_TYPE) {
|
||||||
case ORACLE:
|
case ORACLE:
|
||||||
case ORACLE_12C:
|
case ORACLE_12C:
|
||||||
super.eq("ROWNUM", 1);
|
super.eq("ROWNUM", n);
|
||||||
break;
|
break;
|
||||||
case SQL_SERVER:
|
case SQL_SERVER:
|
||||||
case SQL_SERVER2005:
|
case SQL_SERVER2005:
|
||||||
super.select("TOP 1 *"); // 由于 SQL Server 是通过 SELECT TOP 1 实现限制一条,所以只好使用 * 查询剩余字段
|
super.select("TOP " + n + " *"); // 由于 SQL Server 是通过 SELECT TOP 1 实现限制一条,所以只好使用 * 查询剩余字段
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
super.last("LIMIT 1");
|
super.last("LIMIT " + n);
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,13 +153,13 @@ public interface ErrorCodeConstants {
|
||||||
ErrorCode MAIL_SEND_TEMPLATE_PARAM_MISS = new ErrorCode(1002025000, "模板参数({})缺失");
|
ErrorCode MAIL_SEND_TEMPLATE_PARAM_MISS = new ErrorCode(1002025000, "模板参数({})缺失");
|
||||||
ErrorCode MAIL_SEND_MAIL_NOT_EXISTS = new ErrorCode(1002025000, "邮箱不存在");
|
ErrorCode MAIL_SEND_MAIL_NOT_EXISTS = new ErrorCode(1002025000, "邮箱不存在");
|
||||||
|
|
||||||
// ========== 站内信模版 1002023000 ==========
|
// ========== 站内信模版 1002026000 ==========
|
||||||
ErrorCode NOTIFY_TEMPLATE_NOT_EXISTS = new ErrorCode(1002023000, "站内信模版不存在");
|
ErrorCode NOTIFY_TEMPLATE_NOT_EXISTS = new ErrorCode(1002026000, "站内信模版不存在");
|
||||||
ErrorCode NOTIFY_TEMPLATE_CODE_DUPLICATE = new ErrorCode(1002023001, "已经存在编码为【{}】的站内信模板");
|
ErrorCode NOTIFY_TEMPLATE_CODE_DUPLICATE = new ErrorCode(1002026001, "已经存在编码为【{}】的站内信模板");
|
||||||
ErrorCode NOTIFY_TEMPLATE_PARAM_MISS = new ErrorCode(1002023002, "模板参数({})缺失");
|
|
||||||
|
|
||||||
// ========== 站内信 1002024000 ==========
|
// ========== 站内信模版 1002027000 ==========
|
||||||
ErrorCode NOTIFY_MESSAGE_NOT_EXISTS = new ErrorCode(1002024000, "站内信不存在");
|
|
||||||
ErrorCode NOTIFY_MESSAGE_ID_PARAM_ERROR = new ErrorCode(1002024001, "站内信ID错误");
|
// ========== 站内信发送 1002028000 ==========
|
||||||
|
ErrorCode NOTIFY_SEND_TEMPLATE_PARAM_MISS = new ErrorCode(1002025000, "模板参数({})缺失");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.system.controller.admin.notify;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.log.NotifyLogBaseVO;
|
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.log.NotifyLogPageReqVO;
|
|
||||||
import cn.iocoder.yudao.module.system.convert.notify.NotifyLogConvert;
|
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyMessageDO;
|
|
||||||
import cn.iocoder.yudao.module.system.service.notify.NotifyLogService;
|
|
||||||
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
|
|
||||||
import io.swagger.annotations.Api;
|
|
||||||
import io.swagger.annotations.ApiOperation;
|
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import javax.validation.Valid;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
*
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author LuoWenFeng
|
|
||||||
*/
|
|
||||||
@Api(tags = "管理后台 - 站内信发送日志")
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/system/notify-log")
|
|
||||||
@Validated
|
|
||||||
public class NotifyLogController {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private NotifyLogService notifyLogService;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private AdminUserService userService;
|
|
||||||
|
|
||||||
@GetMapping("/page")
|
|
||||||
@ApiOperation("获得发送站内信日志分页")
|
|
||||||
public CommonResult<PageResult<NotifyLogBaseVO>> getNotifyLogPage(@Valid NotifyLogPageReqVO pageVO) {
|
|
||||||
PageResult<NotifyMessageDO> pageResult = notifyLogService.getNotifyMessageSendPage(pageVO);
|
|
||||||
PageResult<NotifyLogBaseVO> result = NotifyLogConvert.INSTANCE.convertPage(pageResult);
|
|
||||||
result.getList().forEach(v -> {
|
|
||||||
v.setReceiveUserName(userService.getUser(v.getUserId()).getNickname());
|
|
||||||
});
|
|
||||||
return success(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,9 +1,9 @@
|
||||||
package cn.iocoder.yudao.module.system.controller.admin.notify;
|
package cn.iocoder.yudao.module.system.controller.admin.notify;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
|
||||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.message.NotifyMessageMyPageReqVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.message.NotifyMessagePageReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.message.NotifyMessagePageReqVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.message.NotifyMessageRespVO;
|
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.message.NotifyMessageRespVO;
|
||||||
import cn.iocoder.yudao.module.system.convert.notify.NotifyMessageConvert;
|
import cn.iocoder.yudao.module.system.convert.notify.NotifyMessageConvert;
|
||||||
|
@ -18,7 +18,6 @@ import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
@ -33,6 +32,8 @@ public class NotifyMessageController {
|
||||||
@Resource
|
@Resource
|
||||||
private NotifyMessageService notifyMessageService;
|
private NotifyMessageService notifyMessageService;
|
||||||
|
|
||||||
|
// ========== 管理所有的站内信 ==========
|
||||||
|
|
||||||
@GetMapping("/get")
|
@GetMapping("/get")
|
||||||
@ApiOperation("获得站内信")
|
@ApiOperation("获得站内信")
|
||||||
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
@ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
|
||||||
|
@ -50,38 +51,45 @@ public class NotifyMessageController {
|
||||||
return success(NotifyMessageConvert.INSTANCE.convertPage(pageResult));
|
return success(NotifyMessageConvert.INSTANCE.convertPage(pageResult));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/get-recent-list")
|
// ========== 查看自己的站内信 ==========
|
||||||
@ApiOperation("获取当前用户最新站内信,默认10条")
|
|
||||||
@ApiImplicitParam(name = "size", value = "10", defaultValue = "10", dataTypeClass = Integer.class)
|
@GetMapping("/my-page")
|
||||||
public CommonResult<List<NotifyMessageRespVO>> getRecentList(@RequestParam(name = "size", defaultValue = "10") Integer size) {
|
@ApiOperation("获得我的站内信分页")
|
||||||
NotifyMessagePageReqVO reqVO = new NotifyMessagePageReqVO();
|
public CommonResult<PageResult<NotifyMessageRespVO>> getMyMyNotifyMessagePage(@Valid NotifyMessageMyPageReqVO pageVO) {
|
||||||
List<NotifyMessageDO> pageResult = notifyMessageService.getNotifyMessageList(reqVO, size);
|
PageResult<NotifyMessageDO> pageResult = notifyMessageService.getMyMyNotifyMessagePage(pageVO,
|
||||||
if (CollUtil.isNotEmpty(pageResult)) {
|
getLoginUserId(), UserTypeEnum.ADMIN.getValue());
|
||||||
return success(NotifyMessageConvert.INSTANCE.convertList(pageResult));
|
return success(NotifyMessageConvert.INSTANCE.convertPage(pageResult));
|
||||||
}
|
|
||||||
return success(Collections.emptyList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/get-unread-count")
|
@PutMapping("/update-read")
|
||||||
@ApiOperation("获得未读站内信数量")
|
@ApiOperation("标记站内信为已读")
|
||||||
public CommonResult<Long> getUnreadCount() {
|
|
||||||
return success(notifyMessageService.getUnreadNotifyMessageCount(getLoginUserId(), UserTypeEnum.ADMIN.getValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
@PutMapping("/update-list-read")
|
|
||||||
@ApiOperation("批量标记已读")
|
|
||||||
@ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
|
@ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
|
||||||
public CommonResult<Boolean> batchUpdateNotifyMessageReadStatus(@RequestBody List<Long> ids) {
|
public CommonResult<Boolean> updateNotifyMessageRead(@RequestParam("ids") List<Long> ids) {
|
||||||
notifyMessageService.batchUpdateNotifyMessageReadStatus(ids, getLoginUserId());
|
notifyMessageService.updateNotifyMessageRead(ids, getLoginUserId(), UserTypeEnum.ADMIN.getValue());
|
||||||
return success(Boolean.TRUE);
|
return success(Boolean.TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/update-all-read")
|
@PutMapping("/update-all-read")
|
||||||
@ApiOperation("所有未读消息标记已读")
|
@ApiOperation("标记所有站内信为已读")
|
||||||
public CommonResult<Boolean> batchUpdateAllNotifyMessageReadStatus() {
|
public CommonResult<Boolean> updateAllNotifyMessageRead() {
|
||||||
notifyMessageService.batchUpdateAllNotifyMessageReadStatus(getLoginUserId(), UserTypeEnum.ADMIN.getValue());
|
notifyMessageService.updateAllNotifyMessageRead(getLoginUserId(), UserTypeEnum.ADMIN.getValue());
|
||||||
return success(Boolean.TRUE);
|
return success(Boolean.TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@GetMapping("/get-unread-list")
|
||||||
|
@ApiOperation("获取当前用户的最新站内信列表,默认 10 条")
|
||||||
|
@ApiImplicitParam(name = "size", value = "10", defaultValue = "10", dataTypeClass = Integer.class)
|
||||||
|
public CommonResult<List<NotifyMessageRespVO>> getUnreadNotifyMessageList(
|
||||||
|
@RequestParam(name = "size", defaultValue = "10") Integer size) {
|
||||||
|
List<NotifyMessageDO> list = notifyMessageService.getUnreadNotifyMessageList(
|
||||||
|
getLoginUserId(), UserTypeEnum.ADMIN.getValue(), size);
|
||||||
|
return success(NotifyMessageConvert.INSTANCE.convertList(list));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/get-unread-count")
|
||||||
|
@ApiOperation("获得当前用户的未读站内信数量")
|
||||||
|
public CommonResult<Long> getUnreadNotifyMessageCount() {
|
||||||
|
return success(notifyMessageService.getUnreadNotifyMessageCount(getLoginUserId(), UserTypeEnum.ADMIN.getValue()));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,6 @@ package cn.iocoder.yudao.module.system.controller.admin.notify;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
|
||||||
import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.*;
|
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.*;
|
||||||
import cn.iocoder.yudao.module.system.convert.notify.NotifyTemplateConvert;
|
import cn.iocoder.yudao.module.system.convert.notify.NotifyTemplateConvert;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyTemplateDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyTemplateDO;
|
||||||
|
@ -17,13 +15,9 @@ import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
|
|
||||||
|
|
||||||
@Api(tags = "管理后台 - 站内信模版")
|
@Api(tags = "管理后台 - 站内信模版")
|
||||||
@RestController
|
@RestController
|
||||||
|
@ -37,7 +31,6 @@ public class NotifyTemplateController {
|
||||||
@Resource
|
@Resource
|
||||||
private NotifySendService notifySendService;
|
private NotifySendService notifySendService;
|
||||||
|
|
||||||
|
|
||||||
@PostMapping("/create")
|
@PostMapping("/create")
|
||||||
@ApiOperation("创建站内信模版")
|
@ApiOperation("创建站内信模版")
|
||||||
@PreAuthorize("@ss.hasPermission('system:notify-template:create')")
|
@PreAuthorize("@ss.hasPermission('system:notify-template:create')")
|
||||||
|
@ -79,22 +72,12 @@ public class NotifyTemplateController {
|
||||||
return success(NotifyTemplateConvert.INSTANCE.convertPage(pageResult));
|
return success(NotifyTemplateConvert.INSTANCE.convertPage(pageResult));
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/export-excel")
|
|
||||||
@ApiOperation("导出站内信模版 Excel")
|
|
||||||
@PreAuthorize("@ss.hasPermission('system:notify-template:export')")
|
|
||||||
@OperateLog(type = EXPORT)
|
|
||||||
public void exportNotifyTemplateExcel(@Valid NotifyTemplateExportReqVO exportReqVO,
|
|
||||||
HttpServletResponse response) throws IOException {
|
|
||||||
List<NotifyTemplateDO> list = notifyTemplateService.getNotifyTemplateList(exportReqVO);
|
|
||||||
// 导出 Excel
|
|
||||||
List<NotifyTemplateExcelVO> datas = NotifyTemplateConvert.INSTANCE.convertList02(list);
|
|
||||||
ExcelUtils.write(response, "站内信模版.xls", "数据", NotifyTemplateExcelVO.class, datas);
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/send-notify")
|
@PostMapping("/send-notify")
|
||||||
@ApiOperation("发送站内信")
|
@ApiOperation("发送站内信")
|
||||||
|
@PreAuthorize("@ss.hasPermission('system:notify-template:send-notify')")
|
||||||
public CommonResult<Long> sendNotify(@Valid @RequestBody NotifyTemplateSendReqVO sendReqVO) {
|
public CommonResult<Long> sendNotify(@Valid @RequestBody NotifyTemplateSendReqVO sendReqVO) {
|
||||||
return success(notifySendService.sendSingleNotifyToAdmin(sendReqVO.getUserId(),
|
return success(notifySendService.sendSingleNotifyToAdmin(sendReqVO.getUserId(),
|
||||||
sendReqVO.getTemplateCode(), sendReqVO.getTemplateParams()));
|
sendReqVO.getTemplateCode(), sendReqVO.getTemplateParams()));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,44 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.system.controller.admin.notify.vo.log;
|
|
||||||
|
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
|
||||||
import lombok.Data;
|
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
|
||||||
|
|
||||||
import java.util.Date;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 站内信 Base VO,提供给添加、修改、详细的子 VO 使用
|
|
||||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class NotifyLogBaseVO {
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "模版编码")
|
|
||||||
private String templateCode;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "标题")
|
|
||||||
private String title;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "内容", required = true)
|
|
||||||
private String content;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "发送时间", required = true)
|
|
||||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
|
||||||
private Date sendTime;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "芋艿", required = true)
|
|
||||||
private String receiveUserName;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "1", required = true)
|
|
||||||
private Long userId;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "是否已读 false-未读 true-已读")
|
|
||||||
private Boolean readStatus;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "阅读时间")
|
|
||||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
|
||||||
private Date readTime;
|
|
||||||
|
|
||||||
}
|
|
|
@ -4,35 +4,58 @@ import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 站内信 Base VO,提供给添加、修改、详细的子 VO 使用
|
* 站内信消息 Base VO,提供给添加、修改、详细的子 VO 使用
|
||||||
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class NotifyMessageBaseVO {
|
public class NotifyMessageBaseVO {
|
||||||
|
|
||||||
@ApiModelProperty(value = "标题")
|
@ApiModelProperty(value = "用户编号", required = true, example = "25025")
|
||||||
private String title;
|
@NotNull(message = "用户编号不能为空")
|
||||||
|
private Long userId;
|
||||||
|
|
||||||
@ApiModelProperty(value = "内容")
|
@ApiModelProperty(value = "用户类型", required = true, example = "1", notes = "参见 UserTypeEnum 枚举")
|
||||||
private String content;
|
@NotNull(message = "用户类型不能为空")
|
||||||
|
private Byte userType;
|
||||||
|
|
||||||
@ApiModelProperty(value = "发送时间")
|
@ApiModelProperty(value = "模版编号", required = true, example = "13013")
|
||||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
@NotNull(message = "模版编号不能为空")
|
||||||
private Date sendTime;
|
private Long templateId;
|
||||||
|
|
||||||
@ApiModelProperty(value = "芋艿")
|
@ApiModelProperty(value = "模板编码", required = true, example = "test_01")
|
||||||
private String sendUserName;
|
@NotNull(message = "模板编码不能为空")
|
||||||
|
private String templateCode;
|
||||||
|
|
||||||
@ApiModelProperty(value = "是否已读 false-未读 true-已读")
|
@ApiModelProperty(value = "模版发送人名称", required = true, example = "芋艿")
|
||||||
|
@NotNull(message = "模版发送人名称不能为空")
|
||||||
|
private String templateNickname;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "模版内容", required = true, example = "测试内容")
|
||||||
|
@NotNull(message = "模版内容不能为空")
|
||||||
|
private String templateContent;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "模版类型", required = true, example = "2")
|
||||||
|
@NotNull(message = "模版类型不能为空")
|
||||||
|
private Integer templateType;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "模版参数", required = true)
|
||||||
|
@NotNull(message = "模版参数不能为空")
|
||||||
|
private Map<String, Object> templateParams;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "是否已读", required = true, example = "true")
|
||||||
|
@NotNull(message = "是否已读不能为空")
|
||||||
private Boolean readStatus;
|
private Boolean readStatus;
|
||||||
|
|
||||||
@ApiModelProperty(value = "阅读时间")
|
@ApiModelProperty(value = "阅读时间")
|
||||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||||
private Date readTime;
|
private LocalDateTime readTime;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.iocoder.yudao.module.system.controller.admin.notify.vo.log;
|
package cn.iocoder.yudao.module.system.controller.admin.notify.vo.message;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
import io.swagger.annotations.ApiModel;
|
import io.swagger.annotations.ApiModel;
|
||||||
|
@ -8,23 +8,21 @@ import lombok.EqualsAndHashCode;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
import java.util.Date;
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||||
|
|
||||||
@ApiModel("管理后台 - 站内信日志分页 Request VO")
|
@ApiModel("管理后台 - 站内信分页 Request VO")
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
public class NotifyLogPageReqVO extends PageParam {
|
public class NotifyMessageMyPageReqVO extends PageParam {
|
||||||
|
|
||||||
@ApiModelProperty(value = "模版编码")
|
@ApiModelProperty(value = "是否已读", example = "true")
|
||||||
private String templateCode;
|
private Boolean readStatus;
|
||||||
|
|
||||||
@ApiModelProperty(value = "标题")
|
|
||||||
private String title;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "创建时间")
|
@ApiModelProperty(value = "创建时间")
|
||||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||||
private Date[] sendTime;
|
private LocalDateTime[] createTime;
|
||||||
|
|
||||||
}
|
}
|
|
@ -8,6 +8,7 @@ import lombok.EqualsAndHashCode;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||||
|
@ -18,14 +19,20 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
|
||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
public class NotifyMessagePageReqVO extends PageParam {
|
public class NotifyMessagePageReqVO extends PageParam {
|
||||||
|
|
||||||
@ApiModelProperty(value = "标题")
|
@ApiModelProperty(value = "用户编号", example = "25025")
|
||||||
private String title;
|
private Long userId;
|
||||||
|
|
||||||
@ApiModelProperty(value = "是否已读 0-未读 1-已读")
|
@ApiModelProperty(value = "用户类型", example = "1")
|
||||||
private Boolean readStatus;
|
private Integer userType;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "模板编码", example = "test_01")
|
||||||
|
private String templateCode;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "模版类型", example = "2")
|
||||||
|
private Integer templateType;
|
||||||
|
|
||||||
@ApiModelProperty(value = "创建时间")
|
@ApiModelProperty(value = "创建时间")
|
||||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||||
private Date[] createTime;
|
private LocalDateTime[] createTime;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,10 @@ import io.swagger.annotations.*;
|
||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
public class NotifyMessageRespVO extends NotifyMessageBaseVO {
|
public class NotifyMessageRespVO extends NotifyMessageBaseVO {
|
||||||
|
|
||||||
@ApiModelProperty(value = "ID", required = true)
|
@ApiModelProperty(value = "ID", required = true, example = "1024")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "创建时间", required = true)
|
||||||
|
private Date createTime;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.common.validation.InEnum;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,24 +15,32 @@ import javax.validation.constraints.NotNull;
|
||||||
@Data
|
@Data
|
||||||
public class NotifyTemplateBaseVO {
|
public class NotifyTemplateBaseVO {
|
||||||
|
|
||||||
@ApiModelProperty(value = "模版编码", required = true)
|
@ApiModelProperty(value = "模版名称", required = true, example = "测试模版")
|
||||||
|
@NotEmpty(message = "模版名称不能为空")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "模版编码", required = true, example = "SEND_TEST")
|
||||||
@NotNull(message = "模版编码不能为空")
|
@NotNull(message = "模版编码不能为空")
|
||||||
private String code;
|
private String code;
|
||||||
|
|
||||||
@ApiModelProperty(value = "模版标题", required = true)
|
@ApiModelProperty(value = "模版类型", required = true, example = "1", notes = "对应 system_notify_template_type 字典")
|
||||||
@NotNull(message = "模版标题不能为空")
|
@NotNull(message = "模版类型不能为空")
|
||||||
private String title;
|
private Integer type;
|
||||||
|
|
||||||
@ApiModelProperty(value = "模版内容", required = true)
|
@ApiModelProperty(value = "发送人名称", required = true, example = "土豆")
|
||||||
@NotNull(message = "模版内容不能为空")
|
@NotEmpty(message = "发送人名称不能为空")
|
||||||
|
private String nickname;
|
||||||
|
|
||||||
|
@ApiModelProperty(value = "模版内容", required = true, example = "我是模版内容")
|
||||||
|
@NotEmpty(message = "模版内容不能为空")
|
||||||
private String content;
|
private String content;
|
||||||
|
|
||||||
@ApiModelProperty(value = "状态:1-启用 0-禁用", required = true)
|
@ApiModelProperty(value = "状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举")
|
||||||
@NotNull(message = "状态:1-启用 0-禁用不能为空")
|
@NotNull(message = "状态不能为空")
|
||||||
@InEnum(value = CommonStatusEnum.class, message = "状态必须是 {value}")
|
@InEnum(value = CommonStatusEnum.class, message = "状态必须是 {value}")
|
||||||
private Integer status;
|
private Integer status;
|
||||||
|
|
||||||
@ApiModelProperty(value = "备注")
|
@ApiModelProperty(value = "备注", example = "我是备注")
|
||||||
private String remarks;
|
private String remark;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,5 +8,4 @@ import io.swagger.annotations.*;
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
public class NotifyTemplateCreateReqVO extends NotifyTemplateBaseVO {
|
public class NotifyTemplateCreateReqVO extends NotifyTemplateBaseVO {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,43 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.system.controller.admin.notify.vo.template;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.system.enums.DictTypeConstants;
|
|
||||||
import lombok.*;
|
|
||||||
import java.util.*;
|
|
||||||
import io.swagger.annotations.*;
|
|
||||||
|
|
||||||
import com.alibaba.excel.annotation.ExcelProperty;
|
|
||||||
import cn.iocoder.yudao.framework.excel.core.annotations.DictFormat;
|
|
||||||
import cn.iocoder.yudao.framework.excel.core.convert.DictConvert;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 站内信模版 Excel VO
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
public class NotifyTemplateExcelVO {
|
|
||||||
|
|
||||||
@ExcelProperty("ID")
|
|
||||||
private Long id;
|
|
||||||
|
|
||||||
@ExcelProperty("模版编码")
|
|
||||||
private String code;
|
|
||||||
|
|
||||||
@ExcelProperty("模版标题")
|
|
||||||
private String title;
|
|
||||||
|
|
||||||
@ExcelProperty("模版内容")
|
|
||||||
private String content;
|
|
||||||
|
|
||||||
@ExcelProperty(value = "状态:1-启用 0-禁用", converter = DictConvert.class)
|
|
||||||
@DictFormat(DictTypeConstants.COMMON_STATUS)
|
|
||||||
private Integer status;
|
|
||||||
|
|
||||||
@ExcelProperty("备注")
|
|
||||||
private String remarks;
|
|
||||||
|
|
||||||
@ExcelProperty("创建时间")
|
|
||||||
private Date createTime;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.system.controller.admin.notify.vo.template;
|
|
||||||
|
|
||||||
import lombok.*;
|
|
||||||
import java.util.*;
|
|
||||||
import io.swagger.annotations.*;
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
|
||||||
|
|
||||||
@ApiModel(value = "管理后台 - 站内信模版 Excel 导出 Request VO", description = "参数和 NotifyTemplatePageReqVO 是一致的")
|
|
||||||
@Data
|
|
||||||
public class NotifyTemplateExportReqVO {
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "模版编码")
|
|
||||||
private String code;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "模版标题")
|
|
||||||
private String title;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "状态:1-启用 0-禁用")
|
|
||||||
private Integer status;
|
|
||||||
|
|
||||||
@ApiModelProperty(value = "创建时间")
|
|
||||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
|
||||||
private Date[] createTime;
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,6 +1,9 @@
|
||||||
package cn.iocoder.yudao.module.system.controller.admin.notify.vo.template;
|
package cn.iocoder.yudao.module.system.controller.admin.notify.vo.template;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import io.swagger.annotations.*;
|
import io.swagger.annotations.*;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
@ -14,17 +17,17 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
|
||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
public class NotifyTemplatePageReqVO extends PageParam {
|
public class NotifyTemplatePageReqVO extends PageParam {
|
||||||
|
|
||||||
@ApiModelProperty(value = "模版编码")
|
@ApiModelProperty(value = "模版编码", example = "test_01")
|
||||||
private String code;
|
private String code;
|
||||||
|
|
||||||
@ApiModelProperty(value = "模版标题")
|
@ApiModelProperty(value = "模版名称", example = "我是名称")
|
||||||
private String title;
|
private String name;
|
||||||
|
|
||||||
@ApiModelProperty(value = "状态:1-启用 0-禁用")
|
@ApiModelProperty(value = "状态", example = "1", notes = "参见 CommonStatusEnum 枚举类")
|
||||||
private String status;
|
private Integer status;
|
||||||
|
|
||||||
@ApiModelProperty(value = "创建时间")
|
@ApiModelProperty(value = "创建时间")
|
||||||
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||||
private Date[] createTime;
|
private LocalDateTime[] createTime;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ import io.swagger.annotations.*;
|
||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
public class NotifyTemplateRespVO extends NotifyTemplateBaseVO {
|
public class NotifyTemplateRespVO extends NotifyTemplateBaseVO {
|
||||||
|
|
||||||
@ApiModelProperty(value = "ID", required = true)
|
@ApiModelProperty(value = "ID", required = true, example = "1024")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@ApiModelProperty(value = "参数数组", example = "name,code")
|
@ApiModelProperty(value = "参数数组", example = "name,code")
|
||||||
|
|
|
@ -4,6 +4,7 @@ import io.swagger.annotations.ApiModel;
|
||||||
import io.swagger.annotations.ApiModelProperty;
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotEmpty;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -16,7 +17,7 @@ public class NotifyTemplateSendReqVO {
|
||||||
private Long userId;
|
private Long userId;
|
||||||
|
|
||||||
@ApiModelProperty(value = "模板编码", required = true, example = "01")
|
@ApiModelProperty(value = "模板编码", required = true, example = "01")
|
||||||
@NotNull(message = "模板编码不能为空")
|
@NotEmpty(message = "模板编码不能为空")
|
||||||
private String templateCode;
|
private String templateCode;
|
||||||
|
|
||||||
@ApiModelProperty(value = "模板参数")
|
@ApiModelProperty(value = "模板参数")
|
||||||
|
|
|
@ -10,8 +10,8 @@ import javax.validation.constraints.*;
|
||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
public class NotifyTemplateUpdateReqVO extends NotifyTemplateBaseVO {
|
public class NotifyTemplateUpdateReqVO extends NotifyTemplateBaseVO {
|
||||||
|
|
||||||
@ApiModelProperty(value = "ID", required = true)
|
@ApiModelProperty(value = "ID", required = true, example = "1024")
|
||||||
@NotNull(message = "ID不能为空")
|
@NotNull(message = "ID 不能为空")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.system.convert.notify;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.log.NotifyLogBaseVO;
|
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyMessageDO;
|
|
||||||
import org.mapstruct.Mapper;
|
|
||||||
import org.mapstruct.factory.Mappers;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
*
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author LuoWenFeng
|
|
||||||
*/
|
|
||||||
@Mapper
|
|
||||||
public interface NotifyLogConvert {
|
|
||||||
|
|
||||||
NotifyLogConvert INSTANCE = Mappers.getMapper(NotifyLogConvert.class);
|
|
||||||
|
|
||||||
PageResult<NotifyLogBaseVO> convertPage(PageResult<NotifyMessageDO> page);
|
|
||||||
|
|
||||||
}
|
|
|
@ -5,7 +5,6 @@ import java.util.*;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateCreateReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateCreateReqVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateExcelVO;
|
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateRespVO;
|
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateRespVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateUpdateReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateUpdateReqVO;
|
||||||
import org.mapstruct.Mapper;
|
import org.mapstruct.Mapper;
|
||||||
|
@ -32,6 +31,4 @@ public interface NotifyTemplateConvert {
|
||||||
|
|
||||||
PageResult<NotifyTemplateRespVO> convertPage(PageResult<NotifyTemplateDO> page);
|
PageResult<NotifyTemplateRespVO> convertPage(PageResult<NotifyTemplateDO> page);
|
||||||
|
|
||||||
List<NotifyTemplateExcelVO> convertList02(List<NotifyTemplateDO> list);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,19 +2,24 @@ package cn.iocoder.yudao.module.system.dal.dataobject.notify;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO;
|
||||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 站内信 DO
|
* 站内信 DO
|
||||||
*
|
*
|
||||||
* @author xrcoder
|
* @author xrcoder
|
||||||
*/
|
*/
|
||||||
@TableName("system_notify_message")
|
@TableName(value = "system_notify_message", autoResultMap = true)
|
||||||
@KeySequence("system_notify_message_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
@KeySequence("system_notify_message_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ -25,22 +30,10 @@ import java.util.Date;
|
||||||
public class NotifyMessageDO extends BaseDO {
|
public class NotifyMessageDO extends BaseDO {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ID
|
* 站内信编号,自增
|
||||||
*/
|
*/
|
||||||
@TableId
|
@TableId
|
||||||
private Long id;
|
private Long id;
|
||||||
/**
|
|
||||||
* 站内信模版编号
|
|
||||||
*
|
|
||||||
* 关联 {@link NotifyTemplateDO#getId()}
|
|
||||||
*/
|
|
||||||
private Long templateId;
|
|
||||||
/**
|
|
||||||
* 站内信模版编码
|
|
||||||
*
|
|
||||||
* 关联 {@link NotifyTemplateDO#getCode()}
|
|
||||||
*/
|
|
||||||
private String templateCode;
|
|
||||||
/**
|
/**
|
||||||
* 用户编号
|
* 用户编号
|
||||||
*
|
*
|
||||||
|
@ -53,28 +46,49 @@ public class NotifyMessageDO extends BaseDO {
|
||||||
* 枚举 {@link UserTypeEnum}
|
* 枚举 {@link UserTypeEnum}
|
||||||
*/
|
*/
|
||||||
private Integer userType;
|
private Integer userType;
|
||||||
|
|
||||||
|
// ========= 模板相关字段 =========
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 标题
|
* 模版编号
|
||||||
|
*
|
||||||
|
* 关联 {@link NotifyTemplateDO#getId()}
|
||||||
*/
|
*/
|
||||||
private String title;
|
private Long templateId;
|
||||||
/**
|
/**
|
||||||
* 内容
|
* 模版编码
|
||||||
|
*
|
||||||
|
* 关联 {@link NotifyTemplateDO#getCode()}
|
||||||
*/
|
*/
|
||||||
private String content;
|
private String templateCode;
|
||||||
// TODO @luowenfeng:是不是创建时间,直接作为发送时间;
|
|
||||||
/**
|
/**
|
||||||
* 发送时间
|
* 模版类型
|
||||||
|
*
|
||||||
|
* 冗余 {@link NotifyTemplateDO#getType()}
|
||||||
*/
|
*/
|
||||||
private Date sendTime;
|
private Integer templateType;
|
||||||
// TODO @luowenfeng:是不是不用发送 id 和名字😑?
|
|
||||||
/**
|
/**
|
||||||
* 发送用户id
|
* 模版发送人名称
|
||||||
|
*
|
||||||
|
* 冗余 {@link NotifyTemplateDO#getNickname()}
|
||||||
*/
|
*/
|
||||||
private Long sendUserId;
|
private String templateNickname;
|
||||||
/**
|
/**
|
||||||
* 发送用户名
|
* 模版内容
|
||||||
|
*
|
||||||
|
* 基于 {@link NotifyTemplateDO#getContent()} 格式化后的内容
|
||||||
*/
|
*/
|
||||||
private String sendUserName;
|
private String templateContent;
|
||||||
|
/**
|
||||||
|
* 模版参数
|
||||||
|
*
|
||||||
|
* 基于 {@link NotifyTemplateDO#getParams()} 输入后的参数
|
||||||
|
*/
|
||||||
|
@TableField(typeHandler = JacksonTypeHandler.class)
|
||||||
|
private Map<String, Object> templateParams;
|
||||||
|
|
||||||
|
// ========= 读取相关字段 =========
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否已读
|
* 是否已读
|
||||||
*/
|
*/
|
||||||
|
@ -82,6 +96,6 @@ public class NotifyMessageDO extends BaseDO {
|
||||||
/**
|
/**
|
||||||
* 阅读时间
|
* 阅读时间
|
||||||
*/
|
*/
|
||||||
private Date readTime;
|
private LocalDateTime readTime;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,14 +31,24 @@ public class NotifyTemplateDO extends BaseDO {
|
||||||
*/
|
*/
|
||||||
@TableId
|
@TableId
|
||||||
private Long id;
|
private Long id;
|
||||||
|
/**
|
||||||
|
* 模版名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
/**
|
/**
|
||||||
* 模版编码
|
* 模版编码
|
||||||
*/
|
*/
|
||||||
private String code;
|
private String code;
|
||||||
/**
|
/**
|
||||||
* 模版标题
|
* 模版类型
|
||||||
|
*
|
||||||
|
* 对应 system_notify_template_type 字典
|
||||||
*/
|
*/
|
||||||
private String title;
|
private Integer type;
|
||||||
|
/**
|
||||||
|
* 发送人名称
|
||||||
|
*/
|
||||||
|
private String nickname;
|
||||||
/**
|
/**
|
||||||
* 模版内容
|
* 模版内容
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -3,49 +3,61 @@ package cn.iocoder.yudao.module.system.dal.mysql.notify;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.log.NotifyLogPageReqVO;
|
import cn.iocoder.yudao.framework.mybatis.core.query.QueryWrapperX;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.message.NotifyMessageMyPageReqVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.message.NotifyMessagePageReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.message.NotifyMessagePageReqVO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyMessageDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyMessageDO;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
|
||||||
* 站内信 Mapper
|
|
||||||
*
|
|
||||||
* @author xrcoder
|
|
||||||
*/
|
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface NotifyMessageMapper extends BaseMapperX<NotifyMessageDO> {
|
public interface NotifyMessageMapper extends BaseMapperX<NotifyMessageDO> {
|
||||||
|
|
||||||
default PageResult<NotifyMessageDO> selectPage(NotifyMessagePageReqVO reqVO, Long userId, Integer userType) {
|
default PageResult<NotifyMessageDO> selectPage(NotifyMessagePageReqVO reqVO) {
|
||||||
return selectPage(reqVO, new LambdaQueryWrapperX<NotifyMessageDO>()
|
return selectPage(reqVO, new LambdaQueryWrapperX<NotifyMessageDO>()
|
||||||
.likeIfPresent(NotifyMessageDO::getTitle, reqVO.getTitle())
|
.eqIfPresent(NotifyMessageDO::getUserId, reqVO.getUserId())
|
||||||
.eqIfPresent(NotifyMessageDO::getReadStatus, reqVO.getReadStatus())
|
.eqIfPresent(NotifyMessageDO::getUserType, reqVO.getUserType())
|
||||||
|
.likeIfPresent(NotifyMessageDO::getTemplateCode, reqVO.getTemplateCode())
|
||||||
|
.eqIfPresent(NotifyMessageDO::getTemplateType, reqVO.getTemplateType())
|
||||||
|
.betweenIfPresent(NotifyMessageDO::getCreateTime, reqVO.getCreateTime())
|
||||||
|
.orderByDesc(NotifyMessageDO::getId));
|
||||||
|
}
|
||||||
|
|
||||||
|
default PageResult<NotifyMessageDO> selectPage(NotifyMessageMyPageReqVO reqVO, Long userId, Integer userType) {
|
||||||
|
return selectPage(reqVO, new LambdaQueryWrapperX<NotifyMessageDO>()
|
||||||
|
.eq(NotifyMessageDO::getReadStatus, reqVO.getReadStatus())
|
||||||
.betweenIfPresent(NotifyMessageDO::getCreateTime, reqVO.getCreateTime())
|
.betweenIfPresent(NotifyMessageDO::getCreateTime, reqVO.getCreateTime())
|
||||||
.eq(NotifyMessageDO::getUserId, userId)
|
.eq(NotifyMessageDO::getUserId, userId)
|
||||||
.eq(NotifyMessageDO::getUserType, userType)
|
.eq(NotifyMessageDO::getUserType, userType)
|
||||||
.orderByDesc(NotifyMessageDO::getId));
|
.orderByDesc(NotifyMessageDO::getId));
|
||||||
}
|
}
|
||||||
|
|
||||||
default PageResult<NotifyMessageDO> selectSendPage(NotifyLogPageReqVO reqVO, Long userId) {
|
default int updateListRead(Collection<Long> ids, Long userId, Integer userType) {
|
||||||
return selectPage(reqVO, new LambdaQueryWrapperX<NotifyMessageDO>()
|
return update(new NotifyMessageDO().setReadStatus(true).setReadTime(LocalDateTime.now()),
|
||||||
.likeIfPresent(NotifyMessageDO::getTitle, reqVO.getTitle())
|
new LambdaQueryWrapperX<NotifyMessageDO>()
|
||||||
.betweenIfPresent(NotifyMessageDO::getSendTime, reqVO.getSendTime())
|
.in(NotifyMessageDO::getId, ids)
|
||||||
.eqIfPresent(NotifyMessageDO::getTemplateCode, reqVO.getTemplateCode())
|
.eq(NotifyMessageDO::getUserId, userId)
|
||||||
.eq(NotifyMessageDO::getSendUserId, userId)
|
.eq(NotifyMessageDO::getUserType, userType)
|
||||||
.orderByDesc(NotifyMessageDO::getId));
|
.eq(NotifyMessageDO::getReadStatus, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
default List<NotifyMessageDO> selectList(NotifyMessagePageReqVO reqVO, Integer size, Long userId, Integer userType) {
|
default int updateListRead(Long userId, Integer userType) {
|
||||||
return selectList(new LambdaQueryWrapperX<NotifyMessageDO>()
|
return update(new NotifyMessageDO().setReadStatus(true).setReadTime(LocalDateTime.now()),
|
||||||
.likeIfPresent(NotifyMessageDO::getTitle, reqVO.getTitle())
|
new LambdaQueryWrapperX<NotifyMessageDO>()
|
||||||
.eqIfPresent(NotifyMessageDO::getReadStatus, reqVO.getReadStatus())
|
.eq(NotifyMessageDO::getUserId, userId)
|
||||||
.betweenIfPresent(NotifyMessageDO::getCreateTime, reqVO.getCreateTime())
|
.eq(NotifyMessageDO::getUserType, userType)
|
||||||
.eqIfPresent(NotifyMessageDO::getUserId, userId)
|
.eq(NotifyMessageDO::getReadStatus, false));
|
||||||
.eqIfPresent(NotifyMessageDO::getUserType, userType)
|
}
|
||||||
.orderByDesc(NotifyMessageDO::getId)
|
|
||||||
.last("limit " + size));
|
default List<NotifyMessageDO> selectUnreadListByUserIdAndUserType(Long userId, Integer userType, Integer size) {
|
||||||
|
return selectList(new QueryWrapperX<NotifyMessageDO>() // 由于要使用 limitN 语句,所以只能用 QueryWrapperX
|
||||||
|
.eq("user_id", userId)
|
||||||
|
.eq("user_type", userType)
|
||||||
|
.eq("read_status", false)
|
||||||
|
.orderByDesc("id").limitN(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
default Long selectUnreadCountByUserIdAndUserType(Long userId, Integer userType) {
|
default Long selectUnreadCountByUserIdAndUserType(Long userId, Integer userType) {
|
||||||
|
@ -55,11 +67,4 @@ public interface NotifyMessageMapper extends BaseMapperX<NotifyMessageDO> {
|
||||||
.eq(NotifyMessageDO::getUserType, userType));
|
.eq(NotifyMessageDO::getUserType, userType));
|
||||||
}
|
}
|
||||||
|
|
||||||
default List<NotifyMessageDO> selectUnreadListByUserIdAndUserType(Long userId, Integer userType) {
|
|
||||||
return selectList(new LambdaQueryWrapperX<NotifyMessageDO>()
|
|
||||||
.eq(NotifyMessageDO::getReadStatus, false)
|
|
||||||
.eq(NotifyMessageDO::getUserId, userId)
|
|
||||||
.eq(NotifyMessageDO::getUserType, userType));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,45 +1,23 @@
|
||||||
package cn.iocoder.yudao.module.system.dal.mysql.notify;
|
package cn.iocoder.yudao.module.system.dal.mysql.notify;
|
||||||
|
|
||||||
import java.util.*;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateExportReqVO;
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplatePageReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplatePageReqVO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyTemplateDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyTemplateDO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.sms.SmsTemplateDO;
|
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.apache.ibatis.annotations.Select;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 站内信模版 Mapper
|
|
||||||
*
|
|
||||||
* @author xrcoder
|
|
||||||
*/
|
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface NotifyTemplateMapper extends BaseMapperX<NotifyTemplateDO> {
|
public interface NotifyTemplateMapper extends BaseMapperX<NotifyTemplateDO> {
|
||||||
|
|
||||||
@Select("SELECT COUNT(*) FROM system_notify_template WHERE update_time > #{maxUpdateTime}")
|
|
||||||
Long selectCountByUpdateTimeGt(Date maxUpdateTime);
|
|
||||||
|
|
||||||
default NotifyTemplateDO selectByCode(String code) {
|
default NotifyTemplateDO selectByCode(String code) {
|
||||||
return selectOne(NotifyTemplateDO::getCode, code);
|
return selectOne(NotifyTemplateDO::getCode, code);
|
||||||
}
|
}
|
||||||
|
|
||||||
default PageResult<NotifyTemplateDO> selectPage(NotifyTemplatePageReqVO reqVO) {
|
default PageResult<NotifyTemplateDO> selectPage(NotifyTemplatePageReqVO reqVO) {
|
||||||
return selectPage(reqVO, new LambdaQueryWrapperX<NotifyTemplateDO>()
|
return selectPage(reqVO, new LambdaQueryWrapperX<NotifyTemplateDO>()
|
||||||
.eqIfPresent(NotifyTemplateDO::getCode, reqVO.getCode())
|
.likeIfPresent(NotifyTemplateDO::getCode, reqVO.getCode())
|
||||||
.eqIfPresent(NotifyTemplateDO::getTitle, reqVO.getTitle())
|
.likeIfPresent(NotifyTemplateDO::getName, reqVO.getName())
|
||||||
.eqIfPresent(NotifyTemplateDO::getStatus, reqVO.getStatus())
|
|
||||||
.betweenIfPresent(NotifyTemplateDO::getCreateTime, reqVO.getCreateTime())
|
|
||||||
.orderByDesc(NotifyTemplateDO::getId));
|
|
||||||
}
|
|
||||||
|
|
||||||
default List<NotifyTemplateDO> selectList(NotifyTemplateExportReqVO reqVO) {
|
|
||||||
return selectList(new LambdaQueryWrapperX<NotifyTemplateDO>()
|
|
||||||
.eqIfPresent(NotifyTemplateDO::getCode, reqVO.getCode())
|
|
||||||
.eqIfPresent(NotifyTemplateDO::getTitle, reqVO.getTitle())
|
|
||||||
.eqIfPresent(NotifyTemplateDO::getStatus, reqVO.getStatus())
|
.eqIfPresent(NotifyTemplateDO::getStatus, reqVO.getStatus())
|
||||||
.betweenIfPresent(NotifyTemplateDO::getCreateTime, reqVO.getCreateTime())
|
.betweenIfPresent(NotifyTemplateDO::getCreateTime, reqVO.getCreateTime())
|
||||||
.orderByDesc(NotifyTemplateDO::getId));
|
.orderByDesc(NotifyTemplateDO::getId));
|
||||||
|
|
|
@ -22,7 +22,7 @@ public interface SmsCodeMapper extends BaseMapperX<SmsCodeDO> {
|
||||||
.eqIfPresent("scene", scene)
|
.eqIfPresent("scene", scene)
|
||||||
.eqIfPresent("code", code)
|
.eqIfPresent("code", code)
|
||||||
.orderByDesc("id")
|
.orderByDesc("id")
|
||||||
.limit1());
|
.limitN(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ public interface MailLogService {
|
||||||
* @param isSend 是否发送成功
|
* @param isSend 是否发送成功
|
||||||
* @return 日志编号
|
* @return 日志编号
|
||||||
*/
|
*/
|
||||||
Long createMailLog(Long userId,Integer userType, String toMail,
|
Long createMailLog(Long userId, Integer userType, String toMail,
|
||||||
MailAccountDO account, MailTemplateDO template ,
|
MailAccountDO account, MailTemplateDO template ,
|
||||||
String templateContent, Map<String, Object> templateParams, Boolean isSend);
|
String templateContent, Map<String, Object> templateParams, Boolean isSend);
|
||||||
|
|
||||||
|
|
|
@ -88,8 +88,7 @@ public class MailSendServiceImpl implements MailSendService {
|
||||||
|
|
||||||
// 校验邮箱是否存在
|
// 校验邮箱是否存在
|
||||||
mail = checkMail(mail);
|
mail = checkMail(mail);
|
||||||
// 构建有序的模板参数。为什么放在这个位置,是提前保证模板参数的正确性,而不是到了插入发送日志
|
checkTemplateParams(template, templateParams);
|
||||||
List<KeyValue<String, Object>> newTemplateParams = buildTemplateParams(template, templateParams);
|
|
||||||
|
|
||||||
// 创建发送日志。如果模板被禁用,则不发送短信,只记录日志
|
// 创建发送日志。如果模板被禁用,则不发送短信,只记录日志
|
||||||
Boolean isSend = CommonStatusEnum.ENABLE.getStatus().equals(template.getStatus());
|
Boolean isSend = CommonStatusEnum.ENABLE.getStatus().equals(template.getStatus());
|
||||||
|
@ -152,21 +151,19 @@ public class MailSendServiceImpl implements MailSendService {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将参数模板,处理成有序的 KeyValue 数组
|
* 校验邮件参数是否确实
|
||||||
*
|
*
|
||||||
* @param template 邮箱模板
|
* @param template 邮箱模板
|
||||||
* @param templateParams 原始参数
|
* @param templateParams 参数列表
|
||||||
* @return 处理后的参数
|
|
||||||
*/
|
*/
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public List<KeyValue<String, Object>> buildTemplateParams(MailTemplateDO template, Map<String, Object> templateParams) {
|
public void checkTemplateParams(MailTemplateDO template, Map<String, Object> templateParams) {
|
||||||
return template.getParams().stream().map(key -> {
|
template.getParams().forEach(key -> {
|
||||||
Object value = templateParams.get(key);
|
Object value = templateParams.get(key);
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
throw exception(MAIL_SEND_TEMPLATE_PARAM_MISS, key);
|
throw exception(MAIL_SEND_TEMPLATE_PARAM_MISS, key);
|
||||||
}
|
}
|
||||||
return new KeyValue<>(key, value);
|
});
|
||||||
}).collect(Collectors.toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.system.service.notify;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.log.NotifyLogPageReqVO;
|
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyMessageDO;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 站内信日志 Service 接口
|
|
||||||
*
|
|
||||||
* @author LuoWenFeng
|
|
||||||
*/
|
|
||||||
public interface NotifyLogService {
|
|
||||||
|
|
||||||
// TODO @LuoWenFeng:NotifyLogService=》NotifyMessageService
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得站内信发送分页
|
|
||||||
*
|
|
||||||
* @param pageReqVO 分页查询
|
|
||||||
* @return 站内信分页
|
|
||||||
*/
|
|
||||||
PageResult<NotifyMessageDO> getNotifyMessageSendPage(NotifyLogPageReqVO pageReqVO);
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
package cn.iocoder.yudao.module.system.service.notify;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.log.NotifyLogPageReqVO;
|
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyMessageDO;
|
|
||||||
import cn.iocoder.yudao.module.system.dal.mysql.notify.NotifyMessageMapper;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.validation.annotation.Validated;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <p>
|
|
||||||
* 站内信日志 Service 实现类
|
|
||||||
*
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @author LuoWenFeng
|
|
||||||
*/
|
|
||||||
@Service
|
|
||||||
@Validated
|
|
||||||
public class NotifyLogServiceImpl implements NotifyLogService {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private NotifyMessageMapper notifyMessageMapper;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PageResult<NotifyMessageDO> getNotifyMessageSendPage(NotifyLogPageReqVO pageReqVO) {
|
|
||||||
return notifyMessageMapper.selectSendPage(pageReqVO, getLoginUserId());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,11 +1,14 @@
|
||||||
package cn.iocoder.yudao.module.system.service.notify;
|
package cn.iocoder.yudao.module.system.service.notify;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.message.NotifyMessageMyPageReqVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.message.NotifyMessagePageReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.message.NotifyMessagePageReqVO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyMessageDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyMessageDO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyTemplateDO;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 站内信 Service 接口
|
* 站内信 Service 接口
|
||||||
|
@ -15,28 +18,17 @@ import java.util.List;
|
||||||
public interface NotifyMessageService {
|
public interface NotifyMessageService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得站内信
|
* 创建站内信
|
||||||
*
|
*
|
||||||
* @param id 编号
|
* @param userId 用户编号
|
||||||
* @return 站内信
|
* @param userType 用户类型
|
||||||
|
* @param template 模版信息
|
||||||
|
* @param templateContent 模版内容
|
||||||
|
* @param templateParams 模版参数
|
||||||
|
* @return 站内信编号
|
||||||
*/
|
*/
|
||||||
NotifyMessageDO getNotifyMessage(Long id);
|
Long createNotifyMessage(Long userId, Integer userType,
|
||||||
|
NotifyTemplateDO template, String templateContent, Map<String, Object> templateParams);
|
||||||
/**
|
|
||||||
* 获得站内信列表
|
|
||||||
*
|
|
||||||
* @param ids 编号
|
|
||||||
* @return 站内信列表
|
|
||||||
*/
|
|
||||||
List<NotifyMessageDO> getNotifyMessageList(Collection<Long> ids);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得站内信集合
|
|
||||||
*
|
|
||||||
* @param pageReqVO 分页查询
|
|
||||||
* @return 站内信分页
|
|
||||||
*/
|
|
||||||
List<NotifyMessageDO> getNotifyMessageList(NotifyMessagePageReqVO pageReqVO, Integer size);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得站内信分页
|
* 获得站内信分页
|
||||||
|
@ -46,37 +38,60 @@ public interface NotifyMessageService {
|
||||||
*/
|
*/
|
||||||
PageResult<NotifyMessageDO> getNotifyMessagePage(NotifyMessagePageReqVO pageReqVO);
|
PageResult<NotifyMessageDO> getNotifyMessagePage(NotifyMessagePageReqVO pageReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得【我的】站内信分页
|
||||||
|
*
|
||||||
|
* @param pageReqVO 分页查询
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @param userType 用户类型
|
||||||
|
* @return 站内信分页
|
||||||
|
*/
|
||||||
|
PageResult<NotifyMessageDO> getMyMyNotifyMessagePage(NotifyMessageMyPageReqVO pageReqVO, Long userId, Integer userType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得站内信
|
||||||
|
*
|
||||||
|
* @param id 编号
|
||||||
|
* @return 站内信
|
||||||
|
*/
|
||||||
|
NotifyMessageDO getNotifyMessage(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得【我的】未读站内信列表
|
||||||
|
*
|
||||||
|
* @param userId 用户编号
|
||||||
|
* @param userType 用户类型
|
||||||
|
* @param size 数量
|
||||||
|
* @return 站内信列表
|
||||||
|
*/
|
||||||
|
List<NotifyMessageDO> getUnreadNotifyMessageList(Long userId, Integer userType, Integer size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 统计用户未读站内信条数
|
* 统计用户未读站内信条数
|
||||||
*
|
*
|
||||||
* @param userId 用户ID
|
* @param userId 用户编号
|
||||||
* @param userType 用户类型
|
* @param userType 用户类型
|
||||||
* @return 返回未读站内信条数
|
* @return 返回未读站内信条数
|
||||||
*/
|
*/
|
||||||
Long getUnreadNotifyMessageCount(Long userId, Integer userType);
|
Long getUnreadNotifyMessageCount(Long userId, Integer userType);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改站内信阅读状态
|
* 标记站内信为已读
|
||||||
*
|
|
||||||
* @param id 站内信编号
|
|
||||||
* @param status 状态
|
|
||||||
*/
|
|
||||||
void updateNotifyMessageReadStatus(Long id, Boolean status);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量修改站内信阅读状态
|
|
||||||
*
|
*
|
||||||
* @param ids 站内信编号集合
|
* @param ids 站内信编号集合
|
||||||
* @param userId 用户ID
|
* @param userId 用户编号
|
||||||
|
* @param userType 用户类型
|
||||||
|
* @return 更新到的条数
|
||||||
*/
|
*/
|
||||||
void batchUpdateNotifyMessageReadStatus(Collection<Long> ids, Long userId);
|
int updateNotifyMessageRead(Collection<Long> ids, Long userId, Integer userType);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量修改用户所有未读消息标记已读
|
* 标记所有站内信为已读
|
||||||
*
|
*
|
||||||
* @param userId 用户ID
|
* @param userId 用户编号
|
||||||
* @param userType 用户类型
|
* @param userType 用户类型
|
||||||
|
* @return 更新到的条数
|
||||||
*/
|
*/
|
||||||
void batchUpdateAllNotifyMessageReadStatus(Long userId, Integer userType);
|
int updateAllNotifyMessageRead(Long userId, Integer userType);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,30 +1,20 @@
|
||||||
package cn.iocoder.yudao.module.system.service.notify;
|
package cn.iocoder.yudao.module.system.service.notify;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
|
||||||
import cn.hutool.core.util.NumberUtil;
|
|
||||||
import cn.iocoder.yudao.framework.common.core.KeyValue;
|
|
||||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.message.NotifyMessageMyPageReqVO;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.message.NotifyMessagePageReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.message.NotifyMessagePageReqVO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyMessageDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyMessageDO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyTemplateDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyTemplateDO;
|
||||||
import cn.iocoder.yudao.module.system.dal.mysql.notify.NotifyMessageMapper;
|
import cn.iocoder.yudao.module.system.dal.mysql.notify.NotifyMessageMapper;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
|
||||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 站内信 Service 实现类
|
* 站内信 Service 实现类
|
||||||
|
@ -38,43 +28,25 @@ public class NotifyMessageServiceImpl implements NotifyMessageService {
|
||||||
@Resource
|
@Resource
|
||||||
private NotifyMessageMapper notifyMessageMapper;
|
private NotifyMessageMapper notifyMessageMapper;
|
||||||
|
|
||||||
@Resource
|
@Override
|
||||||
private NotifyTemplateService notifyTemplateService;
|
public Long createNotifyMessage(Long userId, Integer userType,
|
||||||
|
NotifyTemplateDO template, String templateContent, Map<String, Object> templateParams) {
|
||||||
|
NotifyMessageDO message = new NotifyMessageDO().setUserId(userId).setUserType(userType)
|
||||||
@VisibleForTesting
|
.setTemplateId(template.getId()).setTemplateCode(template.getCode())
|
||||||
public NotifyTemplateDO checkNotifyTemplateValid(String templateCode) {
|
.setTemplateType(template.getType()).setTemplateNickname(template.getNickname())
|
||||||
// 获得站内信模板。考虑到效率,从缓存中获取
|
.setTemplateContent(templateContent).setTemplateParams(templateParams).setReadStatus(false);
|
||||||
NotifyTemplateDO template = notifyTemplateService.getNotifyTemplateByCodeFromCache(templateCode);
|
notifyMessageMapper.insert(message);
|
||||||
// 站内信模板不存在
|
return message.getId();
|
||||||
if (template == null) {
|
|
||||||
throw exception(NOTIFY_TEMPLATE_NOT_EXISTS);
|
|
||||||
}
|
|
||||||
return template;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* 将参数模板,处理成有序的 KeyValue 数组
|
public PageResult<NotifyMessageDO> getNotifyMessagePage(NotifyMessagePageReqVO pageReqVO) {
|
||||||
*
|
return notifyMessageMapper.selectPage(pageReqVO);
|
||||||
* @param template 站内信模板
|
|
||||||
* @param templateParams 原始参数
|
|
||||||
* @return 处理后的参数
|
|
||||||
*/
|
|
||||||
@VisibleForTesting
|
|
||||||
public List<KeyValue<String, Object>> buildTemplateParams(NotifyTemplateDO template, Map<String, Object> templateParams) {
|
|
||||||
return template.getParams().stream().map(key -> {
|
|
||||||
Object value = templateParams.get(key);
|
|
||||||
if (value == null) {
|
|
||||||
throw exception(NOTIFY_TEMPLATE_PARAM_MISS, key);
|
|
||||||
}
|
|
||||||
return new KeyValue<>(key, value);
|
|
||||||
}).collect(Collectors.toList());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void validateNotifyMessageExists(Long id) {
|
@Override
|
||||||
if (notifyMessageMapper.selectById(id) == null) {
|
public PageResult<NotifyMessageDO> getMyMyNotifyMessagePage(NotifyMessageMyPageReqVO pageReqVO, Long userId, Integer userType) {
|
||||||
throw exception(NOTIFY_MESSAGE_NOT_EXISTS);
|
return notifyMessageMapper.selectPage(pageReqVO, userId, userType);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -83,97 +55,23 @@ public class NotifyMessageServiceImpl implements NotifyMessageService {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<NotifyMessageDO> getNotifyMessageList(Collection<Long> ids) {
|
public List<NotifyMessageDO> getUnreadNotifyMessageList(Long userId, Integer userType, Integer size) {
|
||||||
return notifyMessageMapper.selectBatchIds(ids);
|
return notifyMessageMapper.selectUnreadListByUserIdAndUserType(userId, userType, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<NotifyMessageDO> getNotifyMessageList(NotifyMessagePageReqVO pageReqVO, Integer size) {
|
|
||||||
return notifyMessageMapper.selectList(pageReqVO, size, getLoginUserId(), UserTypeEnum.ADMIN.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public PageResult<NotifyMessageDO> getNotifyMessagePage(NotifyMessagePageReqVO pageReqVO) {
|
|
||||||
return notifyMessageMapper.selectPage(pageReqVO, getLoginUserId(), UserTypeEnum.ADMIN.getValue());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 统计用户未读站内信条数
|
|
||||||
*
|
|
||||||
* @param userId 用户ID
|
|
||||||
* @param userType 用户类型
|
|
||||||
* @return 返回未读站内信条数
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public Long getUnreadNotifyMessageCount(Long userId, Integer userType) {
|
public Long getUnreadNotifyMessageCount(Long userId, Integer userType) {
|
||||||
return notifyMessageMapper.selectUnreadCountByUserIdAndUserType(userId, userType);
|
return notifyMessageMapper.selectUnreadCountByUserIdAndUserType(userId, userType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 修改站内信阅读状态
|
|
||||||
*
|
|
||||||
* @param id 站内信编号
|
|
||||||
* @param status 状态
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void updateNotifyMessageReadStatus(Long id, Boolean status) {
|
public int updateNotifyMessageRead(Collection<Long> ids, Long userId, Integer userType) {
|
||||||
// 校验消息是否存在
|
return notifyMessageMapper.updateListRead(ids, userId, userType);
|
||||||
this.validateNotifyMessageExists(id);
|
|
||||||
// 更新状态
|
|
||||||
batchUpdateReadStatus(CollectionUtils.singleton(id));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量修改站内信阅读状态
|
|
||||||
*
|
|
||||||
* @param ids 站内信编号集合
|
|
||||||
* @param userId 用户ID
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void batchUpdateNotifyMessageReadStatus(Collection<Long> ids, Long userId) {
|
public int updateAllNotifyMessageRead(Long userId, Integer userType) {
|
||||||
List<NotifyMessageDO> list = getNotifyMessageList(ids);
|
return notifyMessageMapper.updateListRead(userId, userType);
|
||||||
if (CollUtil.isEmpty(list)) {
|
|
||||||
throw exception(NOTIFY_MESSAGE_NOT_EXISTS);
|
|
||||||
}
|
|
||||||
// 验证站内信是否是属于用户
|
|
||||||
for (NotifyMessageDO messageDO : list) {
|
|
||||||
checkNotifyMessageIdValid(messageDO, userId);
|
|
||||||
}
|
|
||||||
batchUpdateReadStatus(ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
public void checkNotifyMessageIdValid(NotifyMessageDO notifyMessageDO, Long userId) {
|
|
||||||
if (!NumberUtil.equals(notifyMessageDO.getUserId(), userId)) {
|
|
||||||
throw exception(NOTIFY_MESSAGE_ID_PARAM_ERROR);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量修改用户所有未读消息标记已读
|
|
||||||
*
|
|
||||||
* @param userId 用户ID
|
|
||||||
* @param userType 用户类型
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void batchUpdateAllNotifyMessageReadStatus(Long userId, Integer userType) {
|
|
||||||
List<NotifyMessageDO> list = notifyMessageMapper.selectUnreadListByUserIdAndUserType(userId, userType);
|
|
||||||
if (CollUtil.isNotEmpty(list)) {
|
|
||||||
batchUpdateReadStatus(CollectionUtils.convertList(list, NotifyMessageDO::getId));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量修改阅读状态为已读
|
|
||||||
*
|
|
||||||
* @param ids 站内变编号数组
|
|
||||||
*/
|
|
||||||
private void batchUpdateReadStatus(Collection<Long> ids) {
|
|
||||||
NotifyMessageDO updateObj = new NotifyMessageDO();
|
|
||||||
updateObj.setReadStatus(true);
|
|
||||||
updateObj.setReadTime(new Date());
|
|
||||||
// TODO @luowenfeng:涉及到 mybatis 的操作,都要隐藏到 mapper 中;
|
|
||||||
notifyMessageMapper.update(updateObj, new LambdaQueryWrapperX<NotifyMessageDO>().in(NotifyMessageDO::getId, ids));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,13 @@ package cn.iocoder.yudao.module.system.service.notify;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 站内信发送 Service 接口
|
||||||
|
*
|
||||||
|
* @author xrcoder
|
||||||
|
*/
|
||||||
public interface NotifySendService {
|
public interface NotifySendService {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 发送单条站内信给管理后台的用户
|
* 发送单条站内信给管理后台的用户
|
||||||
*
|
*
|
||||||
|
|
|
@ -1,25 +1,20 @@
|
||||||
package cn.iocoder.yudao.module.system.service.notify;
|
package cn.iocoder.yudao.module.system.service.notify;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyMessageDO;
|
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyTemplateDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyTemplateDO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
|
|
||||||
import cn.iocoder.yudao.module.system.dal.mysql.notify.NotifyMessageMapper;
|
|
||||||
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
|
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.Date;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
|
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.NOTICE_NOT_FOUND;
|
|
||||||
|
|
||||||
// TODO @luowenfeng:可以直接合并到 NotifyMessageService 中;之前 sms 台复杂,所以没合并。
|
|
||||||
/**
|
/**
|
||||||
* 站内信发送 Service 实现类
|
* 站内信发送 Service 实现类
|
||||||
*
|
*
|
||||||
|
@ -34,10 +29,7 @@ public class NotifySendServiceImpl implements NotifySendService {
|
||||||
private NotifyTemplateService notifyTemplateService;
|
private NotifyTemplateService notifyTemplateService;
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private NotifyMessageMapper notifyMessageMapper;
|
private NotifyMessageService notifyMessageService;
|
||||||
|
|
||||||
@Resource
|
|
||||||
private AdminUserService userService;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long sendSingleNotifyToAdmin(Long userId, String templateCode, Map<String, Object> templateParams) {
|
public Long sendSingleNotifyToAdmin(Long userId, String templateCode, Map<String, Object> templateParams) {
|
||||||
|
@ -51,38 +43,44 @@ public class NotifySendServiceImpl implements NotifySendService {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long sendSingleNotify(Long userId, Integer userType, String templateCode, Map<String, Object> templateParams) {
|
public Long sendSingleNotify(Long userId, Integer userType, String templateCode, Map<String, Object> templateParams) {
|
||||||
// 校验短信模板是否合法
|
// 校验模版
|
||||||
NotifyTemplateDO template = this.checkNotifyTemplateValid(templateCode);
|
NotifyTemplateDO template = checkNotifyTemplateValid(templateCode);
|
||||||
String content = notifyTemplateService.formatNotifyTemplateContent(template.getContent(), templateParams);
|
if (Objects.equals(template.getStatus(), CommonStatusEnum.DISABLE.getStatus())) {
|
||||||
// 获得用户
|
log.info("[sendSingleNotify][模版({})已经关闭,无法给用户({}/{})发送]", templateCode, userId, userType);
|
||||||
AdminUserDO sendUser = userService.getUser(getLoginUserId());
|
return null;
|
||||||
|
}
|
||||||
|
// 校验参数
|
||||||
|
checkTemplateParams(template, templateParams);
|
||||||
|
|
||||||
// todo 模板状态未开启时的业务;如果未开启,就直接 return 好了;
|
// 发送站内信
|
||||||
NotifyMessageDO notifyMessageDO = new NotifyMessageDO();
|
String content = notifyTemplateService.formatNotifyTemplateContent(template.getContent(), templateParams);
|
||||||
notifyMessageDO.setContent(content);
|
return notifyMessageService.createNotifyMessage(userId, userType, template, content, templateParams);
|
||||||
notifyMessageDO.setTitle(template.getTitle());
|
|
||||||
notifyMessageDO.setReadStatus(false);
|
|
||||||
notifyMessageDO.setTemplateId(template.getId());
|
|
||||||
notifyMessageDO.setTemplateCode(templateCode);
|
|
||||||
notifyMessageDO.setUserId(userId);
|
|
||||||
notifyMessageDO.setUserType(userType);
|
|
||||||
notifyMessageDO.setSendTime(new Date());
|
|
||||||
notifyMessageDO.setSendUserId(sendUser.getId());
|
|
||||||
notifyMessageDO.setSendUserName(sendUser.getUsername());
|
|
||||||
notifyMessageMapper.insert(notifyMessageDO);
|
|
||||||
return notifyMessageDO.getId();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 此注解的含义
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public NotifyTemplateDO checkNotifyTemplateValid(String templateCode) {
|
public NotifyTemplateDO checkNotifyTemplateValid(String templateCode) {
|
||||||
// 获得短信模板。考虑到效率,从缓存中获取
|
// 获得站内信模板。考虑到效率,从缓存中获取
|
||||||
NotifyTemplateDO template = notifyTemplateService.getNotifyTemplateByCodeFromCache(templateCode);
|
NotifyTemplateDO template = notifyTemplateService.getNotifyTemplateByCodeFromCache(templateCode);
|
||||||
// 短信模板不存在
|
// 站内信模板不存在
|
||||||
if (template == null) {
|
if (template == null) {
|
||||||
throw exception(NOTICE_NOT_FOUND);
|
throw exception(NOTICE_NOT_FOUND);
|
||||||
}
|
}
|
||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 校验站内信模版参数是否确实
|
||||||
|
*
|
||||||
|
* @param template 邮箱模板
|
||||||
|
* @param templateParams 参数列表
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
public void checkTemplateParams(NotifyTemplateDO template, Map<String, Object> templateParams) {
|
||||||
|
template.getParams().forEach(key -> {
|
||||||
|
Object value = templateParams.get(key);
|
||||||
|
if (value == null) {
|
||||||
|
throw exception(NOTIFY_SEND_TEMPLATE_PARAM_MISS, key);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,11 @@ package cn.iocoder.yudao.module.system.service.notify;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateCreateReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateCreateReqVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateExportReqVO;
|
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplatePageReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplatePageReqVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateUpdateReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateUpdateReqVO;
|
||||||
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyTemplateDO;
|
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyTemplateDO;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -17,7 +14,6 @@ import java.util.Map;
|
||||||
*
|
*
|
||||||
* @author xrcoder
|
* @author xrcoder
|
||||||
*/
|
*/
|
||||||
// TODO 芋艿:缺少单测,可以参考 SmsTemplateServiceTest 写下
|
|
||||||
public interface NotifyTemplateService {
|
public interface NotifyTemplateService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,16 +29,6 @@ public interface NotifyTemplateService {
|
||||||
*/
|
*/
|
||||||
NotifyTemplateDO getNotifyTemplateByCodeFromCache(String code);
|
NotifyTemplateDO getNotifyTemplateByCodeFromCache(String code);
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 格式化站内信内容
|
|
||||||
*
|
|
||||||
* @param content 站内信模板的内容
|
|
||||||
* @param params 站内信内容的参数
|
|
||||||
* @return 格式化后的内容
|
|
||||||
*/
|
|
||||||
String formatNotifyTemplateContent(String content, Map<String, Object> params);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 创建站内信模版
|
* 创建站内信模版
|
||||||
*
|
*
|
||||||
|
@ -73,14 +59,6 @@ public interface NotifyTemplateService {
|
||||||
*/
|
*/
|
||||||
NotifyTemplateDO getNotifyTemplate(Long id);
|
NotifyTemplateDO getNotifyTemplate(Long id);
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得站内信模版列表
|
|
||||||
*
|
|
||||||
* @param ids 编号
|
|
||||||
* @return 站内信模版列表
|
|
||||||
*/
|
|
||||||
List<NotifyTemplateDO> getNotifyTemplateList(Collection<Long> ids);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得站内信模版分页
|
* 获得站内信模版分页
|
||||||
*
|
*
|
||||||
|
@ -90,11 +68,12 @@ public interface NotifyTemplateService {
|
||||||
PageResult<NotifyTemplateDO> getNotifyTemplatePage(NotifyTemplatePageReqVO pageReqVO);
|
PageResult<NotifyTemplateDO> getNotifyTemplatePage(NotifyTemplatePageReqVO pageReqVO);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获得站内信模版列表, 用于 Excel 导出
|
* 格式化站内信内容
|
||||||
*
|
*
|
||||||
* @param exportReqVO 查询条件
|
* @param content 站内信模板的内容
|
||||||
* @return 站内信模版列表
|
* @param params 站内信内容的参数
|
||||||
|
* @return 格式化后的内容
|
||||||
*/
|
*/
|
||||||
List<NotifyTemplateDO> getNotifyTemplateList(NotifyTemplateExportReqVO exportReqVO);
|
String formatNotifyTemplateContent(String content, Map<String, Object> params);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,10 @@
|
||||||
package cn.iocoder.yudao.module.system.service.notify;
|
package cn.iocoder.yudao.module.system.service.notify;
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
|
||||||
import cn.hutool.core.util.ReUtil;
|
import cn.hutool.core.util.ReUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateCreateReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateCreateReqVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateExportReqVO;
|
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplatePageReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplatePageReqVO;
|
||||||
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateUpdateReqVO;
|
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateUpdateReqVO;
|
||||||
import cn.iocoder.yudao.module.system.convert.notify.NotifyTemplateConvert;
|
import cn.iocoder.yudao.module.system.convert.notify.NotifyTemplateConvert;
|
||||||
|
@ -15,20 +13,17 @@ import cn.iocoder.yudao.module.system.dal.mysql.notify.NotifyTemplateMapper;
|
||||||
import cn.iocoder.yudao.module.system.mq.producer.notify.NotifyProducer;
|
import cn.iocoder.yudao.module.system.mq.producer.notify.NotifyProducer;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Date;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.NOTIFY_TEMPLATE_CODE_DUPLICATE;
|
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||||
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.NOTIFY_TEMPLATE_NOT_EXISTS;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 站内信模版 Service 实现类
|
* 站内信模版 Service 实现类
|
||||||
|
@ -40,12 +35,6 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.NOTIFY_TEM
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class NotifyTemplateServiceImpl implements NotifyTemplateService {
|
public class NotifyTemplateServiceImpl implements NotifyTemplateService {
|
||||||
|
|
||||||
/**
|
|
||||||
* 定时执行 {@link #schedulePeriodicRefresh()} 的周期
|
|
||||||
* 因为已经通过 Redis Pub/Sub 机制,所以频率不需要高
|
|
||||||
*/
|
|
||||||
private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 正则表达式,匹配 {} 中的变量
|
* 正则表达式,匹配 {} 中的变量
|
||||||
*/
|
*/
|
||||||
|
@ -65,82 +54,25 @@ public class NotifyTemplateServiceImpl implements NotifyTemplateService {
|
||||||
*/
|
*/
|
||||||
private volatile Map<String, NotifyTemplateDO> notifyTemplateCache;
|
private volatile Map<String, NotifyTemplateDO> notifyTemplateCache;
|
||||||
|
|
||||||
/**
|
|
||||||
* 缓存站内信模板的最大更新时间,用于后续的增量轮询,判断是否有更新
|
|
||||||
*/
|
|
||||||
private volatile Date maxUpdateTime;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化站内信模板的本地缓存
|
* 初始化站内信模板的本地缓存
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
|
@PostConstruct
|
||||||
public void initLocalCache() {
|
public void initLocalCache() {
|
||||||
// 获取站内信模板列表,如果有更新
|
// 第一步:查询数据
|
||||||
List<NotifyTemplateDO> notifyTemplateList = this.loadNotifyTemplateIfUpdate(maxUpdateTime);
|
List<NotifyTemplateDO> templates = notifyTemplateMapper.selectList();
|
||||||
if (CollUtil.isEmpty(notifyTemplateList)) {
|
log.info("[initLocalCache][缓存站内信模版,数量为:{}]", templates.size());
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 写入缓存
|
// 第二步:构建缓存
|
||||||
notifyTemplateCache = CollectionUtils.convertMap(notifyTemplateList, NotifyTemplateDO::getCode);
|
notifyTemplateCache = CollectionUtils.convertMap(templates, NotifyTemplateDO::getCode);
|
||||||
maxUpdateTime = CollectionUtils.getMaxValue(notifyTemplateList, NotifyTemplateDO::getUpdateTime);
|
|
||||||
log.info("[initLocalCache][初始化 NotifyTemplate 数量为 {}]", notifyTemplateList.size());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 如果站内信模板发生变化,从数据库中获取最新的全量站内信模板。
|
|
||||||
* 如果未发生变化,则返回空
|
|
||||||
*
|
|
||||||
* @param maxUpdateTime 当前站内信模板的最大更新时间
|
|
||||||
* @return 站内信模板列表
|
|
||||||
*/
|
|
||||||
private List<NotifyTemplateDO> loadNotifyTemplateIfUpdate(Date maxUpdateTime) {
|
|
||||||
// 第一步,判断是否要更新。
|
|
||||||
if (maxUpdateTime == null) { // 如果更新时间为空,说明 DB 一定有新数据
|
|
||||||
log.info("[loadNotifyTemplateIfUpdate][首次加载全量站内信模板]");
|
|
||||||
} else { // 判断数据库中是否有更新的站内信模板
|
|
||||||
if (notifyTemplateMapper.selectCountByUpdateTimeGt(maxUpdateTime) == 0) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
log.info("[loadNotifyTemplateIfUpdate][增量加载全量站内信模板]");
|
|
||||||
}
|
|
||||||
// 第二步,如果有更新,则从数据库加载所有站内信模板
|
|
||||||
return notifyTemplateMapper.selectList();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Scheduled(fixedDelay = SCHEDULER_PERIOD)
|
|
||||||
public void schedulePeriodicRefresh() {
|
|
||||||
initLocalCache();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得站内信模板,从缓存中
|
|
||||||
*
|
|
||||||
* @param code 模板编码
|
|
||||||
* @return 站内信模板
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public NotifyTemplateDO getNotifyTemplateByCodeFromCache(String code) {
|
public NotifyTemplateDO getNotifyTemplateByCodeFromCache(String code) {
|
||||||
return notifyTemplateCache.get(code);
|
return notifyTemplateCache.get(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 格式化站内信内容
|
|
||||||
*
|
|
||||||
* @param content 站内信模板的内容
|
|
||||||
* @param params 站内信内容的参数
|
|
||||||
* @return 格式化后的内容
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String formatNotifyTemplateContent(String content, Map<String, Object> params) {
|
|
||||||
return StrUtil.format(content, params);
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
public List<String> parseTemplateContentParams(String content) {
|
|
||||||
return ReUtil.findAllGroup1(PATTERN_PARAMS, content);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long createNotifyTemplate(NotifyTemplateCreateReqVO createReqVO) {
|
public Long createNotifyTemplate(NotifyTemplateCreateReqVO createReqVO) {
|
||||||
// 校验站内信编码是否重复
|
// 校验站内信编码是否重复
|
||||||
|
@ -150,32 +82,37 @@ public class NotifyTemplateServiceImpl implements NotifyTemplateService {
|
||||||
NotifyTemplateDO notifyTemplate = NotifyTemplateConvert.INSTANCE.convert(createReqVO);
|
NotifyTemplateDO notifyTemplate = NotifyTemplateConvert.INSTANCE.convert(createReqVO);
|
||||||
notifyTemplate.setParams(parseTemplateContentParams(notifyTemplate.getContent()));
|
notifyTemplate.setParams(parseTemplateContentParams(notifyTemplate.getContent()));
|
||||||
notifyTemplateMapper.insert(notifyTemplate);
|
notifyTemplateMapper.insert(notifyTemplate);
|
||||||
|
|
||||||
// 发送刷新消息
|
// 发送刷新消息
|
||||||
notifyProducer.sendNotifyTemplateRefreshMessage();
|
notifyProducer.sendNotifyTemplateRefreshMessage();
|
||||||
// 返回
|
|
||||||
return notifyTemplate.getId();
|
return notifyTemplate.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateNotifyTemplate(NotifyTemplateUpdateReqVO updateReqVO) {
|
public void updateNotifyTemplate(NotifyTemplateUpdateReqVO updateReqVO) {
|
||||||
// 校验存在
|
// 校验存在
|
||||||
this.validateNotifyTemplateExists(updateReqVO.getId());
|
validateNotifyTemplateExists(updateReqVO.getId());
|
||||||
// 校验站内信编码是否重复
|
// 校验站内信编码是否重复
|
||||||
checkNotifyTemplateCodeDuplicate(updateReqVO.getId(), updateReqVO.getCode());
|
checkNotifyTemplateCodeDuplicate(updateReqVO.getId(), updateReqVO.getCode());
|
||||||
|
|
||||||
// 更新
|
// 更新
|
||||||
NotifyTemplateDO updateObj = NotifyTemplateConvert.INSTANCE.convert(updateReqVO);
|
NotifyTemplateDO updateObj = NotifyTemplateConvert.INSTANCE.convert(updateReqVO);
|
||||||
updateObj.setParams(parseTemplateContentParams(updateObj.getContent()));
|
updateObj.setParams(parseTemplateContentParams(updateObj.getContent()));
|
||||||
|
|
||||||
notifyTemplateMapper.updateById(updateObj);
|
notifyTemplateMapper.updateById(updateObj);
|
||||||
|
|
||||||
// 发送刷新消息
|
// 发送刷新消息
|
||||||
notifyProducer.sendNotifyTemplateRefreshMessage();
|
notifyProducer.sendNotifyTemplateRefreshMessage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
public List<String> parseTemplateContentParams(String content) {
|
||||||
|
return ReUtil.findAllGroup1(PATTERN_PARAMS, content);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteNotifyTemplate(Long id) {
|
public void deleteNotifyTemplate(Long id) {
|
||||||
// 校验存在
|
// 校验存在
|
||||||
this.validateNotifyTemplateExists(id);
|
validateNotifyTemplateExists(id);
|
||||||
// 删除
|
// 删除
|
||||||
notifyTemplateMapper.deleteById(id);
|
notifyTemplateMapper.deleteById(id);
|
||||||
// 发送刷新消息
|
// 发送刷新消息
|
||||||
|
@ -193,21 +130,11 @@ public class NotifyTemplateServiceImpl implements NotifyTemplateService {
|
||||||
return notifyTemplateMapper.selectById(id);
|
return notifyTemplateMapper.selectById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<NotifyTemplateDO> getNotifyTemplateList(Collection<Long> ids) {
|
|
||||||
return notifyTemplateMapper.selectBatchIds(ids);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PageResult<NotifyTemplateDO> getNotifyTemplatePage(NotifyTemplatePageReqVO pageReqVO) {
|
public PageResult<NotifyTemplateDO> getNotifyTemplatePage(NotifyTemplatePageReqVO pageReqVO) {
|
||||||
return notifyTemplateMapper.selectPage(pageReqVO);
|
return notifyTemplateMapper.selectPage(pageReqVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public List<NotifyTemplateDO> getNotifyTemplateList(NotifyTemplateExportReqVO exportReqVO) {
|
|
||||||
return notifyTemplateMapper.selectList(exportReqVO);
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public void checkNotifyTemplateCodeDuplicate(Long id, String code) {
|
public void checkNotifyTemplateCodeDuplicate(Long id, String code) {
|
||||||
NotifyTemplateDO template = notifyTemplateMapper.selectByCode(code);
|
NotifyTemplateDO template = notifyTemplateMapper.selectByCode(code);
|
||||||
|
@ -222,4 +149,16 @@ public class NotifyTemplateServiceImpl implements NotifyTemplateService {
|
||||||
throw exception(NOTIFY_TEMPLATE_CODE_DUPLICATE, code);
|
throw exception(NOTIFY_TEMPLATE_CODE_DUPLICATE, code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 格式化站内信内容
|
||||||
|
*
|
||||||
|
* @param content 站内信模板的内容
|
||||||
|
* @param params 站内信内容的参数
|
||||||
|
* @return 格式化后的内容
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String formatNotifyTemplateContent(String content, Map<String, Object> params) {
|
||||||
|
return StrUtil.format(content, params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -145,7 +145,7 @@ class MailSendServiceImplTest extends BaseMockitoUnitTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBuildTemplateParams_paramMiss() {
|
public void testCheckTemplateParams_paramMiss() {
|
||||||
// 准备参数
|
// 准备参数
|
||||||
MailTemplateDO template = randomPojo(MailTemplateDO.class,
|
MailTemplateDO template = randomPojo(MailTemplateDO.class,
|
||||||
o -> o.setParams(Lists.newArrayList("code")));
|
o -> o.setParams(Lists.newArrayList("code")));
|
||||||
|
@ -153,7 +153,7 @@ class MailSendServiceImplTest extends BaseMockitoUnitTest {
|
||||||
// mock 方法
|
// mock 方法
|
||||||
|
|
||||||
// 调用,并断言异常
|
// 调用,并断言异常
|
||||||
assertServiceException(() -> mailSendService.buildTemplateParams(template, templateParams),
|
assertServiceException(() -> mailSendService.checkTemplateParams(template, templateParams),
|
||||||
MAIL_SEND_TEMPLATE_PARAM_MISS, "code");
|
MAIL_SEND_TEMPLATE_PARAM_MISS, "code");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,266 @@
|
||||||
|
package cn.iocoder.yudao.module.system.service.notify;
|
||||||
|
|
||||||
|
import cn.hutool.core.map.MapUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.enums.SqlConstants;
|
||||||
|
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.message.NotifyMessageMyPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.message.NotifyMessagePageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyMessageDO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyTemplateDO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.mysql.notify.NotifyMessageMapper;
|
||||||
|
import com.baomidou.mybatisplus.annotation.DbType;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||||
|
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||||
|
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link NotifyMessageServiceImpl} 的单元测试类
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Import(NotifyMessageServiceImpl.class)
|
||||||
|
public class NotifyMessageServiceImplTest extends BaseDbUnitTest {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private NotifyMessageServiceImpl notifyMessageService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private NotifyMessageMapper notifyMessageMapper;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateNotifyMessage_success() {
|
||||||
|
// 准备参数
|
||||||
|
Long userId = randomLongId();
|
||||||
|
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||||
|
NotifyTemplateDO template = randomPojo(NotifyTemplateDO.class);
|
||||||
|
String templateContent = randomString();
|
||||||
|
Map<String, Object> templateParams = randomTemplateParams();
|
||||||
|
// mock 方法
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
Long messageId = notifyMessageService.createNotifyMessage(userId, userType,
|
||||||
|
template, templateContent, templateParams);
|
||||||
|
// 断言
|
||||||
|
NotifyMessageDO message = notifyMessageMapper.selectById(messageId);
|
||||||
|
assertNotNull(message);
|
||||||
|
assertEquals(userId, message.getUserId());
|
||||||
|
assertEquals(userType, message.getUserType());
|
||||||
|
assertEquals(template.getId(), message.getTemplateId());
|
||||||
|
assertEquals(template.getCode(), message.getTemplateCode());
|
||||||
|
assertEquals(template.getType(), message.getTemplateType());
|
||||||
|
assertEquals(template.getNickname(), message.getTemplateNickname());
|
||||||
|
assertEquals(templateContent, message.getTemplateContent());
|
||||||
|
assertEquals(templateParams, message.getTemplateParams());
|
||||||
|
assertEquals(false, message.getReadStatus());
|
||||||
|
assertNull(message.getReadTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetNotifyMessagePage() {
|
||||||
|
// mock 数据
|
||||||
|
NotifyMessageDO dbNotifyMessage = randomPojo(NotifyMessageDO.class, o -> { // 等会查询到
|
||||||
|
o.setUserId(1L);
|
||||||
|
o.setUserType(UserTypeEnum.ADMIN.getValue());
|
||||||
|
o.setTemplateCode("test_01");
|
||||||
|
o.setTemplateType(10);
|
||||||
|
o.setCreateTime(buildTime(2022, 1, 2));
|
||||||
|
o.setTemplateParams(randomTemplateParams());
|
||||||
|
});
|
||||||
|
notifyMessageMapper.insert(dbNotifyMessage);
|
||||||
|
// 测试 userId 不匹配
|
||||||
|
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setUserId(2L)));
|
||||||
|
// 测试 userType 不匹配
|
||||||
|
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setUserType(UserTypeEnum.MEMBER.getValue())));
|
||||||
|
// 测试 templateCode 不匹配
|
||||||
|
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setTemplateCode("test_11")));
|
||||||
|
// 测试 templateType 不匹配
|
||||||
|
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setTemplateType(20)));
|
||||||
|
// 测试 createTime 不匹配
|
||||||
|
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setCreateTime(buildTime(2022, 2, 1))));
|
||||||
|
// 准备参数
|
||||||
|
NotifyMessagePageReqVO reqVO = new NotifyMessagePageReqVO();
|
||||||
|
reqVO.setUserId(1L);
|
||||||
|
reqVO.setUserType(UserTypeEnum.ADMIN.getValue());
|
||||||
|
reqVO.setTemplateCode("est_01");
|
||||||
|
reqVO.setTemplateType(10);
|
||||||
|
reqVO.setCreateTime(buildBetweenTime(2022, 1, 1, 2022, 1, 10));
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
PageResult<NotifyMessageDO> pageResult = notifyMessageService.getNotifyMessagePage(reqVO);
|
||||||
|
// 断言
|
||||||
|
assertEquals(1, pageResult.getTotal());
|
||||||
|
assertEquals(1, pageResult.getList().size());
|
||||||
|
assertPojoEquals(dbNotifyMessage, pageResult.getList().get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetMyNotifyMessagePage() {
|
||||||
|
// mock 数据
|
||||||
|
NotifyMessageDO dbNotifyMessage = randomPojo(NotifyMessageDO.class, o -> { // 等会查询到
|
||||||
|
o.setUserId(1L);
|
||||||
|
o.setUserType(UserTypeEnum.ADMIN.getValue());
|
||||||
|
o.setReadStatus(true);
|
||||||
|
o.setCreateTime(buildTime(2022, 1, 2));
|
||||||
|
o.setTemplateParams(randomTemplateParams());
|
||||||
|
});
|
||||||
|
notifyMessageMapper.insert(dbNotifyMessage);
|
||||||
|
// 测试 userId 不匹配
|
||||||
|
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setUserId(2L)));
|
||||||
|
// 测试 userType 不匹配
|
||||||
|
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setUserType(UserTypeEnum.MEMBER.getValue())));
|
||||||
|
// 测试 readStatus 不匹配
|
||||||
|
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setReadStatus(false)));
|
||||||
|
// 测试 createTime 不匹配
|
||||||
|
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setCreateTime(buildTime(2022, 2, 1))));
|
||||||
|
// 准备参数
|
||||||
|
Long userId = 1L;
|
||||||
|
Integer userType = UserTypeEnum.ADMIN.getValue();
|
||||||
|
NotifyMessageMyPageReqVO reqVO = new NotifyMessageMyPageReqVO();
|
||||||
|
reqVO.setReadStatus(true);
|
||||||
|
reqVO.setCreateTime(buildBetweenTime(2022, 1, 1, 2022, 1, 10));
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
PageResult<NotifyMessageDO> pageResult = notifyMessageService.getMyMyNotifyMessagePage(reqVO, userId, userType);
|
||||||
|
// 断言
|
||||||
|
assertEquals(1, pageResult.getTotal());
|
||||||
|
assertEquals(1, pageResult.getList().size());
|
||||||
|
assertPojoEquals(dbNotifyMessage, pageResult.getList().get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetUnreadNotifyMessageList() {
|
||||||
|
SqlConstants.init(DbType.MYSQL);
|
||||||
|
// mock 数据
|
||||||
|
NotifyMessageDO dbNotifyMessage = randomPojo(NotifyMessageDO.class, o -> { // 等会查询到
|
||||||
|
o.setUserId(1L);
|
||||||
|
o.setUserType(UserTypeEnum.ADMIN.getValue());
|
||||||
|
o.setReadStatus(false);
|
||||||
|
o.setTemplateParams(randomTemplateParams());
|
||||||
|
});
|
||||||
|
notifyMessageMapper.insert(dbNotifyMessage);
|
||||||
|
// 测试 userId 不匹配
|
||||||
|
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setUserId(2L)));
|
||||||
|
// 测试 userType 不匹配
|
||||||
|
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setUserType(UserTypeEnum.MEMBER.getValue())));
|
||||||
|
// 测试 readStatus 不匹配
|
||||||
|
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setReadStatus(true)));
|
||||||
|
// 准备参数
|
||||||
|
Long userId = 1L;
|
||||||
|
Integer userType = UserTypeEnum.ADMIN.getValue();
|
||||||
|
Integer size = 10;
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
List<NotifyMessageDO> list = notifyMessageService.getUnreadNotifyMessageList(userId, userType, size);
|
||||||
|
// 断言
|
||||||
|
assertEquals(1, list.size());
|
||||||
|
assertPojoEquals(dbNotifyMessage, list.get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetUnreadNotifyMessageCount() {
|
||||||
|
SqlConstants.init(DbType.MYSQL);
|
||||||
|
// mock 数据
|
||||||
|
NotifyMessageDO dbNotifyMessage = randomPojo(NotifyMessageDO.class, o -> { // 等会查询到
|
||||||
|
o.setUserId(1L);
|
||||||
|
o.setUserType(UserTypeEnum.ADMIN.getValue());
|
||||||
|
o.setReadStatus(false);
|
||||||
|
o.setTemplateParams(randomTemplateParams());
|
||||||
|
});
|
||||||
|
notifyMessageMapper.insert(dbNotifyMessage);
|
||||||
|
// 测试 userId 不匹配
|
||||||
|
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setUserId(2L)));
|
||||||
|
// 测试 userType 不匹配
|
||||||
|
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setUserType(UserTypeEnum.MEMBER.getValue())));
|
||||||
|
// 测试 readStatus 不匹配
|
||||||
|
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setReadStatus(true)));
|
||||||
|
// 准备参数
|
||||||
|
Long userId = 1L;
|
||||||
|
Integer userType = UserTypeEnum.ADMIN.getValue();
|
||||||
|
|
||||||
|
// 调用,并断言
|
||||||
|
assertEquals(1, notifyMessageService.getUnreadNotifyMessageCount(userId, userType));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateNotifyMessageRead() {
|
||||||
|
// mock 数据
|
||||||
|
NotifyMessageDO dbNotifyMessage = randomPojo(NotifyMessageDO.class, o -> { // 等会查询到
|
||||||
|
o.setUserId(1L);
|
||||||
|
o.setUserType(UserTypeEnum.ADMIN.getValue());
|
||||||
|
o.setReadStatus(false);
|
||||||
|
o.setReadTime(null);
|
||||||
|
o.setTemplateParams(randomTemplateParams());
|
||||||
|
});
|
||||||
|
notifyMessageMapper.insert(dbNotifyMessage);
|
||||||
|
// 测试 userId 不匹配
|
||||||
|
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setUserId(2L)));
|
||||||
|
// 测试 userType 不匹配
|
||||||
|
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setUserType(UserTypeEnum.MEMBER.getValue())));
|
||||||
|
// 测试 readStatus 不匹配
|
||||||
|
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setReadStatus(true)));
|
||||||
|
// 准备参数
|
||||||
|
Collection<Long> ids = Arrays.asList(dbNotifyMessage.getId(), dbNotifyMessage.getId() + 1,
|
||||||
|
dbNotifyMessage.getId() + 2, dbNotifyMessage.getId() + 3);
|
||||||
|
Long userId = 1L;
|
||||||
|
Integer userType = UserTypeEnum.ADMIN.getValue();
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
int updateCount = notifyMessageService.updateNotifyMessageRead(ids, userId, userType);
|
||||||
|
// 断言
|
||||||
|
assertEquals(1, updateCount);
|
||||||
|
NotifyMessageDO notifyMessage = notifyMessageMapper.selectById(dbNotifyMessage.getId());
|
||||||
|
assertTrue(notifyMessage.getReadStatus());
|
||||||
|
assertNotNull(notifyMessage.getReadTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateAllNotifyMessageRead() {
|
||||||
|
// mock 数据
|
||||||
|
NotifyMessageDO dbNotifyMessage = randomPojo(NotifyMessageDO.class, o -> { // 等会查询到
|
||||||
|
o.setUserId(1L);
|
||||||
|
o.setUserType(UserTypeEnum.ADMIN.getValue());
|
||||||
|
o.setReadStatus(false);
|
||||||
|
o.setReadTime(null);
|
||||||
|
o.setTemplateParams(randomTemplateParams());
|
||||||
|
});
|
||||||
|
notifyMessageMapper.insert(dbNotifyMessage);
|
||||||
|
// 测试 userId 不匹配
|
||||||
|
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setUserId(2L)));
|
||||||
|
// 测试 userType 不匹配
|
||||||
|
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setUserType(UserTypeEnum.MEMBER.getValue())));
|
||||||
|
// 测试 readStatus 不匹配
|
||||||
|
notifyMessageMapper.insert(cloneIgnoreId(dbNotifyMessage, o -> o.setReadStatus(true)));
|
||||||
|
// 准备参数
|
||||||
|
Long userId = 1L;
|
||||||
|
Integer userType = UserTypeEnum.ADMIN.getValue();
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
int updateCount = notifyMessageService.updateAllNotifyMessageRead(userId, userType);
|
||||||
|
// 断言
|
||||||
|
assertEquals(1, updateCount);
|
||||||
|
NotifyMessageDO notifyMessage = notifyMessageMapper.selectById(dbNotifyMessage.getId());
|
||||||
|
assertTrue(notifyMessage.getReadStatus());
|
||||||
|
assertNotNull(notifyMessage.getReadTime());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, Object> randomTemplateParams() {
|
||||||
|
return MapUtil.<String, Object>builder().put(randomString(), randomString())
|
||||||
|
.put(randomString(), randomString()).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,121 @@
|
||||||
|
package cn.iocoder.yudao.module.system.service.notify;
|
||||||
|
|
||||||
|
import cn.hutool.core.map.MapUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
|
import cn.iocoder.yudao.framework.common.enums.UserTypeEnum;
|
||||||
|
import cn.iocoder.yudao.framework.test.core.ut.BaseMockitoUnitTest;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailAccountDO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.dataobject.mail.MailTemplateDO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyTemplateDO;
|
||||||
|
import org.assertj.core.util.Lists;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import static cn.hutool.core.util.RandomUtil.randomEle;
|
||||||
|
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||||
|
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||||
|
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||||
|
import static org.mockito.ArgumentMatchers.eq;
|
||||||
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
class NotifySendServiceImplTest extends BaseMockitoUnitTest {
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
|
private NotifySendServiceImpl notifySendService;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private NotifyTemplateService notifyTemplateService;
|
||||||
|
@Mock
|
||||||
|
private NotifyMessageService notifyMessageService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送成功,当短信模板开启时
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testSendSingleNotify_successWhenMailTemplateEnable() {
|
||||||
|
// 准备参数
|
||||||
|
Long userId = randomLongId();
|
||||||
|
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||||
|
String templateCode = randomString();
|
||||||
|
Map<String, Object> templateParams = MapUtil.<String, Object>builder().put("code", "1234")
|
||||||
|
.put("op", "login").build();
|
||||||
|
// mock NotifyTemplateService 的方法
|
||||||
|
NotifyTemplateDO template = randomPojo(NotifyTemplateDO.class, o -> {
|
||||||
|
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
|
o.setContent("验证码为{code}, 操作为{op}");
|
||||||
|
o.setParams(Lists.newArrayList("code", "op"));
|
||||||
|
});
|
||||||
|
when(notifyTemplateService.getNotifyTemplateByCodeFromCache(eq(templateCode))).thenReturn(template);
|
||||||
|
String content = randomString();
|
||||||
|
when(notifyTemplateService.formatNotifyTemplateContent(eq(template.getContent()), eq(templateParams)))
|
||||||
|
.thenReturn(content);
|
||||||
|
// mock NotifyMessageService 的方法
|
||||||
|
Long messageId = randomLongId();
|
||||||
|
when(notifyMessageService.createNotifyMessage(eq(userId), eq(userType),
|
||||||
|
eq(template), eq(content), eq(templateParams))).thenReturn(messageId);
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
Long resultMessageId = notifySendService.sendSingleNotify(userId, userType, templateCode, templateParams);
|
||||||
|
// 断言
|
||||||
|
assertEquals(messageId, resultMessageId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送成功,当短信模板关闭时
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testSendSingleMail_successWhenSmsTemplateDisable() {
|
||||||
|
// 准备参数
|
||||||
|
Long userId = randomLongId();
|
||||||
|
Integer userType = randomEle(UserTypeEnum.values()).getValue();
|
||||||
|
String templateCode = randomString();
|
||||||
|
Map<String, Object> templateParams = MapUtil.<String, Object>builder().put("code", "1234")
|
||||||
|
.put("op", "login").build();
|
||||||
|
// mock NotifyTemplateService 的方法
|
||||||
|
NotifyTemplateDO template = randomPojo(NotifyTemplateDO.class, o -> {
|
||||||
|
o.setStatus(CommonStatusEnum.DISABLE.getStatus());
|
||||||
|
o.setContent("验证码为{code}, 操作为{op}");
|
||||||
|
o.setParams(Lists.newArrayList("code", "op"));
|
||||||
|
});
|
||||||
|
when(notifyTemplateService.getNotifyTemplateByCodeFromCache(eq(templateCode))).thenReturn(template);
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
Long resultMessageId = notifySendService.sendSingleNotify(userId, userType, templateCode, templateParams);
|
||||||
|
// 断言
|
||||||
|
assertNull(resultMessageId);
|
||||||
|
verify(notifyTemplateService, never()).formatNotifyTemplateContent(anyString(), anyMap());
|
||||||
|
verify(notifyMessageService, never()).createNotifyMessage(anyLong(), anyInt(), any(), anyString(), anyMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCheckMailTemplateValid_notExists() {
|
||||||
|
// 准备参数
|
||||||
|
String templateCode = randomString();
|
||||||
|
// mock 方法
|
||||||
|
|
||||||
|
// 调用,并断言异常
|
||||||
|
assertServiceException(() -> notifySendService.checkNotifyTemplateValid(templateCode),
|
||||||
|
NOTICE_NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCheckTemplateParams_paramMiss() {
|
||||||
|
// 准备参数
|
||||||
|
NotifyTemplateDO template = randomPojo(NotifyTemplateDO.class,
|
||||||
|
o -> o.setParams(Lists.newArrayList("code")));
|
||||||
|
Map<String, Object> templateParams = new HashMap<>();
|
||||||
|
// mock 方法
|
||||||
|
|
||||||
|
// 调用,并断言异常
|
||||||
|
assertServiceException(() -> notifySendService.checkTemplateParams(template, templateParams),
|
||||||
|
NOTIFY_SEND_TEMPLATE_PARAM_MISS, "code");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,146 @@
|
||||||
|
package cn.iocoder.yudao.module.system.service.notify;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateCreateReqVO;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplatePageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.system.controller.admin.notify.vo.template.NotifyTemplateUpdateReqVO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.dataobject.notify.NotifyTemplateDO;
|
||||||
|
import cn.iocoder.yudao.module.system.dal.mysql.notify.NotifyTemplateMapper;
|
||||||
|
import cn.iocoder.yudao.module.system.mq.producer.notify.NotifyProducer;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildBetweenTime;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.date.LocalDateTimeUtils.buildTime;
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.object.ObjectUtils.cloneIgnoreId;
|
||||||
|
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertPojoEquals;
|
||||||
|
import static cn.iocoder.yudao.framework.test.core.util.AssertUtils.assertServiceException;
|
||||||
|
import static cn.iocoder.yudao.framework.test.core.util.RandomUtils.*;
|
||||||
|
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.NOTIFY_TEMPLATE_NOT_EXISTS;
|
||||||
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link NotifyTemplateServiceImpl} 的单元测试类
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Import(NotifyTemplateServiceImpl.class)
|
||||||
|
public class NotifyTemplateServiceImplTest extends BaseDbUnitTest {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private NotifyTemplateServiceImpl notifyTemplateService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private NotifyTemplateMapper notifyTemplateMapper;
|
||||||
|
|
||||||
|
@MockBean
|
||||||
|
private NotifyProducer notifyProducer;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateNotifyTemplate_success() {
|
||||||
|
// 准备参数
|
||||||
|
NotifyTemplateCreateReqVO reqVO = randomPojo(NotifyTemplateCreateReqVO.class,
|
||||||
|
o -> o.setStatus(randomCommonStatus()));
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
Long notifyTemplateId = notifyTemplateService.createNotifyTemplate(reqVO);
|
||||||
|
// 断言
|
||||||
|
assertNotNull(notifyTemplateId);
|
||||||
|
// 校验记录的属性是否正确
|
||||||
|
NotifyTemplateDO notifyTemplate = notifyTemplateMapper.selectById(notifyTemplateId);
|
||||||
|
assertPojoEquals(reqVO, notifyTemplate);
|
||||||
|
verify(notifyProducer).sendNotifyTemplateRefreshMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateNotifyTemplate_success() {
|
||||||
|
// mock 数据
|
||||||
|
NotifyTemplateDO dbNotifyTemplate = randomPojo(NotifyTemplateDO.class);
|
||||||
|
notifyTemplateMapper.insert(dbNotifyTemplate);// @Sql: 先插入出一条存在的数据
|
||||||
|
// 准备参数
|
||||||
|
NotifyTemplateUpdateReqVO reqVO = randomPojo(NotifyTemplateUpdateReqVO.class, o -> {
|
||||||
|
o.setId(dbNotifyTemplate.getId()); // 设置更新的 ID
|
||||||
|
o.setStatus(randomCommonStatus());
|
||||||
|
});
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
notifyTemplateService.updateNotifyTemplate(reqVO);
|
||||||
|
// 校验是否更新正确
|
||||||
|
NotifyTemplateDO notifyTemplate = notifyTemplateMapper.selectById(reqVO.getId()); // 获取最新的
|
||||||
|
assertPojoEquals(reqVO, notifyTemplate);
|
||||||
|
verify(notifyProducer).sendNotifyTemplateRefreshMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testUpdateNotifyTemplate_notExists() {
|
||||||
|
// 准备参数
|
||||||
|
NotifyTemplateUpdateReqVO reqVO = randomPojo(NotifyTemplateUpdateReqVO.class);
|
||||||
|
|
||||||
|
// 调用, 并断言异常
|
||||||
|
assertServiceException(() -> notifyTemplateService.updateNotifyTemplate(reqVO), NOTIFY_TEMPLATE_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteNotifyTemplate_success() {
|
||||||
|
// mock 数据
|
||||||
|
NotifyTemplateDO dbNotifyTemplate = randomPojo(NotifyTemplateDO.class);
|
||||||
|
notifyTemplateMapper.insert(dbNotifyTemplate);// @Sql: 先插入出一条存在的数据
|
||||||
|
// 准备参数
|
||||||
|
Long id = dbNotifyTemplate.getId();
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
notifyTemplateService.deleteNotifyTemplate(id);
|
||||||
|
// 校验数据不存在了
|
||||||
|
assertNull(notifyTemplateMapper.selectById(id));
|
||||||
|
verify(notifyProducer).sendNotifyTemplateRefreshMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDeleteNotifyTemplate_notExists() {
|
||||||
|
// 准备参数
|
||||||
|
Long id = randomLongId();
|
||||||
|
|
||||||
|
// 调用, 并断言异常
|
||||||
|
assertServiceException(() -> notifyTemplateService.deleteNotifyTemplate(id), NOTIFY_TEMPLATE_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testGetNotifyTemplatePage() {
|
||||||
|
// mock 数据
|
||||||
|
NotifyTemplateDO dbNotifyTemplate = randomPojo(NotifyTemplateDO.class, o -> { // 等会查询到
|
||||||
|
o.setName("芋头");
|
||||||
|
o.setCode("test_01");
|
||||||
|
o.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
|
o.setCreateTime(buildTime(2022, 2, 3));
|
||||||
|
});
|
||||||
|
notifyTemplateMapper.insert(dbNotifyTemplate);
|
||||||
|
// 测试 name 不匹配
|
||||||
|
notifyTemplateMapper.insert(cloneIgnoreId(dbNotifyTemplate, o -> o.setName("投")));
|
||||||
|
// 测试 code 不匹配
|
||||||
|
notifyTemplateMapper.insert(cloneIgnoreId(dbNotifyTemplate, o -> o.setCode("test_02")));
|
||||||
|
// 测试 status 不匹配
|
||||||
|
notifyTemplateMapper.insert(cloneIgnoreId(dbNotifyTemplate, o -> o.setStatus(CommonStatusEnum.DISABLE.getStatus())));
|
||||||
|
// 测试 createTime 不匹配
|
||||||
|
notifyTemplateMapper.insert(cloneIgnoreId(dbNotifyTemplate, o -> o.setCreateTime(buildTime(2022, 1, 5))));
|
||||||
|
// 准备参数
|
||||||
|
NotifyTemplatePageReqVO reqVO = new NotifyTemplatePageReqVO();
|
||||||
|
reqVO.setName("芋");
|
||||||
|
reqVO.setCode("est_01");
|
||||||
|
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
|
reqVO.setCreateTime(buildBetweenTime(2022, 2, 1, 2022, 2, 5));
|
||||||
|
|
||||||
|
// 调用
|
||||||
|
PageResult<NotifyTemplateDO> pageResult = notifyTemplateService.getNotifyTemplatePage(reqVO);
|
||||||
|
// 断言
|
||||||
|
assertEquals(1, pageResult.getTotal());
|
||||||
|
assertEquals(1, pageResult.getList().size());
|
||||||
|
assertPojoEquals(dbNotifyTemplate, pageResult.getList().get(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -28,3 +28,5 @@ DELETE FROM "system_oauth2_code";
|
||||||
DELETE FROM "system_mail_account";
|
DELETE FROM "system_mail_account";
|
||||||
DELETE FROM "system_mail_template";
|
DELETE FROM "system_mail_template";
|
||||||
DELETE FROM "system_mail_log";
|
DELETE FROM "system_mail_log";
|
||||||
|
DELETE FROM "system_notify_template";
|
||||||
|
DELETE FROM "system_notify_message";
|
||||||
|
|
|
@ -626,3 +626,43 @@ CREATE TABLE IF NOT EXISTS "system_mail_log" (
|
||||||
"deleted" bit NOT NULL DEFAULT FALSE,
|
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||||
PRIMARY KEY ("id")
|
PRIMARY KEY ("id")
|
||||||
) COMMENT '邮件日志表';
|
) COMMENT '邮件日志表';
|
||||||
|
|
||||||
|
-- 将该建表 SQL 语句,添加到 yudao-module-system-biz 模块的 test/resources/sql/create_tables.sql 文件里
|
||||||
|
CREATE TABLE IF NOT EXISTS "system_notify_template" (
|
||||||
|
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||||
|
"name" varchar NOT NULL,
|
||||||
|
"code" varchar NOT NULL,
|
||||||
|
"nickname" varchar NOT NULL,
|
||||||
|
"content" varchar NOT NULL,
|
||||||
|
"type" varchar NOT NULL,
|
||||||
|
"params" varchar,
|
||||||
|
"status" varchar NOT NULL,
|
||||||
|
"remark" varchar,
|
||||||
|
"creator" varchar DEFAULT '',
|
||||||
|
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updater" varchar DEFAULT '',
|
||||||
|
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||||
|
PRIMARY KEY ("id")
|
||||||
|
) COMMENT '站内信模板表';
|
||||||
|
|
||||||
|
CREATE TABLE IF NOT EXISTS "system_notify_message" (
|
||||||
|
"id" bigint NOT NULL GENERATED BY DEFAULT AS IDENTITY,
|
||||||
|
"user_id" bigint NOT NULL,
|
||||||
|
"user_type" varchar NOT NULL,
|
||||||
|
"template_id" bigint NOT NULL,
|
||||||
|
"template_code" varchar NOT NULL,
|
||||||
|
"template_nickname" varchar NOT NULL,
|
||||||
|
"template_content" varchar NOT NULL,
|
||||||
|
"template_type" int NOT NULL,
|
||||||
|
"template_params" varchar NOT NULL,
|
||||||
|
"read_status" bit NOT NULL,
|
||||||
|
"read_time" varchar,
|
||||||
|
"creator" varchar DEFAULT '',
|
||||||
|
"create_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
"updater" varchar DEFAULT '',
|
||||||
|
"update_time" datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
"deleted" bit NOT NULL DEFAULT FALSE,
|
||||||
|
"tenant_id" bigint not null default '0',
|
||||||
|
PRIMARY KEY ("id")
|
||||||
|
) COMMENT '站内信消息表';
|
||||||
|
|
|
@ -115,6 +115,7 @@ yudao:
|
||||||
- cn.iocoder.yudao.module.member.enums.ErrorCodeConstants
|
- cn.iocoder.yudao.module.member.enums.ErrorCodeConstants
|
||||||
- cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants
|
- cn.iocoder.yudao.module.pay.enums.ErrorCodeConstants
|
||||||
- cn.iocoder.yudao.module.system.enums.ErrorCodeConstants
|
- cn.iocoder.yudao.module.system.enums.ErrorCodeConstants
|
||||||
|
- cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants
|
||||||
tenant: # 多租户相关配置项
|
tenant: # 多租户相关配置项
|
||||||
enable: true
|
enable: true
|
||||||
ignore-urls:
|
ignore-urls:
|
||||||
|
@ -141,6 +142,7 @@ yudao:
|
||||||
- system_mail_account
|
- system_mail_account
|
||||||
- system_mail_template
|
- system_mail_template
|
||||||
- system_mail_log
|
- system_mail_log
|
||||||
|
- system_notify_template
|
||||||
- infra_codegen_column
|
- infra_codegen_column
|
||||||
- infra_codegen_table
|
- infra_codegen_table
|
||||||
- infra_test_demo
|
- infra_test_demo
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
import request from '@/utils/request'
|
||||||
|
import qs from 'qs'
|
||||||
|
|
||||||
|
// 获得我的站内信分页
|
||||||
|
export function getNotifyMessagePage(query) {
|
||||||
|
return request({
|
||||||
|
url: '/system/notify-message/page',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获得我的站内信分页
|
||||||
|
export function getMyNotifyMessagePage(query) {
|
||||||
|
return request({
|
||||||
|
url: '/system/notify-message/my-page',
|
||||||
|
method: 'get',
|
||||||
|
params: query
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量标记已读
|
||||||
|
export function updateNotifyMessageRead(ids) {
|
||||||
|
return request({
|
||||||
|
url: '/system/notify-message/update-read?' + qs.stringify({ids: ids}, { indices: false }),
|
||||||
|
method: 'put'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 标记所有站内信为已读
|
||||||
|
export function updateAllNotifyMessageRead() {
|
||||||
|
return request({
|
||||||
|
url: '/system/notify-message/update-all-read',
|
||||||
|
method: 'put'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取当前用户的最新站内信列表
|
||||||
|
export function getUnreadNotifyMessageList() {
|
||||||
|
return request({
|
||||||
|
url: '/system/notify-message/get-unread-list',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getUnreadNotifyMessageCount() {
|
||||||
|
return request({
|
||||||
|
url: '/system/notify-message/get-unread-count',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
|
@ -1,38 +0,0 @@
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
|
|
||||||
// 获得我的站内信分页
|
|
||||||
export function getNotifyMessagePage(query) {
|
|
||||||
return request({
|
|
||||||
url: '/system/notify-message/page',
|
|
||||||
method: 'get',
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 获得单条我的站内信
|
|
||||||
export function getNotifyMessage(query) {
|
|
||||||
return request({
|
|
||||||
url: '/system/notify-message/get',
|
|
||||||
method: 'get',
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 批量标记已读
|
|
||||||
export function updateNotifyMessageListRead(data) {
|
|
||||||
return request({
|
|
||||||
url: '/system/notify-message/update-list-read',
|
|
||||||
method: 'put',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// 所有未读消息标记已读
|
|
||||||
export function updateNotifyMessageAllRead(data) {
|
|
||||||
return request({
|
|
||||||
url: '/system/notify-message/update-all-read',
|
|
||||||
method: 'put',
|
|
||||||
data: data
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
import request from '@/utils/request'
|
|
||||||
|
|
||||||
|
|
||||||
// 获得我的站内信分页
|
|
||||||
export function getNotifyLogPage(query) {
|
|
||||||
return request({
|
|
||||||
url: '/system/notify-log/page',
|
|
||||||
method: 'get',
|
|
||||||
params: query
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -9,7 +9,7 @@ export default {
|
||||||
name: 'YudaoDoc',
|
name: 'YudaoDoc',
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
url: 'http://www.iocoder.cn/Yudao/build-debugger-environment/?yudao'
|
url: 'https://doc.iocoder.cn/'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<el-popover placement="bottom" width="600" trigger="click">
|
||||||
|
<!-- icon 展示 -->
|
||||||
|
<el-badge slot="reference" :is-dot="unreadCount > 0" type="danger">
|
||||||
|
<svg-icon icon-class="message" @click="getList"/>
|
||||||
|
</el-badge>
|
||||||
|
|
||||||
|
<!-- 弹出列表 -->
|
||||||
|
<el-table v-loading="loading" :data="list">
|
||||||
|
<el-table-column width="120" property="templateNickname" label="日期" />
|
||||||
|
<el-table-column width="180" property="title" label="发送时间">
|
||||||
|
<template slot-scope="scope">
|
||||||
|
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="类型" align="center" prop="templateType" width="100">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE" :value="scope.row.templateType" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column property="templateContent" label="内容" />
|
||||||
|
</el-table>
|
||||||
|
|
||||||
|
<!-- 更多 -->
|
||||||
|
<div style="text-align: right; margin-top: 10px">
|
||||||
|
<el-button type="primary" size="mini" @click="goMyList">查看全部</el-button>
|
||||||
|
</div>
|
||||||
|
</el-popover>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {getUnreadNotifyMessageCount, getUnreadNotifyMessageList} from "@/api/system/notify/message";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'NotifyMessage',
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 遮罩层
|
||||||
|
loading: false,
|
||||||
|
// 列表
|
||||||
|
list: [],
|
||||||
|
// 未读数量,
|
||||||
|
unreadCount: 0,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
// 首次加载小红点
|
||||||
|
this.getUnreadCount()
|
||||||
|
// 轮询刷新小红点
|
||||||
|
window.timer = setInterval(()=>{
|
||||||
|
this.getUnreadCount()
|
||||||
|
},1000 * 60 * 2)
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getList: function() {
|
||||||
|
this.loading = true;
|
||||||
|
getUnreadNotifyMessageList().then(response => {
|
||||||
|
this.list = response.data;
|
||||||
|
this.loading = false;
|
||||||
|
// 强制设置 unreadCount 为 0,避免小红点因为轮询太慢,不消除
|
||||||
|
this.unreadCount = 0
|
||||||
|
});
|
||||||
|
},
|
||||||
|
getUnreadCount: function() {
|
||||||
|
getUnreadNotifyMessageCount().then(response => {
|
||||||
|
this.unreadCount = response.data;
|
||||||
|
})
|
||||||
|
},
|
||||||
|
goMyList: function() {
|
||||||
|
this.$router.push({
|
||||||
|
name: 'MyNotifyMessage'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style>
|
||||||
|
.el-badge__content.is-fixed {
|
||||||
|
top: 10px; /* 保证徽章的位置 */
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -9,6 +9,9 @@
|
||||||
<template v-if="device!=='mobile'">
|
<template v-if="device!=='mobile'">
|
||||||
<search id="header-search" class="right-menu-item" />
|
<search id="header-search" class="right-menu-item" />
|
||||||
|
|
||||||
|
<!-- 站内信 -->
|
||||||
|
<notify-message class="right-menu-item hover-effect" />
|
||||||
|
|
||||||
<el-tooltip content="源码地址" effect="dark" placement="bottom">
|
<el-tooltip content="源码地址" effect="dark" placement="bottom">
|
||||||
<ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" />
|
<ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" />
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
@ -57,6 +60,7 @@ import SizeSelect from '@/components/SizeSelect'
|
||||||
import Search from '@/components/HeaderSearch'
|
import Search from '@/components/HeaderSearch'
|
||||||
import RuoYiGit from '@/components/RuoYi/Git'
|
import RuoYiGit from '@/components/RuoYi/Git'
|
||||||
import RuoYiDoc from '@/components/RuoYi/Doc'
|
import RuoYiDoc from '@/components/RuoYi/Doc'
|
||||||
|
import NotifyMessage from '@/layout/components/Message'
|
||||||
import {getPath} from "@/utils/ruoyi";
|
import {getPath} from "@/utils/ruoyi";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -68,7 +72,8 @@ export default {
|
||||||
SizeSelect,
|
SizeSelect,
|
||||||
Search,
|
Search,
|
||||||
RuoYiGit,
|
RuoYiGit,
|
||||||
RuoYiDoc
|
RuoYiDoc,
|
||||||
|
NotifyMessage
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters([
|
...mapGetters([
|
||||||
|
|
|
@ -75,7 +75,8 @@ export const constantRoutes = [
|
||||||
meta: {title: '首页', icon: 'dashboard', affix: true}
|
meta: {title: '首页', icon: 'dashboard', affix: true}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
path: '/user',
|
path: '/user',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
hidden: true,
|
hidden: true,
|
||||||
|
@ -85,9 +86,14 @@ export const constantRoutes = [
|
||||||
component: (resolve) => require(['@/views/system/user/profile/index'], resolve),
|
component: (resolve) => require(['@/views/system/user/profile/index'], resolve),
|
||||||
name: 'Profile',
|
name: 'Profile',
|
||||||
meta: {title: '个人中心', icon: 'user'}
|
meta: {title: '个人中心', icon: 'user'}
|
||||||
}
|
}, {
|
||||||
]
|
path: 'notify-message',
|
||||||
}, {
|
component: (resolve) => require(['@/views/system/notify/my/index'], resolve),
|
||||||
|
name: 'MyNotifyMessage',
|
||||||
|
meta: { title: '我的站内信', icon: 'message' },
|
||||||
|
}]
|
||||||
|
},
|
||||||
|
{
|
||||||
path: '/dict',
|
path: '/dict',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
hidden: true,
|
hidden: true,
|
||||||
|
@ -98,18 +104,8 @@ export const constantRoutes = [
|
||||||
meta: {title: '字典数据', icon: '', activeMenu: '/system/dict'}
|
meta: {title: '字典数据', icon: '', activeMenu: '/system/dict'}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}, {
|
},
|
||||||
path: '/property',
|
{
|
||||||
component: Layout,
|
|
||||||
hidden: true,
|
|
||||||
children: [{
|
|
||||||
path: 'value/:propertyId(\\d+)',
|
|
||||||
component: (resolve) => require(['@/views/mall/product/property/value'], resolve),
|
|
||||||
name: 'PropertyValue',
|
|
||||||
meta: {title: '商品属性值', icon: '', activeMenu: '/product/property'}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}, {
|
|
||||||
path: '/job',
|
path: '/job',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
hidden: true,
|
hidden: true,
|
||||||
|
@ -131,24 +127,8 @@ export const constantRoutes = [
|
||||||
meta: {title: '修改生成配置', activeMenu: '/infra/codegen'}
|
meta: {title: '修改生成配置', activeMenu: '/infra/codegen'}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}, {
|
},
|
||||||
path: '/spu',
|
{
|
||||||
component: Layout,
|
|
||||||
hidden: true,
|
|
||||||
children: [{
|
|
||||||
path: 'edit/:spuId(\\d+)',
|
|
||||||
component: (resolve) => require(['@/views/mall/product/spu/save'], resolve),
|
|
||||||
name: 'SpuEdit',
|
|
||||||
meta: {title: '修改商品', activeMenu: '/product/spu'}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
path: 'add',
|
|
||||||
component: (resolve) => require(['@/views/mall/product/spu/save'], resolve),
|
|
||||||
name: 'SpuAdd',
|
|
||||||
meta: {title: '添加商品', activeMenu: '/product/spu'}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}, {
|
|
||||||
path: '/bpm',
|
path: '/bpm',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
hidden: true,
|
hidden: true,
|
||||||
|
@ -165,7 +145,8 @@ export const constantRoutes = [
|
||||||
meta: {title: '查看 OA 请假', icon: 'view', activeMenu: '/bpm/oa/leave'}
|
meta: {title: '查看 OA 请假', icon: 'view', activeMenu: '/bpm/oa/leave'}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
path: '/bpm',
|
path: '/bpm',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
hidden: true,
|
hidden: true,
|
||||||
|
@ -197,6 +178,36 @@ export const constantRoutes = [
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/property',
|
||||||
|
component: Layout,
|
||||||
|
hidden: true,
|
||||||
|
children: [{
|
||||||
|
path: 'value/:propertyId(\\d+)',
|
||||||
|
component: (resolve) => require(['@/views/mall/product/property/value'], resolve),
|
||||||
|
name: 'PropertyValue',
|
||||||
|
meta: {title: '商品属性值', icon: '', activeMenu: '/product/property'}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/spu',
|
||||||
|
component: Layout,
|
||||||
|
hidden: true,
|
||||||
|
children: [{
|
||||||
|
path: 'edit/:spuId(\\d+)',
|
||||||
|
component: (resolve) => require(['@/views/mall/product/spu/save'], resolve),
|
||||||
|
name: 'SpuEdit',
|
||||||
|
meta: {title: '修改商品', activeMenu: '/product/spu'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: 'add',
|
||||||
|
component: (resolve) => require(['@/views/mall/product/spu/save'], resolve),
|
||||||
|
name: 'SpuAdd',
|
||||||
|
meta: {title: '添加商品', activeMenu: '/product/spu'}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: '/trade/order',
|
path: '/trade/order',
|
||||||
component: Layout,
|
component: Layout,
|
||||||
|
|
|
@ -25,8 +25,8 @@ export const DICT_TYPE = {
|
||||||
SYSTEM_SMS_RECEIVE_STATUS: 'system_sms_receive_status',
|
SYSTEM_SMS_RECEIVE_STATUS: 'system_sms_receive_status',
|
||||||
SYSTEM_ERROR_CODE_TYPE: 'system_error_code_type',
|
SYSTEM_ERROR_CODE_TYPE: 'system_error_code_type',
|
||||||
SYSTEM_OAUTH2_GRANT_TYPE: 'system_oauth2_grant_type',
|
SYSTEM_OAUTH2_GRANT_TYPE: 'system_oauth2_grant_type',
|
||||||
SYSTEM_NOTIFY_READ_STATUS: "system_notify_read_status",
|
|
||||||
SYSTEM_MAIL_SEND_STATUS: 'system_mail_send_status',
|
SYSTEM_MAIL_SEND_STATUS: 'system_mail_send_status',
|
||||||
|
SYSTEM_NOTIFY_TEMPLATE_TYPE: 'system_notify_template_type',
|
||||||
|
|
||||||
// ========== INFRA 模块 ==========
|
// ========== INFRA 模块 ==========
|
||||||
INFRA_BOOLEAN_STRING: 'infra_boolean_string',
|
INFRA_BOOLEAN_STRING: 'infra_boolean_string',
|
||||||
|
|
|
@ -140,7 +140,7 @@ export default {
|
||||||
// 邮件日志列表
|
// 邮件日志列表
|
||||||
list: [],
|
list: [],
|
||||||
// 弹出层标题
|
// 弹出层标题
|
||||||
title: "",
|
title: "邮件发送日志详细",
|
||||||
// 是否显示弹出层
|
// 是否显示弹出层
|
||||||
open: false,
|
open: false,
|
||||||
// 查询参数
|
// 查询参数
|
||||||
|
|
|
@ -0,0 +1,179 @@
|
||||||
|
<template>
|
||||||
|
<div class="app-container">
|
||||||
|
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
|
<el-form-item label="用户编号" prop="userId">
|
||||||
|
<el-input v-model="queryParams.userId" placeholder="请输入用户编号" clearable @keyup.enter.native="handleQuery"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="用户类型" prop="userType">
|
||||||
|
<el-select v-model="queryParams.userType" placeholder="请选择用户类型" clearable size="small">
|
||||||
|
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.USER_TYPE)"
|
||||||
|
:key="dict.value" :label="dict.label" :value="dict.value"/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="模板编码" prop="templateCode">
|
||||||
|
<el-input v-model="queryParams.templateCode" placeholder="请输入模板编码" clearable @keyup.enter.native="handleQuery"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="模版类型" prop="templateType">
|
||||||
|
<el-select v-model="queryParams.templateType" placeholder="请选择模版类型" clearable size="small">
|
||||||
|
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE)"
|
||||||
|
:key="dict.value" :label="dict.label" :value="dict.value"/>
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="创建时间" prop="createTime">
|
||||||
|
<el-date-picker v-model="queryParams.createTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange"
|
||||||
|
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item>
|
||||||
|
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
|
||||||
|
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<!-- 操作工具栏 -->
|
||||||
|
<el-row :gutter="10" class="mb8">
|
||||||
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
|
</el-row>
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<el-table v-loading="loading" :data="list">
|
||||||
|
<el-table-column label="编号" align="center" prop="id" />
|
||||||
|
<el-table-column label="用户编号" align="center" prop="userId" />
|
||||||
|
<el-table-column label="用户类型" align="center" prop="userType">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.USER_TYPE" :value="scope.row.userType" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="模板编码" align="center" prop="templateCode" />
|
||||||
|
<el-table-column label="发送人名称" align="center" prop="templateNickname" />
|
||||||
|
<el-table-column label="模版内容" align="center" prop="templateContent" />
|
||||||
|
<el-table-column label="模版类型" align="center" prop="templateType">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE" :value="scope.row.templateType" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="是否已读" align="center" prop="readStatus">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.readStatus" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="阅读时间" align="center" prop="readTime" width="180">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<span>{{ parseTime(scope.row.readTime) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="创建时间" align="center" prop="createTime" width="180">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<el-button size="mini" type="text" icon="el-icon-view" @click="handleView(scope.row)"
|
||||||
|
v-hasPermi="['system:notify-message:query']">详细</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- 分页组件 -->
|
||||||
|
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
|
||||||
|
@pagination="getList"/>
|
||||||
|
|
||||||
|
<!-- 站内信详细-->
|
||||||
|
<el-dialog :title="title" :visible.sync="open" width="700px" v-dialogDrag append-to-body>
|
||||||
|
<el-form ref="form" :model="form" label-width="160px">
|
||||||
|
<el-row>
|
||||||
|
<el-col :span="24">
|
||||||
|
<el-form-item label="日志主键:">{{ form.id }}</el-form-item>
|
||||||
|
<el-form-item label="发送时间:">{{ parseTime(form.createTime) }}</el-form-item>
|
||||||
|
<el-form-item label="用户编号:">{{ form.userId }}</el-form-item>
|
||||||
|
<el-form-item label="用户类型:">
|
||||||
|
<dict-tag :type="DICT_TYPE.USER_TYPE" :value="form.userType"/>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="模板编号:">{{ form.templateId }}</el-form-item>
|
||||||
|
<el-form-item label="模板编码:">{{ form.templateCode }}</el-form-item>
|
||||||
|
<el-form-item label="模板类型:">
|
||||||
|
<dict-tag :type="DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE" :value="form.templateType" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="模版发送人名称:">{{ form.templateNickname }}</el-form-item>
|
||||||
|
<el-form-item label="邮件内容:">{{ form.templateContent }}</el-form-item>
|
||||||
|
<el-form-item label="模版参数:">{{ form.templateParams }}</el-form-item>
|
||||||
|
<el-form-item label="是否已读:">
|
||||||
|
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="form.readStatus" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="阅读时间:">{{ parseTime(form.readTime) }}</el-form-item>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-form>
|
||||||
|
<div slot="footer" class="dialog-footer">
|
||||||
|
<el-button @click="open = false">关 闭</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { getNotifyMessagePage } from "@/api/system/notify/message";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: "NotifyMessage",
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
// 遮罩层
|
||||||
|
loading: true,
|
||||||
|
// 显示搜索条件
|
||||||
|
showSearch: true,
|
||||||
|
// 总条数
|
||||||
|
total: 0,
|
||||||
|
// 站内信消息列表
|
||||||
|
list: [],
|
||||||
|
// 弹出层标题
|
||||||
|
title: "站内信详细",
|
||||||
|
// 是否显示弹出层
|
||||||
|
open: false,
|
||||||
|
// 查询参数
|
||||||
|
queryParams: {
|
||||||
|
pageNo: 1,
|
||||||
|
pageSize: 10,
|
||||||
|
userId: null,
|
||||||
|
userType: null,
|
||||||
|
templateCode: null,
|
||||||
|
templateType: null,
|
||||||
|
createTime: [],
|
||||||
|
},
|
||||||
|
// 表单参数
|
||||||
|
form: {},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
/** 查询列表 */
|
||||||
|
getList() {
|
||||||
|
this.loading = true;
|
||||||
|
// 执行查询
|
||||||
|
getNotifyMessagePage(this.queryParams).then(response => {
|
||||||
|
this.list = response.data.list;
|
||||||
|
this.total = response.data.total;
|
||||||
|
this.loading = false;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
/** 搜索按钮操作 */
|
||||||
|
handleQuery() {
|
||||||
|
this.queryParams.pageNo = 1;
|
||||||
|
this.getList();
|
||||||
|
},
|
||||||
|
/** 重置按钮操作 */
|
||||||
|
resetQuery() {
|
||||||
|
this.resetForm("queryForm");
|
||||||
|
this.handleQuery();
|
||||||
|
},
|
||||||
|
/** 详细按钮操作 */
|
||||||
|
handleView(row) {
|
||||||
|
this.open = true;
|
||||||
|
this.form = row;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -1,17 +1,14 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<!-- 搜索工作栏 -->
|
<!-- 搜索工作栏 -->
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="150px">
|
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
<el-form-item label="模板标题" prop="title">
|
<el-form-item label="是否已读" prop="readStatus">
|
||||||
<el-input v-model="queryParams.title" placeholder="请输入模板标题" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="读取状态" prop="readStatus">
|
|
||||||
<el-select v-model="queryParams.readStatus" placeholder="请选择状态" clearable>
|
<el-select v-model="queryParams.readStatus" placeholder="请选择状态" clearable>
|
||||||
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.SYSTEM_NOTIFY_READ_STATUS)"
|
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.INFRA_BOOLEAN_STRING)"
|
||||||
:key="dict.value" :label="dict.label" :value="dict.value"/>
|
:key="dict.value" :label="dict.label" :value="dict.value"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="创建时间" prop="createTime">
|
<el-form-item label="发送时间" prop="createTime">
|
||||||
<el-date-picker v-model="queryParams.createTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange"
|
<el-date-picker v-model="queryParams.createTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange"
|
||||||
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" />
|
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
@ -35,17 +32,21 @@
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<el-table v-loading="loading" ref="tables" :data="list">
|
<el-table v-loading="loading" ref="tables" :data="list">
|
||||||
<el-table-column type="selection" width="55" />
|
<el-table-column type="selection" width="55" />
|
||||||
<el-table-column label="模板标题" align="center" prop="title" />
|
<el-table-column label="发送人" align="center" prop="templateNickname" width="120" />
|
||||||
<el-table-column label="模板内容" align="center" prop="content" width="300" />
|
<el-table-column label="发送时间" align="center" prop="createTime" width="180">
|
||||||
<el-table-column label="发送人" align="center" prop="sendUserName" />
|
|
||||||
<el-table-column label="发送时间" align="center" prop="sendTime" width="180">
|
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span>{{ parseTime(scope.row.sendTime) }}</span>
|
<span>{{ parseTime(scope.row.createTime) }}</span>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="读取状态" align="center" prop="readStatus">
|
<el-table-column label="类型" align="center" prop="templateType" width="80">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE" :value="scope.row.templateType" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="内容" align="center" prop="templateContent" />
|
||||||
|
<el-table-column label="是否已读" align="center" prop="readStatus" width="80">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<dict-tag :type="DICT_TYPE.SYSTEM_NOTIFY_READ_STATUS" :value="scope.row.readStatus"/>
|
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.readStatus"/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="150">
|
<el-table-column label="操作" align="center" class-name="small-padding fixed-width" width="150">
|
||||||
|
@ -62,7 +63,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { getNotifyMessagePage, updateNotifyMessageListRead, updateNotifyMessageAllRead} from "@/api/system/notify/myNotify";
|
import {getMyNotifyMessagePage, updateAllNotifyMessageRead, updateNotifyMessageRead} from "@/api/system/notify/message";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "myNotify",
|
name: "myNotify",
|
||||||
|
@ -70,25 +71,17 @@ export default {
|
||||||
return {
|
return {
|
||||||
// 遮罩层
|
// 遮罩层
|
||||||
loading: true,
|
loading: true,
|
||||||
// 导出遮罩层
|
|
||||||
exportLoading: false,
|
|
||||||
// 显示搜索条件
|
// 显示搜索条件
|
||||||
showSearch: true,
|
showSearch: true,
|
||||||
// 总条数
|
// 总条数
|
||||||
total: 0,
|
total: 0,
|
||||||
// 我的站内信列表
|
// 我的站内信列表
|
||||||
list: [],
|
list: [],
|
||||||
// 弹出层标题
|
|
||||||
title: "",
|
|
||||||
// 是否显示弹出层
|
|
||||||
open: false,
|
|
||||||
// 查询参数
|
// 查询参数
|
||||||
queryParams: {
|
queryParams: {
|
||||||
pageNo: 1,
|
pageNo: 1,
|
||||||
pageSize: 10,
|
pageSize: 10,
|
||||||
readStatus: null,
|
readStatus: null,
|
||||||
code: null,
|
|
||||||
title: null,
|
|
||||||
createTime: []
|
createTime: []
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -101,7 +94,7 @@ export default {
|
||||||
getList() {
|
getList() {
|
||||||
this.loading = true;
|
this.loading = true;
|
||||||
// 执行查询
|
// 执行查询
|
||||||
getNotifyMessagePage(this.queryParams).then(response => {
|
getMyNotifyMessagePage(this.queryParams).then(response => {
|
||||||
this.list = response.data.list;
|
this.list = response.data.list;
|
||||||
this.total = response.data.total;
|
this.total = response.data.total;
|
||||||
this.loading = false;
|
this.loading = false;
|
||||||
|
@ -117,25 +110,26 @@ export default {
|
||||||
this.resetForm("queryForm");
|
this.resetForm("queryForm");
|
||||||
this.handleQuery();
|
this.handleQuery();
|
||||||
},
|
},
|
||||||
handleUpdateList(){
|
handleUpdateList() {
|
||||||
let list = this.$refs["tables"].selection;
|
let list = this.$refs["tables"].selection;
|
||||||
if(list.length != 0){
|
if (list.length === 0) {
|
||||||
this.handleUpdate(list.map(v=>v.id))
|
return;
|
||||||
}
|
}
|
||||||
|
this.handleUpdate(list.map(v => v.id))
|
||||||
},
|
},
|
||||||
handleUpdateSingle(row){
|
handleUpdateSingle(row) {
|
||||||
this.handleUpdate([row.id])
|
this.handleUpdate([row.id])
|
||||||
},
|
},
|
||||||
handleUpdate(ids){
|
handleUpdate(ids) {
|
||||||
updateNotifyMessageListRead(ids).then(response => {
|
updateNotifyMessageRead(ids).then(response => {
|
||||||
this.$modal.msgSuccess("修改成功");
|
this.$modal.msgSuccess("标记已读成功!");
|
||||||
this.getList();
|
this.getList();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
handleUpdateAll(){
|
handleUpdateAll(){
|
||||||
updateNotifyMessageAllRead().then(response => {
|
updateAllNotifyMessageRead().then(response => {
|
||||||
this.$modal.msgSuccess("修改成功");
|
this.$modal.msgSuccess("全部已读成功!");
|
||||||
this.getList();
|
this.getList();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,120 +0,0 @@
|
||||||
<template>
|
|
||||||
<div class="app-container">
|
|
||||||
<!-- 搜索工作栏 -->
|
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="150px">
|
|
||||||
<el-form-item label="模板编码" prop="templateCode">
|
|
||||||
<el-input v-model="queryParams.templateCode" placeholder="请输入模板编码" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="模板标题" prop="title">
|
|
||||||
<el-input v-model="queryParams.title" placeholder="请输入模板标题" clearable @keyup.enter.native="handleQuery"/>
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item label="发送时间" prop="sendTime">
|
|
||||||
<el-date-picker v-model="queryParams.sendTime" style="width: 240px" value-format="yyyy-MM-dd HH:mm:ss" type="daterange"
|
|
||||||
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" :default-time="['00:00:00', '23:59:59']" />
|
|
||||||
</el-form-item>
|
|
||||||
<el-form-item>
|
|
||||||
<el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
|
|
||||||
<el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
|
|
||||||
</el-form-item>
|
|
||||||
</el-form>
|
|
||||||
|
|
||||||
<!-- 操作工具栏 -->
|
|
||||||
<!-- <el-row :gutter="10" class="mb8">
|
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading"
|
|
||||||
v-hasPermi="['system:notify-log:export']">导出</el-button>
|
|
||||||
</el-col>
|
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
|
||||||
</el-row> -->
|
|
||||||
|
|
||||||
<!-- 列表 -->
|
|
||||||
<el-table v-loading="loading" :data="list">
|
|
||||||
<el-table-column label="模板编码" align="center" prop="templateCode" />
|
|
||||||
<el-table-column label="模板标题" align="center" prop="title" />
|
|
||||||
<el-table-column label="模板内容" align="center" prop="content" width="300" />
|
|
||||||
<el-table-column label="阅读状态" align="center" prop="readStatus">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<dict-tag :type="DICT_TYPE.SYSTEM_NOTIFY_READ_STATUS" :value="scope.row.readStatus"/>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="接收人" align="center" prop="receiveUserName" />
|
|
||||||
<el-table-column label="发送时间" align="center" prop="sendTime" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.sendTime) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="阅读时间" align="center" prop="createTime" width="180">
|
|
||||||
<template slot-scope="scope">
|
|
||||||
<span>{{ parseTime(scope.row.readTime) }}</span>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
<!-- 分页组件 -->
|
|
||||||
<pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
|
|
||||||
@pagination="getList"/>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { getNotifyLogPage} from "@/api/system/notify/notifyLog";
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: "notifyLog",
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
// 遮罩层
|
|
||||||
loading: true,
|
|
||||||
// 导出遮罩层
|
|
||||||
exportLoading: false,
|
|
||||||
// 显示搜索条件
|
|
||||||
showSearch: true,
|
|
||||||
// 总条数
|
|
||||||
total: 0,
|
|
||||||
// 我的站内信列表
|
|
||||||
list: [],
|
|
||||||
// 弹出层标题
|
|
||||||
title: "",
|
|
||||||
// 是否显示弹出层
|
|
||||||
open: false,
|
|
||||||
// 查询参数
|
|
||||||
queryParams: {
|
|
||||||
pageNo: 1,
|
|
||||||
pageSize: 10,
|
|
||||||
templateCode: null,
|
|
||||||
title: null,
|
|
||||||
sendTime: []
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
/** 查询列表 */
|
|
||||||
getList() {
|
|
||||||
this.loading = true;
|
|
||||||
// 执行查询
|
|
||||||
getNotifyLogPage(this.queryParams).then(response => {
|
|
||||||
this.list = response.data.list;
|
|
||||||
this.total = response.data.total;
|
|
||||||
this.loading = false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/** 搜索按钮操作 */
|
|
||||||
handleQuery() {
|
|
||||||
this.queryParams.pageNo = 1;
|
|
||||||
this.getList();
|
|
||||||
},
|
|
||||||
/** 重置按钮操作 */
|
|
||||||
resetQuery() {
|
|
||||||
this.resetForm("queryForm");
|
|
||||||
this.handleQuery();
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
|
|
||||||
</style>
|
|
|
@ -1,15 +1,15 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
<!-- 搜索工作栏 -->
|
<!-- 搜索工作栏 -->
|
||||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="150px">
|
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
||||||
<el-form-item label="模板编码" prop="code">
|
<el-form-item label="模板名称" prop="name">
|
||||||
<el-input v-model="queryParams.code" placeholder="请输入模板编码" clearable @keyup.enter.native="handleQuery"/>
|
<el-input v-model="queryParams.name" placeholder="请输入模板名称" clearable @keyup.enter.native="handleQuery"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="模板标题" prop="title">
|
<el-form-item label="模版编码" prop="code">
|
||||||
<el-input v-model="queryParams.title" placeholder="请输入模板标题" clearable @keyup.enter.native="handleQuery"/>
|
<el-input v-model="queryParams.code" placeholder="请输入模版编码" clearable @keyup.enter.native="handleQuery"/>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="开启状态" prop="status">
|
<el-form-item label="状态" prop="status">
|
||||||
<el-select v-model="queryParams.status" placeholder="请选择开启状态" clearable>
|
<el-select v-model="queryParams.status" placeholder="请选择状态" clearable size="small">
|
||||||
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.COMMON_STATUS)"
|
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.COMMON_STATUS)"
|
||||||
:key="dict.value" :label="dict.label" :value="dict.value"/>
|
:key="dict.value" :label="dict.label" :value="dict.value"/>
|
||||||
</el-select>
|
</el-select>
|
||||||
|
@ -30,17 +30,19 @@
|
||||||
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
|
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
|
||||||
v-hasPermi="['system:notify-template:create']">新增</el-button>
|
v-hasPermi="['system:notify-template:create']">新增</el-button>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="1.5">
|
|
||||||
<el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading"
|
|
||||||
v-hasPermi="['system:notify-template:export']">导出</el-button>
|
|
||||||
</el-col>
|
|
||||||
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
<right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<el-table v-loading="loading" :data="list">
|
<el-table v-loading="loading" :data="list">
|
||||||
<el-table-column label="模板编码" align="center" prop="code" />
|
<el-table-column label="模板编码" align="center" prop="code" />
|
||||||
<el-table-column label="模板标题" align="center" prop="title" />
|
<el-table-column label="模板名称" align="center" prop="name" />
|
||||||
|
<el-table-column label="类型" align="center" prop="type">
|
||||||
|
<template v-slot="scope">
|
||||||
|
<dict-tag :type="DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE" :value="scope.row.type" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="发送人名称" align="center" prop="nickname" />
|
||||||
<el-table-column label="模板内容" align="center" prop="content" width="300" />
|
<el-table-column label="模板内容" align="center" prop="content" width="300" />
|
||||||
<el-table-column label="开启状态" align="center" prop="status">
|
<el-table-column label="开启状态" align="center" prop="status">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
|
@ -74,12 +76,21 @@
|
||||||
<el-form-item label="模板编号" prop="code">
|
<el-form-item label="模板编号" prop="code">
|
||||||
<el-input v-model="form.code" placeholder="请输入模板编号" />
|
<el-input v-model="form.code" placeholder="请输入模板编号" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="模板标题" prop="title">
|
<el-form-item label="模板名称" prop="name">
|
||||||
<el-input v-model="form.title" placeholder="请输入标题名称" />
|
<el-input v-model="form.name" placeholder="请输入模版名称" />
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="发件人名称" prop="nickname">
|
||||||
|
<el-input v-model="form.nickname" placeholder="请输入发件人名称" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item label="模板内容" prop="content">
|
<el-form-item label="模板内容" prop="content">
|
||||||
<el-input type="textarea" v-model="form.content" placeholder="请输入模板内容" />
|
<el-input type="textarea" v-model="form.content" placeholder="请输入模板内容" />
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
|
<el-form-item label="类型" prop="type">
|
||||||
|
<el-select v-model="form.type" placeholder="请选择类型">
|
||||||
|
<el-option v-for="dict in this.getDictDatas(DICT_TYPE.SYSTEM_NOTIFY_TEMPLATE_TYPE)"
|
||||||
|
:key="dict.value" :label="dict.label" :value="parseInt(dict.value)" />
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
<el-form-item label="开启状态" prop="status">
|
<el-form-item label="开启状态" prop="status">
|
||||||
<el-radio-group v-model="form.status">
|
<el-radio-group v-model="form.status">
|
||||||
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.COMMON_STATUS)"
|
<el-radio v-for="dict in this.getDictDatas(DICT_TYPE.COMMON_STATUS)"
|
||||||
|
@ -122,8 +133,9 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { createNotifyTemplate, updateNotifyTemplate, deleteNotifyTemplate, getNotifyTemplate, getNotifyTemplatePage,
|
import { createNotifyTemplate, updateNotifyTemplate, deleteNotifyTemplate, getNotifyTemplate, getNotifyTemplatePage,
|
||||||
exportNotifyTemplateExcel, sendNotify } from "@/api/system/notify/notifyTemplate";
|
sendNotify } from "@/api/system/notify/template";
|
||||||
import {listSimpleUsers} from "@/api/system/user";
|
import {listSimpleUsers} from "@/api/system/user";
|
||||||
|
import {CommonStatusEnum} from "@/utils/constants";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: "NotifyTemplate",
|
name: "NotifyTemplate",
|
||||||
|
@ -131,8 +143,6 @@ export default {
|
||||||
return {
|
return {
|
||||||
// 遮罩层
|
// 遮罩层
|
||||||
loading: true,
|
loading: true,
|
||||||
// 导出遮罩层
|
|
||||||
exportLoading: false,
|
|
||||||
// 显示搜索条件
|
// 显示搜索条件
|
||||||
showSearch: true,
|
showSearch: true,
|
||||||
// 总条数
|
// 总条数
|
||||||
|
@ -156,11 +166,12 @@ export default {
|
||||||
form: {},
|
form: {},
|
||||||
// 表单校验
|
// 表单校验
|
||||||
rules: {
|
rules: {
|
||||||
status: [{ required: true, message: "开启状态不能为空", trigger: "blur" }],
|
name: [{ required: true, message: "模板名称不能为空", trigger: "blur" }],
|
||||||
code: [{ required: true, message: "模板编码不能为空", trigger: "blur" }],
|
code: [{ required: true, message: "模版编码不能为空", trigger: "blur" }],
|
||||||
title: [{ required: true, message: "模板标题不能为空", trigger: "blur" }],
|
nickname: [{ required: true, message: "发件人名称不能为空", trigger: "blur" }],
|
||||||
content: [{ required: true, message: "模板内容不能为空", trigger: "blur" }],
|
content: [{ required: true, message: "模版内容不能为空", trigger: "blur" }],
|
||||||
userId: [{ required: true, message: "接收人不能为空", trigger: "blur" }]
|
type: [{ required: true, message: "类型不能为空", trigger: "change" }],
|
||||||
|
status: [{ required: true, message: "状态不能为空", trigger: "blur" }],
|
||||||
},
|
},
|
||||||
// 用户列表
|
// 用户列表
|
||||||
users: [],
|
users: [],
|
||||||
|
@ -170,8 +181,8 @@ export default {
|
||||||
params: [], // 模板的参数列表
|
params: [], // 模板的参数列表
|
||||||
},
|
},
|
||||||
sendNotifyRules: {
|
sendNotifyRules: {
|
||||||
mobile: [{ required: true, message: "手机不能为空", trigger: "blur" }],
|
userId: [{ required: true, message: "接收人不能为空", trigger: "blur" }],
|
||||||
templateCode: [{ required: true, message: "手机不能为空", trigger: "blur" }],
|
templateCode: [{ required: true, message: "模版编号不能为空", trigger: "blur" }],
|
||||||
templateParams: { }
|
templateParams: { }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -203,10 +214,13 @@ export default {
|
||||||
reset() {
|
reset() {
|
||||||
this.form = {
|
this.form = {
|
||||||
id: undefined,
|
id: undefined,
|
||||||
status: undefined,
|
name: undefined,
|
||||||
code: undefined,
|
code: undefined,
|
||||||
title: undefined,
|
nickname: undefined,
|
||||||
content: undefined,
|
content: undefined,
|
||||||
|
type: undefined,
|
||||||
|
params: undefined,
|
||||||
|
status: CommonStatusEnum.ENABLE,
|
||||||
remark: undefined,
|
remark: undefined,
|
||||||
};
|
};
|
||||||
this.resetForm("form");
|
this.resetForm("form");
|
||||||
|
@ -270,21 +284,6 @@ export default {
|
||||||
this.$modal.msgSuccess("删除成功");
|
this.$modal.msgSuccess("删除成功");
|
||||||
}).catch(() => {});
|
}).catch(() => {});
|
||||||
},
|
},
|
||||||
/** 导出按钮操作 */
|
|
||||||
handleExport() {
|
|
||||||
// 处理查询参数
|
|
||||||
let params = {...this.queryParams};
|
|
||||||
params.pageNo = undefined;
|
|
||||||
params.pageSize = undefined;
|
|
||||||
// 执行导出
|
|
||||||
this.$modal.confirm('是否确认导出所有站内信模板数据项?', "警告").then(() => {
|
|
||||||
this.exportLoading = true;
|
|
||||||
return exportNotifyTemplateExcel(params);
|
|
||||||
}).then(response => {
|
|
||||||
this.$download.excel(response, '短信模板.xls');
|
|
||||||
this.exportLoading = false;
|
|
||||||
}).catch(() => {});
|
|
||||||
},
|
|
||||||
/** 发送站内信按钮 */
|
/** 发送站内信按钮 */
|
||||||
handleSendNotify(row) {
|
handleSendNotify(row) {
|
||||||
this.resetSendNotify(row);
|
this.resetSendNotify(row);
|
Loading…
Reference in New Issue