feat(mp): 新增公众号消息模板功能
- 新增消息模板和模板发送记录的增删改查接口 - 新增消息模板和发送记录的分页查询及导出功能 - 新增批量发送模板消息功能 - 新增同步公众号模板功能 - 添加相关数据对象和错误码定义 - 扩展用户分页请求参数支持openid列表查询 - 完善模板消息相关的VO类和转换逻辑
This commit is contained in:
@@ -61,4 +61,7 @@ public interface ErrorCodeConstants {
|
|||||||
ErrorCode AUTO_REPLY_ADD_MESSAGE_FAIL_EXISTS = new ErrorCode(1_006_009_002, "操作失败,原因:已存在该消息类型的回复");
|
ErrorCode AUTO_REPLY_ADD_MESSAGE_FAIL_EXISTS = new ErrorCode(1_006_009_002, "操作失败,原因:已存在该消息类型的回复");
|
||||||
ErrorCode AUTO_REPLY_ADD_KEYWORD_FAIL_EXISTS = new ErrorCode(1_006_009_003, "操作失败,原因:已关在该关键字的回复");
|
ErrorCode AUTO_REPLY_ADD_KEYWORD_FAIL_EXISTS = new ErrorCode(1_006_009_003, "操作失败,原因:已关在该关键字的回复");
|
||||||
|
|
||||||
|
// ========== 公众号消息模板 1-006-010-000 ============
|
||||||
|
ErrorCode MSG_TEMPLATE_NOT_EXISTS = new ErrorCode(1_006_010_000, "消息模板不存在");
|
||||||
|
ErrorCode MSG_TEMPLATE_LOG_NOT_EXISTS = new ErrorCode(1_006_010_001, "微信模版消息发送记录不存在");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,136 @@
|
|||||||
|
package cn.iocoder.yudao.module.mp.controller.admin.template;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants.BAD_REQUEST;
|
||||||
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.error;
|
||||||
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
|
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.template.vo.MsgTemplateBatchReqVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.template.vo.MsgTemplatePageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.template.vo.MsgTemplateRespVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.template.vo.MsgTemplateSaveReqVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.dal.dataobject.template.MsgTemplateDO;
|
||||||
|
import cn.iocoder.yudao.module.mp.service.template.MsgTemplateService;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import me.chanjar.weixin.common.error.WxErrorException;
|
||||||
|
/**
|
||||||
|
* @author dengsl
|
||||||
|
*/
|
||||||
|
@Tag(name = "管理后台 - 消息模板")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/mp/template")
|
||||||
|
@Validated
|
||||||
|
public class MsgTemplateController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private MsgTemplateService msgTemplateService;
|
||||||
|
|
||||||
|
@PostMapping("/create")
|
||||||
|
@Operation(summary = "创建消息模板")
|
||||||
|
@PreAuthorize("@ss.hasPermission('mp:template:create')")
|
||||||
|
public CommonResult<Long> createMsgTemplate(@Valid @RequestBody MsgTemplateSaveReqVO createReqVO) {
|
||||||
|
return success(msgTemplateService.createMsgTemplate(createReqVO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/update")
|
||||||
|
@Operation(summary = "更新消息模板")
|
||||||
|
@PreAuthorize("@ss.hasPermission('mp:template:update')")
|
||||||
|
public CommonResult<Boolean> updateMsgTemplate(@Valid @RequestBody MsgTemplateSaveReqVO updateReqVO) {
|
||||||
|
msgTemplateService.updateMsgTemplate(updateReqVO);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/delete")
|
||||||
|
@Operation(summary = "删除消息模板")
|
||||||
|
@Parameter(name = "id", description = "编号", required = true)
|
||||||
|
@PreAuthorize("@ss.hasPermission('mp:template:delete')")
|
||||||
|
public CommonResult<Boolean> deleteMsgTemplate(@RequestParam("id") Long id) {
|
||||||
|
//msgTemplateService.deleteMsgTemplate(id);
|
||||||
|
//TODO 该逻辑没有实现 删除需要判断该消息模板是否被关联
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/delete-list")
|
||||||
|
@Parameter(name = "ids", description = "编号", required = true)
|
||||||
|
@Operation(summary = "批量删除消息模板")
|
||||||
|
@PreAuthorize("@ss.hasPermission('mp:template:delete')")
|
||||||
|
public CommonResult<Boolean> deleteMsgTemplateList(@RequestBody List<Long> ids) {
|
||||||
|
//msgTemplateService.deleteMsgTemplateListByIds(ids);
|
||||||
|
//TODO 该逻辑没有实现 删除需要判断该消息模板是否被关联
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/get")
|
||||||
|
@Operation(summary = "获得消息模板")
|
||||||
|
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||||
|
@PreAuthorize("@ss.hasPermission('mp:template:query')")
|
||||||
|
public CommonResult<MsgTemplateRespVO> getMsgTemplate(@RequestParam("id") Long id) {
|
||||||
|
MsgTemplateDO msgTemplate = msgTemplateService.getMsgTemplate(id);
|
||||||
|
return success(BeanUtils.toBean(msgTemplate, MsgTemplateRespVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/page")
|
||||||
|
@Operation(summary = "获得消息模板分页")
|
||||||
|
@PreAuthorize("@ss.hasPermission('mp:template:query')")
|
||||||
|
public CommonResult<PageResult<MsgTemplateRespVO>> getMsgTemplatePage(@Valid MsgTemplatePageReqVO pageReqVO) {
|
||||||
|
PageResult<MsgTemplateDO> pageResult = msgTemplateService.getMsgTemplatePage(pageReqVO);
|
||||||
|
return success(BeanUtils.toBean(pageResult, MsgTemplateRespVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/export-excel")
|
||||||
|
@Operation(summary = "导出消息模板 Excel")
|
||||||
|
@PreAuthorize("@ss.hasPermission('mp:template:export')")
|
||||||
|
@ApiAccessLog(operateType = EXPORT)
|
||||||
|
public void exportMsgTemplateExcel(@Valid MsgTemplatePageReqVO pageReqVO,
|
||||||
|
HttpServletResponse response) throws IOException {
|
||||||
|
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||||
|
List<MsgTemplateDO> list = msgTemplateService.getMsgTemplatePage(pageReqVO).getList();
|
||||||
|
// 导出 Excel
|
||||||
|
ExcelUtils.write(response, "消息模板.xls", "数据", MsgTemplateRespVO.class,
|
||||||
|
BeanUtils.toBean(list, MsgTemplateRespVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/syncMsgTemplate")
|
||||||
|
@Operation(summary = "同步公众号模板")
|
||||||
|
@PreAuthorize("@ss.hasPermission('mp:template:sync')")
|
||||||
|
public CommonResult<Boolean> syncWxTemplate(@RequestParam("accountId") Long accountId) throws WxErrorException {
|
||||||
|
msgTemplateService.syncWxTemplate(accountId);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量向用户发送模板消息
|
||||||
|
* 通过用户筛选条件(一般使用标签筛选),将消息发送给数据库中所有符合筛选条件的用户
|
||||||
|
*/
|
||||||
|
@PostMapping("/sendMsgBatch")
|
||||||
|
@Operation(summary = "批量向用户发送模板消息")
|
||||||
|
@PreAuthorize("@ss.hasPermission('mp:template:send')")
|
||||||
|
public CommonResult<Boolean> sendMsgBatch(@Valid @RequestBody MsgTemplateBatchReqVO batchReqVO) {
|
||||||
|
if (StrUtil.isEmpty(batchReqVO.getOpenid()) && StrUtil.isEmpty(batchReqVO.getUnionId())
|
||||||
|
&& StrUtil.isEmpty(batchReqVO.getNickname()) && CollUtil.isEmpty((batchReqVO.getOpenidList()))) {
|
||||||
|
return error(BAD_REQUEST.getCode(), "请选择用户");
|
||||||
|
}
|
||||||
|
msgTemplateService.sendMsgBatch(batchReqVO);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,105 @@
|
|||||||
|
package cn.iocoder.yudao.module.mp.controller.admin.template;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
|
||||||
|
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.apilog.core.annotation.ApiAccessLog;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
|
import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.template.vo.MsgTemplateLogPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.template.vo.MsgTemplateLogRespVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.template.vo.MsgTemplateLogSaveReqVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.dal.dataobject.template.MsgTemplateLogDO;
|
||||||
|
import cn.iocoder.yudao.module.mp.service.template.MsgTemplateLogService;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
/**
|
||||||
|
* @author dengsl
|
||||||
|
*/
|
||||||
|
@Tag(name = "管理后台 - 微信模版消息发送记录")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/mp/template/log")
|
||||||
|
@Validated
|
||||||
|
public class MsgTemplateLogController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private MsgTemplateLogService msgTemplateLogService;
|
||||||
|
|
||||||
|
@PostMapping("/create")
|
||||||
|
@Operation(summary = "创建微信模版消息发送记录")
|
||||||
|
@PreAuthorize("@ss.hasPermission('mp:template-log:create')")
|
||||||
|
public CommonResult<Long> createMsgTemplateLog(@Valid @RequestBody MsgTemplateLogSaveReqVO createReqVO) {
|
||||||
|
return success(msgTemplateLogService.createMsgTemplateLog(createReqVO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@PutMapping("/update")
|
||||||
|
@Operation(summary = "更新微信模版消息发送记录")
|
||||||
|
@PreAuthorize("@ss.hasPermission('mp:template-log:update')")
|
||||||
|
public CommonResult<Boolean> updateMsgTemplateLog(@Valid @RequestBody MsgTemplateLogSaveReqVO updateReqVO) {
|
||||||
|
msgTemplateLogService.updateMsgTemplateLog(updateReqVO);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/delete")
|
||||||
|
@Operation(summary = "删除微信模版消息发送记录")
|
||||||
|
@Parameter(name = "id", description = "编号", required = true)
|
||||||
|
@PreAuthorize("@ss.hasPermission('mp:template-log:delete')")
|
||||||
|
public CommonResult<Boolean> deleteMsgTemplateLog(@RequestParam("id") Long id) {
|
||||||
|
msgTemplateLogService.deleteMsgTemplateLog(id);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@DeleteMapping("/delete-list")
|
||||||
|
@Parameter(name = "ids", description = "编号", required = true)
|
||||||
|
@Operation(summary = "批量删除微信模版消息发送记录")
|
||||||
|
@PreAuthorize("@ss.hasPermission('mp:template-log:delete')")
|
||||||
|
public CommonResult<Boolean> deleteMsgTemplateLogList(@RequestParam("ids") List<Long> ids) {
|
||||||
|
msgTemplateLogService.deleteMsgTemplateLogListByIds(ids);
|
||||||
|
return success(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/get")
|
||||||
|
@Operation(summary = "获得微信模版消息发送记录")
|
||||||
|
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||||
|
@PreAuthorize("@ss.hasPermission('mp:template-log:query')")
|
||||||
|
public CommonResult<MsgTemplateLogRespVO> getMsgTemplateLog(@RequestParam("id") Long id) {
|
||||||
|
MsgTemplateLogDO msgTemplateLog = msgTemplateLogService.getMsgTemplateLog(id);
|
||||||
|
return success(BeanUtils.toBean(msgTemplateLog, MsgTemplateLogRespVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/page")
|
||||||
|
@Operation(summary = "获得微信模版消息发送记录分页")
|
||||||
|
@PreAuthorize("@ss.hasPermission('mp:template-log:query')")
|
||||||
|
public CommonResult<PageResult<MsgTemplateLogRespVO>> getMsgTemplateLogPage(@Valid MsgTemplateLogPageReqVO pageReqVO) {
|
||||||
|
PageResult<MsgTemplateLogDO> pageResult = msgTemplateLogService.getMsgTemplateLogPage(pageReqVO);
|
||||||
|
return success(BeanUtils.toBean(pageResult, MsgTemplateLogRespVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/export-excel")
|
||||||
|
@Operation(summary = "导出微信模版消息发送记录 Excel")
|
||||||
|
@PreAuthorize("@ss.hasPermission('mp:template-log:export')")
|
||||||
|
@ApiAccessLog(operateType = EXPORT)
|
||||||
|
public void exportMsgTemplateLogExcel(@Valid MsgTemplateLogPageReqVO pageReqVO,
|
||||||
|
HttpServletResponse response) throws IOException {
|
||||||
|
pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
|
||||||
|
List<MsgTemplateLogDO> list = msgTemplateLogService.getMsgTemplateLogPage(pageReqVO).getList();
|
||||||
|
// 导出 Excel
|
||||||
|
ExcelUtils.write(response, "微信模版消息发送记录.xls", "数据", MsgTemplateLogRespVO.class,
|
||||||
|
BeanUtils.toBean(list, MsgTemplateLogRespVO.class));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
package cn.iocoder.yudao.module.mp.controller.admin.template.vo;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.user.vo.MpUserPageReqVO;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dengsl
|
||||||
|
*/
|
||||||
|
@Schema(description = "管理后台 - 消息批量推送 Request VO")
|
||||||
|
@Data
|
||||||
|
public class MsgTemplateBatchReqVO extends MpUserPageReqVO {
|
||||||
|
|
||||||
|
@Schema(description = "appId", example = "9758")
|
||||||
|
@NotNull(message = "appId不能为空")
|
||||||
|
private String appId;
|
||||||
|
|
||||||
|
@Schema(description = "公众号模板ID", example = "14517")
|
||||||
|
@NotNull(message = "公众号模板ID不能为空")
|
||||||
|
private String templateId;
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package cn.iocoder.yudao.module.mp.controller.admin.template.vo;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dengsl
|
||||||
|
*/
|
||||||
|
@Schema(description = "管理后台 - 微信模版消息发送记录分页 Request VO")
|
||||||
|
@Data
|
||||||
|
public class MsgTemplateLogPageReqVO extends PageParam {
|
||||||
|
|
||||||
|
@Schema(description = "appId", example = "6914")
|
||||||
|
private String appId;
|
||||||
|
|
||||||
|
@Schema(description = "用户openid")
|
||||||
|
private String toUser;
|
||||||
|
|
||||||
|
@Schema(description = "公众号模板ID", example = "8374")
|
||||||
|
private String templateId;
|
||||||
|
|
||||||
|
@Schema(description = "消息内容")
|
||||||
|
private String data;
|
||||||
|
|
||||||
|
@Schema(description = "链接", example = "https://www.iocoder.cn")
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
@Schema(description = "小程序appid", example = "21567")
|
||||||
|
private String miniProgramAppId;
|
||||||
|
|
||||||
|
@Schema(description = "小程序页面路径")
|
||||||
|
private String miniProgramPagePath;
|
||||||
|
|
||||||
|
@Schema(description = "发送时间")
|
||||||
|
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||||
|
private LocalDateTime[] sendTime;
|
||||||
|
|
||||||
|
@Schema(description = "发送状态 0成功,1失败", example = "2")
|
||||||
|
private Integer sendStatus;
|
||||||
|
|
||||||
|
@Schema(description = "发送结果")
|
||||||
|
private String sendResult;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
|
||||||
|
private LocalDateTime[] createTime;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,66 @@
|
|||||||
|
package cn.iocoder.yudao.module.mp.controller.admin.template.vo;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||||
|
import cn.idev.excel.annotation.ExcelProperty;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author dengsl
|
||||||
|
*/
|
||||||
|
@Schema(description = "管理后台 - 微信模版消息发送记录 Response VO")
|
||||||
|
@Data
|
||||||
|
@ExcelIgnoreUnannotated
|
||||||
|
public class MsgTemplateLogRespVO {
|
||||||
|
|
||||||
|
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "22254")
|
||||||
|
@ExcelProperty("主键")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "appId", requiredMode = Schema.RequiredMode.REQUIRED, example = "6914")
|
||||||
|
@ExcelProperty("appId")
|
||||||
|
private String appId;
|
||||||
|
|
||||||
|
@Schema(description = "用户openid")
|
||||||
|
@ExcelProperty("用户openid")
|
||||||
|
private String toUser;
|
||||||
|
|
||||||
|
@Schema(description = "公众号模板ID", example = "8374")
|
||||||
|
@ExcelProperty("公众号模板ID")
|
||||||
|
private String templateId;
|
||||||
|
|
||||||
|
@Schema(description = "消息内容")
|
||||||
|
@ExcelProperty("消息内容")
|
||||||
|
private String data;
|
||||||
|
|
||||||
|
@Schema(description = "链接", example = "https://www.iocoder.cn")
|
||||||
|
@ExcelProperty("链接")
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
@Schema(description = "小程序appid", example = "21567")
|
||||||
|
@ExcelProperty("小程序appid")
|
||||||
|
private String miniProgramAppId;
|
||||||
|
|
||||||
|
@Schema(description = "小程序页面路径")
|
||||||
|
@ExcelProperty("小程序页面路径")
|
||||||
|
private String miniProgramPagePath;
|
||||||
|
|
||||||
|
@Schema(description = "发送时间")
|
||||||
|
@ExcelProperty("发送时间")
|
||||||
|
private LocalDateTime sendTime;
|
||||||
|
|
||||||
|
@Schema(description = "发送状态 0成功,1失败", example = "2")
|
||||||
|
@ExcelProperty("发送状态 0成功,1失败")
|
||||||
|
private String sendStatus;
|
||||||
|
|
||||||
|
@Schema(description = "发送结果")
|
||||||
|
@ExcelProperty("发送结果")
|
||||||
|
private String sendResult;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@ExcelProperty("创建时间")
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
package cn.iocoder.yudao.module.mp.controller.admin.template.vo;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
import lombok.Data;
|
||||||
|
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
|
||||||
|
/**
|
||||||
|
* @author dengsl
|
||||||
|
*/
|
||||||
|
@Schema(description = "管理后台 - 微信模版消息发送记录新增/修改 Request VO")
|
||||||
|
@Data
|
||||||
|
public class MsgTemplateLogSaveReqVO {
|
||||||
|
|
||||||
|
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "22254")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "appId", requiredMode = Schema.RequiredMode.REQUIRED, example = "6914")
|
||||||
|
@NotEmpty(message = "appId不能为空")
|
||||||
|
private String appId;
|
||||||
|
|
||||||
|
@Schema(description = "用户openid")
|
||||||
|
private String toUser;
|
||||||
|
|
||||||
|
@Schema(description = "公众号模板ID", example = "8374")
|
||||||
|
private String templateId;
|
||||||
|
|
||||||
|
@Schema(description = "消息内容")
|
||||||
|
private String data;
|
||||||
|
|
||||||
|
@Schema(description = "链接", example = "https://www.iocoder.cn")
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
@Schema(description = "小程序appid", example = "21567")
|
||||||
|
private String miniProgramAppId;
|
||||||
|
|
||||||
|
@Schema(description = "小程序页面路径")
|
||||||
|
private String miniProgramPagePath;
|
||||||
|
|
||||||
|
@Schema(description = "发送时间")
|
||||||
|
private LocalDateTime sendTime;
|
||||||
|
|
||||||
|
@Schema(description = "发送状态 0成功,1失败", example = "2")
|
||||||
|
private Integer sendStatus;
|
||||||
|
|
||||||
|
@Schema(description = "发送结果")
|
||||||
|
private String sendResult;
|
||||||
|
|
||||||
|
public MsgTemplateLogSaveReqVO(WxMpTemplateMessage msg, String appid, Integer sendStatus, String sendResult) {
|
||||||
|
this.appId = appid;
|
||||||
|
this.toUser = msg.getToUser();
|
||||||
|
this.templateId = msg.getTemplateId();
|
||||||
|
this.url = msg.getUrl();
|
||||||
|
if (ObjectUtil.isNotEmpty(msg.getMiniProgram())) {
|
||||||
|
this.miniProgramAppId = msg.getMiniProgram().getAppid();
|
||||||
|
this.miniProgramPagePath = msg.getMiniProgram().getPagePath();
|
||||||
|
}
|
||||||
|
this.sendStatus = sendStatus;
|
||||||
|
this.data = JSON.toJSONString(msg.getData());
|
||||||
|
this.sendTime = LocalDateTime.now();
|
||||||
|
this.sendResult = sendResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package cn.iocoder.yudao.module.mp.controller.admin.template.vo;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageParam;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
/**
|
||||||
|
* @author dengsl
|
||||||
|
*/
|
||||||
|
@Schema(description = "管理后台 - 消息模板分页 Request VO")
|
||||||
|
@Data
|
||||||
|
public class MsgTemplatePageReqVO extends PageParam {
|
||||||
|
|
||||||
|
@Schema(description = "appId", example = "9758")
|
||||||
|
private String appId;
|
||||||
|
|
||||||
|
@Schema(description = "公众号账号的编号", example = "9758")
|
||||||
|
private Long accountId;
|
||||||
|
|
||||||
|
@Schema(description = "公众号模板ID", example = "14517")
|
||||||
|
private String templateId;
|
||||||
|
|
||||||
|
@Schema(description = "模版名称", example = "赵六")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "标题")
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
@Schema(description = "模板内容")
|
||||||
|
private String content;
|
||||||
|
|
||||||
|
@Schema(description = "消息内容")
|
||||||
|
private String data;
|
||||||
|
|
||||||
|
@Schema(description = "链接", example = "https://www.iocoder.cn")
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
@Schema(description = "小程序appid")
|
||||||
|
private String miniProgramAppId;
|
||||||
|
|
||||||
|
@Schema(description = "小程序页面路径")
|
||||||
|
private String miniProgramPagePath;
|
||||||
|
|
||||||
|
@Schema(description = "是否有效", example = "1")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间")
|
||||||
|
private LocalDateTime[] createTime;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,78 @@
|
|||||||
|
package cn.iocoder.yudao.module.mp.controller.admin.template.vo;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import cn.idev.excel.annotation.ExcelIgnore;
|
||||||
|
import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
|
||||||
|
import cn.idev.excel.annotation.ExcelProperty;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
/**
|
||||||
|
* @author dengsl
|
||||||
|
*/
|
||||||
|
@Schema(description = "管理后台 - 消息模板 Response VO")
|
||||||
|
@Data
|
||||||
|
@ExcelIgnoreUnannotated
|
||||||
|
public class MsgTemplateRespVO {
|
||||||
|
|
||||||
|
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "7019")
|
||||||
|
@ExcelProperty("主键")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "appId", requiredMode = Schema.RequiredMode.REQUIRED, example = "9758")
|
||||||
|
@ExcelProperty("appId")
|
||||||
|
private String appId;
|
||||||
|
|
||||||
|
@Schema(description = "公众号模板ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "14517")
|
||||||
|
@ExcelProperty("公众号模板ID")
|
||||||
|
private String templateId;
|
||||||
|
|
||||||
|
@Schema(description = "模版名称", example = "赵六")
|
||||||
|
@ExcelProperty("模版名称")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "标题")
|
||||||
|
@ExcelProperty("标题")
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
@Schema(description = "模板内容")
|
||||||
|
@ExcelProperty("模板内容")
|
||||||
|
private String content;
|
||||||
|
|
||||||
|
@Schema(description = "消息内容")
|
||||||
|
@ExcelProperty("消息内容")
|
||||||
|
private String data;
|
||||||
|
|
||||||
|
@Schema(description = "链接", example = "https://www.iocoder.cn")
|
||||||
|
@ExcelProperty("链接")
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
@Schema(description = "小程序appId")
|
||||||
|
@ExcelProperty("小程序appId")
|
||||||
|
private String miniProgramAppId;
|
||||||
|
|
||||||
|
@Schema(description = "小程序页面路径")
|
||||||
|
@ExcelProperty("小程序页面路径")
|
||||||
|
private String miniProgramPagePath;
|
||||||
|
|
||||||
|
@Schema(description = "是否有效", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
@ExcelProperty("是否有效")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
@Schema(description = "公众号是否已移除 0未移除,1已移除", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
@ExcelProperty("公众号是否已移除")
|
||||||
|
private Integer isRemoved;
|
||||||
|
|
||||||
|
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||||
|
@ExcelProperty("创建时间")
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
|
||||||
|
@Schema(description = "模板消息配置id")
|
||||||
|
@ExcelIgnore
|
||||||
|
private Long configId;
|
||||||
|
|
||||||
|
@Schema(description = "模板类型")
|
||||||
|
@ExcelIgnore
|
||||||
|
private String templateType;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,56 @@
|
|||||||
|
package cn.iocoder.yudao.module.mp.controller.admin.template.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
|
import lombok.Data;
|
||||||
|
/**
|
||||||
|
* @author dengsl
|
||||||
|
*/
|
||||||
|
@Schema(description = "管理后台 - 消息模板新增/修改 Request VO")
|
||||||
|
@Data
|
||||||
|
public class MsgTemplateSaveReqVO {
|
||||||
|
|
||||||
|
@Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "7019")
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Schema(description = "appId", requiredMode = Schema.RequiredMode.REQUIRED, example = "9758")
|
||||||
|
@NotEmpty(message = "appId不能为空")
|
||||||
|
private String appId;
|
||||||
|
|
||||||
|
@Schema(description = "公众号模板ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "14517")
|
||||||
|
@NotEmpty(message = "公众号模板ID不能为空")
|
||||||
|
private String templateId;
|
||||||
|
|
||||||
|
@Schema(description = "模版名称", example = "赵六")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Schema(description = "标题")
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
@Schema(description = "模板内容")
|
||||||
|
private String content;
|
||||||
|
|
||||||
|
@Schema(description = "消息内容")
|
||||||
|
private String data;
|
||||||
|
|
||||||
|
@Schema(description = "链接", example = "https://www.iocoder.cn")
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
@Schema(description = "小程序appid")
|
||||||
|
private String miniProgramAppId;
|
||||||
|
|
||||||
|
@Schema(description = "小程序页面路径")
|
||||||
|
private String miniProgramPagePath;
|
||||||
|
|
||||||
|
@Schema(description = "模板所属行业的一级行业")
|
||||||
|
private String primaryIndustry;
|
||||||
|
|
||||||
|
@Schema(description = "模板所属行业的二级行业")
|
||||||
|
private String deputyIndustry;
|
||||||
|
|
||||||
|
@Schema(description = "是否有效", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||||
|
@NotNull(message = "是否有效不能为空")
|
||||||
|
private Integer status;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -7,6 +7,8 @@ import lombok.Data;
|
|||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.ToString;
|
import lombok.ToString;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Schema(description = "管理后台 - 公众号粉丝分页 Request VO")
|
@Schema(description = "管理后台 - 公众号粉丝分页 Request VO")
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@@ -26,4 +28,6 @@ public class MpUserPageReqVO extends PageParam {
|
|||||||
@Schema(description = "公众号粉丝昵称,模糊匹配", example = "芋艿")
|
@Schema(description = "公众号粉丝昵称,模糊匹配", example = "芋艿")
|
||||||
private String nickname;
|
private String nickname;
|
||||||
|
|
||||||
|
@Schema(description = "公众号粉丝标识", example = "o6_bmjrPTlm6_2sgVt7hMZOPfL2M")
|
||||||
|
private List<String> openidList;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import cn.hutool.core.date.LocalDateTimeUtil;
|
|||||||
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
|
||||||
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.mp.controller.admin.template.vo.MsgTemplateBatchReqVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.user.vo.MpUserPageReqVO;
|
||||||
import cn.iocoder.yudao.module.mp.controller.admin.user.vo.MpUserRespVO;
|
import cn.iocoder.yudao.module.mp.controller.admin.user.vo.MpUserRespVO;
|
||||||
import cn.iocoder.yudao.module.mp.controller.admin.user.vo.MpUserUpdateReqVO;
|
import cn.iocoder.yudao.module.mp.controller.admin.user.vo.MpUserUpdateReqVO;
|
||||||
import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
|
import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
|
||||||
@@ -23,6 +25,8 @@ public interface MpUserConvert {
|
|||||||
|
|
||||||
MpUserRespVO convert(MpUserDO bean);
|
MpUserRespVO convert(MpUserDO bean);
|
||||||
|
|
||||||
|
MpUserPageReqVO convert(MsgTemplateBatchReqVO bean);
|
||||||
|
|
||||||
List<MpUserRespVO> convertList(List<MpUserDO> list);
|
List<MpUserRespVO> convertList(List<MpUserDO> list);
|
||||||
|
|
||||||
PageResult<MpUserRespVO> convertPage(PageResult<MpUserDO> page);
|
PageResult<MpUserRespVO> convertPage(PageResult<MpUserDO> page);
|
||||||
|
|||||||
@@ -0,0 +1,92 @@
|
|||||||
|
package cn.iocoder.yudao.module.mp.dal.dataobject.template;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息模板 DO
|
||||||
|
*
|
||||||
|
* @author dengsl
|
||||||
|
*/
|
||||||
|
@TableName("mp_msg_template")
|
||||||
|
@KeySequence("mp_msg_template_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class MsgTemplateDO extends BaseDO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* appid
|
||||||
|
*/
|
||||||
|
private String appId;
|
||||||
|
/**
|
||||||
|
* 公众号模板ID
|
||||||
|
*/
|
||||||
|
private String templateId;
|
||||||
|
/**
|
||||||
|
* 模版名称
|
||||||
|
*/
|
||||||
|
private String name;
|
||||||
|
public String getName() {
|
||||||
|
return this.templateId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 标题
|
||||||
|
*/
|
||||||
|
private String title;
|
||||||
|
/**
|
||||||
|
* 模板内容
|
||||||
|
*/
|
||||||
|
private String content;
|
||||||
|
/**
|
||||||
|
* 消息内容
|
||||||
|
*/
|
||||||
|
private String data;
|
||||||
|
/**
|
||||||
|
* 链接
|
||||||
|
*/
|
||||||
|
private String url;
|
||||||
|
/**
|
||||||
|
* 小程序appid
|
||||||
|
*/
|
||||||
|
private String miniProgramAppId;
|
||||||
|
/**
|
||||||
|
* 小程序页面路径
|
||||||
|
*/
|
||||||
|
private String miniProgramPagePath;
|
||||||
|
/**
|
||||||
|
* 模板所属行业的一级行业
|
||||||
|
*/
|
||||||
|
private String primaryIndustry;
|
||||||
|
/**
|
||||||
|
* 模板所属行业的二级行业
|
||||||
|
*/
|
||||||
|
private String deputyIndustry;
|
||||||
|
/**
|
||||||
|
* 模板示例
|
||||||
|
*/
|
||||||
|
private String example;
|
||||||
|
/**
|
||||||
|
* 是否有效 0有效,1无效
|
||||||
|
*/
|
||||||
|
private Integer status;
|
||||||
|
/**
|
||||||
|
* 公众号是否已移除 0未移除,1已移除
|
||||||
|
*/
|
||||||
|
private Integer isRemoved;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
package cn.iocoder.yudao.module.mp.dal.dataobject.template;
|
||||||
|
|
||||||
|
import lombok.*;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.*;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信模版消息发送记录 DO
|
||||||
|
*
|
||||||
|
* @author dengsl
|
||||||
|
*/
|
||||||
|
@TableName("mp_msg_template_log")
|
||||||
|
@KeySequence("mp_msg_template_log_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
@Builder
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class MsgTemplateLogDO extends BaseDO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 主键
|
||||||
|
*/
|
||||||
|
@TableId
|
||||||
|
private Long id;
|
||||||
|
/**
|
||||||
|
* appId
|
||||||
|
*/
|
||||||
|
private String appId;
|
||||||
|
/**
|
||||||
|
* 用户openid
|
||||||
|
*/
|
||||||
|
private String toUser;
|
||||||
|
/**
|
||||||
|
* 公众号模板ID
|
||||||
|
*/
|
||||||
|
private String templateId;
|
||||||
|
/**
|
||||||
|
* 消息内容
|
||||||
|
*/
|
||||||
|
private String data;
|
||||||
|
/**
|
||||||
|
* 链接
|
||||||
|
*/
|
||||||
|
private String url;
|
||||||
|
/**
|
||||||
|
* 小程序appid
|
||||||
|
*/
|
||||||
|
private String miniProgramAppId;
|
||||||
|
/**
|
||||||
|
* 小程序页面路径
|
||||||
|
*/
|
||||||
|
private String miniProgramPagePath;
|
||||||
|
/**
|
||||||
|
* 发送时间
|
||||||
|
*/
|
||||||
|
private LocalDateTime sendTime;
|
||||||
|
/**
|
||||||
|
* 发送状态 0成功,1失败
|
||||||
|
*/
|
||||||
|
private Integer sendStatus;
|
||||||
|
/**
|
||||||
|
* 发送结果
|
||||||
|
*/
|
||||||
|
private String sendResult;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package cn.iocoder.yudao.module.mp.dal.mysql.template;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.template.vo.MsgTemplateLogPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.dal.dataobject.template.MsgTemplateLogDO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信模版消息发送记录 Mapper
|
||||||
|
*
|
||||||
|
* @author dengsl
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface MsgTemplateLogMapper extends BaseMapperX<MsgTemplateLogDO> {
|
||||||
|
|
||||||
|
default PageResult<MsgTemplateLogDO> selectPage(MsgTemplateLogPageReqVO reqVO) {
|
||||||
|
return selectPage(reqVO, new LambdaQueryWrapperX<MsgTemplateLogDO>()
|
||||||
|
.eqIfPresent(MsgTemplateLogDO::getAppId, reqVO.getAppId())
|
||||||
|
.eqIfPresent(MsgTemplateLogDO::getToUser, reqVO.getToUser())
|
||||||
|
.eqIfPresent(MsgTemplateLogDO::getTemplateId, reqVO.getTemplateId())
|
||||||
|
.eqIfPresent(MsgTemplateLogDO::getData, reqVO.getData())
|
||||||
|
.eqIfPresent(MsgTemplateLogDO::getUrl, reqVO.getUrl())
|
||||||
|
.eqIfPresent(MsgTemplateLogDO::getMiniProgramAppId, reqVO.getMiniProgramAppId())
|
||||||
|
.eqIfPresent(MsgTemplateLogDO::getMiniProgramPagePath, reqVO.getMiniProgramPagePath())
|
||||||
|
.betweenIfPresent(MsgTemplateLogDO::getSendTime, reqVO.getSendTime())
|
||||||
|
.eqIfPresent(MsgTemplateLogDO::getSendStatus, reqVO.getSendStatus())
|
||||||
|
.eqIfPresent(MsgTemplateLogDO::getSendResult, reqVO.getSendResult())
|
||||||
|
.betweenIfPresent(MsgTemplateLogDO::getCreateTime, reqVO.getCreateTime())
|
||||||
|
.orderByDesc(MsgTemplateLogDO::getId));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package cn.iocoder.yudao.module.mp.dal.mysql.template;
|
||||||
|
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.template.vo.MsgTemplatePageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.dal.dataobject.template.MsgTemplateDO;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息模板 Mapper
|
||||||
|
*
|
||||||
|
* @author dengsl
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface MsgTemplateMapper extends BaseMapperX<MsgTemplateDO> {
|
||||||
|
|
||||||
|
default PageResult<MsgTemplateDO> selectPage(MsgTemplatePageReqVO reqVO) {
|
||||||
|
return selectPage(reqVO, new LambdaQueryWrapperX<MsgTemplateDO>()
|
||||||
|
.eqIfPresent(MsgTemplateDO::getAppId, reqVO.getAppId())
|
||||||
|
.eqIfPresent(MsgTemplateDO::getTemplateId, reqVO.getTemplateId())
|
||||||
|
.likeIfPresent(MsgTemplateDO::getName, reqVO.getName())
|
||||||
|
.eqIfPresent(MsgTemplateDO::getTitle, reqVO.getTitle())
|
||||||
|
.eqIfPresent(MsgTemplateDO::getContent, reqVO.getContent())
|
||||||
|
.eqIfPresent(MsgTemplateDO::getData, reqVO.getData())
|
||||||
|
.eqIfPresent(MsgTemplateDO::getUrl, reqVO.getUrl())
|
||||||
|
.eqIfPresent(MsgTemplateDO::getMiniProgramAppId, reqVO.getMiniProgramAppId())
|
||||||
|
.eqIfPresent(MsgTemplateDO::getMiniProgramPagePath, reqVO.getMiniProgramPagePath())
|
||||||
|
.eqIfPresent(MsgTemplateDO::getStatus, reqVO.getStatus())
|
||||||
|
.betweenIfPresent(MsgTemplateDO::getCreateTime, reqVO.getCreateTime())
|
||||||
|
.orderByDesc(MsgTemplateDO::getId));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package cn.iocoder.yudao.module.mp.service.template;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.template.vo.MsgTemplateLogPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.template.vo.MsgTemplateLogSaveReqVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.dal.dataobject.template.MsgTemplateLogDO;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信模版消息发送记录 Service 接口
|
||||||
|
*
|
||||||
|
* @author dengsl
|
||||||
|
*/
|
||||||
|
public interface MsgTemplateLogService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建微信模版消息发送记录
|
||||||
|
*
|
||||||
|
* @param createReqVO 创建信息
|
||||||
|
* @return 编号
|
||||||
|
*/
|
||||||
|
Long createMsgTemplateLog(@Valid MsgTemplateLogSaveReqVO createReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新微信模版消息发送记录
|
||||||
|
*
|
||||||
|
* @param updateReqVO 更新信息
|
||||||
|
*/
|
||||||
|
void updateMsgTemplateLog(@Valid MsgTemplateLogSaveReqVO updateReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除微信模版消息发送记录
|
||||||
|
*
|
||||||
|
* @param id 编号
|
||||||
|
*/
|
||||||
|
void deleteMsgTemplateLog(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除微信模版消息发送记录
|
||||||
|
*
|
||||||
|
* @param ids 编号
|
||||||
|
*/
|
||||||
|
void deleteMsgTemplateLogListByIds(List<Long> ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得微信模版消息发送记录
|
||||||
|
*
|
||||||
|
* @param id 编号
|
||||||
|
* @return 微信模版消息发送记录
|
||||||
|
*/
|
||||||
|
MsgTemplateLogDO getMsgTemplateLog(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得微信模版消息发送记录分页
|
||||||
|
*
|
||||||
|
* @param pageReqVO 分页查询
|
||||||
|
* @return 微信模版消息发送记录分页
|
||||||
|
*/
|
||||||
|
PageResult<MsgTemplateLogDO> getMsgTemplateLogPage(MsgTemplateLogPageReqVO pageReqVO);
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
package cn.iocoder.yudao.module.mp.service.template;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
|
import static cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants.MSG_TEMPLATE_LOG_NOT_EXISTS;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.template.vo.MsgTemplateLogPageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.template.vo.MsgTemplateLogSaveReqVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.dal.dataobject.template.MsgTemplateLogDO;
|
||||||
|
import cn.iocoder.yudao.module.mp.dal.mysql.template.MsgTemplateLogMapper;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信模版消息发送记录 Service 实现类
|
||||||
|
*
|
||||||
|
* @author dengsl
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Validated
|
||||||
|
public class MsgTemplateLogServiceImpl implements MsgTemplateLogService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private MsgTemplateLogMapper msgTemplateLogMapper;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long createMsgTemplateLog(MsgTemplateLogSaveReqVO createReqVO) {
|
||||||
|
// 插入
|
||||||
|
MsgTemplateLogDO msgTemplateLog = BeanUtils.toBean(createReqVO, MsgTemplateLogDO.class);
|
||||||
|
msgTemplateLogMapper.insert(msgTemplateLog);
|
||||||
|
// 返回
|
||||||
|
return msgTemplateLog.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateMsgTemplateLog(MsgTemplateLogSaveReqVO updateReqVO) {
|
||||||
|
// 校验存在
|
||||||
|
validateMsgTemplateLogExists(updateReqVO.getId());
|
||||||
|
// 更新
|
||||||
|
MsgTemplateLogDO updateObj = BeanUtils.toBean(updateReqVO, MsgTemplateLogDO.class);
|
||||||
|
msgTemplateLogMapper.updateById(updateObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteMsgTemplateLog(Long id) {
|
||||||
|
// 校验存在
|
||||||
|
validateMsgTemplateLogExists(id);
|
||||||
|
// 删除
|
||||||
|
msgTemplateLogMapper.deleteById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteMsgTemplateLogListByIds(List<Long> ids) {
|
||||||
|
// 校验存在
|
||||||
|
validateMsgTemplateLogExists(ids);
|
||||||
|
// 删除
|
||||||
|
msgTemplateLogMapper.deleteByIds(ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateMsgTemplateLogExists(List<Long> ids) {
|
||||||
|
List<MsgTemplateLogDO> list = msgTemplateLogMapper.selectByIds(ids);
|
||||||
|
if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
|
||||||
|
throw exception(MSG_TEMPLATE_LOG_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateMsgTemplateLogExists(Long id) {
|
||||||
|
if (msgTemplateLogMapper.selectById(id) == null) {
|
||||||
|
throw exception(MSG_TEMPLATE_LOG_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MsgTemplateLogDO getMsgTemplateLog(Long id) {
|
||||||
|
return msgTemplateLogMapper.selectById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageResult<MsgTemplateLogDO> getMsgTemplateLogPage(MsgTemplateLogPageReqVO pageReqVO) {
|
||||||
|
return msgTemplateLogMapper.selectPage(pageReqVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
package cn.iocoder.yudao.module.mp.service.template;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.template.vo.MsgTemplateBatchReqVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.template.vo.MsgTemplatePageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.template.vo.MsgTemplateSaveReqVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.dal.dataobject.template.MsgTemplateDO;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import me.chanjar.weixin.common.error.WxErrorException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息模板 Service 接口
|
||||||
|
*
|
||||||
|
* @author dengsl
|
||||||
|
*/
|
||||||
|
public interface MsgTemplateService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建消息模板
|
||||||
|
*
|
||||||
|
* @param createReqVO 创建信息
|
||||||
|
* @return 编号
|
||||||
|
*/
|
||||||
|
Long createMsgTemplate(@Valid MsgTemplateSaveReqVO createReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新消息模板
|
||||||
|
*
|
||||||
|
* @param updateReqVO 更新信息
|
||||||
|
*/
|
||||||
|
void updateMsgTemplate(@Valid MsgTemplateSaveReqVO updateReqVO);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除消息模板
|
||||||
|
*
|
||||||
|
* @param id 编号
|
||||||
|
*/
|
||||||
|
void deleteMsgTemplate(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量删除消息模板
|
||||||
|
*
|
||||||
|
* @param ids 编号
|
||||||
|
*/
|
||||||
|
void deleteMsgTemplateListByIds(List<Long> ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得消息模板
|
||||||
|
*
|
||||||
|
* @param id 编号
|
||||||
|
* @return 消息模板
|
||||||
|
*/
|
||||||
|
MsgTemplateDO getMsgTemplate(Long id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得消息模板分页
|
||||||
|
*
|
||||||
|
* @param pageReqVO 分页查询
|
||||||
|
* @return 消息模板分页
|
||||||
|
*/
|
||||||
|
PageResult<MsgTemplateDO> getMsgTemplatePage(MsgTemplatePageReqVO pageReqVO);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 同步公众号已添加的消息模板
|
||||||
|
*
|
||||||
|
* @throws WxErrorException
|
||||||
|
*/
|
||||||
|
void syncWxTemplate(Long accountId) throws WxErrorException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得公众号已添加的消息模板
|
||||||
|
*
|
||||||
|
* @param appId 公众号 AppId
|
||||||
|
* @return 模板列表
|
||||||
|
*/
|
||||||
|
MsgTemplateDO getWxTemplate(String appId, String templateId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量消息发送
|
||||||
|
*
|
||||||
|
* @param batchReqVO
|
||||||
|
*/
|
||||||
|
void sendMsgBatch(MsgTemplateBatchReqVO batchReqVO);
|
||||||
|
}
|
||||||
@@ -0,0 +1,313 @@
|
|||||||
|
package cn.iocoder.yudao.module.mp.service.template;
|
||||||
|
|
||||||
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
|
import static cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants.MSG_TEMPLATE_NOT_EXISTS;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Optional;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import cn.hutool.core.text.CharSequenceUtil;
|
||||||
|
import cn.iocoder.yudao.module.mp.framework.mp.core.MpServiceFactory;
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
|
import com.github.yulichang.toolkit.MPJWrappers;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.iocoder.yudao.framework.common.exception.ServiceException;
|
||||||
|
import cn.iocoder.yudao.framework.common.exception.enums.GlobalErrorCodeConstants;
|
||||||
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
|
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.template.vo.MsgTemplateBatchReqVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.template.vo.MsgTemplateLogSaveReqVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.template.vo.MsgTemplatePageReqVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.controller.admin.template.vo.MsgTemplateSaveReqVO;
|
||||||
|
import cn.iocoder.yudao.module.mp.convert.user.MpUserConvert;
|
||||||
|
import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
|
||||||
|
import cn.iocoder.yudao.module.mp.dal.dataobject.template.MsgTemplateDO;
|
||||||
|
import cn.iocoder.yudao.module.mp.dal.dataobject.user.MpUserDO;
|
||||||
|
import cn.iocoder.yudao.module.mp.dal.mysql.template.MsgTemplateMapper;
|
||||||
|
import cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants;
|
||||||
|
import cn.iocoder.yudao.module.mp.service.account.MpAccountService;
|
||||||
|
import cn.iocoder.yudao.module.mp.service.user.MpUserService;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import me.chanjar.weixin.common.error.WxErrorException;
|
||||||
|
import me.chanjar.weixin.mp.bean.template.WxMpTemplate;
|
||||||
|
import me.chanjar.weixin.mp.bean.template.WxMpTemplateData;
|
||||||
|
import me.chanjar.weixin.mp.bean.template.WxMpTemplateMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 消息模板 Service 实现类
|
||||||
|
*
|
||||||
|
* @author dengsl
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
@Validated
|
||||||
|
@Slf4j
|
||||||
|
public class MsgTemplateServiceImpl implements MsgTemplateService {
|
||||||
|
@Resource
|
||||||
|
@Lazy // 延迟加载,为了解决延迟加载
|
||||||
|
private MpServiceFactory mpServiceFactory;
|
||||||
|
@Resource
|
||||||
|
private MsgTemplateMapper msgTemplateMapper;
|
||||||
|
@Resource
|
||||||
|
private MpUserService mpUserService;
|
||||||
|
@Resource
|
||||||
|
private MpAccountService mpAccountService;
|
||||||
|
@Resource
|
||||||
|
private MsgTemplateLogService msgTemplateLogService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long createMsgTemplate(MsgTemplateSaveReqVO createReqVO) {
|
||||||
|
// 插入
|
||||||
|
MsgTemplateDO msgTemplate = BeanUtils.toBean(createReqVO, MsgTemplateDO.class);
|
||||||
|
msgTemplateMapper.insert(msgTemplate);
|
||||||
|
// 返回
|
||||||
|
return msgTemplate.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateMsgTemplate(MsgTemplateSaveReqVO updateReqVO) {
|
||||||
|
// 校验存在
|
||||||
|
validateMsgTemplateExists(updateReqVO.getId());
|
||||||
|
// 更新
|
||||||
|
MsgTemplateDO updateObj = BeanUtils.toBean(updateReqVO, MsgTemplateDO.class);
|
||||||
|
msgTemplateMapper.updateById(updateObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteMsgTemplate(Long id) {
|
||||||
|
// 校验存在
|
||||||
|
validateMsgTemplateExists(id);
|
||||||
|
// 删除
|
||||||
|
msgTemplateMapper.deleteById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteMsgTemplateListByIds(List<Long> ids) {
|
||||||
|
// 校验存在
|
||||||
|
validateMsgTemplateExists(ids);
|
||||||
|
// 删除
|
||||||
|
msgTemplateMapper.deleteByIds(ids);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateMsgTemplateExists(List<Long> ids) {
|
||||||
|
List<MsgTemplateDO> list = msgTemplateMapper.selectByIds(ids);
|
||||||
|
if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
|
||||||
|
throw exception(MSG_TEMPLATE_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateMsgTemplateExists(Long id) {
|
||||||
|
if (msgTemplateMapper.selectById(id) == null) {
|
||||||
|
throw exception(MSG_TEMPLATE_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MsgTemplateDO getMsgTemplate(Long id) {
|
||||||
|
return msgTemplateMapper.selectById(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PageResult<MsgTemplateDO> getMsgTemplatePage(MsgTemplatePageReqVO pageReqVO) {
|
||||||
|
MpAccountDO account = mpAccountService.getAccount(pageReqVO.getAccountId());
|
||||||
|
if (account == null) {
|
||||||
|
throw exception(ErrorCodeConstants.ACCOUNT_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
pageReqVO.setAppId(account.getAppId());
|
||||||
|
return msgTemplateMapper.selectPage(pageReqVO);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void syncWxTemplate(Long accountId) throws WxErrorException {
|
||||||
|
// 1. 处理新增的模板(在微信中存在但在数据库中不存在)
|
||||||
|
// 2. 处理已删除的模板(在数据库中存在但在微信中不存在)
|
||||||
|
// 3. 处理已存在的模板(在两边都存在)- 更新
|
||||||
|
MpAccountDO mpAccountDO = mpAccountService.getAccount(accountId);
|
||||||
|
String appId = mpAccountDO.getAppId();
|
||||||
|
List<WxMpTemplate> wxTemplates = mpServiceFactory.getRequiredMpService(appId).getTemplateMsgService().getAllPrivateTemplate();
|
||||||
|
if (CollUtil.isNotEmpty(wxTemplates)) {
|
||||||
|
List<MsgTemplateDO> dbTemplates = msgTemplateMapper.selectList(new QueryWrapper<MsgTemplateDO>()
|
||||||
|
.lambda().eq(MsgTemplateDO::getAppId, appId));
|
||||||
|
// 将微信模板转换为Map,便于查找
|
||||||
|
Map<String, WxMpTemplate> wxTemplateMap = wxTemplates.stream()
|
||||||
|
.collect(Collectors.toMap(WxMpTemplate::getTemplateId, Function.identity()));
|
||||||
|
|
||||||
|
// 将数据库模板转换为Map,便于查找
|
||||||
|
Map<String, MsgTemplateDO> dbTemplateMap = dbTemplates.stream()
|
||||||
|
.collect(Collectors.toMap(MsgTemplateDO::getTemplateId, Function.identity()));
|
||||||
|
|
||||||
|
// 1. 处理新增的模板(在微信中存在但在数据库中不存在)
|
||||||
|
handleNewTemplates(appId, wxTemplateMap, dbTemplateMap);
|
||||||
|
// 2. 处理已删除的模板(在数据库中存在但在微信中不存在)
|
||||||
|
handleDeletedTemplates(wxTemplateMap, dbTemplateMap);
|
||||||
|
// 3. 处理已存在的模板(在两边都存在)- 清空已设置的信息
|
||||||
|
handleUpdatedTemplates(wxTemplateMap, dbTemplateMap);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log.info("没有模板 appId {} ", appId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理新增的模板
|
||||||
|
*/
|
||||||
|
private void handleNewTemplates(String appId, Map<String, WxMpTemplate> wxTemplateMap,
|
||||||
|
Map<String, MsgTemplateDO> dbTemplateMap) {
|
||||||
|
List<MsgTemplateDO> newTemplates = new ArrayList<>();
|
||||||
|
wxTemplateMap.forEach((templateId, wxTemplate) -> {
|
||||||
|
if (!dbTemplateMap.containsKey(templateId)) {
|
||||||
|
MsgTemplateDO newTemplate = new MsgTemplateDO()
|
||||||
|
.setAppId(appId)
|
||||||
|
.setTemplateId(templateId)
|
||||||
|
.setTitle(wxTemplate.getTitle())
|
||||||
|
.setPrimaryIndustry(wxTemplate.getPrimaryIndustry())
|
||||||
|
.setDeputyIndustry(wxTemplate.getDeputyIndustry())
|
||||||
|
.setContent(wxTemplate.getContent())
|
||||||
|
.setExample(wxTemplate.getExample());
|
||||||
|
newTemplates.add(newTemplate);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (CollUtil.isNotEmpty(newTemplates)) {
|
||||||
|
msgTemplateMapper.insertBatch(newTemplates);
|
||||||
|
log.info("批量新增公众号模板: appId={}, count={}", appId, newTemplates.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理已删除的模板
|
||||||
|
*/
|
||||||
|
private void handleDeletedTemplates(Map<String, WxMpTemplate> wxTemplateMap,
|
||||||
|
Map<String, MsgTemplateDO> dbTemplateMap) {
|
||||||
|
List<MsgTemplateDO> removedTemplates = new ArrayList<>();
|
||||||
|
dbTemplateMap.forEach((templateId, dbTemplate) -> {
|
||||||
|
if (!wxTemplateMap.containsKey(templateId) && dbTemplate.getIsRemoved() == 0) {
|
||||||
|
dbTemplate.setIsRemoved(1);
|
||||||
|
removedTemplates.add(dbTemplate);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (CollUtil.isNotEmpty(removedTemplates)) {
|
||||||
|
msgTemplateMapper.update(new LambdaUpdateWrapper<MsgTemplateDO>()
|
||||||
|
.set(MsgTemplateDO::getIsRemoved, 1)
|
||||||
|
.in(MsgTemplateDO::getId, removedTemplates.stream().map(MsgTemplateDO::getId).collect(Collectors.toList())));
|
||||||
|
log.info("批量标记公众号模板为已删除: count={}", removedTemplates.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理已存在的模板(在两边都存在)- 清空已设置的信息
|
||||||
|
*/
|
||||||
|
private void handleUpdatedTemplates(Map<String, WxMpTemplate> wxTemplateMap,
|
||||||
|
Map<String, MsgTemplateDO> dbTemplateMap) {
|
||||||
|
List<Long> updatedIds = new ArrayList<>();
|
||||||
|
dbTemplateMap.forEach((templateId, dbTemplate) -> {
|
||||||
|
WxMpTemplate wxTemplate = wxTemplateMap.get(templateId);
|
||||||
|
if (wxTemplate != null) {
|
||||||
|
// 更新数据库模板信息
|
||||||
|
updatedIds.add(dbTemplate.getId());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
if (CollUtil.isNotEmpty(updatedIds)) {
|
||||||
|
msgTemplateMapper.update(new LambdaUpdateWrapper<MsgTemplateDO>()
|
||||||
|
.set(MsgTemplateDO::getData, null)
|
||||||
|
.set(MsgTemplateDO::getUrl, null)
|
||||||
|
.set(MsgTemplateDO::getMiniProgramAppId, null)
|
||||||
|
.set(MsgTemplateDO::getMiniProgramPagePath, null)
|
||||||
|
.set(MsgTemplateDO::getExample, null)
|
||||||
|
.in(MsgTemplateDO::getId, updatedIds));
|
||||||
|
log.info("批量更新公众号模板: count={}", updatedIds.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MsgTemplateDO getWxTemplate(String appId, String templateId) {
|
||||||
|
return msgTemplateMapper.selectOne(new LambdaQueryWrapperX<MsgTemplateDO>()
|
||||||
|
.eq(MsgTemplateDO::getAppId, appId)
|
||||||
|
.eq(CharSequenceUtil.isNotEmpty(templateId), MsgTemplateDO::getTemplateId, templateId));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMsgBatch(MsgTemplateBatchReqVO batchReqVO) {
|
||||||
|
log.info("批量发送模板消息任务开始, 参数:{}", batchReqVO);
|
||||||
|
|
||||||
|
// 获取微信模板信息
|
||||||
|
MsgTemplateDO msgTemplateDO = getWxTemplate(batchReqVO.getAppId(), batchReqVO.getTemplateId());
|
||||||
|
if (ObjectUtil.isNull(msgTemplateDO)) {
|
||||||
|
log.error("未找到对应的模板信息, appId: {}, templateId: {}", batchReqVO.getAppId(), batchReqVO.getTemplateId());
|
||||||
|
throw exception(MSG_TEMPLATE_NOT_EXISTS);
|
||||||
|
}
|
||||||
|
if (msgTemplateDO.getIsRemoved() == 1) {
|
||||||
|
throw new ServiceException(GlobalErrorCodeConstants.ERROR_CONFIGURATION.getCode(), "模板未发布");
|
||||||
|
}
|
||||||
|
if (msgTemplateDO.getStatus() == 1) {
|
||||||
|
throw new ServiceException(GlobalErrorCodeConstants.ERROR_CONFIGURATION.getCode(), "模板无效");
|
||||||
|
}
|
||||||
|
// 构建基础模板消息
|
||||||
|
WxMpTemplateMessage.WxMpTemplateMessageBuilder builder = WxMpTemplateMessage.builder()
|
||||||
|
.templateId(msgTemplateDO.getTemplateId())
|
||||||
|
.url(msgTemplateDO.getUrl())
|
||||||
|
.miniProgram(new WxMpTemplateMessage.MiniProgram(
|
||||||
|
msgTemplateDO.getMiniProgramAppId(),
|
||||||
|
msgTemplateDO.getMiniProgramPagePath(),
|
||||||
|
false))
|
||||||
|
.data(JSON.parseArray(msgTemplateDO.getData(), WxMpTemplateData.class));
|
||||||
|
|
||||||
|
int currentPage = 1;
|
||||||
|
long totalPages = Long.MAX_VALUE;
|
||||||
|
|
||||||
|
while (currentPage <= totalPages) {
|
||||||
|
// 按条件查询用户
|
||||||
|
batchReqVO.setPageNo(currentPage);
|
||||||
|
batchReqVO.setPageSize(500);
|
||||||
|
|
||||||
|
PageResult<MpUserDO> wxUsers = mpUserService.getUserPage(MpUserConvert.INSTANCE.convert(batchReqVO));
|
||||||
|
log.info("批量发送模板消息任务, 使用查询条件,处理第{}页,总用户数:{}", currentPage, wxUsers.getTotal());
|
||||||
|
|
||||||
|
// 如果没有用户数据,直接退出循环
|
||||||
|
if (CollUtil.isEmpty(wxUsers.getList())) {
|
||||||
|
log.warn("当前页无用户数据,结束处理, 当前页:{}", currentPage);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 遍历用户并发送模板消息
|
||||||
|
wxUsers.getList().forEach(user -> {
|
||||||
|
WxMpTemplateMessage wxMpTemplateMessage = builder.toUser(user.getOpenid()).build();
|
||||||
|
try {
|
||||||
|
String result = mpServiceFactory.getRequiredMpService(batchReqVO.getAppId()).getTemplateMsgService().sendTemplateMsg(wxMpTemplateMessage);
|
||||||
|
|
||||||
|
//保存发送日志
|
||||||
|
MsgTemplateLogSaveReqVO log = new MsgTemplateLogSaveReqVO(wxMpTemplateMessage, batchReqVO.getAppId(), 0, result);
|
||||||
|
msgTemplateLogService.createMsgTemplateLog(log);
|
||||||
|
} catch (WxErrorException e) {
|
||||||
|
log.error("发送模板消息失败, 用户OpenId: {}, 错误信息: {}", user.getOpenid(), e.getMessage(), e);
|
||||||
|
// 可以选择继续处理其他用户,而不是直接抛出异常
|
||||||
|
//保存发送日志
|
||||||
|
MsgTemplateLogSaveReqVO log = new MsgTemplateLogSaveReqVO(wxMpTemplateMessage, batchReqVO.getAppId(), 1, e.getMessage());
|
||||||
|
msgTemplateLogService.createMsgTemplateLog(log);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 更新分页参数
|
||||||
|
currentPage++;
|
||||||
|
// 计算总页数
|
||||||
|
totalPages = (wxUsers.getTotal() + batchReqVO.getPageSize() - 1) / batchReqVO.getPageSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("批量发送模板消息任务完成");
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user