Commit 39d377b0bdae941043ce7ab28f9f855db39177e0

Authored by YunaiV
1 parent cdb7348b

mp:完成关注和取消的 user 保存

Showing 22 changed files with 122 additions and 716 deletions
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/open/MpOpenController.java
@@ -100,6 +100,9 @@ public class MpOpenController { @@ -100,6 +100,9 @@ public class MpOpenController {
100 // 第二步,处理消息 100 // 第二步,处理消息
101 WxMpMessageRouter mpMessageRouter = mpServiceFactory.getRequiredMpMessageRouter(appId); 101 WxMpMessageRouter mpMessageRouter = mpServiceFactory.getRequiredMpMessageRouter(appId);
102 WxMpXmlOutMessage outMessage = mpMessageRouter.route(inMessage); 102 WxMpXmlOutMessage outMessage = mpMessageRouter.route(inMessage);
  103 + if (outMessage == null) {
  104 + return "";
  105 + }
103 106
104 // 第三步,返回消息 107 // 第三步,返回消息
105 if (StrUtil.isBlank(reqVO.getEncrypt_type())) { // 明文模式 108 if (StrUtil.isBlank(reqVO.getEncrypt_type())) { // 明文模式
@@ -107,7 +110,7 @@ public class MpOpenController { @@ -107,7 +110,7 @@ public class MpOpenController {
107 } else if (Objects.equals(reqVO.getEncrypt_type(), MpOpenHandleMessageReqVO.ENCRYPT_TYPE_AES)) { // AES 加密模式 110 } else if (Objects.equals(reqVO.getEncrypt_type(), MpOpenHandleMessageReqVO.ENCRYPT_TYPE_AES)) { // AES 加密模式
108 return outMessage.toEncryptedXml(mppService.getWxMpConfigStorage()); 111 return outMessage.toEncryptedXml(mppService.getWxMpConfigStorage());
109 } 112 }
110 - return null; 113 + return "";
111 } 114 }
112 115
113 } 116 }
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/subscribetext/WxSubscribeTextController.java deleted
1 -package cn.iocoder.yudao.module.mp.controller.admin.subscribetext;  
2 -  
3 -import org.springframework.web.bind.annotation.*;  
4 -  
5 -import javax.annotation.Resource;  
6 -  
7 -import org.springframework.validation.annotation.Validated;  
8 -import org.springframework.security.access.prepost.PreAuthorize;  
9 -import io.swagger.annotations.*;  
10 -  
11 -import javax.validation.*;  
12 -import javax.servlet.http.*;  
13 -import java.util.*;  
14 -import java.io.IOException;  
15 -  
16 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
17 -import cn.iocoder.yudao.framework.common.pojo.CommonResult;  
18 -  
19 -import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;  
20 -  
21 -import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;  
22 -  
23 -import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;  
24 -  
25 -import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;  
26 -  
27 -import cn.iocoder.yudao.module.mp.controller.admin.subscribetext.vo.*;  
28 -import cn.iocoder.yudao.module.mp.dal.dataobject.subscribetext.WxSubscribeTextDO;  
29 -import cn.iocoder.yudao.module.mp.convert.subscribetext.WxSubscribeTextConvert;  
30 -import cn.iocoder.yudao.module.mp.service.subscribetext.WxSubscribeTextService;  
31 -  
32 -@Api(tags = "管理后台 - 关注欢迎语")  
33 -@RestController  
34 -@RequestMapping("/wechatMp/wx-subscribe-text")  
35 -@Validated  
36 -public class WxSubscribeTextController {  
37 -  
38 - @Resource  
39 - private WxSubscribeTextService wxSubscribeTextService;  
40 -  
41 - @PostMapping("/create")  
42 - @ApiOperation("创建关注欢迎语")  
43 - @PreAuthorize("@ss.hasPermission('wechatMp:wx-subscribe-text:create')")  
44 - public CommonResult<Integer> createWxSubscribeText(@Valid @RequestBody WxSubscribeTextCreateReqVO createReqVO) {  
45 - return success(wxSubscribeTextService.createWxSubscribeText(createReqVO));  
46 - }  
47 -  
48 - @PutMapping("/update")  
49 - @ApiOperation("更新关注欢迎语")  
50 - @PreAuthorize("@ss.hasPermission('wechatMp:wx-subscribe-text:update')")  
51 - public CommonResult<Boolean> updateWxSubscribeText(@Valid @RequestBody WxSubscribeTextUpdateReqVO updateReqVO) {  
52 - wxSubscribeTextService.updateWxSubscribeText(updateReqVO);  
53 - return success(true);  
54 - }  
55 -  
56 - @DeleteMapping("/delete")  
57 - @ApiOperation("删除关注欢迎语")  
58 - @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Integer.class)  
59 - @PreAuthorize("@ss.hasPermission('wechatMp:wx-subscribe-text:delete')")  
60 - public CommonResult<Boolean> deleteWxSubscribeText(@RequestParam("id") Integer id) {  
61 - wxSubscribeTextService.deleteWxSubscribeText(id);  
62 - return success(true);  
63 - }  
64 -  
65 - @GetMapping("/get")  
66 - @ApiOperation("获得关注欢迎语")  
67 - @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Integer.class)  
68 - @PreAuthorize("@ss.hasPermission('wechatMp:wx-subscribe-text:query')")  
69 - public CommonResult<WxSubscribeTextRespVO> getWxSubscribeText(@RequestParam("id") Integer id) {  
70 - WxSubscribeTextDO wxSubscribeText = wxSubscribeTextService.getWxSubscribeText(id);  
71 - return success(WxSubscribeTextConvert.INSTANCE.convert(wxSubscribeText));  
72 - }  
73 -  
74 - @GetMapping("/list")  
75 - @ApiOperation("获得关注欢迎语列表")  
76 - @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)  
77 - @PreAuthorize("@ss.hasPermission('wechatMp:wx-subscribe-text:query')")  
78 - public CommonResult<List<WxSubscribeTextRespVO>> getWxSubscribeTextList(@RequestParam("ids") Collection<Integer> ids) {  
79 - List<WxSubscribeTextDO> list = wxSubscribeTextService.getWxSubscribeTextList(ids);  
80 - return success(WxSubscribeTextConvert.INSTANCE.convertList(list));  
81 - }  
82 -  
83 - @GetMapping("/page")  
84 - @ApiOperation("获得关注欢迎语分页")  
85 - @PreAuthorize("@ss.hasPermission('wechatMp:wx-subscribe-text:query')")  
86 - public CommonResult<PageResult<WxSubscribeTextRespVO>> getWxSubscribeTextPage(@Valid WxSubscribeTextPageReqVO pageVO) {  
87 - PageResult<WxSubscribeTextDO> pageResult = wxSubscribeTextService.getWxSubscribeTextPage(pageVO);  
88 - return success(WxSubscribeTextConvert.INSTANCE.convertPage(pageResult));  
89 - }  
90 -  
91 - @GetMapping("/export-excel")  
92 - @ApiOperation("导出关注欢迎语 Excel")  
93 - @PreAuthorize("@ss.hasPermission('wechatMp:wx-subscribe-text:export')")  
94 - @OperateLog(type = EXPORT)  
95 - public void exportWxSubscribeTextExcel(@Valid WxSubscribeTextExportReqVO exportReqVO,  
96 - HttpServletResponse response) throws IOException {  
97 - List<WxSubscribeTextDO> list = wxSubscribeTextService.getWxSubscribeTextList(exportReqVO);  
98 - // 导出 Excel  
99 - List<WxSubscribeTextExcelVO> datas = WxSubscribeTextConvert.INSTANCE.convertList02(list);  
100 - ExcelUtils.write(response, "关注欢迎语.xls", "数据", WxSubscribeTextExcelVO.class, datas);  
101 - }  
102 -  
103 -}  
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/subscribetext/vo/WxSubscribeTextBaseVO.java deleted
1 -package cn.iocoder.yudao.module.mp.controller.admin.subscribetext.vo;  
2 -  
3 -import lombok.*;  
4 -import io.swagger.annotations.*;  
5 -  
6 -/**  
7 - * 关注欢迎语 Base VO,提供给添加、修改、详细的子 VO 使用  
8 - * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成  
9 - */  
10 -@Data  
11 -public class WxSubscribeTextBaseVO {  
12 -  
13 - @ApiModelProperty(value = "消息类型 1文本消息;2图文消息;")  
14 - private String msgType;  
15 -  
16 - @ApiModelProperty(value = "模板ID")  
17 - private String tplId;  
18 -  
19 - @ApiModelProperty(value = "微信账号ID")  
20 - private String wxAccountId;  
21 -  
22 -}  
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/subscribetext/vo/WxSubscribeTextCreateReqVO.java deleted
1 -package cn.iocoder.yudao.module.mp.controller.admin.subscribetext.vo;  
2 -  
3 -import lombok.*;  
4 -import io.swagger.annotations.*;  
5 -  
6 -@ApiModel("管理后台 - 关注欢迎语创建 Request VO")  
7 -@Data  
8 -@EqualsAndHashCode(callSuper = true)  
9 -@ToString(callSuper = true)  
10 -public class WxSubscribeTextCreateReqVO extends WxSubscribeTextBaseVO {  
11 -  
12 -}  
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/subscribetext/vo/WxSubscribeTextExcelVO.java deleted
1 -package cn.iocoder.yudao.module.mp.controller.admin.subscribetext.vo;  
2 -  
3 -import lombok.*;  
4 -  
5 -import java.util.*;  
6 -  
7 -import com.alibaba.excel.annotation.ExcelProperty;  
8 -  
9 -/**  
10 - * 关注欢迎语 Excel VO  
11 - *  
12 - * @author 芋道源码  
13 - */  
14 -@Data  
15 -public class WxSubscribeTextExcelVO {  
16 -  
17 - @ExcelProperty("主键")  
18 - private Integer id;  
19 -  
20 - @ExcelProperty("消息类型 1文本消息;2图文消息;")  
21 - private String msgType;  
22 -  
23 - @ExcelProperty("模板ID")  
24 - private String tplId;  
25 -  
26 - @ExcelProperty("微信账号ID")  
27 - private String wxAccountId;  
28 -  
29 - @ExcelProperty("创建时间")  
30 - private Date createTime;  
31 -  
32 -}  
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/subscribetext/vo/WxSubscribeTextExportReqVO.java deleted
1 -package cn.iocoder.yudao.module.mp.controller.admin.subscribetext.vo;  
2 -  
3 -import lombok.*;  
4 -  
5 -import java.util.*;  
6 -  
7 -import io.swagger.annotations.*;  
8 -import org.springframework.format.annotation.DateTimeFormat;  
9 -  
10 -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;  
11 -  
12 -@ApiModel(value = "管理后台 - 关注欢迎语 Excel 导出 Request VO", description = "参数和 WxSubscribeTextPageReqVO 是一致的")  
13 -@Data  
14 -public class WxSubscribeTextExportReqVO {  
15 -  
16 - @ApiModelProperty(value = "消息类型 1文本消息;2图文消息;")  
17 - private String msgType;  
18 -  
19 - @ApiModelProperty(value = "模板ID")  
20 - private String tplId;  
21 -  
22 - @ApiModelProperty(value = "微信账号ID")  
23 - private String wxAccountId;  
24 -  
25 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
26 - @ApiModelProperty(value = "开始创建时间")  
27 - private Date beginCreateTime;  
28 -  
29 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
30 - @ApiModelProperty(value = "结束创建时间")  
31 - private Date endCreateTime;  
32 -  
33 -}  
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/subscribetext/vo/WxSubscribeTextPageReqVO.java deleted
1 -package cn.iocoder.yudao.module.mp.controller.admin.subscribetext.vo;  
2 -  
3 -import lombok.*;  
4 -  
5 -import java.util.*;  
6 -  
7 -import io.swagger.annotations.*;  
8 -import cn.iocoder.yudao.framework.common.pojo.PageParam;  
9 -import org.springframework.format.annotation.DateTimeFormat;  
10 -  
11 -import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;  
12 -  
13 -@ApiModel("管理后台 - 关注欢迎语分页 Request VO")  
14 -@Data  
15 -@EqualsAndHashCode(callSuper = true)  
16 -@ToString(callSuper = true)  
17 -public class WxSubscribeTextPageReqVO extends PageParam {  
18 -  
19 - @ApiModelProperty(value = "消息类型 1文本消息;2图文消息;")  
20 - private String msgType;  
21 -  
22 - @ApiModelProperty(value = "模板ID")  
23 - private String tplId;  
24 -  
25 - @ApiModelProperty(value = "微信账号ID")  
26 - private String wxAccountId;  
27 -  
28 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
29 - @ApiModelProperty(value = "开始创建时间")  
30 - private Date beginCreateTime;  
31 -  
32 - @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)  
33 - @ApiModelProperty(value = "结束创建时间")  
34 - private Date endCreateTime;  
35 -  
36 -}  
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/subscribetext/vo/WxSubscribeTextRespVO.java deleted
1 -package cn.iocoder.yudao.module.mp.controller.admin.subscribetext.vo;  
2 -  
3 -import lombok.*;  
4 -  
5 -import java.util.*;  
6 -  
7 -import io.swagger.annotations.*;  
8 -  
9 -@ApiModel("管理后台 - 关注欢迎语 Response VO")  
10 -@Data  
11 -@EqualsAndHashCode(callSuper = true)  
12 -@ToString(callSuper = true)  
13 -public class WxSubscribeTextRespVO extends WxSubscribeTextBaseVO {  
14 -  
15 - @ApiModelProperty(value = "主键", required = true)  
16 - private Integer id;  
17 -  
18 - @ApiModelProperty(value = "创建时间", required = true)  
19 - private Date createTime;  
20 -  
21 -}  
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/subscribetext/vo/WxSubscribeTextUpdateReqVO.java deleted
1 -package cn.iocoder.yudao.module.mp.controller.admin.subscribetext.vo;  
2 -  
3 -import lombok.*;  
4 -import io.swagger.annotations.*;  
5 -  
6 -import javax.validation.constraints.*;  
7 -  
8 -@ApiModel("管理后台 - 关注欢迎语更新 Request VO")  
9 -@Data  
10 -@EqualsAndHashCode(callSuper = true)  
11 -@ToString(callSuper = true)  
12 -public class WxSubscribeTextUpdateReqVO extends WxSubscribeTextBaseVO {  
13 -  
14 - @ApiModelProperty(value = "主键", required = true)  
15 - @NotNull(message = "主键不能为空")  
16 - private Integer id;  
17 -  
18 -}  
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/vo/MpUserBaseVO.java
@@ -31,9 +31,6 @@ public class MpUserBaseVO { @@ -31,9 +31,6 @@ public class MpUserBaseVO {
31 @ApiModelProperty(value = "昵称") 31 @ApiModelProperty(value = "昵称")
32 private String nickname; 32 private String nickname;
33 33
34 - @ApiModelProperty(value = "性别,1男,2女,0未知")  
35 - private Integer gender;  
36 -  
37 @ApiModelProperty(value = "语言") 34 @ApiModelProperty(value = "语言")
38 private String language; 35 private String language;
39 36
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/convert/subscribetext/WxSubscribeTextConvert.java deleted
1 -package cn.iocoder.yudao.module.mp.convert.subscribetext;  
2 -  
3 -import java.util.*;  
4 -  
5 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
6 -  
7 -import org.mapstruct.Mapper;  
8 -import org.mapstruct.factory.Mappers;  
9 -import cn.iocoder.yudao.module.mp.controller.admin.subscribetext.vo.*;  
10 -import cn.iocoder.yudao.module.mp.dal.dataobject.subscribetext.WxSubscribeTextDO;  
11 -  
12 -/**  
13 - * 关注欢迎语 Convert  
14 - *  
15 - * @author 芋道源码  
16 - */  
17 -@Mapper  
18 -public interface WxSubscribeTextConvert {  
19 -  
20 - WxSubscribeTextConvert INSTANCE = Mappers.getMapper(WxSubscribeTextConvert.class);  
21 -  
22 - WxSubscribeTextDO convert(WxSubscribeTextCreateReqVO bean);  
23 -  
24 - WxSubscribeTextDO convert(WxSubscribeTextUpdateReqVO bean);  
25 -  
26 - WxSubscribeTextRespVO convert(WxSubscribeTextDO bean);  
27 -  
28 - List<WxSubscribeTextRespVO> convertList(List<WxSubscribeTextDO> list);  
29 -  
30 - PageResult<WxSubscribeTextRespVO> convertPage(PageResult<WxSubscribeTextDO> page);  
31 -  
32 - List<WxSubscribeTextExcelVO> convertList02(List<WxSubscribeTextDO> list);  
33 -  
34 -}  
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/convert/user/MpUserConvert.java
1 package cn.iocoder.yudao.module.mp.convert.user; 1 package cn.iocoder.yudao.module.mp.convert.user;
2 2
  3 +import cn.hutool.core.date.LocalDateTimeUtil;
  4 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 5 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.module.mp.controller.admin.user.vo.MpUserRespVO; 6 import cn.iocoder.yudao.module.mp.controller.admin.user.vo.MpUserRespVO;
  7 +import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
5 import cn.iocoder.yudao.module.mp.dal.dataobject.user.MpUserDO; 8 import cn.iocoder.yudao.module.mp.dal.dataobject.user.MpUserDO;
  9 +import me.chanjar.weixin.mp.bean.result.WxMpUser;
6 import org.mapstruct.Mapper; 10 import org.mapstruct.Mapper;
  11 +import org.mapstruct.Mapping;
  12 +import org.mapstruct.Mappings;
7 import org.mapstruct.factory.Mappers; 13 import org.mapstruct.factory.Mappers;
8 14
9 import java.util.List; 15 import java.util.List;
@@ -19,4 +25,23 @@ public interface MpUserConvert { @@ -19,4 +25,23 @@ public interface MpUserConvert {
19 25
20 PageResult<MpUserRespVO> convertPage(PageResult<MpUserDO> page); 26 PageResult<MpUserRespVO> convertPage(PageResult<MpUserDO> page);
21 27
  28 + @Mappings(value = {
  29 + @Mapping(source = "openId", target = "openid"),
  30 + @Mapping(source = "headImgUrl", target = "headImageUrl"),
  31 + @Mapping(target = "subscribeTime", ignore = true), // 单独转换
  32 + })
  33 + MpUserDO convert(WxMpUser wxMpUser);
  34 +
  35 + default MpUserDO convert(MpAccountDO account, WxMpUser wxMpUser) {
  36 + MpUserDO user = convert(wxMpUser);
  37 + user.setSubscribeStatus(wxMpUser.getSubscribe() ? CommonStatusEnum.ENABLE.getStatus()
  38 + : CommonStatusEnum.DISABLE.getStatus());
  39 + user.setSubscribeTime(LocalDateTimeUtil.of(wxMpUser.getSubscribeTime() * 1000L));
  40 + if (account != null) {
  41 + user.setAccountId(account.getId());
  42 + user.setAppId(account.getAppId());
  43 + }
  44 + return user;
  45 + }
  46 +
22 } 47 }
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/dataobject/subscribetext/WxSubscribeTextDO.java deleted
1 -package cn.iocoder.yudao.module.mp.dal.dataobject.subscribetext;  
2 -  
3 -import lombok.*;  
4 -  
5 -import java.util.*;  
6 -  
7 -import com.baomidou.mybatisplus.annotation.*;  
8 -import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;  
9 -  
10 -/**  
11 - * 关注欢迎语 DO  
12 - *  
13 - * @author 芋道源码  
14 - */  
15 -@TableName("wx_subscribe_text")  
16 -@KeySequence("wx_subscribe_text_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。  
17 -@Data  
18 -@EqualsAndHashCode(callSuper = true)  
19 -@ToString(callSuper = true)  
20 -@Builder  
21 -@NoArgsConstructor  
22 -@AllArgsConstructor  
23 -public class WxSubscribeTextDO extends BaseDO {  
24 -  
25 - /**  
26 - * 主键  
27 - */  
28 - @TableId  
29 - private Integer id;  
30 - /**  
31 - * 消息类型 1文本消息;2图文消息;  
32 - */  
33 - private String msgType;  
34 - /**  
35 - * 模板ID  
36 - */  
37 - private String tplId;  
38 - /**  
39 - * 微信账号ID  
40 - */  
41 - private String wxAccountId;  
42 -  
43 -}  
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/dataobject/user/MpUserDO.java
@@ -52,15 +52,16 @@ public class MpUserDO extends BaseDO { @@ -52,15 +52,16 @@ public class MpUserDO extends BaseDO {
52 private LocalDateTime unsubscribeTime; 52 private LocalDateTime unsubscribeTime;
53 /** 53 /**
54 * 昵称 54 * 昵称
  55 + *
  56 + * 注意,2021-12-27 公众号接口不再返回头像和昵称,只能通过微信公众号的网页登录获取
55 */ 57 */
56 private String nickname; 58 private String nickname;
57 /** 59 /**
58 - * 性别 60 + * 头像地址
59 * 61 *
60 - * 1- 男  
61 - * 2- 女 62 + * 注意,2021-12-27 公众号接口不再返回头像和昵称,只能通过微信公众号的网页登录获取
62 */ 63 */
63 - private Integer gender; 64 + private String headImageUrl;
64 /** 65 /**
65 * 语言 66 * 语言
66 */ 67 */
@@ -78,10 +79,6 @@ public class MpUserDO extends BaseDO { @@ -78,10 +79,6 @@ public class MpUserDO extends BaseDO {
78 */ 79 */
79 private String city; 80 private String city;
80 /** 81 /**
81 - * 头像地址  
82 - */  
83 - private String headImageUrl;  
84 - /**  
85 * 备注 82 * 备注
86 */ 83 */
87 private String remark; 84 private String remark;
@@ -91,7 +88,7 @@ public class MpUserDO extends BaseDO { @@ -91,7 +88,7 @@ public class MpUserDO extends BaseDO {
91 * 88 *
92 * 关联 {@link MpAccountDO#getId()} 89 * 关联 {@link MpAccountDO#getId()}
93 */ 90 */
94 - private String accountId; 91 + private Long accountId;
95 /** 92 /**
96 * 微信公众号 appid 93 * 微信公众号 appid
97 * 94 *
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/mysql/accountfans/MpUserMapper.java
@@ -18,4 +18,9 @@ public interface MpUserMapper extends BaseMapperX&lt;MpUserDO&gt; { @@ -18,4 +18,9 @@ public interface MpUserMapper extends BaseMapperX&lt;MpUserDO&gt; {
18 .orderByDesc(MpUserDO::getId)); 18 .orderByDesc(MpUserDO::getId));
19 } 19 }
20 20
  21 + default MpUserDO selectByAppIdAndOpenid(String appId, String openId) {
  22 + return selectOne(MpUserDO::getAppId, appId,
  23 + MpUserDO::getOpenid, openId);
  24 + }
  25 +
21 } 26 }
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/mysql/subscribetext/WxSubscribeTextMapper.java deleted
1 -package cn.iocoder.yudao.module.mp.dal.mysql.subscribetext;  
2 -  
3 -import java.util.*;  
4 -  
5 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
6 -import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;  
7 -import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;  
8 -import cn.iocoder.yudao.module.mp.dal.dataobject.subscribetext.WxSubscribeTextDO;  
9 -import org.apache.ibatis.annotations.Mapper;  
10 -import cn.iocoder.yudao.module.mp.controller.admin.subscribetext.vo.*;  
11 -  
12 -/**  
13 - * 关注欢迎语 Mapper  
14 - *  
15 - * @author 芋道源码  
16 - */  
17 -@Mapper  
18 -public interface WxSubscribeTextMapper extends BaseMapperX<WxSubscribeTextDO> {  
19 -  
20 - default PageResult<WxSubscribeTextDO> selectPage(WxSubscribeTextPageReqVO reqVO) {  
21 - return selectPage(reqVO, new LambdaQueryWrapperX<WxSubscribeTextDO>()  
22 - .eqIfPresent(WxSubscribeTextDO::getMsgType, reqVO.getMsgType())  
23 - .eqIfPresent(WxSubscribeTextDO::getTplId, reqVO.getTplId())  
24 - .eqIfPresent(WxSubscribeTextDO::getWxAccountId, reqVO.getWxAccountId())  
25 - .betweenIfPresent(WxSubscribeTextDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())  
26 - .orderByDesc(WxSubscribeTextDO::getId));  
27 - }  
28 -  
29 - default List<WxSubscribeTextDO> selectList(WxSubscribeTextExportReqVO reqVO) {  
30 - return selectList(new LambdaQueryWrapperX<WxSubscribeTextDO>()  
31 - .eqIfPresent(WxSubscribeTextDO::getMsgType, reqVO.getMsgType())  
32 - .eqIfPresent(WxSubscribeTextDO::getTplId, reqVO.getTplId())  
33 - .eqIfPresent(WxSubscribeTextDO::getWxAccountId, reqVO.getWxAccountId())  
34 - .betweenIfPresent(WxSubscribeTextDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())  
35 - .orderByDesc(WxSubscribeTextDO::getId));  
36 - }  
37 -  
38 -}  
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/handler/user/SubscribeHandler.java
1 package cn.iocoder.yudao.module.mp.service.handler.user; 1 package cn.iocoder.yudao.module.mp.service.handler.user;
2 2
3 -import cn.hutool.core.date.DateUtil;  
4 -import cn.iocoder.yudao.framework.common.util.json.JsonUtils;  
5 import cn.iocoder.yudao.module.mp.builder.TextBuilder; 3 import cn.iocoder.yudao.module.mp.builder.TextBuilder;
6 -import cn.iocoder.yudao.module.mp.controller.admin.user.vo.WxAccountFansCreateReqVO;  
7 -import cn.iocoder.yudao.module.mp.controller.admin.user.vo.WxAccountFansUpdateReqVO;  
8 -import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;  
9 import cn.iocoder.yudao.module.mp.dal.dataobject.user.MpUserDO; 4 import cn.iocoder.yudao.module.mp.dal.dataobject.user.MpUserDO;
10 -import cn.iocoder.yudao.module.mp.dal.dataobject.subscribetext.WxSubscribeTextDO;  
11 -import cn.iocoder.yudao.module.mp.dal.dataobject.texttemplate.WxTextTemplateDO; 5 +import cn.iocoder.yudao.module.mp.framework.mp.core.context.MpContextHolder;
12 import cn.iocoder.yudao.module.mp.service.account.MpAccountService; 6 import cn.iocoder.yudao.module.mp.service.account.MpAccountService;
13 import cn.iocoder.yudao.module.mp.service.user.MpUserService; 7 import cn.iocoder.yudao.module.mp.service.user.MpUserService;
14 -import cn.iocoder.yudao.module.mp.service.accountfanstag.WxAccountFansTagService;  
15 -import cn.iocoder.yudao.module.mp.service.subscribetext.WxSubscribeTextService;  
16 -import cn.iocoder.yudao.module.mp.service.texttemplate.WxTextTemplateService;  
17 import lombok.extern.slf4j.Slf4j; 8 import lombok.extern.slf4j.Slf4j;
18 import me.chanjar.weixin.common.error.WxErrorException; 9 import me.chanjar.weixin.common.error.WxErrorException;
19 import me.chanjar.weixin.common.session.WxSessionManager; 10 import me.chanjar.weixin.common.session.WxSessionManager;
@@ -22,12 +13,10 @@ import me.chanjar.weixin.mp.api.WxMpService; @@ -22,12 +13,10 @@ import me.chanjar.weixin.mp.api.WxMpService;
22 import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; 13 import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
23 import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; 14 import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
24 import me.chanjar.weixin.mp.bean.result.WxMpUser; 15 import me.chanjar.weixin.mp.bean.result.WxMpUser;
25 -import org.springframework.beans.factory.annotation.Autowired;  
26 import org.springframework.context.annotation.Lazy; 16 import org.springframework.context.annotation.Lazy;
27 import org.springframework.stereotype.Component; 17 import org.springframework.stereotype.Component;
28 18
29 import javax.annotation.Resource; 19 import javax.annotation.Resource;
30 -import java.io.UnsupportedEncodingException;  
31 import java.util.Map; 20 import java.util.Map;
32 21
33 /** 22 /**
@@ -41,120 +30,33 @@ import java.util.Map; @@ -41,120 +30,33 @@ import java.util.Map;
41 @Slf4j 30 @Slf4j
42 public class SubscribeHandler implements WxMpMessageHandler { 31 public class SubscribeHandler implements WxMpMessageHandler {
43 32
44 - @Autowired  
45 - private WxTextTemplateService wxTextTemplateService;  
46 -  
47 @Resource 33 @Resource
48 @Lazy // 延迟加载,解决循环依赖的问题 34 @Lazy // 延迟加载,解决循环依赖的问题
49 private MpAccountService mpAccountService; 35 private MpAccountService mpAccountService;
50 36
51 - @Autowired  
52 - private WxSubscribeTextService wxSubscribeTextService;  
53 -  
54 - @Autowired  
55 - private MpUserService wxAccountFansService;  
56 -  
57 - @Autowired  
58 - private WxAccountFansTagService wxAccountFansTagService; 37 + @Resource
  38 + private MpUserService mpUserService;
59 39
60 @Override 40 @Override
61 - public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,  
62 - Map<String, Object> context, WxMpService weixinService,  
63 - WxSessionManager sessionManager) throws WxErrorException {  
64 -  
65 - log.info("新关注用户 OPENID: " + wxMessage.getFromUser());  
66 -  
67 - // 获取微信用户基本信息 41 + public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context,
  42 + WxMpService weixinService, WxSessionManager sessionManager) throws WxErrorException {
  43 + // 第一步,从公众号平台,获取用户信息
  44 + log.info("[handle][用户({}) 关注]", wxMessage.getFromUser());
  45 + WxMpUser wxMpUser = null;
68 try { 46 try {
69 - WxMpUser wxmpUser = weixinService.getUserService()  
70 - .userInfo(wxMessage.getFromUser(), null);  
71 - if (wxmpUser != null) {  
72 - // 可以添加关注用户到本地数据库  
73 - MpAccountDO wxAccount = mpAccountService.findBy(MpAccountDO::getAccount, wxMessage.getToUser());  
74 - if (wxAccount != null) {  
75 - MpUserDO wxAccountFans = wxAccountFansService.findBy(MpUserDO::getOpenid, wxmpUser.getOpenId());  
76 - if (wxAccountFans == null) {//insert  
77 - WxAccountFansCreateReqVO wxAccountFansCreateReqVO = new WxAccountFansCreateReqVO();  
78 - wxAccountFansCreateReqVO.setOpenid(wxmpUser.getOpenId());  
79 - wxAccountFansCreateReqVO.setSubscribeStatus(wxmpUser.getSubscribe() ? "1" : "0");  
80 - wxAccountFansCreateReqVO.setSubscribeTime(DateUtil.date(wxmpUser.getSubscribeTime() * 1000L));  
81 - try {  
82 - wxAccountFansCreateReqVO.setNickname(wxmpUser.getNickname().getBytes("UTF-8"));  
83 - } catch (UnsupportedEncodingException e) {  
84 - e.printStackTrace();  
85 - }  
86 - wxAccountFansCreateReqVO.setLanguage(wxmpUser.getLanguage());  
87 - wxAccountFansCreateReqVO.setHeadimgUrl(wxmpUser.getHeadImgUrl());  
88 - wxAccountFansCreateReqVO.setRemark(wxmpUser.getRemark());  
89 - wxAccountFansCreateReqVO.setWxAccountId(String.valueOf(wxAccount.getId()));  
90 - wxAccountFansCreateReqVO.setWxAccountAppid(wxAccount.getAppId());  
91 - wxAccountFansService.createWxAccountFans(wxAccountFansCreateReqVO);  
92 -  
93 - //process tags  
94 - wxAccountFansTagService.processFansTags(wxAccount, wxmpUser);  
95 -  
96 - } else {//update  
97 - WxAccountFansUpdateReqVO wxAccountFansUpdateReqVO = new WxAccountFansUpdateReqVO();  
98 - wxAccountFansUpdateReqVO.setId(wxAccountFans.getId());  
99 - wxAccountFansUpdateReqVO.setOpenid(wxmpUser.getOpenId());  
100 - wxAccountFansUpdateReqVO.setSubscribeStatus(wxmpUser.getSubscribe() ? "1" : "0");  
101 - wxAccountFansUpdateReqVO.setSubscribeTime(DateUtil.date(wxmpUser.getSubscribeTime() * 1000L));  
102 - try {  
103 - wxAccountFans.setNickname(wxmpUser.getNickname().getBytes("UTF-8"));  
104 - } catch (UnsupportedEncodingException e) {  
105 - e.printStackTrace();  
106 - }  
107 - wxAccountFansUpdateReqVO.setLanguage(wxmpUser.getLanguage());  
108 - wxAccountFansUpdateReqVO.setHeadimgUrl(wxmpUser.getHeadImgUrl());  
109 - wxAccountFansUpdateReqVO.setRemark(wxmpUser.getRemark());  
110 - wxAccountFansUpdateReqVO.setWxAccountId(String.valueOf(wxAccount.getId()));  
111 - wxAccountFansUpdateReqVO.setWxAccountAppid(wxAccount.getAppId());  
112 - wxAccountFansService.updateWxAccountFans(wxAccountFansUpdateReqVO);  
113 -  
114 - //process tags  
115 - wxAccountFansTagService.processFansTags(wxAccount, wxmpUser);  
116 -  
117 - }  
118 - }  
119 -  
120 - } 47 + wxMpUser = weixinService.getUserService().userInfo(wxMessage.getFromUser());
121 } catch (WxErrorException e) { 48 } catch (WxErrorException e) {
122 - if (e.getError().getErrorCode() == 48001) {  
123 - log.info("该公众号没有获取用户信息权限!");  
124 - }  
125 - }  
126 -  
127 -  
128 - WxMpXmlOutMessage responseResult = null;  
129 - try {  
130 - responseResult = this.handleSpecial(wxMessage);  
131 - } catch (Exception e) {  
132 - log.error(e.getMessage(), e); 49 + log.error("[handle][用户({})] 获取用户信息失败!", wxMessage.getFromUser(), e);
133 } 50 }
134 51
135 - if (responseResult != null) {  
136 - return responseResult; 52 + // 第二步,保存用户信息
  53 + MpUserDO mpUser = null;
  54 + if (wxMpUser != null) {
  55 + mpUser = mpUserService.saveUser(MpContextHolder.getAppId(), wxMpUser);
137 } 56 }
138 57
139 - try {  
140 - String content = "感谢关注!";//默认  
141 - MpAccountDO wxAccount = mpAccountService.findBy(MpAccountDO::getAccount, wxMessage.getToUser());  
142 - if (wxAccount != null) {  
143 - WxSubscribeTextDO wxSubscribeText = wxSubscribeTextService.findBy(WxSubscribeTextDO::getWxAccountId, String.valueOf(wxAccount.getId()));  
144 - if (wxSubscribeText != null) {  
145 - WxTextTemplateDO wxTextTemplate = wxTextTemplateService.getWxTextTemplate(Integer.parseInt(wxSubscribeText.getTplId()));  
146 - if (wxTextTemplate != null) {  
147 - content = wxTextTemplate.getContent();  
148 - }  
149 - }  
150 - }  
151 - log.info("wxMessage : {}", JsonUtils.toJsonString(wxMessage));  
152 - return new TextBuilder().build(content, wxMessage, weixinService);  
153 - } catch (Exception e) {  
154 - log.error(e.getMessage(), e);  
155 - }  
156 -  
157 - return null; 58 + // 第三步,回复关注的欢迎语 TODO 芋艿:关注的欢迎语
  59 + return new TextBuilder().build("感谢关注", wxMessage, weixinService);
158 } 60 }
159 61
160 /** 62 /**
@@ -162,6 +64,7 @@ public class SubscribeHandler implements WxMpMessageHandler { @@ -162,6 +64,7 @@ public class SubscribeHandler implements WxMpMessageHandler {
162 */ 64 */
163 private WxMpXmlOutMessage handleSpecial(WxMpXmlMessage wxMessage) 65 private WxMpXmlOutMessage handleSpecial(WxMpXmlMessage wxMessage)
164 throws Exception { 66 throws Exception {
  67 +
165 //TODO 68 //TODO
166 return null; 69 return null;
167 } 70 }
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/handler/user/UnsubscribeHandler.java
1 package cn.iocoder.yudao.module.mp.service.handler.user; 1 package cn.iocoder.yudao.module.mp.service.handler.user;
2 2
3 -import cn.iocoder.yudao.module.mp.controller.admin.user.vo.WxAccountFansUpdateReqVO;  
4 -import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;  
5 -import cn.iocoder.yudao.module.mp.dal.dataobject.user.MpUserDO;  
6 -import cn.iocoder.yudao.module.mp.service.account.MpAccountService; 3 +import cn.iocoder.yudao.module.mp.framework.mp.core.context.MpContextHolder;
7 import cn.iocoder.yudao.module.mp.service.user.MpUserService; 4 import cn.iocoder.yudao.module.mp.service.user.MpUserService;
8 import lombok.extern.slf4j.Slf4j; 5 import lombok.extern.slf4j.Slf4j;
9 import me.chanjar.weixin.common.session.WxSessionManager; 6 import me.chanjar.weixin.common.session.WxSessionManager;
@@ -11,7 +8,6 @@ import me.chanjar.weixin.mp.api.WxMpMessageHandler; @@ -11,7 +8,6 @@ import me.chanjar.weixin.mp.api.WxMpMessageHandler;
11 import me.chanjar.weixin.mp.api.WxMpService; 8 import me.chanjar.weixin.mp.api.WxMpService;
12 import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; 9 import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
13 import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; 10 import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
14 -import org.springframework.beans.factory.annotation.Autowired;  
15 import org.springframework.context.annotation.Lazy; 11 import org.springframework.context.annotation.Lazy;
16 import org.springframework.stereotype.Component; 12 import org.springframework.stereotype.Component;
17 13
@@ -22,8 +18,6 @@ import java.util.Map; @@ -22,8 +18,6 @@ import java.util.Map;
22 * 取消关注的事件处理器 18 * 取消关注的事件处理器
23 * 19 *
24 * @author 芋道源码 20 * @author 芋道源码
25 - *  
26 - * // TODO 芋艿:待实现  
27 */ 21 */
28 @Component 22 @Component
29 @Slf4j 23 @Slf4j
@@ -31,31 +25,14 @@ public class UnsubscribeHandler implements WxMpMessageHandler { @@ -31,31 +25,14 @@ public class UnsubscribeHandler implements WxMpMessageHandler {
31 25
32 @Resource 26 @Resource
33 @Lazy // 延迟加载,解决循环依赖的问题 27 @Lazy // 延迟加载,解决循环依赖的问题
34 - private MpAccountService mpAccountService;  
35 -  
36 - @Autowired  
37 - private MpUserService wxAccountFansService; 28 + private MpUserService mpUserService;
38 29
39 @Override 30 @Override
40 public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, 31 public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
41 Map<String, Object> context, WxMpService wxMpService, 32 Map<String, Object> context, WxMpService wxMpService,
42 WxSessionManager sessionManager) { 33 WxSessionManager sessionManager) {
43 - String openId = wxMessage.getFromUser();  
44 - log.info("取消关注用户 OPENID: " + openId);  
45 - // TODO 可以更新本地数据库为取消关注状态  
46 -  
47 - MpAccountDO wxAccountDO = mpAccountService.findBy(MpAccountDO::getAccount, wxMessage.getToUser());  
48 - if (wxAccountDO != null) {  
49 - MpUserDO wxAccountFansDO = wxAccountFansService.findBy(MpUserDO::getOpenid, openId);  
50 - if (wxAccountFansDO != null) {  
51 - WxAccountFansUpdateReqVO wxAccountFansUpdateReqVO = new WxAccountFansUpdateReqVO();  
52 - wxAccountFansUpdateReqVO.setId(wxAccountDO.getId());  
53 - wxAccountFansDO.setSubscribeStatus("0");//取消订阅  
54 - wxAccountFansService.updateWxAccountFans(wxAccountFansUpdateReqVO);  
55 - }  
56 - }  
57 -  
58 - 34 + log.info("[handle][用户({}) 取消关注]", wxMessage.getFromUser());
  35 + mpUserService.updateUserUnsubscribe(MpContextHolder.getAppId(), wxMessage.getFromUser());
59 return null; 36 return null;
60 } 37 }
61 38
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/subscribetext/WxSubscribeTextService.java deleted
1 -package cn.iocoder.yudao.module.mp.service.subscribetext;  
2 -  
3 -import java.util.*;  
4 -import javax.validation.*;  
5 -  
6 -import cn.iocoder.yudao.module.mp.controller.admin.subscribetext.vo.*;  
7 -import cn.iocoder.yudao.module.mp.dal.dataobject.subscribetext.WxSubscribeTextDO;  
8 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
9 -import com.baomidou.mybatisplus.core.toolkit.support.SFunction;  
10 -  
11 -/**  
12 - * 关注欢迎语 Service 接口  
13 - *  
14 - * @author 芋道源码  
15 - */  
16 -public interface WxSubscribeTextService {  
17 -  
18 - /**  
19 - * 创建关注欢迎语  
20 - *  
21 - * @param createReqVO 创建信息  
22 - * @return 编号  
23 - */  
24 - Integer createWxSubscribeText(@Valid WxSubscribeTextCreateReqVO createReqVO);  
25 -  
26 - /**  
27 - * 更新关注欢迎语  
28 - *  
29 - * @param updateReqVO 更新信息  
30 - */  
31 - void updateWxSubscribeText(@Valid WxSubscribeTextUpdateReqVO updateReqVO);  
32 -  
33 - /**  
34 - * 删除关注欢迎语  
35 - *  
36 - * @param id 编号  
37 - */  
38 - void deleteWxSubscribeText(Integer id);  
39 -  
40 - /**  
41 - * 获得关注欢迎语  
42 - *  
43 - * @param id 编号  
44 - * @return 关注欢迎语  
45 - */  
46 - WxSubscribeTextDO getWxSubscribeText(Integer id);  
47 -  
48 - /**  
49 - * 获得关注欢迎语列表  
50 - *  
51 - * @param ids 编号  
52 - * @return 关注欢迎语列表  
53 - */  
54 - List<WxSubscribeTextDO> getWxSubscribeTextList(Collection<Integer> ids);  
55 -  
56 - /**  
57 - * 获得关注欢迎语分页  
58 - *  
59 - * @param pageReqVO 分页查询  
60 - * @return 关注欢迎语分页  
61 - */  
62 - PageResult<WxSubscribeTextDO> getWxSubscribeTextPage(WxSubscribeTextPageReqVO pageReqVO);  
63 -  
64 - /**  
65 - * 获得关注欢迎语列表, 用于 Excel 导出  
66 - *  
67 - * @param exportReqVO 查询条件  
68 - * @return 关注欢迎语列表  
69 - */  
70 - List<WxSubscribeTextDO> getWxSubscribeTextList(WxSubscribeTextExportReqVO exportReqVO);  
71 -  
72 - /**  
73 - * 关注欢迎语分页  
74 - *  
75 - * @param column  
76 - * @param obj  
77 - * @return  
78 - */  
79 - WxSubscribeTextDO findBy(SFunction<WxSubscribeTextDO, ?> column, Object obj);  
80 -}  
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/subscribetext/WxSubscribeTextServiceImpl.java deleted
1 -package cn.iocoder.yudao.module.mp.service.subscribetext;  
2 -  
3 -import com.baomidou.mybatisplus.core.toolkit.support.SFunction;  
4 -import org.springframework.stereotype.Service;  
5 -  
6 -import javax.annotation.Resource;  
7 -  
8 -import org.springframework.validation.annotation.Validated;  
9 -  
10 -import java.util.*;  
11 -  
12 -import cn.iocoder.yudao.module.mp.controller.admin.subscribetext.vo.*;  
13 -import cn.iocoder.yudao.module.mp.dal.dataobject.subscribetext.WxSubscribeTextDO;  
14 -import cn.iocoder.yudao.framework.common.pojo.PageResult;  
15 -  
16 -import cn.iocoder.yudao.module.mp.convert.subscribetext.WxSubscribeTextConvert;  
17 -import cn.iocoder.yudao.module.mp.dal.mysql.subscribetext.WxSubscribeTextMapper;  
18 -  
19 -import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;  
20 -import static cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants.*;  
21 -  
22 -/**  
23 - * 关注欢迎语 Service 实现类  
24 - *  
25 - * @author 芋道源码  
26 - */  
27 -@Service  
28 -@Validated  
29 -public class WxSubscribeTextServiceImpl implements WxSubscribeTextService {  
30 -  
31 - @Resource  
32 - private WxSubscribeTextMapper wxSubscribeTextMapper;  
33 -  
34 - @Override  
35 - public Integer createWxSubscribeText(WxSubscribeTextCreateReqVO createReqVO) {  
36 - // 插入  
37 - WxSubscribeTextDO wxSubscribeText = WxSubscribeTextConvert.INSTANCE.convert(createReqVO);  
38 - wxSubscribeTextMapper.insert(wxSubscribeText);  
39 - // 返回  
40 - return wxSubscribeText.getId();  
41 - }  
42 -  
43 - @Override  
44 - public void updateWxSubscribeText(WxSubscribeTextUpdateReqVO updateReqVO) {  
45 - // 校验存在  
46 - this.validateWxSubscribeTextExists(updateReqVO.getId());  
47 - // 更新  
48 - WxSubscribeTextDO updateObj = WxSubscribeTextConvert.INSTANCE.convert(updateReqVO);  
49 - wxSubscribeTextMapper.updateById(updateObj);  
50 - }  
51 -  
52 - @Override  
53 - public void deleteWxSubscribeText(Integer id) {  
54 - // 校验存在  
55 - this.validateWxSubscribeTextExists(id);  
56 - // 删除  
57 - wxSubscribeTextMapper.deleteById(id);  
58 - }  
59 -  
60 - private void validateWxSubscribeTextExists(Integer id) {  
61 - if (wxSubscribeTextMapper.selectById(id) == null) {  
62 - throw exception(COMMON_NOT_EXISTS);  
63 - }  
64 - }  
65 -  
66 - @Override  
67 - public WxSubscribeTextDO getWxSubscribeText(Integer id) {  
68 - return wxSubscribeTextMapper.selectById(id);  
69 - }  
70 -  
71 - @Override  
72 - public List<WxSubscribeTextDO> getWxSubscribeTextList(Collection<Integer> ids) {  
73 - return wxSubscribeTextMapper.selectBatchIds(ids);  
74 - }  
75 -  
76 - @Override  
77 - public PageResult<WxSubscribeTextDO> getWxSubscribeTextPage(WxSubscribeTextPageReqVO pageReqVO) {  
78 - return wxSubscribeTextMapper.selectPage(pageReqVO);  
79 - }  
80 -  
81 - @Override  
82 - public List<WxSubscribeTextDO> getWxSubscribeTextList(WxSubscribeTextExportReqVO exportReqVO) {  
83 - return wxSubscribeTextMapper.selectList(exportReqVO);  
84 - }  
85 -  
86 - @Override  
87 - public WxSubscribeTextDO findBy(SFunction<WxSubscribeTextDO, ?> column, Object obj) {  
88 - return wxSubscribeTextMapper.selectOne(column, obj);  
89 - }  
90 -}  
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/user/MpUserService.java
@@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.mp.service.user; @@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.mp.service.user;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 3 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.module.mp.controller.admin.user.vo.MpUserPageReqVO; 4 import cn.iocoder.yudao.module.mp.controller.admin.user.vo.MpUserPageReqVO;
5 import cn.iocoder.yudao.module.mp.dal.dataobject.user.MpUserDO; 5 import cn.iocoder.yudao.module.mp.dal.dataobject.user.MpUserDO;
  6 +import me.chanjar.weixin.mp.bean.result.WxMpUser;
6 7
7 import java.util.Collection; 8 import java.util.Collection;
8 import java.util.List; 9 import java.util.List;
@@ -38,4 +39,23 @@ public interface MpUserService { @@ -38,4 +39,23 @@ public interface MpUserService {
38 */ 39 */
39 PageResult<MpUserDO> getUserPage(MpUserPageReqVO pageReqVO); 40 PageResult<MpUserDO> getUserPage(MpUserPageReqVO pageReqVO);
40 41
  42 + /**
  43 + * 保存微信公众号粉丝
  44 + *
  45 + * 新增或更新,根据是否存在数据库中
  46 + *
  47 + * @param appId 微信公众号 appId
  48 + * @param wxMpUser 微信公众号粉丝的信息
  49 + * @return 微信公众号粉丝
  50 + */
  51 + MpUserDO saveUser(String appId, WxMpUser wxMpUser);
  52 +
  53 + /**
  54 + * 更新微信公众号粉丝,取消关注
  55 + *
  56 + * @param appId 微信公众号 appId
  57 + * @param openId 微信公众号粉丝的 openid
  58 + */
  59 + void updateUserUnsubscribe(String appId, String openId);
  60 +
41 } 61 }
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/user/MpUserServiceImpl.java
1 package cn.iocoder.yudao.module.mp.service.user; 1 package cn.iocoder.yudao.module.mp.service.user;
2 2
  3 +import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
3 import cn.iocoder.yudao.framework.common.pojo.PageResult; 4 import cn.iocoder.yudao.framework.common.pojo.PageResult;
4 import cn.iocoder.yudao.module.mp.controller.admin.user.vo.MpUserPageReqVO; 5 import cn.iocoder.yudao.module.mp.controller.admin.user.vo.MpUserPageReqVO;
  6 +import cn.iocoder.yudao.module.mp.convert.user.MpUserConvert;
  7 +import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
5 import cn.iocoder.yudao.module.mp.dal.dataobject.user.MpUserDO; 8 import cn.iocoder.yudao.module.mp.dal.dataobject.user.MpUserDO;
6 import cn.iocoder.yudao.module.mp.dal.mysql.accountfans.MpUserMapper; 9 import cn.iocoder.yudao.module.mp.dal.mysql.accountfans.MpUserMapper;
  10 +import cn.iocoder.yudao.module.mp.service.account.MpAccountService;
  11 +import lombok.extern.slf4j.Slf4j;
  12 +import me.chanjar.weixin.mp.bean.result.WxMpUser;
  13 +import org.springframework.context.annotation.Lazy;
7 import org.springframework.stereotype.Service; 14 import org.springframework.stereotype.Service;
8 import org.springframework.validation.annotation.Validated; 15 import org.springframework.validation.annotation.Validated;
9 16
10 import javax.annotation.Resource; 17 import javax.annotation.Resource;
  18 +import java.time.LocalDateTime;
11 import java.util.Collection; 19 import java.util.Collection;
12 import java.util.List; 20 import java.util.List;
13 21
@@ -18,9 +26,14 @@ import java.util.List; @@ -18,9 +26,14 @@ import java.util.List;
18 */ 26 */
19 @Service 27 @Service
20 @Validated 28 @Validated
  29 +@Slf4j
21 public class MpUserServiceImpl implements MpUserService { 30 public class MpUserServiceImpl implements MpUserService {
22 31
23 @Resource 32 @Resource
  33 + @Lazy // 延迟加载,解决循环依赖的问题
  34 + private MpAccountService accountService;
  35 +
  36 + @Resource
24 private MpUserMapper mpUserMapper; 37 private MpUserMapper mpUserMapper;
25 38
26 @Override 39 @Override
@@ -38,4 +51,32 @@ public class MpUserServiceImpl implements MpUserService { @@ -38,4 +51,32 @@ public class MpUserServiceImpl implements MpUserService {
38 return mpUserMapper.selectPage(pageReqVO); 51 return mpUserMapper.selectPage(pageReqVO);
39 } 52 }
40 53
  54 + @Override
  55 + public MpUserDO saveUser(String appId, WxMpUser wxMpUser) {
  56 + // 构建保存的 MpUserDO 对象
  57 + MpAccountDO account = accountService.getAccountFromCache(appId);
  58 + MpUserDO user = MpUserConvert.INSTANCE.convert(account, wxMpUser);
  59 +
  60 + // 根据情况,插入或更新
  61 + MpUserDO dbUser = mpUserMapper.selectByAppIdAndOpenid(appId, wxMpUser.getOpenId());
  62 + if (dbUser == null) {
  63 + mpUserMapper.insert(user);
  64 + } else {
  65 + user.setId(dbUser.getId());
  66 + mpUserMapper.updateById(user);
  67 + }
  68 + return user;
  69 + }
  70 +
  71 + @Override
  72 + public void updateUserUnsubscribe(String appId, String openId) {
  73 + MpUserDO dbUser = mpUserMapper.selectByAppIdAndOpenid(appId, openId);
  74 + if (dbUser == null) {
  75 + log.error("[updateUserUnsubscribe][微信公众号粉丝 appId({}) openId({}) 不存在]", appId, openId);
  76 + return;
  77 + }
  78 + mpUserMapper.updateById(new MpUserDO().setId(dbUser.getId()).setSubscribeStatus(CommonStatusEnum.DISABLE.getStatus())
  79 + .setSubscribeTime(LocalDateTime.now()));
  80 + }
  81 +
41 } 82 }