Browse Source

对接微信信息模板

Yangzw 10 months ago
parent
commit
f0154c2835
49 changed files with 1984 additions and 18 deletions
  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. 22 0
      feifan-module-mall/feifan-module-trade-api/src/main/java/cn/newfeifan/mall/module/trade/enums/aftersale/AfterSaleMessageEnum.java
  4. 20 0
      feifan-module-mall/feifan-module-trade-api/src/main/java/cn/newfeifan/mall/module/trade/enums/wxmessage/WcChatMessageTemplateIdEnum.java
  5. 0 12
      feifan-module-mall/feifan-module-trade-biz/pom.xml
  6. 93 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/controller/admin/messagelog/MessageLogController.java
  7. 52 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/controller/admin/messagelog/vo/MessageLogPageReqVO.java
  8. 59 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/controller/admin/messagelog/vo/MessageLogRespVO.java
  9. 51 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/controller/admin/messagelog/vo/MessageLogSaveReqVO.java
  10. 68 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/dal/dataobject/messagelog/MessageLogDO.java
  11. 33 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/dal/mysql/messagelog/MessageLogMapper.java
  12. 51 6
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/service/aftersale/AfterSaleServiceImpl.java
  13. 55 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/service/messagelog/MessageLogService.java
  14. 71 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/service/messagelog/MessageLogServiceImpl.java
  15. 13 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/utils/wechat/WcChatMessageDto.java
  16. 271 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/utils/wechat/WcChatMessageUtils.java
  17. 36 0
      feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/utils/wechat/WeChatTemplateMessage.java
  18. 1 0
      feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/service/user/MemberUserService.java
  19. 6 0
      feifan-module-member/feifan-module-member-biz/src/main/java/cn/newfeifan/mall/module/member/service/user/MemberUserServiceImpl.java
  20. 10 0
      feifan-module-system/feifan-module-system-api/src/main/java/cn/newfeifan/mall/module/system/constant/SystemConstants.java
  21. 3 0
      feifan-module-system/feifan-module-system-api/src/main/java/cn/newfeifan/mall/module/system/enums/ErrorCodeConstants.java
  22. 62 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/config/StartConfig.java
  23. 93 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/config/SystemConfigController.java
  24. 31 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/config/bo/SystemConfigBO.java
  25. 39 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/config/vo/ConfigPageReqVO.java
  26. 43 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/config/vo/ConfigRespVO.java
  27. 28 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/config/vo/ConfigSaveReqVO.java
  28. 93 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/wechatmsgtemplate/WechatMsgTemplateController.java
  29. 17 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/wechatmsgtemplate/bo/WechatMsgTemplateBO.java
  30. 33 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/wechatmsgtemplate/vo/WechatMsgTemplatePageReqVO.java
  31. 35 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/wechatmsgtemplate/vo/WechatMsgTemplateRespVO.java
  32. 22 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/controller/admin/wechatmsgtemplate/vo/WechatMsgTemplateSaveReqVO.java
  33. 50 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/dal/dataobject/config/SystemConfigDO.java
  34. 17 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/dal/dataobject/user/AdminUserDO.java
  35. 42 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/dal/dataobject/wechatmsgtemplate/WechatMsgTemplateDO.java
  36. 29 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/dal/mysql/config/SystemConfigMapper.java
  37. 2 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/dal/mysql/social/SocialUserMapper.java
  38. 28 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/dal/mysql/wechatmsgtemplate/WechatMsgTemplateMapper.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. 2 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/permission/PermissionService.java
  42. 18 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/permission/PermissionServiceImpl.java
  43. 1 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/social/SocialUserService.java
  44. 5 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/social/SocialUserServiceImpl.java
  45. 7 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/user/AdminUserService.java
  46. 13 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/user/AdminUserServiceImpl.java
  47. 69 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/wechatmsgtemplate/WechatMsgTemplateService.java
  48. 100 0
      feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/wechatmsgtemplate/WechatMsgTemplateServiceImpl.java
  49. 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

