Преглед изворни кода

确认微信模板信息是否发送

Yangzw пре 10 месеци
родитељ
комит
b1308e747a
46 измењених фајлова са 1561 додато и 42 уклоњено
  1. 2 0
      feifan-module-mall/feifan-module-trade-api/src/main/java/cn/newfeifan/mall/module/trade/enums/ErrorCodeConstants.java
  2. 14 0
      feifan-module-mall/feifan-module-trade-api/src/main/java/cn/newfeifan/mall/module/trade/enums/MessageTemplateConstants.java
  3. 20 0
      feifan-module-mall/feifan-module-trade-api/src/main/java/cn/newfeifan/mall/module/trade/enums/wxmessage/WcChatMessageTemplateIdEnum.java
  4. 93 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/controller/admin/messagelog/MessageLogController.java
  5. 52 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/controller/admin/messagelog/vo/MessageLogPageReqVO.java
  6. 59 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/controller/admin/messagelog/vo/MessageLogRespVO.java
  7. 48 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/controller/admin/messagelog/vo/MessageLogSaveReqVO.java
  8. 7 11
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/controller/admin/order/TradeOrderController.java
  9. 68 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/dal/dataobject/messagelog/MessageLogDO.java
  10. 33 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/dal/mysql/messagelog/MessageLogMapper.java
  11. 7 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/dal/mysql/order/TradeOrderItemMapper.java
  12. 1 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/service/delivery/DeliveryExpressService.java
  13. 5 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/service/delivery/DeliveryExpressServiceImpl.java
  14. 55 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/service/messagelog/MessageLogService.java
  15. 71 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/service/messagelog/MessageLogServiceImpl.java
  16. 15 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/service/order/TradeOrderUpdateServiceImpl.java
  17. 13 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/utils/wechat/WcChatMessageDto.java
  18. 266 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/utils/wechat/WcChatMessageUtils.java
  19. 36 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/utils/wechat/WeChatTemplateMessage.java
  20. 12 0
      feifan-module-mall/feifan-module-trade-biz/src/main/resources/mapper/messagelog/MessageLogMapper.xml
  21. 2 0
      feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/service/user/MemberUserService.java
  22. 6 0
      feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/service/user/MemberUserServiceImpl.java
  23. 10 0
      feifan-module-system/feifan-module-system-api/src/main/java/cn/newfeifan/mall/module/system/constant/SystemConstants.java
  24. 2 0
      feifan-module-system/feifan-module-system-api/src/main/java/cn/newfeifan/mall/module/system/enums/ErrorCodeConstants.java
  25. 62 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/config/StartConfig.java
  26. 93 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/config/SystemConfigController.java
  27. 31 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/config/bo/SystemConfigBO.java
  28. 39 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/config/vo/ConfigPageReqVO.java
  29. 43 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/config/vo/ConfigRespVO.java
  30. 28 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/config/vo/ConfigSaveReqVO.java
  31. 20 21
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/wechatmsgtemplate/WechatMsgTemplateController.java
  32. 17 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/wechatmsgtemplate/bo/WechatMsgTemplateBO.java
  33. 6 3
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/wechatmsgtemplate/vo/WechatMsgTemplatePageReqVO.java
  34. 5 3
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/wechatmsgtemplate/vo/WechatMsgTemplateRespVO.java
  35. 2 2
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/wechatmsgtemplate/vo/WechatMsgTemplateSaveReqVO.java
  36. 50 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/dal/dataobject/config/SystemConfigDO.java
  37. 29 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/dal/mysql/config/SystemConfigMapper.java
  38. 2 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/dal/mysql/social/SocialUserMapper.java
  39. 67 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/config/SystemConfigService.java
  40. 97 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/config/SystemConfigServiceImpl.java
  41. 1 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/social/SocialUserService.java
  42. 5 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/social/SocialUserServiceImpl.java
  43. 15 1
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/wechatmsgtemplate/WechatMsgTemplateService.java
  44. 30 1
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/wechatmsgtemplate/WechatMsgTemplateServiceImpl.java
  45. 12 0
      feifan-module-system/feifan-module-system-biz/src/main/resources/mapper/config/ConfigMapper.xml
  46. 10 0
      feifan-module-system/feifan-module-system-biz/src/main/resources/mapper/social/SocialUserMapper.xml

+ 2 - 0
feifan-module-mall/feifan-module-trade-api/src/main/java/cn/newfeifan/mall/module/trade/enums/ErrorCodeConstants.java

@@ -96,5 +96,7 @@ public interface ErrorCodeConstants {
     ErrorCode CALLBACK_PARAMETER_ERROR = new ErrorCode(1_011_008_005, "第三方回调参数为Null");
     ErrorCode ORDER_CALLBACK_LOGS_NOT_EXISTS = new ErrorCode(1_011_008_007, "回调日志不存在");
     ErrorCode CREATE_TRADE_ORDER_LOGS_ERROR = new ErrorCode(1_011_008_008, "创建第三方日志异常");
+    ErrorCode MESSAGE_LOG_NOT_EXISTS = new ErrorCode(1_011_008_009, "微信模板消息日志不存在");
+
 
 }

+ 14 - 0
feifan-module-mall/feifan-module-trade-api/src/main/java/cn/newfeifan/mall/module/trade/enums/MessageTemplateConstants.java

@@ -1,6 +1,9 @@
 package cn.newfeifan.mall.module.trade.enums;
 
 // TODO @非繁人:枚举
+
+import java.util.Arrays;
+
 /**
  * 通知模板枚举类
  *
@@ -13,4 +16,15 @@ public interface MessageTemplateConstants {
     String BROKERAGE_WITHDRAW_AUDIT_APPROVE = "brokerage_withdraw_audit_approve"; // 佣金提现(审核通过)
     String BROKERAGE_WITHDRAW_AUDIT_REJECT = "brokerage_withdraw_audit_reject"; // 佣金提现(审核不通过)
 
+    /**
+     * 售后订单待审核通知需要的权限
+     */
+    String[] AFTER_SALE_NO_CHECK_List = Arrays.asList("trade:after-sale:query", "trade:after-sale:agree", "trade:after-sale:disagree"
+            , "trade:after-sale:receive", "trade:after-sale:receive", "trade:after-sale:refund").toArray(new String[0]);
+
+    /**
+     * 订单待发货通知需要的权限
+     */
+    String[] ORDER_NO_DELIVERY_List = Arrays.asList("trade:order:query", "trade:order:update", "trade:order:pick-up").toArray(new String[0]);
+
 }

+ 20 - 0
feifan-module-mall/feifan-module-trade-api/src/main/java/cn/newfeifan/mall/module/trade/enums/wxmessage/WcChatMessageTemplateIdEnum.java

@@ -0,0 +1,20 @@
+package cn.newfeifan.mall.module.trade.enums.wxmessage;
+
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+
+/**
+ * 自定义的微信消息模板枚举
+ */
+@Getter
+@RequiredArgsConstructor
+public enum WcChatMessageTemplateIdEnum {
+
+    ORDER_DELIVERY("1","订单发货通知"),
+    AFTER_SALE_CHECK("2","售后订单审核通知"),
+    AFTER_SALE_NO_CHECK("3","售后订单待审核通知"),
+    ORDER_NO_DELIVERY("4","订单待发货通知");
+
+    private final String templateId;
+    private final String name;
+}

+ 93 - 0
feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/controller/admin/messagelog/MessageLogController.java

