Commit 39d377b0bdae941043ce7ab28f9f855db39177e0
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<MpUserDO> { | @@ -18,4 +18,9 @@ public interface MpUserMapper extends BaseMapperX<MpUserDO> { | ||
| 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 | } |