@@ -93,4 +93,6 @@ public interface ErrorCodeConstants {
     ErrorCode BROKERAGE_WITHDRAW_MIN_PRICE = new ErrorCode(1_011_008_002, "提现金额不能低于 {} 元");
     ErrorCode BROKERAGE_WITHDRAW_USER_BALANCE_NOT_ENOUGH = new ErrorCode(1_011_008_003, "您当前最多可提现 {} 元");
 
+    ErrorCode MESSAGE_LOG_NOT_EXISTS = new ErrorCode(1_011_008_004, "微信模板消息日志不存在");
+
 }

+ 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]);
+
 }

+ 22 - 0
feifan-module-mall/feifan-module-trade-api/src/main/java/cn/newfeifan/mall/module/trade/enums/aftersale/AfterSaleMessageEnum.java

@@ -0,0 +1,22 @@
+package cn.newfeifan.mall.module.trade.enums.aftersale;
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+@AllArgsConstructor
+@Getter
+public enum AfterSaleMessageEnum {
+
+    APPLY_FOR_AFTER_SALE(1,"申请售后"),
+    WAIT_FOR_RECEIVING(2,"待收货");
+
+    /**
+     * 状态
+     */
+    private final Integer status;
+    /**
+     * 状态名
+     */
+    private final String name;
+
+}

+ 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;
+}

+ 0 - 12
feifan-module-mall/feifan-module-trade-biz/pom.xml

@@ -124,12 +124,6 @@
             <version>2.0.0-jdk8-snapshot</version>
             <scope>compile</scope>
         </dependency>
-        <dependency>
-            <groupId>cn.newfeifan.zx</groupId>
-            <artifactId>feifan-module-member-biz</artifactId>
-            <version>2.0.0-jdk8-snapshot</version>
-            <scope>compile</scope>
-        </dependency>
         <dependency>
             <groupId>cn.newfeifan.zx</groupId>
             <artifactId>feifan-module-distri-biz</artifactId>
@@ -142,12 +136,6 @@
             <version>2.0.0-jdk8-snapshot</version>
             <scope>compile</scope>
         </dependency>
-        <dependency>
-            <groupId>cn.newfeifan.zx</groupId>
-            <artifactId>feifan-module-pay-biz</artifactId>
-            <version>2.0.0-jdk8-snapshot</version>
-            <scope>compile</scope>
-        </dependency>
 
 
     </dependencies>

+ 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;
+
+}

+ 51 - 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,51 @@
+package cn.newfeifan.mall.module.trade.controller.admin.messagelog.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Builder;
+import lombok.Data;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+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;
+
+}

+ 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));
+    }
+
+}

+ 51 - 6
feifan-module-mall/feifan-module-trade-biz/src/main/java/cn/newfeifan/mall/module/trade/service/aftersale/AfterSaleServiceImpl.java

@@ -6,8 +6,10 @@ import cn.hutool.core.util.StrUtil;
 import cn.newfeifan.mall.framework.common.pojo.PageParam;
 import cn.newfeifan.mall.framework.common.pojo.PageResult;
 import cn.newfeifan.mall.framework.common.util.object.ObjectUtils;
+import cn.newfeifan.mall.module.member.service.user.MemberUserService;
 import cn.newfeifan.mall.module.pay.api.refund.PayRefundApi;
 import cn.newfeifan.mall.module.pay.api.refund.dto.PayRefundCreateReqDTO;
+import cn.newfeifan.mall.module.system.service.user.AdminUserService;
 import cn.newfeifan.mall.module.trade.controller.admin.aftersale.vo.AfterSaleDisagreeReqVO;
 import cn.newfeifan.mall.module.trade.controller.admin.aftersale.vo.AfterSalePageReqVO;
 import cn.newfeifan.mall.module.trade.controller.admin.aftersale.vo.AfterSaleRefuseReqVO;
@@ -20,18 +22,17 @@ import cn.newfeifan.mall.module.trade.dal.dataobject.order.TradeOrderDO;
 import cn.newfeifan.mall.module.trade.dal.dataobject.order.TradeOrderItemDO;
 import cn.newfeifan.mall.module.trade.dal.mysql.aftersale.AfterSaleMapper;
 import cn.newfeifan.mall.module.trade.dal.redis.no.TradeNoRedisDAO;