@@ -0,0 +1,93 @@
+package cn.newfeifan.mall.module.trade.controller.admin.messagelog;
+
+import cn.newfeifan.mall.framework.common.pojo.CommonResult;
+import cn.newfeifan.mall.framework.common.pojo.PageParam;
+import cn.newfeifan.mall.framework.common.pojo.PageResult;
+import cn.newfeifan.mall.framework.common.util.object.BeanUtils;
+import cn.newfeifan.mall.framework.excel.core.util.ExcelUtils;
+import cn.newfeifan.mall.framework.operatelog.core.annotations.OperateLog;
+import cn.newfeifan.mall.module.trade.controller.admin.messagelog.vo.MessageLogPageReqVO;
+import cn.newfeifan.mall.module.trade.controller.admin.messagelog.vo.MessageLogRespVO;
+import cn.newfeifan.mall.module.trade.controller.admin.messagelog.vo.MessageLogSaveReqVO;
+import cn.newfeifan.mall.module.trade.dal.dataobject.messagelog.MessageLogDO;
+import cn.newfeifan.mall.module.trade.service.messagelog.MessageLogService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import java.io.IOException;
+import java.util.List;
+
+import static cn.newfeifan.mall.framework.common.pojo.CommonResult.success;
+import static cn.newfeifan.mall.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
+
+@Tag(name = "管理后台 - 微信消息记录")
+@RestController
+@RequestMapping("/wechat/message-log")
+@Validated
+public class MessageLogController {
+
+    @Resource
+    private MessageLogService messageLogService;
+
+    @PostMapping("/create")
+    @Operation(summary = "创建微信消息记录")
+    @PreAuthorize("@ss.hasPermission('wechat:message-log:create')")
+    public CommonResult<Long> createMessageLog(@Valid @RequestBody MessageLogSaveReqVO createReqVO) {
+        return success(messageLogService.createMessageLog(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @Operation(summary = "更新微信消息记录")
+    @PreAuthorize("@ss.hasPermission('wechat:message-log:update')")
+    public CommonResult<Boolean> updateMessageLog(@Valid @RequestBody MessageLogSaveReqVO updateReqVO) {
+        messageLogService.updateMessageLog(updateReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @Operation(summary = "删除微信消息记录")
+    @Parameter(name = "id", description = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('wechat:message-log:delete')")
+    public CommonResult<Boolean> deleteMessageLog(@RequestParam("id") Long id) {
+        messageLogService.deleteMessageLog(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @Operation(summary = "获得微信消息记录")
+    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    @PreAuthorize("@ss.hasPermission('wechat:message-log:query')")
+    public CommonResult<MessageLogRespVO> getMessageLog(@RequestParam("id") Long id) {
+        MessageLogDO messageLog = messageLogService.getMessageLog(id);
+        return success(BeanUtils.toBean(messageLog, MessageLogRespVO.class));
+    }
+
+    @GetMapping("/page")
+    @Operation(summary = "获得微信消息记录分页")
+    @PreAuthorize("@ss.hasPermission('wechat:message-log:query')")
+    public CommonResult<PageResult<MessageLogRespVO>> getMessageLogPage(@Valid MessageLogPageReqVO pageReqVO) {
+        PageResult<MessageLogDO> pageResult = messageLogService.getMessageLogPage(pageReqVO);
+        return success(BeanUtils.toBean(pageResult, MessageLogRespVO.class));
+    }
+
+    @GetMapping("/export-excel")
+    @Operation(summary = "导出微信消息记录 Excel")
+    @PreAuthorize("@ss.hasPermission('wechat:message-log:export')")
+    @OperateLog(type = EXPORT)
+    public void exportMessageLogExcel(@Valid MessageLogPageReqVO pageReqVO,
+              HttpServletResponse response) throws IOException {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        List<MessageLogDO> list = messageLogService.getMessageLogPage(pageReqVO).getList();
+        // 导出 Excel
+        ExcelUtils.write(response, "微信消息记录.xls", "数据", MessageLogRespVO.class,
+                        BeanUtils.toBean(list, MessageLogRespVO.class));
+    }
+
+}

+ 52 - 0
feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/controller/admin/messagelog/vo/MessageLogPageReqVO.java

@@ -0,0 +1,52 @@
+package cn.newfeifan.mall.module.trade.controller.admin.messagelog.vo;
+
+import cn.newfeifan.mall.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDateTime;
+
+import static cn.newfeifan.mall.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@Schema(description = "管理后台 - 微信消息记录分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class MessageLogPageReqVO extends PageParam {
+
+    @Schema(description = "接收消息用户的openid", example = "20952")
+    private String openid;
+
+    @Schema(description = "会员用户ID", example = "16486")
+    private Long memberUserId;
+
+    @Schema(description = "系统用户ID", example = "13077")
+    private Long systemUserId;
+
+    @Schema(description = "微信消息模板ID", example = "13313")
+    private Long wechatMsgTemplateId;
+
+    @Schema(description = "微信消息模板参数")
+    private String wechatMsgTemplateParams;
+
+    @Schema(description = "对应的业务对象ID,如订单ID、售后订单ID", example = "30167")
+    private Long objectId;
+
+    @Schema(description = "发送时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] sendTime;
+
+    @Schema(description = "微信返回的消息发送状态", example = "1")
+    private Boolean sendStatus;
+
+    @Schema(description = "微信返回的消息响应结果")
+    private String responseResult;
+
+    @Schema(description = "创建时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] createTime;
+
+}

+ 59 - 0
feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/controller/admin/messagelog/vo/MessageLogRespVO.java

@@ -0,0 +1,59 @@
+package cn.newfeifan.mall.module.trade.controller.admin.messagelog.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 微信消息记录 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class MessageLogRespVO {
+
+    @Schema(description = "消息记录ID,自增主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "20647")
+    @ExcelProperty("消息记录ID,自增主键")
+    private Long id;
+
+    @Schema(description = "接收消息用户的openid", requiredMode = Schema.RequiredMode.REQUIRED, example = "20952")
+    @ExcelProperty("接收消息用户的openid")
+    private String openid;
+
+    @Schema(description = "会员用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "16486")
+    @ExcelProperty("会员用户ID")
+    private Long memberUserId;
+
+    @Schema(description = "系统用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "13077")
+    @ExcelProperty("系统用户ID")
+    private Long systemUserId;
+
+    @Schema(description = "微信消息模板ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "13313")
+    @ExcelProperty("微信消息模板ID")
+    private Long wechatMsgTemplateId;
+
+    @Schema(description = "微信消息模板参数")
+    @ExcelProperty("微信消息模板参数")
+    private String wechatMsgTemplateParams;
+
+    @Schema(description = "对应的业务对象ID,如订单ID、售后订单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "30167")
+    @ExcelProperty("对应的业务对象ID,如订单ID、售后订单ID")
+    private Long objectId;
+
+    @Schema(description = "发送时间")
+    @ExcelProperty("发送时间")
+    private LocalDateTime sendTime;
+
+    @Schema(description = "微信返回的消息发送状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @ExcelProperty("微信返回的消息发送状态")
+    private Boolean sendStatus;
+
+    @Schema(description = "微信返回的消息响应结果")
+    @ExcelProperty("微信返回的消息响应结果")
+    private String responseResult;
+
+    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("创建时间")
+    private LocalDateTime createTime;
+
+}

+ 48 - 0
feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/controller/admin/messagelog/vo/MessageLogSaveReqVO.java

@@ -0,0 +1,48 @@
+package cn.newfeifan.mall.module.trade.controller.admin.messagelog.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.*;
+import javax.validation.constraints.*;
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 微信消息记录新增/修改 Request VO")
+@Data
+@Builder
+public class MessageLogSaveReqVO {
+
+    @Schema(description = "消息记录ID,自增主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "20647")
+    private Long id;
+
+    @Schema(description = "接收消息用户的openid", requiredMode = Schema.RequiredMode.REQUIRED, example = "20952")
+    @NotEmpty(message = "接收消息用户的openid不能为空")
+    private String openid;
+
+    @Schema(description = "会员用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "16486")
+    @NotNull(message = "会员用户ID不能为空")
+    private Long memberUserId;
+
+    @Schema(description = "系统用户ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "13077")
+    private Long systemUserId;
+
+    @Schema(description = "微信消息模板ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "13313")
+    @NotNull(message = "微信消息模板ID不能为空")
+    private Long wechatMsgTemplateId;
+
+    @Schema(description = "微信消息模板参数")
+    private String wechatMsgTemplateParams;
+
+    @Schema(description = "对应的业务对象ID,如订单ID、售后订单ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "30167")
+    @NotNull(message = "对应的业务对象ID,如订单ID、售后订单ID不能为空")
+    private Long objectId;
+
+    @Schema(description = "发送时间")
+    private LocalDateTime sendTime;
+
+    @Schema(description = "微信返回的消息发送状态", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
+    @NotNull(message = "微信返回的消息发送状态不能为空")
+    private Boolean sendStatus;
+
+    @Schema(description = "微信返回的消息响应结果")
+    private String responseResult;
+
+}

+ 7 - 11
feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/controller/admin/order/TradeOrderController.java

@@ -20,9 +20,7 @@ import cn.newfeifan.mall.module.trade.dal.dataobject.order.TradeOrderItemDO;
 import cn.newfeifan.mall.module.trade.dal.dataobject.order.TradeOrderLogDO;
 import cn.newfeifan.mall.module.trade.enums.order.TradeOrderStateEnum;
 import cn.newfeifan.mall.module.trade.enums.order.TradeOrderStatusEnum;
-import cn.newfeifan.mall.module.trade.framework.order.config.TradeOrderProperties;
 import cn.newfeifan.mall.module.trade.service.aftersale.AfterSaleService;
-import cn.newfeifan.mall.module.trade.service.delivery.DeliveryExpressService;
 import cn.newfeifan.mall.module.trade.service.order.TradeOrderLogService;
 import cn.newfeifan.mall.module.trade.service.order.TradeOrderQueryService;
 import cn.newfeifan.mall.module.trade.service.order.TradeOrderUpdateService;
@@ -54,7 +52,6 @@ import static cn.newfeifan.mall.framework.common.util.collection.CollectionUtils
 import static cn.newfeifan.mall.framework.common.util.collection.CollectionUtils.convertSet;
 import static cn.newfeifan.mall.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 import static cn.newfeifan.mall.module.trade.enums.ErrorCodeConstants.CALLBACK_PARAMETER_ERROR;
-import static cn.newfeifan.mall.module.trade.enums.ErrorCodeConstants.CREATE_TRADE_ORDER_LOGS_ERROR;
 
 @Tag(name = "管理后台 - 交易订单")
 @RestController
@@ -190,6 +187,7 @@ public class TradeOrderController {
         subscribeResp.setReturnCode("200");
         subscribeResp.setMessage("成功");
         //加密如果相等,属于快递100推送;否则可以忽略掉当前请求
+        ObjectMapper mapper = new ObjectMapper();
         if (ourSign.equals(sign)) {
             //判断订单状态是否是已签收
             if (state.equals(TradeOrderStateEnum.RECEIVED.getState())) {
@@ -201,16 +199,14 @@ public class TradeOrderController {
                 tradeOrderUpdateService.updateOrderById(order);
             }
 
-            //添加到日志
-            ObjectMapper mapper = new ObjectMapper();
-            try {
-                orderCallbackLogsService.create(orderId,param,mapper.writeValueAsString(lastResult),lastResult.get("status").toString());
-            } catch (JsonProcessingException e) {
-                throw exception(CREATE_TRADE_ORDER_LOGS_ERROR);
-            }
             return subscribeResp;
         }
-        orderCallbackLogsService.create(orderId,param,null,lastResult.get("status").toString());
+        //添加到日志
+        try {
+            orderCallbackLogsService.create(orderId, param, mapper.writeValueAsString(lastResult), lastResult.get("status").toString());
+        } catch (JsonProcessingException e) {
+            throw new RuntimeException(e);
+        }
         return null;
     }
 

+ 68 - 0
feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/dal/dataobject/messagelog/MessageLogDO.java

@@ -0,0 +1,68 @@
+package cn.newfeifan.mall.module.trade.dal.dataobject.messagelog;
+
+import cn.newfeifan.mall.framework.mybatis.core.dataobject.BaseDO;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.*;
+
+import java.time.LocalDateTime;
+
+/**
+ * 微信消息记录 DO
+ *
+ * @author 非繁人
+ */
+@TableName("wechat_message_log")
+@KeySequence("wechat_message_log_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class MessageLogDO extends BaseDO {
+
+    /**
+     * 消息记录ID,自增主键
+     */
+    @TableId
+    private Long id;
+    /**
+     * 接收消息用户的openid
+     */
+    private String openid;
+    /**
+     * 会员用户ID
+     */
+    private Long memberUserId;
+    /**
+     * 系统用户ID
+     */
+    private Long systemUserId;
+    /**
+     * 微信消息模板ID
+     */
+    private Long wechatMsgTemplateId;
+    /**
+     * 微信消息模板参数
+     */
+    private String wechatMsgTemplateParams;
+    /**
+     * 对应的业务对象ID,如订单ID、售后订单ID
+     */
+    private Long objectId;
+    /**
+     * 发送时间
+     */
+    private LocalDateTime sendTime;
+    /**
+     * 微信返回的消息发送状态
+     */
+    private Boolean sendStatus;
+    /**
+     * 微信返回的消息响应结果
+     */
+    private String responseResult;
+
+}

+ 33 - 0
feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/dal/mysql/messagelog/MessageLogMapper.java

@@ -0,0 +1,33 @@
+package cn.newfeifan.mall.module.trade.dal.mysql.messagelog;
+
+import cn.newfeifan.mall.framework.common.pojo.PageResult;
+import cn.newfeifan.mall.framework.mybatis.core.mapper.BaseMapperX;
+import cn.newfeifan.mall.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.newfeifan.mall.module.trade.controller.admin.messagelog.vo.MessageLogPageReqVO;
+import cn.newfeifan.mall.module.trade.dal.dataobject.messagelog.MessageLogDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 微信消息记录 Mapper
+ *
+ * @author 非繁人
+ */
+@Mapper
+public interface MessageLogMapper extends BaseMapperX<MessageLogDO> {
+
+    default PageResult<MessageLogDO> selectPage(MessageLogPageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<MessageLogDO>()
+                .eqIfPresent(MessageLogDO::getOpenid, reqVO.getOpenid())
+                .eqIfPresent(MessageLogDO::getMemberUserId, reqVO.getMemberUserId())
+                .eqIfPresent(MessageLogDO::getSystemUserId, reqVO.getSystemUserId())
+                .eqIfPresent(MessageLogDO::getWechatMsgTemplateId, reqVO.getWechatMsgTemplateId())
+                .eqIfPresent(MessageLogDO::getWechatMsgTemplateParams, reqVO.getWechatMsgTemplateParams())
+                .eqIfPresent(MessageLogDO::getObjectId, reqVO.getObjectId())
+                .betweenIfPresent(MessageLogDO::getSendTime, reqVO.getSendTime())
+                .eqIfPresent(MessageLogDO::getSendStatus, reqVO.getSendStatus())
+                .eqIfPresent(MessageLogDO::getResponseResult, reqVO.getResponseResult())
+                .betweenIfPresent(MessageLogDO::getCreateTime, reqVO.getCreateTime())
+                .orderByDesc(MessageLogDO::getId));
+    }
+
+}

+ 7 - 0
feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/dal/mysql/order/TradeOrderItemMapper.java

@@ -5,6 +5,7 @@ import cn.hutool.core.map.MapUtil;
 import cn.newfeifan.mall.framework.mybatis.core.mapper.BaseMapperX;
 import cn.newfeifan.mall.framework.mybatis.core.query.LambdaQueryWrapperX;
 import cn.newfeifan.mall.module.trade.dal.dataobject.order.TradeOrderItemDO;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import org.apache.ibatis.annotations.Mapper;
@@ -14,6 +15,7 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 @Mapper
 public interface TradeOrderItemMapper extends BaseMapperX<TradeOrderItemDO> {
@@ -52,5 +54,10 @@ public interface TradeOrderItemMapper extends BaseMapperX<TradeOrderItemDO> {
         // 获得数量
         return CollUtil.getFirst(result) != null ? MapUtil.getInt(result.get(0), "sumCount") : 0;
     }
+    default String getSupNameByOrderId(Long orderId){
+        List<TradeOrderItemDO> tradeOrderItemDOS = selectList(new LambdaQueryWrapper<TradeOrderItemDO>()
+                .eq(TradeOrderItemDO::getOrderId, orderId));
+        return tradeOrderItemDOS.stream().map(TradeOrderItemDO::getSpuName).collect(Collectors.joining(","));
+    }
 
 }

+ 1 - 0
feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/service/delivery/DeliveryExpressService.java

@@ -79,4 +79,5 @@ public interface DeliveryExpressService {
      */
     List<DeliveryExpressDO> getDeliveryExpressListByStatus(Integer status);
 
+    String getDeliveryNameById(Long id);
 }

+ 5 - 0
feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/service/delivery/DeliveryExpressServiceImpl.java

@@ -111,4 +111,9 @@ public class DeliveryExpressServiceImpl implements DeliveryExpressService {
         return deliveryExpressMapper.selectListByStatus(status);
     }
 
+    @Override
+    public String getDeliveryNameById(Long id) {
+        return deliveryExpressMapper.selectById(id).getName();
+    }
+
 }

+ 55 - 0
feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/service/messagelog/MessageLogService.java

@@ -0,0 +1,55 @@
+package cn.newfeifan.mall.module.trade.service.messagelog;
+
+import cn.newfeifan.mall.framework.common.pojo.PageResult;
+import cn.newfeifan.mall.module.trade.controller.admin.messagelog.vo.MessageLogPageReqVO;
+import cn.newfeifan.mall.module.trade.controller.admin.messagelog.vo.MessageLogSaveReqVO;
+import cn.newfeifan.mall.module.trade.dal.dataobject.messagelog.MessageLogDO;
+
+import javax.validation.Valid;
+
+/**
+ * 微信消息记录 Service 接口
+ *
+ * @author 非繁人
+ */
+public interface MessageLogService {
+
+    /**
+     * 创建微信消息记录
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createMessageLog(@Valid MessageLogSaveReqVO createReqVO);
+
+    /**
+     * 更新微信消息记录
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateMessageLog(@Valid MessageLogSaveReqVO updateReqVO);
+
+    /**
+     * 删除微信消息记录
+     *
+     * @param id 编号
+     */
+    void deleteMessageLog(Long id);
+
+    /**
+     * 获得微信消息记录
+     *
+     * @param id 编号
+     * @return 微信消息记录
+     */
+    MessageLogDO getMessageLog(Long id);
+
+    /**
+     * 获得微信消息记录分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 微信消息记录分页
+     */
+    PageResult<MessageLogDO> getMessageLogPage(MessageLogPageReqVO pageReqVO);
+
+}

+ 71 - 0
feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/service/messagelog/MessageLogServiceImpl.java

@@ -0,0 +1,71 @@
+package cn.newfeifan.mall.module.trade.service.messagelog;
+
+import cn.newfeifan.mall.framework.common.pojo.PageResult;
+import cn.newfeifan.mall.framework.common.util.object.BeanUtils;
+import cn.newfeifan.mall.module.trade.controller.admin.messagelog.vo.MessageLogPageReqVO;
+import cn.newfeifan.mall.module.trade.controller.admin.messagelog.vo.MessageLogSaveReqVO;
+import cn.newfeifan.mall.module.trade.dal.dataobject.messagelog.MessageLogDO;
+import cn.newfeifan.mall.module.trade.dal.mysql.messagelog.MessageLogMapper;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import javax.annotation.Resource;
+
+import static cn.newfeifan.mall.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.newfeifan.mall.module.trade.enums.ErrorCodeConstants.MESSAGE_LOG_NOT_EXISTS;
+
+/**
+ * 微信消息记录 Service 实现类
+ *
+ * @author 非繁人
+ */
+@Service
+@Validated
+public class MessageLogServiceImpl implements MessageLogService {
+
+    @Resource
+    private MessageLogMapper messageLogMapper;
+
+    @Override
+    public Long createMessageLog(MessageLogSaveReqVO createReqVO) {
+        // 插入
+        MessageLogDO messageLog = BeanUtils.toBean(createReqVO, MessageLogDO.class);
+        messageLogMapper.insert(messageLog);
+        // 返回
+        return messageLog.getId();
+    }
+
+    @Override
+    public void updateMessageLog(MessageLogSaveReqVO updateReqVO) {
+        // 校验存在
+        validateMessageLogExists(updateReqVO.getId());
+        // 更新
+        MessageLogDO updateObj = BeanUtils.toBean(updateReqVO, MessageLogDO.class);
+        messageLogMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteMessageLog(Long id) {
+        // 校验存在
+        validateMessageLogExists(id);
+        // 删除
+        messageLogMapper.deleteById(id);
+    }
+
+    private void validateMessageLogExists(Long id) {
+        if (messageLogMapper.selectById(id) == null) {
+            throw exception(MESSAGE_LOG_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public MessageLogDO getMessageLog(Long id) {
+        return messageLogMapper.selectById(id);
+    }
+
+    @Override
+    public PageResult<MessageLogDO> getMessageLogPage(MessageLogPageReqVO pageReqVO) {
+        return messageLogMapper.selectPage(pageReqVO);
+    }
+
+}

+ 15 - 0
feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/service/order/TradeOrderUpdateServiceImpl.java

@@ -37,6 +37,7 @@ import cn.newfeifan.mall.module.trade.dal.mysql.order.TradeOrderMapper;
 import cn.newfeifan.mall.module.trade.dal.redis.no.TradeNoRedisDAO;
 import cn.newfeifan.mall.module.trade.enums.delivery.DeliveryTypeEnum;
 import cn.newfeifan.mall.module.trade.enums.order.*;
+import cn.newfeifan.mall.module.trade.enums.wxmessage.WcChatMessageTemplateIdEnum;
 import cn.newfeifan.mall.module.trade.framework.order.config.TradeOrderProperties;
 import cn.newfeifan.mall.module.trade.framework.order.core.annotations.TradeOrderLog;
 import cn.newfeifan.mall.module.trade.framework.order.core.utils.TradeOrderLogUtils;
@@ -49,6 +50,7 @@ import cn.newfeifan.mall.module.trade.service.price.TradePriceService;
 import cn.newfeifan.mall.module.trade.service.price.bo.TradePriceCalculateReqBO;
 import cn.newfeifan.mall.module.trade.service.price.bo.TradePriceCalculateRespBO;
 import cn.newfeifan.mall.module.trade.service.price.calculator.TradePriceCalculatorHelper;
+import cn.newfeifan.mall.module.trade.utils.wechat.WcChatMessageUtils;
 import com.google.gson.Gson;
 import com.google.gson.JsonObject;
 import com.kuaidi100.sdk.api.Subscribe;
@@ -66,6 +68,7 @@ import org.springframework.transaction.annotation.Transactional;
 
 import javax.annotation.Resource;
 import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Objects;
@@ -117,6 +120,8 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
 
     @Resource
     private TradeOrderProperties tradeOrderProperties;
+    @Resource
+    private WcChatMessageUtils wcChatMessageUtils;
 
     @Value("${feifan.trade.express.kd100.key}")
     private String key;
@@ -391,6 +396,16 @@ public class TradeOrderUpdateServiceImpl implements TradeOrderUpdateService {
         // 4. 发送站内信
         tradeMessageService.sendMessageWhenDeliveryOrder(new TradeOrderMessageWhenDeliveryOrderReqBO()
                 .setOrderId(order.getId()).setUserId(order.getUserId()).setMessage(null));
+        //5.发送微信模板消息
+        List<String> params = new ArrayList<>();
+        params.add(order.getNo());
+        params.add(deliveryExpressService.getDeliveryNameById(order.getLogisticsId()));
+        params.add(order.getLogisticsNo());
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        params.add(LocalDateTime.now().format(formatter));
+        params.add(tradeOrderItemMapper.getSupNameByOrderId(order.getId()));
+        wcChatMessageUtils.sendWcChatMessage(order.getUserId(), WcChatMessageTemplateIdEnum.ORDER_DELIVERY.getTemplateId(),
+                params, null,order.getUserId(), order.getId());
     }
 
     /**

+ 13 - 0
feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/utils/wechat/WcChatMessageDto.java

@@ -0,0 +1,13 @@
+package cn.newfeifan.mall.module.trade.utils.wechat;
+
+import lombok.Data;
+
+/**
+ * 调用微信消息的模板参数类
+ */
+@Data
+public class WcChatMessageDto {
+    private Long userId;
+    private Long wechatMsgTemplateId;
+
+}

+ 266 - 0
feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/utils/wechat/WcChatMessageUtils.java

@@ -0,0 +1,266 @@
+package cn.newfeifan.mall.module.trade.utils.wechat;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.http.HttpUtil;
+import cn.hutool.json.JSONUtil;
+import cn.newfeifan.mall.module.member.service.user.MemberUserService;
+import cn.newfeifan.mall.module.system.dal.dataobject.config.SystemConfigDO;
+import cn.newfeifan.mall.module.system.dal.dataobject.wechatmsgtemplate.WechatMsgTemplateDO;
+import cn.newfeifan.mall.module.system.service.config.SystemConfigService;
+import cn.newfeifan.mall.module.system.service.permission.PermissionService;
+import cn.newfeifan.mall.module.system.service.social.SocialUserService;
+import cn.newfeifan.mall.module.system.service.wechatmsgtemplate.WechatMsgTemplateService;
+import cn.newfeifan.mall.module.trade.controller.admin.messagelog.vo.MessageLogSaveReqVO;
+import cn.newfeifan.mall.module.trade.enums.wxmessage.WcChatMessageTemplateIdEnum;
+import cn.newfeifan.mall.module.trade.service.messagelog.MessageLogService;
+import com.google.gson.JsonObject;
+import lombok.Data;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+import java.time.LocalDateTime;
+import java.util.Arrays;
+import java.util.List;
+import java.util.UUID;
+
+import static cn.newfeifan.mall.module.system.constant.SystemConstants.SYSTEM_WX_ACCESS_TOKEN;
+import static cn.newfeifan.mall.module.trade.enums.MessageTemplateConstants.AFTER_SALE_NO_CHECK_List;
+import static cn.newfeifan.mall.module.trade.enums.MessageTemplateConstants.ORDER_NO_DELIVERY_List;
+
+/**
+ * 发送微信消息的工具类
+ */
+@Data
+@Component
+@Slf4j
+public class WcChatMessageUtils {
+
+    @Value("${wx.mp.app-id}")
+    private String appid;
+    @Value("${wx.mp.secret}")
+    private String Wxgsecret;
+
+    @Resource
+    private StringRedisTemplate stringRedisTemplate;
+    @Resource
+    private WechatMsgTemplateService wechatMsgTemplateService;
+    @Resource
+    private SocialUserService socialUserService;
+    @Resource
+    private MessageLogService messageLogService;
+    @Resource
+    private SystemConfigService configService;
+    @Resource
+    private PermissionService permissionService;
+    @Resource
+    private MemberUserService memberUserService;
+
+    /**
+     * 获取微信的accessToken
+     *
+     * @return accessToken
+     */
+    public String getAccessToken() {
+
+        String accessToken = stringRedisTemplate.opsForValue().get(SYSTEM_WX_ACCESS_TOKEN);
+
+        if (StrUtil.isEmpty(accessToken)) {
+            // 服务号的appid以及秘钥
+            String requestUrl = StrUtil.format("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={}&secret={}", appid, Wxgsecret);
+            String returnMsg = HttpUtil.get(requestUrl);
+            cn.hutool.json.JSONObject responseJsonObject = JSONUtil.parseObj(returnMsg);
+            if (ObjectUtil.isNull(responseJsonObject)) try {
+                throw new Exception("响应异常:获取信息为空!");
+            } catch (Exception e) {
+                throw new RuntimeException(e);
+            }
+            accessToken = responseJsonObject.getStr("access_token");
+
+            //微信的accessToken的失效时间是两个小时,这里改为一小时五十五分钟,怕双方的时间误差导致accessToken失效
+            long expireTime = 60 * 60 + 55 * 60; // 1小时55分钟转换为秒
+            stringRedisTemplate.opsForValue().set(SYSTEM_WX_ACCESS_TOKEN, accessToken, expireTime, java.util.concurrent.TimeUnit.SECONDS);
+        }
+
+
+        return accessToken;
+    }
+
+    /**
+     * 发送微信消息
+     *
+     * @param userId              接口消息的用户id
+     * @param data                模板参数
+     * @param wechatMsgTemplateId 自定义的消息模板id
+     */
+    private void sendWxgMessage(Long userId, JsonObject data, String wechatMsgTemplateId, Long systemUserId, Long memberUserId, Long objectId) {
+
+        // 组装消息内容
+        String userOpenId = null;
+        if (wechatMsgTemplateId.equals(WcChatMessageTemplateIdEnum.AFTER_SALE_NO_CHECK.getTemplateId()) ||
+                wechatMsgTemplateId.equals(WcChatMessageTemplateIdEnum.ORDER_NO_DELIVERY.getTemplateId())) {
+            userOpenId = getOpenIdBySysTemUserId(systemUserId);
+        } else {
+            userOpenId = getOpenId(userId);
+        }
+
+        //如果用户没有绑定微信,则不发送消息
+        if (userOpenId == null) {
+            return;
+        }
+
+        String templateId = getTemplateId(wechatMsgTemplateId).getWechatMsgTemplateId(); // 模板id
+        String url = getDoMain(String.valueOf(wechatMsgTemplateId), objectId);       // 跳转路径(小程序之外)
+        String client_msg_id = UUID.randomUUID().toString();  // 防重入id
+
+
+        WeChatTemplateMessage message = new WeChatTemplateMessage();
+        message.setTouser(userOpenId);
+        message.setTemplate_id(templateId);
+        message.setUrl(url);
+        message.setClient_msg_id(client_msg_id);
+        message.setData(data);
+
+        // 发送消息
+        String returnMsg = HttpUtil.post(StrUtil.format("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token={}", getAccessToken()), message.toString());
+        cn.hutool.json.JSONObject jsonObject2 = JSONUtil.parseObj(returnMsg);
+        String errmsg = jsonObject2.getStr("errmsg");
+
+        //记录发送的微信消息
+        MessageLogSaveReqVO messageLogSaveReqVO = MessageLogSaveReqVO.builder()
+                .openid(userOpenId)
+                .memberUserId(userId)
+                .systemUserId(systemUserId)
+                .memberUserId(memberUserId)
+                .wechatMsgTemplateId(Long.valueOf(wechatMsgTemplateId))
+                .wechatMsgTemplateParams(message.toString())
+                .objectId(objectId)
+                .sendStatus(true)
+                .sendTime(LocalDateTime.now())
+                .responseResult(returnMsg)
+                .build();
+        if (!StrUtil.equals("ok", errmsg)) {
+            log.info("=====消息发送失败,原因:{}", errmsg);
+            messageLogSaveReqVO.setSendStatus(false);
+        }
+
+        messageLogService.createMessageLog(messageLogSaveReqVO);
+    }
+
+    /**
+     * 获取待发货模板参数
+     *
+     * @return 待发货模板参数
+     */
+    public JsonObject getTemplateData(List<String> dataParams, List<String> params) {
+
+        JsonObject data = new JsonObject();
+
+        // 添加字段及其值
+        for (int i = 0; i < Math.min(params.size(), dataParams.size()); i++) {
+            String paramName = dataParams.get(i);
+            String paramValue = params.get(i);
+
+            JsonObject obj = new JsonObject();
+            obj.addProperty("value", paramValue);
+            data.add(paramName, obj);
+        }
+
+        return data;
+    }
+
+    /**
+     * 发送微信信息
+     *
+     * @param userId       用户id
+     * @param templateId   自定义消息模板id
+     * @param params       消息参数
+     * @param systemUserId 系统用户id
+     * @param memberUserId 会员用户id
+     * @param objectId     对象id
+     */
+    public void sendWcChatMessage(Long userId, String templateId, List<String> params, Long systemUserId, Long memberUserId, Long objectId) {
+        WechatMsgTemplateDO template = getTemplateId(templateId);
+        String messageTemplateParameters = template.getMessageTemplateParameters();
+
+        // 去除首尾的括号,并去除空格
+        messageTemplateParameters = messageTemplateParameters.substring(1, messageTemplateParameters.length() - 1).trim();
+
+        // 使用逗号分割字符串,并去除空格
+        String[] parts = messageTemplateParameters.split(",\\s*");
+
+        // 创建集合并将数组转换为集合
+        List<String> dataParams = Arrays.asList(parts);
+        JsonObject templateData = getTemplateData(dataParams, params);
+
+        // 发送微信消息
+        sendWxgMessage(userId, templateData, templateId, systemUserId, memberUserId, objectId);
+    }
+
+    /**
+     * 判断用户是否有接收者调消息的权限
+     *
+     * @param userId     用户id
+     * @param templateId 自定义的模板id
+     * @return 是否有权限
+     */
+    public Boolean isHavePermission(Long userId, String templateId) {
+        if (templateId.equals(WcChatMessageTemplateIdEnum.AFTER_SALE_NO_CHECK.getTemplateId())) {
+            // 售后待审核
+            return permissionService.hasAnyPermissions(userId, AFTER_SALE_NO_CHECK_List);
+        } else if (templateId.equals(WcChatMessageTemplateIdEnum.ORDER_NO_DELIVERY.getTemplateId())) {
+            // 订单待发货
+            return permissionService.hasAnyPermissions(userId, ORDER_NO_DELIVERY_List);
+        }
+        return false;
+    }
+
+    /**
+     * 获取不同端域名(不同的端的代码略有不同)
+     *
+     * @param templateId 自定义模板id
+     * @return 域名加路径
+     */
+    public String getDoMain(String templateId, Long objectId) {
+        SystemConfigDO redisConfig = configService.getRedisConfig();
+        if (templateId.equals(WcChatMessageTemplateIdEnum.ORDER_DELIVERY.getTemplateId())) {
+            //订单已发货
+            return redisConfig.getMallDomain() + "/#/pages/order/detail?id=" + objectId;
+        } else if (templateId.equals(WcChatMessageTemplateIdEnum.AFTER_SALE_CHECK.getTemplateId())) {
+            //售后订单审核完成
+            return redisConfig.getMallDomain() + "/#/pages/order/aftersale/detail?id=" + objectId;
+        } else if (templateId.equals(WcChatMessageTemplateIdEnum.AFTER_SALE_NO_CHECK.getTemplateId())) {
+            //售后订单待审核
+            return redisConfig.getPlatformDomain() + "/after-sale";
+        } else if (templateId.equals(WcChatMessageTemplateIdEnum.ORDER_NO_DELIVERY.getTemplateId())) {
+            //订单待发货
+            return redisConfig.getMallDomain() + "/order";
+        }
+        return null;
+    }
+
+    /**
+     * 通过自己定义消息模板id获取微信第三方模板
+     *
+     * @param wechatMsgTemplateId 自己定义消息模板id
+     * @return 微信第三方模板
+     */
+    private WechatMsgTemplateDO getTemplateId(String wechatMsgTemplateId) {
+        return wechatMsgTemplateService.getWechatSsgTemplate(Long.valueOf(wechatMsgTemplateId));
+    }
+
+    private String getOpenId(Long userId) {
+        return socialUserService.getOpenIdByUserId(userId);
+    }
+
+    private String getOpenIdBySysTemUserId(Long systemUserId) {
+        Long memberUserId = memberUserService.getUserIdBySystemUserId(systemUserId);
+        if (memberUserId == null) {
+            return null;
+        }
+        return getOpenId(memberUserId);
+    }
+}

+ 36 - 0
feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/utils/wechat/WeChatTemplateMessage.java

@@ -0,0 +1,36 @@
+package cn.newfeifan.mall.module.trade.utils.wechat;
+
+import com.google.gson.JsonObject;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+/**
+ * 微信模板消息
+ */
+@Data
+public class WeChatTemplateMessage {
+    private String touser;
+
+    private String template_id;
+
+    private String url;
+
+    private MiniProgram miniprogram;
+
+    private String client_msg_id;
+
+    private JsonObject data;
+
+    // Inner classes
+    @Data
+    @AllArgsConstructor
+    public static class MiniProgram {
+        private String appid;
+        private String pagepath;
+    }
+
+
+    public String toString(){
+        return "{\"touser\":\"" + touser + "\",\"template_id\":\"" + template_id + "\",\"url\":\"" + url + "\",\"client_msg_id\":\"" + client_msg_id + "\",\"data\":" + data.toString() + "}";
+    }
+}

+ 12 - 0
feifan-module-mall/feifan-module-trade-biz/src/main/resources/mapper/messagelog/MessageLogMapper.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.newfeifan.mall.module.wechat.dal.mysql.messagelog.MessageLogMapper">
+
+    <!--
+        一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
+        无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
+        代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
+        文档可见:https://www.zhongxing.cn/MyBatis/x-plugins/
+     -->
+
+</mapper>

+ 2 - 0
feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/service/user/MemberUserService.java

@@ -188,4 +188,6 @@ public interface MemberUserService {
     boolean updateUserPoint(Long userId, Integer point);
 
     void updateUserByMobile(Long id, String mobile);
+
+    Long getUserIdBySystemUserId(Long systemUserId);
 }

+ 6 - 0
feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/service/user/MemberUserServiceImpl.java

@@ -325,4 +325,10 @@ public class MemberUserServiceImpl implements MemberUserService {
         memberUserMapper.updateById(memberUserDO);
     }
 
+    @Override
+    public Long getUserIdBySystemUserId(Long systemUserId) {
+        MemberUserDO memberUserDO = memberUserMapper.selectOne(MemberUserDO::getSystemUsersId, systemUserId);
+        return memberUserDO == null ? null : memberUserDO.getId();
+    }
+
 }

+ 10 - 0
feifan-module-system/feifan-module-system-api/src/main/java/cn/newfeifan/mall/module/system/constant/SystemConstants.java

@@ -0,0 +1,10 @@
+package cn.newfeifan.mall.module.system.constant;
+
+public class SystemConstants {
+    public static final String SYSTEM_WX_ACCESS_TOKEN = "system:wx:access_token";
+
+    public static final String SYSTEM_WX_MESSAGE_TEMPLATE = "system:wx:message:template:";
+
+    public static final String SYSTEM_CONFIG = "system:config";
+
+}

+ 2 - 0
feifan-module-system/feifan-module-system-api/src/main/java/cn/newfeifan/mall/module/system/enums/ErrorCodeConstants.java

@@ -173,4 +173,6 @@ public interface ErrorCodeConstants {
 
     ErrorCode WECHAT_MSG_TEMPLATE_NOT_EXISTS = new ErrorCode(1_002_028_001, "微信消息模板不存在");
 
+    ErrorCode CONFIG_NOT_EXISTS = new ErrorCode(1_002_028_002, "系统配置不存在");
+
 }

+ 62 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/config/StartConfig.java

@@ -0,0 +1,62 @@
+package cn.newfeifan.mall.module.system.config;
+
+import cn.newfeifan.mall.framework.common.util.json.JsonUtils;
+import cn.newfeifan.mall.module.system.dal.dataobject.config.SystemConfigDO;
+import cn.newfeifan.mall.module.system.dal.dataobject.wechatmsgtemplate.WechatMsgTemplateDO;
+import cn.newfeifan.mall.module.system.service.config.SystemConfigService;
+import cn.newfeifan.mall.module.system.service.wechatmsgtemplate.WechatMsgTemplateService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.Resource;
+import java.util.List;
+
+import static cn.newfeifan.mall.module.system.constant.SystemConstants.SYSTEM_CONFIG;
+import static cn.newfeifan.mall.module.system.constant.SystemConstants.SYSTEM_WX_MESSAGE_TEMPLATE;
+
+
+/**
+ * 启动配置类
+ */
+@Component
+@Slf4j
+public class StartConfig {
+
+    @Resource
+    private StringRedisTemplate stringRedisTemplate;
+
+    @Resource
+    private WechatMsgTemplateService wechatMsgTemplateService;
+
+    @Resource
+    private SystemConfigService configService;
+
+    @PostConstruct
+    public void init() {
+        initWechatMsgTemplate();
+
+        initSystemConfig();
+    }
+
+    /**
+     * 初始化微信模板配置
+     */
+    private void initWechatMsgTemplate() {
+        List<WechatMsgTemplateDO> wechatMsgTemplateDOS = wechatMsgTemplateService.selectList();
+        wechatMsgTemplateDOS.forEach(wechatMsgTemplateDO -> stringRedisTemplate.opsForValue().set(SYSTEM_WX_MESSAGE_TEMPLATE + wechatMsgTemplateDO.getId(), JsonUtils.toJsonString(wechatMsgTemplateDO)));
+
+        log.info("======初始化微信模板配置成功======");
+    }
+
+    /**
+     * 初始化系统配置
+     */
+    private void initSystemConfig(){
+        SystemConfigDO config = configService.getConfig();
+        stringRedisTemplate.opsForValue().set(SYSTEM_CONFIG, JsonUtils.toJsonString(config));
+
+        log.info("======初始化系统配置成功======");
+    }
+}

+ 93 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/config/SystemConfigController.java

@@ -0,0 +1,93 @@
+package cn.newfeifan.mall.module.system.controller.admin.config;
+
+import cn.newfeifan.mall.framework.common.pojo.CommonResult;
+import cn.newfeifan.mall.framework.common.pojo.PageParam;
+import cn.newfeifan.mall.framework.common.pojo.PageResult;
+import cn.newfeifan.mall.framework.common.util.object.BeanUtils;
+import cn.newfeifan.mall.framework.excel.core.util.ExcelUtils;
+import cn.newfeifan.mall.framework.operatelog.core.annotations.OperateLog;
+import cn.newfeifan.mall.module.system.controller.admin.config.vo.ConfigPageReqVO;
+import cn.newfeifan.mall.module.system.controller.admin.config.vo.ConfigRespVO;
+import cn.newfeifan.mall.module.system.controller.admin.config.vo.ConfigSaveReqVO;
+import cn.newfeifan.mall.module.system.dal.dataobject.config.SystemConfigDO;
+import cn.newfeifan.mall.module.system.service.config.SystemConfigService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import java.io.IOException;
+import java.util.List;
+
+import static cn.newfeifan.mall.framework.common.pojo.CommonResult.success;
+import static cn.newfeifan.mall.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
+
+@Tag(name = "管理后台 - 系统配置")
+@RestController
+@RequestMapping("/system/config")
+@Validated
+public class SystemConfigController {
+
+    @Resource
+    private SystemConfigService configService;
+
+    @PostMapping("/create")
+    @Operation(summary = "创建系统配置")
+    @PreAuthorize("@ss.hasPermission('system:config:create')")
+    public CommonResult<Long> createConfig(@Valid @RequestBody ConfigSaveReqVO createReqVO) {
+        return success(configService.createConfig(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @Operation(summary = "更新系统配置")
+    @PreAuthorize("@ss.hasPermission('system:config:update')")
+    public CommonResult<Boolean> updateConfig(@Valid @RequestBody ConfigSaveReqVO updateReqVO) {
+        configService.updateConfig(updateReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @Operation(summary = "删除系统配置")
+    @Parameter(name = "id", description = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('system:config:delete')")
+    public CommonResult<Boolean> deleteConfig(@RequestParam("id") Long id) {
+        configService.deleteConfig(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @Operation(summary = "获得系统配置")
+    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    @PreAuthorize("@ss.hasPermission('system:config:query')")
+    public CommonResult<ConfigRespVO> getConfig(@RequestParam("id") Long id) {
+        SystemConfigDO config = configService.getConfig(id);
+        return success(BeanUtils.toBean(config, ConfigRespVO.class));
+    }
+
+    @GetMapping("/page")
+    @Operation(summary = "获得系统配置分页")
+    @PreAuthorize("@ss.hasPermission('system:config:query')")
+    public CommonResult<PageResult<ConfigRespVO>> getConfigPage(@Valid ConfigPageReqVO pageReqVO) {
+        PageResult<SystemConfigDO> pageResult = configService.getConfigPage(pageReqVO);
+        return success(BeanUtils.toBean(pageResult, ConfigRespVO.class));
+    }
+
+    @GetMapping("/export-excel")
+    @Operation(summary = "导出系统配置 Excel")
+    @PreAuthorize("@ss.hasPermission('system:config:export')")
+    @OperateLog(type = EXPORT)
+    public void exportConfigExcel(@Valid ConfigPageReqVO pageReqVO,
+              HttpServletResponse response) throws IOException {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        List<SystemConfigDO> list = configService.getConfigPage(pageReqVO).getList();
+        // 导出 Excel
+        ExcelUtils.write(response, "系统配置.xls", "数据", ConfigRespVO.class,
+                        BeanUtils.toBean(list, ConfigRespVO.class));
+    }
+
+}

+ 31 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/config/bo/SystemConfigBO.java

@@ -0,0 +1,31 @@
+package cn.newfeifan.mall.module.system.controller.admin.config.bo;
+
+import lombok.Data;
+
+/**
+ * 用来接收redis缓存中的值
+ */
+@Data
+public class SystemConfigBO {
+    private Long id;
+    /**
+     * 微信服务号appid
+     */
+    private String wechatAppid;
+    /**
+     * 微信服务号秘钥
+     */
+    private String wechatSecretKey;
+    /**
+     * 平台端协议+域名+端口
+     */
+    private String platformDomain;
+    /**
+     * 商户端协议+域名+端口
+     */
+    private String merchantDomain;
+    /**
+     * 移动商城端协议+域名+端口
+     */
+    private String mallDomain;
+}

+ 39 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/config/vo/ConfigPageReqVO.java

@@ -0,0 +1,39 @@
+package cn.newfeifan.mall.module.system.controller.admin.config.vo;
+
+import cn.newfeifan.mall.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDateTime;
+
+import static cn.newfeifan.mall.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
+
+@Schema(description = "管理后台 - 系统配置分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class ConfigPageReqVO extends PageParam {
+
+    @Schema(description = "微信服务号appid", example = "31635")
+    private String wechatAppid;
+
+    @Schema(description = "微信服务号秘钥")
+    private String wechatSecretKey;
+
+    @Schema(description = "平台端协议+域名+端口")
+    private String platformDomain;
+
+    @Schema(description = "商户端协议+域名+端口")
+    private String merchantDomain;
+
+    @Schema(description = "移动商城端协议+域名+端口")
+    private String mallDomain;
+
+    @Schema(description = "创建时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] createTime;
+
+}

+ 43 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/config/vo/ConfigRespVO.java

@@ -0,0 +1,43 @@
+package cn.newfeifan.mall.module.system.controller.admin.config.vo;
+
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 系统配置 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class ConfigRespVO {
+
+    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "18615")
+    @ExcelProperty("主键")
+    private Long id;
+
+    @Schema(description = "微信服务号appid", example = "31635")
+    @ExcelProperty("微信服务号appid")
+    private String wechatAppid;
+
+    @Schema(description = "微信服务号秘钥")
+    @ExcelProperty("微信服务号秘钥")
+    private String wechatSecretKey;
+
+    @Schema(description = "平台端协议+域名+端口")
+    @ExcelProperty("平台端协议+域名+端口")
+    private String platformDomain;
+
+    @Schema(description = "商户端协议+域名+端口")
+    @ExcelProperty("商户端协议+域名+端口")
+    private String merchantDomain;
+
+    @Schema(description = "移动商城端协议+域名+端口")
+    @ExcelProperty("移动商城端协议+域名+端口")
+    private String mallDomain;
+
+    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("创建时间")
+    private LocalDateTime createTime;
+
+}

+ 28 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/config/vo/ConfigSaveReqVO.java

@@ -0,0 +1,28 @@
+package cn.newfeifan.mall.module.system.controller.admin.config.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "管理后台 - 系统配置新增/修改 Request VO")
+@Data
+public class ConfigSaveReqVO {
+
+    @Schema(description = "主键", requiredMode = Schema.RequiredMode.REQUIRED, example = "18615")
+    private Long id;
+
+    @Schema(description = "微信服务号appid", example = "31635")
+    private String wechatAppid;
+
+    @Schema(description = "微信服务号秘钥")
+    private String wechatSecretKey;
+
+    @Schema(description = "平台端协议+域名+端口")
+    private String platformDomain;
+
+    @Schema(description = "商户端协议+域名+端口")
+    private String merchantDomain;
+
+    @Schema(description = "移动商城端协议+域名+端口")
+    private String mallDomain;
+
+}

+ 20 - 21
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/wechatmsgtemplate/WechatMsgTemplateController.java

@@ -1,32 +1,31 @@
 package cn.newfeifan.mall.module.system.controller.admin.wechatmsgtemplate;
 
-import org.springframework.web.bind.annotation.*;
-import javax.annotation.Resource;
-import org.springframework.validation.annotation.Validated;
-import org.springframework.security.access.prepost.PreAuthorize;
-import io.swagger.v3.oas.annotations.tags.Tag;
-import io.swagger.v3.oas.annotations.Parameter;
-import io.swagger.v3.oas.annotations.Operation;
-
-import javax.validation.*;
-import javax.servlet.http.*;
-import java.util.*;
-import java.io.IOException;
-
+import cn.newfeifan.mall.framework.common.pojo.CommonResult;
 import cn.newfeifan.mall.framework.common.pojo.PageParam;
 import cn.newfeifan.mall.framework.common.pojo.PageResult;
-import cn.newfeifan.mall.framework.common.pojo.CommonResult;
 import cn.newfeifan.mall.framework.common.util.object.BeanUtils;
-import static cn.newfeifan.mall.framework.common.pojo.CommonResult.success;
-
 import cn.newfeifan.mall.framework.excel.core.util.ExcelUtils;
-
 import cn.newfeifan.mall.framework.operatelog.core.annotations.OperateLog;
-import static cn.newfeifan.mall.framework.operatelog.core.enums.OperateTypeEnum.*;
-
-import cn.newfeifan.mall.module.system.controller.admin.wechatmsgtemplate.vo.*;
+import cn.newfeifan.mall.module.system.controller.admin.wechatmsgtemplate.vo.WechatMsgTemplatePageReqVO;
+import cn.newfeifan.mall.module.system.controller.admin.wechatmsgtemplate.vo.WechatMsgTemplateRespVO;
+import cn.newfeifan.mall.module.system.controller.admin.wechatmsgtemplate.vo.WechatMsgTemplateSaveReqVO;
 import cn.newfeifan.mall.module.system.dal.dataobject.wechatmsgtemplate.WechatMsgTemplateDO;
 import cn.newfeifan.mall.module.system.service.wechatmsgtemplate.WechatMsgTemplateService;
+import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.Parameter;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import java.io.IOException;
+import java.util.List;
+
+import static cn.newfeifan.mall.framework.common.pojo.CommonResult.success;
+import static cn.newfeifan.mall.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
 
 @Tag(name = "管理后台 - 微信消息模板")
 @RestController
@@ -91,4 +90,4 @@ public class WechatMsgTemplateController {
                         BeanUtils.toBean(list, WechatMsgTemplateRespVO.class));
     }
 
-}
+}

+ 17 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/wechatmsgtemplate/bo/WechatMsgTemplateBO.java

@@ -0,0 +1,17 @@
+package cn.newfeifan.mall.module.system.controller.admin.wechatmsgtemplate.bo;
+
+import lombok.Data;
+
+/**
+ * 用来接收redis缓存中的值
+ */
+@Data
+public class WechatMsgTemplateBO {
+    private Long id;
+
+    private String wechatMsgTemplateId;
+
+    private String remark;
+
+    private String messageTemplateParameters;
+}

+ 6 - 3
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/wechatmsgtemplate/vo/WechatMsgTemplatePageReqVO.java

@@ -1,9 +1,12 @@
 package cn.newfeifan.mall.module.system.controller.admin.wechatmsgtemplate.vo;
 
-import lombok.*;
-import io.swagger.v3.oas.annotations.media.Schema;
 import cn.newfeifan.mall.framework.common.pojo.PageParam;
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
 import org.springframework.format.annotation.DateTimeFormat;
+
 import java.time.LocalDateTime;
 
 import static cn.newfeifan.mall.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
@@ -27,4 +30,4 @@ public class WechatMsgTemplatePageReqVO extends PageParam {
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
     private LocalDateTime[] createTime;
 
-}
+}

+ 5 - 3
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/wechatmsgtemplate/vo/WechatMsgTemplateRespVO.java

@@ -1,9 +1,11 @@
 package cn.newfeifan.mall.module.system.controller.admin.wechatmsgtemplate.vo;
 
+import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
+import com.alibaba.excel.annotation.ExcelProperty;
 import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.*;
+import lombok.Data;
+
 import java.time.LocalDateTime;
-import com.alibaba.excel.annotation.*;
 
 @Schema(description = "管理后台 - 微信消息模板 Response VO")
 @Data
@@ -30,4 +32,4 @@ public class WechatMsgTemplateRespVO {
     @ExcelProperty("创建时间")
     private LocalDateTime createTime;
 
-}
+}

+ 2 - 2
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/wechatmsgtemplate/vo/WechatMsgTemplateSaveReqVO.java

@@ -1,7 +1,7 @@
 package cn.newfeifan.mall.module.system.controller.admin.wechatmsgtemplate.vo;
 
 import io.swagger.v3.oas.annotations.media.Schema;
-import lombok.*;
+import lombok.Data;
 
 @Schema(description = "管理后台 - 微信消息模板新增/修改 Request VO")
 @Data
@@ -19,4 +19,4 @@ public class WechatMsgTemplateSaveReqVO {
     @Schema(description = "消息模板参数")
     private String messageTemplateParameters;
 
-}
+}

+ 50 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/dal/dataobject/config/SystemConfigDO.java

@@ -0,0 +1,50 @@
+package cn.newfeifan.mall.module.system.dal.dataobject.config;
+
+import cn.newfeifan.mall.framework.mybatis.core.dataobject.BaseDO;
+import com.baomidou.mybatisplus.annotation.KeySequence;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.*;
+
+/**
+ * 系统配置 DO
+ *
+ * @author 非繁人
+ */
+@TableName("system_config")
+@KeySequence("system_config_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class SystemConfigDO extends BaseDO {
+
+    /**
+     * 主键
+     */
+    @TableId
+    private Long id;
+    /**
+     * 微信服务号appid
+     */
+    private String wechatAppid;
+    /**
+     * 微信服务号秘钥
+     */
+    private String wechatSecretKey;
+    /**
+     * 平台端协议+域名+端口
+     */
+    private String platformDomain;
+    /**
+     * 商户端协议+域名+端口
+     */
+    private String merchantDomain;
+    /**
+     * 移动商城端协议+域名+端口
+     */
+    private String mallDomain;
+
+}

+ 29 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/dal/mysql/config/SystemConfigMapper.java

@@ -0,0 +1,29 @@
+package cn.newfeifan.mall.module.system.dal.mysql.config;
+
+import cn.newfeifan.mall.framework.common.pojo.PageResult;
+import cn.newfeifan.mall.framework.mybatis.core.mapper.BaseMapperX;
+import cn.newfeifan.mall.framework.mybatis.core.query.LambdaQueryWrapperX;
+import cn.newfeifan.mall.module.system.controller.admin.config.vo.ConfigPageReqVO;
+import cn.newfeifan.mall.module.system.dal.dataobject.config.SystemConfigDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 系统配置 Mapper
+ *
+ * @author 非繁人
+ */
+@Mapper
+public interface SystemConfigMapper extends BaseMapperX<SystemConfigDO> {
+
+    default PageResult<SystemConfigDO> selectPage(ConfigPageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<SystemConfigDO>()
+                .eqIfPresent(SystemConfigDO::getWechatAppid, reqVO.getWechatAppid())
+                .eqIfPresent(SystemConfigDO::getWechatSecretKey, reqVO.getWechatSecretKey())
+                .eqIfPresent(SystemConfigDO::getPlatformDomain, reqVO.getPlatformDomain())
+                .eqIfPresent(SystemConfigDO::getMerchantDomain, reqVO.getMerchantDomain())
+                .eqIfPresent(SystemConfigDO::getMallDomain, reqVO.getMallDomain())
+                .betweenIfPresent(SystemConfigDO::getCreateTime, reqVO.getCreateTime())
+                .orderByDesc(SystemConfigDO::getId));
+    }
+
+}

+ 2 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/dal/mysql/social/SocialUserMapper.java

@@ -7,6 +7,7 @@ import cn.newfeifan.mall.module.system.controller.admin.socail.vo.user.SocialUse
 import cn.newfeifan.mall.module.system.dal.dataobject.social.SocialUserDO;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 @Mapper
 public interface SocialUserMapper extends BaseMapperX<SocialUserDO> {
@@ -33,4 +34,5 @@ public interface SocialUserMapper extends BaseMapperX<SocialUserDO> {
                 .orderByDesc(SocialUserDO::getId));
     }
 
+    String getOpenIdByUserId(@Param("userId") Long userId);
 }

+ 67 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/config/SystemConfigService.java

@@ -0,0 +1,67 @@
+package cn.newfeifan.mall.module.system.service.config;
+
+import cn.newfeifan.mall.framework.common.pojo.PageResult;
+import cn.newfeifan.mall.module.system.controller.admin.config.vo.ConfigPageReqVO;
+import cn.newfeifan.mall.module.system.controller.admin.config.vo.ConfigSaveReqVO;
+import cn.newfeifan.mall.module.system.dal.dataobject.config.SystemConfigDO;
+
+import javax.validation.Valid;
+
+/**
+ * 系统配置 Service 接口
+ *
+ * @author 非繁人
+ */
+public interface SystemConfigService {
+
+    /**
+     * 创建系统配置
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createConfig(@Valid ConfigSaveReqVO createReqVO);
+
+    /**
+     * 更新系统配置
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateConfig(@Valid ConfigSaveReqVO updateReqVO);
+
+    /**
+     * 删除系统配置
+     *
+     * @param id 编号
+     */
+    void deleteConfig(Long id);
+
+    /**
+     * 获得系统配置
+     *
+     * @param id 编号
+     * @return 系统配置
+     */
+    SystemConfigDO getConfig(Long id);
+
+    /**
+     * 获取系统配置
+     * @return 系统配置
+     */
+    SystemConfigDO getConfig();
+
+    /**
+     * 获取常量系统配置
+     * @return 系统配置
+     */
+    SystemConfigDO getRedisConfig();
+
+    /**
+     * 获得系统配置分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 系统配置分页
+     */
+    PageResult<SystemConfigDO> getConfigPage(ConfigPageReqVO pageReqVO);
+
+}

+ 97 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/config/SystemConfigServiceImpl.java

@@ -0,0 +1,97 @@
+package cn.newfeifan.mall.module.system.service.config;
+
+import cn.newfeifan.mall.framework.common.pojo.PageResult;
+import cn.newfeifan.mall.framework.common.util.object.BeanUtils;
+import cn.newfeifan.mall.module.system.controller.admin.config.bo.SystemConfigBO;
+import cn.newfeifan.mall.module.system.controller.admin.config.vo.ConfigPageReqVO;
+import cn.newfeifan.mall.module.system.controller.admin.config.vo.ConfigSaveReqVO;
+import cn.newfeifan.mall.module.system.dal.dataobject.config.SystemConfigDO;
+import cn.newfeifan.mall.module.system.dal.mysql.config.SystemConfigMapper;
+import com.alibaba.fastjson.JSONObject;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import javax.annotation.Resource;
+
+import static cn.newfeifan.mall.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.newfeifan.mall.module.system.constant.SystemConstants.SYSTEM_CONFIG;
+import static cn.newfeifan.mall.module.system.enums.ErrorCodeConstants.CONFIG_NOT_EXISTS;
+
+/**
+ * 系统配置 Service 实现类
+ *
+ * @author 非繁人
+ */
+@Service
+@Validated
+public class SystemConfigServiceImpl implements SystemConfigService {
+
+    @Resource
+    private SystemConfigMapper systemConfigMapper;
+    @Resource
+    private StringRedisTemplate stringRedisTemplate;
+
+    @Override
+    public Long createConfig(ConfigSaveReqVO createReqVO) {
+        // 插入
+        SystemConfigDO config = BeanUtils.toBean(createReqVO, SystemConfigDO.class);
+        systemConfigMapper.insert(config);
+        // 返回
+        return config.getId();
+    }
+
+    @Override
+    public void updateConfig(ConfigSaveReqVO updateReqVO) {
+        // 校验存在
+        validateConfigExists(updateReqVO.getId());
+        // 更新
+        SystemConfigDO updateObj = BeanUtils.toBean(updateReqVO, SystemConfigDO.class);
+        systemConfigMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteConfig(Long id) {
+        // 校验存在
+        validateConfigExists(id);
+        // 删除
+        systemConfigMapper.deleteById(id);
+    }
+
+    private void validateConfigExists(Long id) {
+        if (systemConfigMapper.selectById(id) == null) {
+            throw exception(CONFIG_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public SystemConfigDO getConfig(Long id) {
+        return systemConfigMapper.selectById(id);
+    }
+
+    @Override
+    public SystemConfigDO getConfig() {
+        return systemConfigMapper.selectList().get(0);
+    }
+
+    @Override
+    public SystemConfigDO getRedisConfig() {
+        String s = stringRedisTemplate.opsForValue().get(SYSTEM_CONFIG);
+        if (s != null) {
+            SystemConfigBO systemConfigBO = JSONObject.parseObject(s, SystemConfigBO.class);
+            return SystemConfigDO.builder()
+                    .id(systemConfigBO.getId())
+                    .mallDomain(systemConfigBO.getMallDomain())
+                    .merchantDomain(systemConfigBO.getMerchantDomain())
+                    .platformDomain(systemConfigBO.getPlatformDomain())
+                    .build();
+        }
+        return getConfig();
+    }
+
+    @Override
+    public PageResult<SystemConfigDO> getConfigPage(ConfigPageReqVO pageReqVO) {
+        return systemConfigMapper.selectPage(pageReqVO);
+    }
+
+}

+ 1 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/social/SocialUserService.java

@@ -86,4 +86,5 @@ public interface SocialUserService {
      */
     PageResult<SocialUserDO> getSocialUserPage(SocialUserPageReqVO pageReqVO);
 
+    String getOpenIdByUserId(Long userId);
 }

+ 5 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/social/SocialUserServiceImpl.java

@@ -170,4 +170,9 @@ public class SocialUserServiceImpl implements SocialUserService {
         return socialUserMapper.selectPage(pageReqVO);
     }
 
+    @Override
+    public String getOpenIdByUserId(Long userId) {
+        return socialUserMapper.getOpenIdByUserId(userId);
+    }
+
 }

+ 15 - 1
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/wechatmsgtemplate/WechatMsgTemplateService.java

@@ -5,6 +5,8 @@ import cn.newfeifan.mall.module.system.controller.admin.wechatmsgtemplate.vo.*;
 import cn.newfeifan.mall.module.system.dal.dataobject.wechatmsgtemplate.WechatMsgTemplateDO;
 import cn.newfeifan.mall.framework.common.pojo.PageResult;
 
+import java.util.List;
+
 /**
  * 微信消息模板 Service 接口
  *
@@ -50,4 +52,16 @@ public interface WechatMsgTemplateService {
      */
     PageResult<WechatMsgTemplateDO> getWechatMsgTemplatePage(WechatMsgTemplatePageReqVO pageReqVO);
 
-}
+    /**
+     * 获取微信模板
+     * @param wechatMsgId 自定义的模板id
+     * @return 微信模板
+     */
+    WechatMsgTemplateDO getWechatSsgTemplate(Long wechatMsgId);
+
+    /**
+     * 获取微信模板
+     * @return 微信模板
+     */
+    List<WechatMsgTemplateDO> selectList();
+}

+ 30 - 1
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/wechatmsgtemplate/WechatMsgTemplateServiceImpl.java

@@ -1,5 +1,8 @@
 package cn.newfeifan.mall.module.system.service.wechatmsgtemplate;
 
+import cn.newfeifan.mall.module.system.controller.admin.wechatmsgtemplate.bo.WechatMsgTemplateBO;
+import com.alibaba.fastjson.JSONObject;
+import org.springframework.data.redis.core.StringRedisTemplate;
 import org.springframework.stereotype.Service;
 import javax.annotation.Resource;
 import org.springframework.validation.annotation.Validated;
@@ -10,7 +13,10 @@ import cn.newfeifan.mall.framework.common.util.object.BeanUtils;
 
 import cn.newfeifan.mall.module.system.dal.mysql.wechatmsgtemplate.WechatMsgTemplateMapper;
 
+import java.util.List;
+
 import static cn.newfeifan.mall.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.newfeifan.mall.module.system.constant.SystemConstants.SYSTEM_WX_MESSAGE_TEMPLATE;
 import static cn.newfeifan.mall.module.system.enums.ErrorCodeConstants.*;
 
 /**
@@ -24,6 +30,8 @@ public class WechatMsgTemplateServiceImpl implements WechatMsgTemplateService {
 
     @Resource
     private WechatMsgTemplateMapper wechatMsgTemplateMapper;
+    @Resource
+    private StringRedisTemplate stringRedisTemplate;
 
     @Override
     public Long createWechatMsgTemplate(WechatMsgTemplateSaveReqVO createReqVO) {
@@ -67,4 +75,25 @@ public class WechatMsgTemplateServiceImpl implements WechatMsgTemplateService {
         return wechatMsgTemplateMapper.selectPage(pageReqVO);
     }
 
-}
+    @Override
+    public WechatMsgTemplateDO getWechatSsgTemplate(Long wechatMsgId) {
+        String s = stringRedisTemplate.opsForValue().get(SYSTEM_WX_MESSAGE_TEMPLATE + wechatMsgId);
+        if(s != null){
+            WechatMsgTemplateBO wechatMsgTemplateBO = JSONObject.parseObject(s, WechatMsgTemplateBO.class);
+            return WechatMsgTemplateDO.builder()
+                    .wechatMsgTemplateId(wechatMsgTemplateBO.getWechatMsgTemplateId())
+                    .messageTemplateParameters(wechatMsgTemplateBO.getMessageTemplateParameters())
+                    .remark(wechatMsgTemplateBO.getRemark())
+                    .id(wechatMsgTemplateBO.getId())
+                    .build();
+        }
+
+        return wechatMsgTemplateMapper.selectById(wechatMsgId);
+    }
+
+    @Override
+    public List<WechatMsgTemplateDO> selectList() {
+        return wechatMsgTemplateMapper.selectList();
+    }
+
+}

+ 12 - 0
feifan-module-system/feifan-module-system-biz/src/main/resources/mapper/config/ConfigMapper.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.newfeifan.mall.module.system.dal.mysql.config.SystemConfigMapper">
+
+    <!--
+        一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
+        无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
+        代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
+        文档可见:https://www.zhongxing.cn/MyBatis/x-plugins/
+     -->
+
+</mapper>

+ 10 - 0
feifan-module-system/feifan-module-system-biz/src/main/resources/mapper/social/SocialUserMapper.xml

@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="cn.newfeifan.mall.module.system.dal.mysql.social.SocialUserMapper">
+
+    <select id="getOpenIdByUserId" resultType="string" parameterType="long">
+        SELECT openid FROM `system_social_user` u
+        left join system_social_user_bind b on u.id = b.social_user_id
+        where b.user_id = #{userId}
+    </select>
+</mapper>