-import cn.newfeifan.mall.module.trade.enums.aftersale.AfterSaleOperateTypeEnum;
-import cn.newfeifan.mall.module.trade.enums.aftersale.AfterSaleStatusEnum;
-import cn.newfeifan.mall.module.trade.enums.aftersale.AfterSaleTypeEnum;
-import cn.newfeifan.mall.module.trade.enums.aftersale.AfterSaleWayEnum;
+import cn.newfeifan.mall.module.trade.enums.aftersale.*;
 import cn.newfeifan.mall.module.trade.enums.order.TradeOrderItemAfterSaleStatusEnum;
 import cn.newfeifan.mall.module.trade.enums.order.TradeOrderStatusEnum;
+import cn.newfeifan.mall.module.trade.enums.wxmessage.WcChatMessageTemplateIdEnum;
 import cn.newfeifan.mall.module.trade.framework.aftersale.core.annotations.AfterSaleLog;
 import cn.newfeifan.mall.module.trade.framework.aftersale.core.utils.AfterSaleLogUtils;
 import cn.newfeifan.mall.module.trade.framework.order.config.TradeOrderProperties;
 import cn.newfeifan.mall.module.trade.service.delivery.DeliveryExpressService;
 import cn.newfeifan.mall.module.trade.service.order.TradeOrderQueryService;
 import cn.newfeifan.mall.module.trade.service.order.TradeOrderUpdateService;
+import cn.newfeifan.mall.module.trade.utils.wechat.WcChatMessageUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
@@ -40,10 +41,15 @@ import org.springframework.transaction.support.TransactionSynchronizationManager
 import org.springframework.validation.annotation.Validated;
 
 import javax.annotation.Resource;
+import java.text.DecimalFormat;
 import java.time.LocalDateTime;
+import java.time.format.DateTimeFormatter;
+import java.util.ArrayList;
+import java.util.List;
 
 import static cn.newfeifan.mall.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.newfeifan.mall.module.trade.enums.ErrorCodeConstants.*;
+import cn.newfeifan.mall.module.trade.enums.aftersale.AfterSaleMessageEnum;
 
 /**
  * 售后订单 Service 实现类
@@ -72,6 +78,13 @@ public class AfterSaleServiceImpl implements AfterSaleService {
 
     @Resource
     private TradeOrderProperties tradeOrderProperties;
+    @Resource
+    private WcChatMessageUtils wcChatMessageUtils;
+    @Resource
+    private MemberUserService memberUserService;
+    @Resource
+    private AdminUserService adminUserService;
+
 
     @Override
     public PageResult<AfterSaleDO> getAfterSalePage(AfterSalePageReqVO pageReqVO) {
@@ -172,7 +185,10 @@ public class AfterSaleServiceImpl implements AfterSaleService {
         AfterSaleLogUtils.setAfterSaleInfo(afterSale.getId(), null,
                 AfterSaleStatusEnum.APPLY.getStatus());
 
-        // TODO 发送售后消息
+        // 发送售后消息
+        //发送微信模板消息给店铺及管理员
+        sentWcChatMessage(afterSale,AfterSaleMessageEnum.APPLY_FOR_AFTER_SALE.getName());
+
         return afterSale;
     }
 
@@ -269,7 +285,36 @@ public class AfterSaleServiceImpl implements AfterSaleService {
                 MapUtil.<String, Object>builder().put("deliveryName", express.getName())
                         .put("logisticsNo", deliveryReqVO.getLogisticsNo()).build());
 
-        // TODO 发送售后消息
+        // 发送售后消息
+        // 发送微信模板消息给店铺及管理员
+        sentWcChatMessage(afterSale,AfterSaleMessageEnum.WAIT_FOR_RECEIVING.getName());
+    }
+
+    /**
+     * 发送微信消息
+     *
+     * @param afterSale       售后订单
+     * @param afterSaleStatus 售后状态
+     */
+    private void sentWcChatMessage(AfterSaleDO afterSale, String afterSaleStatus) {
+        List<String> params = new ArrayList<>();
+        params.add(afterSale.getNo());
+        params.add(memberUserService.getUser(afterSale.getUserId()).getNickname());
+
+        DecimalFormat df = new DecimalFormat("0.00");
+        String formattedPrice = df.format((double) afterSale.getRefundPrice() / 100);
+
+        params.add("¥ " + formattedPrice);
+        params.add(afterSaleStatus);
+        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+        params.add(LocalDateTime.now().format(formatter));
+
+        List<Long> adminUsers = adminUserService.getUserIdsByShop(afterSale.getShopId());
+        for (Long aUserId : adminUsers) {
+            //发送信息
+            wcChatMessageUtils.sendWcChatMessage(afterSale.getUserId(), WcChatMessageTemplateIdEnum.AFTER_SALE_NO_CHECK.getTemplateId(),
+                    params, aUserId, null, afterSale.getId());
+        }
     }
 
     @Override

+ 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);
+    }
+
+}

+ 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;
+
+}

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

@@ -0,0 +1,271 @@
+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())) {
+            //如果该用户没有该消息的权限,则不发送消息
+            if (!isHavePermission(systemUserId, wechatMsgTemplateId)) {
+                return;
+            }
+            userOpenId = getOpenIdBySysTemUserId(systemUserId);
+            memberUserId = memberUserService.getUserIdBySystemUserId(systemUserId);
+        } else {
+            userOpenId = getOpenId(userId);
+        }
+
+        //如果用户没有绑定微信,则不发送消息
+        if (userOpenId == null) {
+            return;
+        }
+
+        String templateId = getTemplateId(wechatMsgTemplateId).getWechatMsgTemplateId(); // 模板id
+        String url = getDoMain(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.isHavePermission(userId, AFTER_SALE_NO_CHECK_List);
+        } else if (templateId.equals(WcChatMessageTemplateIdEnum.ORDER_NO_DELIVERY.getTemplateId())) {
+            // 订单待发货
+            return permissionService.isHavePermission(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.getMerchantDomain() + "/after-sale";
+        } else if (templateId.equals(WcChatMessageTemplateIdEnum.ORDER_NO_DELIVERY.getTemplateId())) {
+            //订单待发货
+            return redisConfig.getMerchantDomain() + "/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() + "}";
+    }
+}

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

@@ -190,4 +190,5 @@ public interface MemberUserService {
      */
     boolean updateUserPoint(Long userId, Integer point);
 
+    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

@@ -343,4 +343,10 @@ public class MemberUserServiceImpl implements MemberUserService {
         return true;
     }
 
+    @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";
+
+}

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

@@ -173,4 +173,7 @@ public interface ErrorCodeConstants {
     // ========== 站内信发送 1-002-028-000 ==========
     ErrorCode NOTIFY_SEND_TEMPLATE_PARAM_MISS = new ErrorCode(1_002_028_000, "模板参数({})缺失");
 
+    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;
+
+}

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

@@ -0,0 +1,93 @@
+package cn.newfeifan.mall.module.system.controller.admin.wechatmsgtemplate;
+
+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.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
+@RequestMapping("/system/wechat-msg-template")
+@Validated
+public class WechatMsgTemplateController {
+
+    @Resource
+    private WechatMsgTemplateService wechatMsgTemplateService;
+
+    @PostMapping("/create")
+    @Operation(summary = "创建微信消息模板")
+    @PreAuthorize("@ss.hasPermission('system:wechat-msg-template:create')")
+    public CommonResult<Long> createWechatMsgTemplate(@Valid @RequestBody WechatMsgTemplateSaveReqVO createReqVO) {
+        return success(wechatMsgTemplateService.createWechatMsgTemplate(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @Operation(summary = "更新微信消息模板")
+    @PreAuthorize("@ss.hasPermission('system:wechat-msg-template:update')")
+    public CommonResult<Boolean> updateWechatMsgTemplate(@Valid @RequestBody WechatMsgTemplateSaveReqVO updateReqVO) {
+        wechatMsgTemplateService.updateWechatMsgTemplate(updateReqVO);
+        return success(true);
+    }
+
+    @DeleteMapping("/delete")
+    @Operation(summary = "删除微信消息模板")
+    @Parameter(name = "id", description = "编号", required = true)
+    @PreAuthorize("@ss.hasPermission('system:wechat-msg-template:delete')")
+    public CommonResult<Boolean> deleteWechatMsgTemplate(@RequestParam("id") Long id) {
+        wechatMsgTemplateService.deleteWechatMsgTemplate(id);
+        return success(true);
+    }
+
+    @GetMapping("/get")
+    @Operation(summary = "获得微信消息模板")
+    @Parameter(name = "id", description = "编号", required = true, example = "1024")
+    @PreAuthorize("@ss.hasPermission('system:wechat-msg-template:query')")
+    public CommonResult<WechatMsgTemplateRespVO> getWechatMsgTemplate(@RequestParam("id") Long id) {
+        WechatMsgTemplateDO wechatMsgTemplate = wechatMsgTemplateService.getWechatMsgTemplate(id);
+        return success(BeanUtils.toBean(wechatMsgTemplate, WechatMsgTemplateRespVO.class));
+    }
+
+    @GetMapping("/page")
+    @Operation(summary = "获得微信消息模板分页")
+    @PreAuthorize("@ss.hasPermission('system:wechat-msg-template:query')")
+    public CommonResult<PageResult<WechatMsgTemplateRespVO>> getWechatMsgTemplatePage(@Valid WechatMsgTemplatePageReqVO pageReqVO) {
+        PageResult<WechatMsgTemplateDO> pageResult = wechatMsgTemplateService.getWechatMsgTemplatePage(pageReqVO);
+        return success(BeanUtils.toBean(pageResult, WechatMsgTemplateRespVO.class));
+    }
+
+    @GetMapping("/export-excel")
+    @Operation(summary = "导出微信消息模板 Excel")
+    @PreAuthorize("@ss.hasPermission('system:wechat-msg-template:export')")
+    @OperateLog(type = EXPORT)
+    public void exportWechatMsgTemplateExcel(@Valid WechatMsgTemplatePageReqVO pageReqVO,
+              HttpServletResponse response) throws IOException {
+        pageReqVO.setPageSize(PageParam.PAGE_SIZE_NONE);
+        List<WechatMsgTemplateDO> list = wechatMsgTemplateService.getWechatMsgTemplatePage(pageReqVO).getList();
+        // 导出 Excel
+        ExcelUtils.write(response, "微信消息模板.xls", "数据", WechatMsgTemplateRespVO.class,
+                        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;
+}

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

@@ -0,0 +1,33 @@
+package cn.newfeifan.mall.module.system.controller.admin.wechatmsgtemplate.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 WechatMsgTemplatePageReqVO extends PageParam {
+
+    @Schema(description = "微信消息模板id", example = "29466")
+    private String wechatMsgTemplateId;
+
+    @Schema(description = "备注、说明", example = "随便")
+    private String remark;
+
+    @Schema(description = "消息模板参数")
+    private String messageTemplateParameters;
+
+    @Schema(description = "创建时间")
+    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
+    private LocalDateTime[] createTime;
+
+}

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

@@ -0,0 +1,35 @@
+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.Data;
+
+import java.time.LocalDateTime;
+
+@Schema(description = "管理后台 - 微信消息模板 Response VO")
+@Data
+@ExcelIgnoreUnannotated
+public class WechatMsgTemplateRespVO {
+
+    @Schema(description = "模板id,非自增,由开发人员编号,对应java中的常量", requiredMode = Schema.RequiredMode.REQUIRED, example = "13788")
+    @ExcelProperty("模板id,非自增,由开发人员编号,对应java中的常量")
+    private Long id;
+
+    @Schema(description = "微信消息模板id", example = "29466")
+    @ExcelProperty("微信消息模板id")
+    private String wechatMsgTemplateId;
+
+    @Schema(description = "备注、说明", example = "随便")
+    @ExcelProperty("备注、说明")
+    private String remark;
+
+    @Schema(description = "消息模板参数")
+    @ExcelProperty("消息模板参数")
+    private String messageTemplateParameters;
+
+    @Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)
+    @ExcelProperty("创建时间")
+    private LocalDateTime createTime;
+
+}

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

@@ -0,0 +1,22 @@
+package cn.newfeifan.mall.module.system.controller.admin.wechatmsgtemplate.vo;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+@Schema(description = "管理后台 - 微信消息模板新增/修改 Request VO")
+@Data
+public class WechatMsgTemplateSaveReqVO {
+
+    @Schema(description = "模板id,非自增,由开发人员编号,对应java中的常量", requiredMode = Schema.RequiredMode.REQUIRED, example = "13788")
+    private Long id;
+
+    @Schema(description = "微信消息模板id", example = "29466")
+    private String wechatMsgTemplateId;
+
+    @Schema(description = "备注、说明", example = "随便")
+    private String remark;
+
+    @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;
+
+}

+ 17 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/dal/dataobject/user/AdminUserDO.java

@@ -93,4 +93,21 @@ public class AdminUserDO extends TenantBaseDO {
      */
     private LocalDateTime loginDate;
 
+    /**
+     * 店铺id
+     */
+    private Long shopId;
+    /**
+     * 所在地
+     */
+    private Long areaId;
+    /**
+     * 商户id
+     */
+    private Long merchantId;
+    /**
+     * 姓名,只是用来看的,不是用户名
+     */
+    private String name;
+
 }

+ 42 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/dal/dataobject/wechatmsgtemplate/WechatMsgTemplateDO.java

@@ -0,0 +1,42 @@
+package cn.newfeifan.mall.module.system.dal.dataobject.wechatmsgtemplate;
+
+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_wechat_msg_template")
+@KeySequence("system_wechat_msg_template_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+@Builder
+@NoArgsConstructor
+@AllArgsConstructor
+public class WechatMsgTemplateDO extends BaseDO {
+
+    /**
+     * 模板id,非自增,由开发人员编号,对应java中的常量
+     */
+    @TableId
+    private Long id;
+    /**
+     * 微信消息模板id
+     */
+    private String wechatMsgTemplateId;
+    /**
+     * 备注、说明
+     */
+    private String remark;
+    /**
+     * 消息模板参数
+     */
+    private String messageTemplateParameters;
+
+}

+ 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);
 }

+ 28 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/dal/mysql/wechatmsgtemplate/WechatMsgTemplateMapper.java

@@ -0,0 +1,28 @@
+package cn.newfeifan.mall.module.system.dal.mysql.wechatmsgtemplate;
+
+
+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.wechatmsgtemplate.vo.WechatMsgTemplatePageReqVO;
+import cn.newfeifan.mall.module.system.dal.dataobject.wechatmsgtemplate.WechatMsgTemplateDO;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * 微信消息模板 Mapper
+ *
+ * @author 非繁人
+ */
+@Mapper
+public interface WechatMsgTemplateMapper extends BaseMapperX<WechatMsgTemplateDO> {
+
+    default PageResult<WechatMsgTemplateDO> selectPage(WechatMsgTemplatePageReqVO reqVO) {
+        return selectPage(reqVO, new LambdaQueryWrapperX<WechatMsgTemplateDO>()
+                .eqIfPresent(WechatMsgTemplateDO::getWechatMsgTemplateId, reqVO.getWechatMsgTemplateId())
+                .eqIfPresent(WechatMsgTemplateDO::getRemark, reqVO.getRemark())
+                .eqIfPresent(WechatMsgTemplateDO::getMessageTemplateParameters, reqVO.getMessageTemplateParameters())
+                .betweenIfPresent(WechatMsgTemplateDO::getCreateTime, reqVO.getCreateTime())
+                .orderByDesc(WechatMsgTemplateDO::getId));
+    }
+
+}

+ 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.infra.enums.ErrorCodeConstants.CONFIG_NOT_EXISTS;
+import static cn.newfeifan.mall.module.system.constant.SystemConstants.SYSTEM_CONFIG;
+
+/**
+ * 系统配置 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);
+    }
+
+}

+ 2 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/permission/PermissionService.java

@@ -143,4 +143,6 @@ public interface PermissionService {
      */
     DeptDataPermissionRespDTO getDeptDataPermission(Long userId);
 
+    Boolean isHavePermission(Long userId, String... permissions);
+
 }

+ 18 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/permission/PermissionServiceImpl.java

@@ -19,6 +19,7 @@ import cn.newfeifan.mall.module.system.enums.permission.DataScopeEnum;
 import cn.newfeifan.mall.module.system.service.dept.DeptService;
 import cn.newfeifan.mall.module.system.service.user.AdminUserService;
 import com.baomidou.dynamic.datasource.annotation.DSTransactional;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.google.common.annotations.VisibleForTesting;
 import com.google.common.base.Suppliers;
 import com.google.common.collect.Sets;
@@ -32,6 +33,7 @@ import org.springframework.transaction.annotation.Transactional;
 import javax.annotation.Resource;
 import java.util.*;
 import java.util.function.Supplier;
+import java.util.stream.Collectors;
 
 import static cn.newfeifan.mall.framework.common.util.collection.CollectionUtils.convertSet;
 import static cn.newfeifan.mall.framework.common.util.json.JsonUtils.toJsonString;
@@ -325,6 +327,22 @@ public class PermissionServiceImpl implements PermissionService {
         return result;
     }
 
+    @Override
+    public Boolean isHavePermission(Long userId, String... permissions) {
+        List<UserRoleDO> userRoleDOS = userRoleMapper.selectList(new LambdaQueryWrapper<UserRoleDO>()
+                .eq(UserRoleDO::getUserId, userId));
+        List<Long> roleIds = userRoleDOS.stream().map(UserRoleDO::getRoleId).collect(Collectors.toList());
+        List<RoleMenuDO> roleMenuDOS = roleMenuMapper.selectList(new LambdaQueryWrapper<RoleMenuDO>()
+                .in(RoleMenuDO::getRoleId, roleIds));
+        List<Long> menuIds = roleMenuDOS.stream().map(RoleMenuDO::getMenuId).collect(Collectors.toList());
+
+        List<MenuDO> menuList = menuService.getMenuList(menuIds);
+        List<String> menuPermissions = menuList.stream().map(MenuDO::getPermission).collect(Collectors.toList());
+
+        Set<String> permissionSet = new HashSet<>(Arrays.asList(permissions));
+        return menuPermissions.stream().anyMatch(permissionSet::contains);
+    }
+
     /**
      * 获得自身的代理对象,解决 AOP 生效问题
      *

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

@@ -99,4 +99,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

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

+ 7 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/user/AdminUserService.java

@@ -208,4 +208,11 @@ public interface AdminUserService {
      */
     Long getUserIdByMobile(String mobile);
 
+    /**
+     * 通过店铺查询用户编号
+     * @param shopId 店铺id
+     * @return 用户编号
+     */
+    List<Long> getUserIdsByShop(Long shopId);
+
 }

+ 13 - 0
feifan-module-system/feifan-module-system-biz/src/main/java/cn/newfeifan/mall/module/system/service/user/AdminUserServiceImpl.java

@@ -26,6 +26,7 @@ import cn.newfeifan.mall.module.system.service.dept.DeptService;
 import cn.newfeifan.mall.module.system.service.dept.PostService;
 import cn.newfeifan.mall.module.system.service.permission.PermissionService;
 import cn.newfeifan.mall.module.system.service.tenant.TenantService;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.google.common.annotations.VisibleForTesting;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
@@ -38,6 +39,7 @@ import javax.annotation.Resource;
 import java.io.InputStream;
 import java.time.LocalDateTime;
 import java.util.*;
+import java.util.stream.Collectors;
 
 import static cn.newfeifan.mall.framework.common.exception.util.ServiceExceptionUtil.exception;
 import static cn.newfeifan.mall.framework.common.util.collection.CollectionUtils.convertList;
@@ -453,6 +455,17 @@ public class AdminUserServiceImpl implements AdminUserService {
         return adminUserDO != null ? adminUserDO.getId() : null;
     }
 
+    @Override
+    public List<Long> getUserIdsByShop(Long shopId) {
+        if(shopId != null){
+            List<AdminUserDO> adminUserDOS = userMapper.selectList(new LambdaQueryWrapper<AdminUserDO>()
+                    .eq(AdminUserDO::getShopId, shopId)
+            );
+            return adminUserDOS.stream().map(AdminUserDO::getId).collect(Collectors.toList());
+        }
+        return null;
+    }
+
     /**
      * 对密码进行加密
      *

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

@@ -0,0 +1,69 @@
+package cn.newfeifan.mall.module.system.service.wechatmsgtemplate;
+
+import cn.newfeifan.mall.framework.common.pojo.PageResult;
+import cn.newfeifan.mall.module.system.controller.admin.wechatmsgtemplate.vo.WechatMsgTemplatePageReqVO;
+import cn.newfeifan.mall.module.system.controller.admin.wechatmsgtemplate.vo.WechatMsgTemplateSaveReqVO;
+import cn.newfeifan.mall.module.system.dal.dataobject.wechatmsgtemplate.WechatMsgTemplateDO;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 微信消息模板 Service 接口
+ *
+ * @author 非繁人
+ */
+public interface WechatMsgTemplateService {
+
+    /**
+     * 创建微信消息模板
+     *
+     * @param createReqVO 创建信息
+     * @return 编号
+     */
+    Long createWechatMsgTemplate(@Valid WechatMsgTemplateSaveReqVO createReqVO);
+
+    /**
+     * 更新微信消息模板
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateWechatMsgTemplate(@Valid WechatMsgTemplateSaveReqVO updateReqVO);
+
+    /**
+     * 删除微信消息模板
+     *
+     * @param id 编号
+     */
+    void deleteWechatMsgTemplate(Long id);
+
+    /**
+     * 获得微信消息模板
+     *
+     * @param id 编号
+     * @return 微信消息模板
+     */
+    WechatMsgTemplateDO getWechatMsgTemplate(Long id);
+
+    /**
+     * 获得微信消息模板分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 微信消息模板分页
+     */
+    PageResult<WechatMsgTemplateDO> getWechatMsgTemplatePage(WechatMsgTemplatePageReqVO pageReqVO);
+
+    /**
+     * 获取微信模板
+     * @param wechatMsgId 自定义的模板id
+     * @return 微信模板
+     */
+    WechatMsgTemplateDO getWechatSsgTemplate(Long wechatMsgId);
+
+    /**
+     * 获取微信模板
+     * @return 微信模板
+     */
+    List<WechatMsgTemplateDO> selectList();
+
+}

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

@@ -0,0 +1,100 @@
+package cn.newfeifan.mall.module.system.service.wechatmsgtemplate;
+
+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.wechatmsgtemplate.bo.WechatMsgTemplateBO;
+import cn.newfeifan.mall.module.system.controller.admin.wechatmsgtemplate.vo.WechatMsgTemplatePageReqVO;
+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.dal.mysql.wechatmsgtemplate.WechatMsgTemplateMapper;
+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 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.WECHAT_MSG_TEMPLATE_NOT_EXISTS;
+
+/**
+ * 微信消息模板 Service 实现类
+ *
+ * @author 非繁人
+ */
+@Service
+@Validated
+public class WechatMsgTemplateServiceImpl implements WechatMsgTemplateService {
+
+    @Resource
+    private WechatMsgTemplateMapper wechatMsgTemplateMapper;
+
+    @Resource
+    private StringRedisTemplate stringRedisTemplate;
+
+    @Override
+    public Long createWechatMsgTemplate(WechatMsgTemplateSaveReqVO createReqVO) {
+        // 插入
+        WechatMsgTemplateDO wechatMsgTemplate = BeanUtils.toBean(createReqVO, WechatMsgTemplateDO.class);
+        wechatMsgTemplateMapper.insert(wechatMsgTemplate);
+        // 返回
+        return wechatMsgTemplate.getId();
+    }
+
+    @Override
+    public void updateWechatMsgTemplate(WechatMsgTemplateSaveReqVO updateReqVO) {
+        // 校验存在
+        validateWechatMsgTemplateExists(updateReqVO.getId());
+        // 更新
+        WechatMsgTemplateDO updateObj = BeanUtils.toBean(updateReqVO, WechatMsgTemplateDO.class);
+        wechatMsgTemplateMapper.updateById(updateObj);
+    }
+
+    @Override
+    public void deleteWechatMsgTemplate(Long id) {
+        // 校验存在
+        validateWechatMsgTemplateExists(id);
+        // 删除
+        wechatMsgTemplateMapper.deleteById(id);
+    }
+
+    private void validateWechatMsgTemplateExists(Long id) {
+        if (wechatMsgTemplateMapper.selectById(id) == null) {
+            throw exception(WECHAT_MSG_TEMPLATE_NOT_EXISTS);
+        }
+    }
+
+    @Override
+    public WechatMsgTemplateDO getWechatMsgTemplate(Long id) {
+        return wechatMsgTemplateMapper.selectById(id);
+    }
+
+    @Override
+    public PageResult<WechatMsgTemplateDO> getWechatMsgTemplatePage(WechatMsgTemplatePageReqVO pageReqVO) {
+        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();
+    }
+
+}

+ 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>