Commit d1cc9dde0c22e0192941c3739748c46c6d3d342c

Authored by YunaiV
1 parent acee0752

mp:实现 tag 模块的后端接口

yudao-module-mp/yudao-module-mp-api/src/main/java/cn/iocoder/yudao/module/mp/enums/ErrorCodeConstants.java
@@ -14,12 +14,19 @@ public interface ErrorCodeConstants { @@ -14,12 +14,19 @@ public interface ErrorCodeConstants {
14 ErrorCode ACCOUNT_GENERATE_QR_CODE_FAIL = new ErrorCode(1006000001, "生成公众号二维码失败,原因:{}"); 14 ErrorCode ACCOUNT_GENERATE_QR_CODE_FAIL = new ErrorCode(1006000001, "生成公众号二维码失败,原因:{}");
15 ErrorCode ACCOUNT_CLEAR_QUOTA_FAIL = new ErrorCode(1006000001, "清空公众号的 API 配额失败,原因:{}"); 15 ErrorCode ACCOUNT_CLEAR_QUOTA_FAIL = new ErrorCode(1006000001, "清空公众号的 API 配额失败,原因:{}");
16 16
17 - // ========== 公众号账号 1006001000============ 17 + // ========== 公众号统计 1006001000============
18 ErrorCode STATISTICS_GET_USER_SUMMARY_FAIL = new ErrorCode(1006001000, "获取用户增减数据失败,原因:{}"); 18 ErrorCode STATISTICS_GET_USER_SUMMARY_FAIL = new ErrorCode(1006001000, "获取用户增减数据失败,原因:{}");
19 ErrorCode STATISTICS_GET_USER_CUMULATE_FAIL = new ErrorCode(1006001001, "获得用户累计数据失败,原因:{}"); 19 ErrorCode STATISTICS_GET_USER_CUMULATE_FAIL = new ErrorCode(1006001001, "获得用户累计数据失败,原因:{}");
20 ErrorCode STATISTICS_GET_UPSTREAM_MESSAGE_FAIL = new ErrorCode(1006001002, "获得消息发送概况数据失败,原因:{}"); 20 ErrorCode STATISTICS_GET_UPSTREAM_MESSAGE_FAIL = new ErrorCode(1006001002, "获得消息发送概况数据失败,原因:{}");
21 ErrorCode STATISTICS_GET_INTERFACE_SUMMARY_FAIL = new ErrorCode(1006001003, "获得接口分析数据失败,原因:{}"); 21 ErrorCode STATISTICS_GET_INTERFACE_SUMMARY_FAIL = new ErrorCode(1006001003, "获得接口分析数据失败,原因:{}");
22 22
  23 + // ========== 公众号标签 1006002000============
  24 + ErrorCode TAG_NOT_EXISTS = new ErrorCode(1006002000, "标签不存在");
  25 + ErrorCode TAG_CREATE_FAIL = new ErrorCode(1006002001, "创建标签失败,原因:{}");
  26 + ErrorCode TAG_UPDATE_FAIL = new ErrorCode(1006002001, "更新标签失败,原因:{}");
  27 + ErrorCode TAG_DELETE_FAIL = new ErrorCode(1006002001, "删除标签失败,原因:{}");
  28 + ErrorCode TAG_GET_FAIL = new ErrorCode(1006002001, "获得标签失败,原因:{}");
  29 +
23 // TODO 要处理下 30 // TODO 要处理下
24 ErrorCode COMMON_NOT_EXISTS = new ErrorCode(1006001002, "用户不存在"); 31 ErrorCode COMMON_NOT_EXISTS = new ErrorCode(1006001002, "用户不存在");
25 32
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/menu/MpMenuController.http
1 -### 请求 /login 接口 => 成功 1 +### 请求 /mp/menu/save 接口 => 成功
2 POST {{baseUrl}}/mp/menu/save 2 POST {{baseUrl}}/mp/menu/save
3 Content-Type: application/json 3 Content-Type: application/json
4 Authorization: Bearer {{token}} 4 Authorization: Bearer {{token}}
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/MpTagController.http 0 → 100644
  1 +### 请求 /mp/tag/create 接口 => 成功
  2 +POST {{baseUrl}}/mp/tag/create
  3 +Content-Type: application/json
  4 +Authorization: Bearer {{token}}
  5 +tenant-id: {{adminTenentId}}
  6 +
  7 +{
  8 + "accountId": "1",
  9 + "name": "测试"
  10 +}
  11 +
  12 +### 请求 /mp/tag/update 接口 => 成功
  13 +PUT {{baseUrl}}/mp/tag/update
  14 +Content-Type: application/json
  15 +Authorization: Bearer {{token}}
  16 +tenant-id: {{adminTenentId}}
  17 +
  18 +{
  19 + "id": "3",
  20 + "name": "测试标签啦"
  21 +}
  22 +
  23 +### 请求 /mp/tag/delete 接口 => 成功
  24 +DELETE {{baseUrl}}/mp/tag/delete?id=3
  25 +Content-Type: application/json
  26 +Authorization: Bearer {{token}}
  27 +tenant-id: {{adminTenentId}}
  28 +
  29 +### 请求 /mp/tag/page 接口 => 成功
  30 +GET {{baseUrl}}/mp/tag/page?accountId=1&pageNo=1&pageSize=10
  31 +Content-Type: application/json
  32 +Authorization: Bearer {{token}}
  33 +tenant-id: {{adminTenentId}}
  34 +
  35 +### 请求 /mp/tag/sync 接口 => 成功
  36 +POST {{baseUrl}}/mp/tag/sync?accountId=1
  37 +Content-Type: application/json
  38 +Authorization: Bearer {{token}}
  39 +tenant-id: {{adminTenentId}}
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/MpTagController.java
@@ -62,4 +62,13 @@ public class MpTagController { @@ -62,4 +62,13 @@ public class MpTagController {
62 return success(MpTagConvert.INSTANCE.convertPage(pageResult)); 62 return success(MpTagConvert.INSTANCE.convertPage(pageResult));
63 } 63 }
64 64
  65 + @PostMapping("/sync")
  66 + @ApiOperation("同步公众标签")
  67 + @ApiImplicitParam(name = "id", value = "公众号账号的编号", required = true, dataTypeClass = Long.class)
  68 + @PreAuthorize("@ss.hasPermission('mp:tag:sync')")
  69 + public CommonResult<Boolean> syncTag(@RequestParam("accountId") Long accountId) {
  70 + mpTagService.syncTag(accountId);
  71 + return success(true);
  72 + }
  73 +
65 } 74 }
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagRespVO.java
@@ -6,7 +6,6 @@ import lombok.Data; @@ -6,7 +6,6 @@ import lombok.Data;
6 import lombok.EqualsAndHashCode; 6 import lombok.EqualsAndHashCode;
7 import lombok.ToString; 7 import lombok.ToString;
8 8
9 -import javax.validation.constraints.NotNull;  
10 import java.util.Date; 9 import java.util.Date;
11 10
12 @ApiModel("管理后台 - 公众号标签 Response VO") 11 @ApiModel("管理后台 - 公众号标签 Response VO")
@@ -15,10 +14,12 @@ import java.util.Date; @@ -15,10 +14,12 @@ import java.util.Date;
15 @ToString(callSuper = true) 14 @ToString(callSuper = true)
16 public class MpTagRespVO extends MpTagBaseVO { 15 public class MpTagRespVO extends MpTagBaseVO {
17 16
18 - @ApiModelProperty(value = "编号", required = true)  
19 - @NotNull(message = "编号不能为空") 17 + @ApiModelProperty(value = "编号", required = true, example = "1024")
20 private Long id; 18 private Long id;
21 19
  20 + @ApiModelProperty(value = "此标签下粉丝数量", required = true, example = "0")
  21 + private Integer count;
  22 +
22 @ApiModelProperty(value = "创建时间", required = true) 23 @ApiModelProperty(value = "创建时间", required = true)
23 private Date createTime; 24 private Date createTime;
24 25
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/convert/tag/MpTagConvert.java
1 package cn.iocoder.yudao.module.mp.convert.tag; 1 package cn.iocoder.yudao.module.mp.convert.tag;
2 2
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.tag.vo.MpTagCreateReqVO;  
5 import cn.iocoder.yudao.module.mp.controller.admin.tag.vo.MpTagRespVO; 4 import cn.iocoder.yudao.module.mp.controller.admin.tag.vo.MpTagRespVO;
6 import cn.iocoder.yudao.module.mp.controller.admin.tag.vo.MpTagUpdateReqVO; 5 import cn.iocoder.yudao.module.mp.controller.admin.tag.vo.MpTagUpdateReqVO;
  6 +import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
7 import cn.iocoder.yudao.module.mp.dal.dataobject.tag.MpTagDO; 7 import cn.iocoder.yudao.module.mp.dal.dataobject.tag.MpTagDO;
8 import me.chanjar.weixin.mp.bean.tag.WxUserTag; 8 import me.chanjar.weixin.mp.bean.tag.WxUserTag;
9 import org.mapstruct.Mapper; 9 import org.mapstruct.Mapper;
  10 +import org.mapstruct.Mapping;
  11 +import org.mapstruct.Mappings;
10 import org.mapstruct.factory.Mappers; 12 import org.mapstruct.factory.Mappers;
11 13
12 import java.util.List; 14 import java.util.List;
@@ -16,8 +18,6 @@ public interface MpTagConvert { @@ -16,8 +18,6 @@ public interface MpTagConvert {
16 18
17 MpTagConvert INSTANCE = Mappers.getMapper(MpTagConvert.class); 19 MpTagConvert INSTANCE = Mappers.getMapper(MpTagConvert.class);
18 20
19 - WxUserTag convert(MpTagCreateReqVO bean);  
20 -  
21 WxUserTag convert(MpTagUpdateReqVO bean); 21 WxUserTag convert(MpTagUpdateReqVO bean);
22 22
23 MpTagRespVO convert(WxUserTag bean); 23 MpTagRespVO convert(WxUserTag bean);
@@ -26,4 +26,14 @@ public interface MpTagConvert { @@ -26,4 +26,14 @@ public interface MpTagConvert {
26 26
27 PageResult<MpTagRespVO> convertPage(PageResult<MpTagDO> page); 27 PageResult<MpTagRespVO> convertPage(PageResult<MpTagDO> page);
28 28
  29 + @Mappings({
  30 + @Mapping(target = "id", ignore = true),
  31 + @Mapping(source = "tag.id", target = "tagId"),
  32 + @Mapping(source = "tag.name", target = "name"),
  33 + @Mapping(source = "tag.count", target = "count"),
  34 + @Mapping(source = "account.id", target = "accountId"),
  35 + @Mapping(source = "account.appId", target = "appId"),
  36 + })
  37 + MpTagDO convert(WxUserTag tag, MpAccountDO account);
  38 +
29 } 39 }
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/dataobject/tag/MpTagDO.java
@@ -5,6 +5,7 @@ import lombok.*; @@ -5,6 +5,7 @@ import lombok.*;
5 5
6 import com.baomidou.mybatisplus.annotation.*; 6 import com.baomidou.mybatisplus.annotation.*;
7 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO; 7 import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
  8 +import me.chanjar.weixin.mp.bean.tag.WxUserTag;
8 9
9 /** 10 /**
10 * 公众号标签 DO 11 * 公众号标签 DO
@@ -31,6 +32,12 @@ public class MpTagDO extends BaseDO { @@ -31,6 +32,12 @@ public class MpTagDO extends BaseDO {
31 * 标签名 32 * 标签名
32 */ 33 */
33 private String name; 34 private String name;
  35 + /**
  36 + * 此标签下粉丝数
  37 + *
  38 + * 冗余:{@link WxUserTag#getCount()} 字段,需要管理员点击【同步】后,更新该字段
  39 + */
  40 + private Integer count;
34 41
35 /** 42 /**
36 * 微信公众号 ID 43 * 微信公众号 ID
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/mysql/tag/MpTagMapper.java
@@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.mp.controller.admin.tag.vo.MpTagPageReqVO; @@ -7,6 +7,8 @@ import cn.iocoder.yudao.module.mp.controller.admin.tag.vo.MpTagPageReqVO;
7 import cn.iocoder.yudao.module.mp.dal.dataobject.tag.MpTagDO; 7 import cn.iocoder.yudao.module.mp.dal.dataobject.tag.MpTagDO;
8 import org.apache.ibatis.annotations.Mapper; 8 import org.apache.ibatis.annotations.Mapper;
9 9
  10 +import java.util.List;
  11 +
10 @Mapper 12 @Mapper
11 public interface MpTagMapper extends BaseMapperX<MpTagDO> { 13 public interface MpTagMapper extends BaseMapperX<MpTagDO> {
12 14
@@ -17,4 +19,8 @@ public interface MpTagMapper extends BaseMapperX&lt;MpTagDO&gt; { @@ -17,4 +19,8 @@ public interface MpTagMapper extends BaseMapperX&lt;MpTagDO&gt; {
17 .orderByDesc(MpTagDO::getId)); 19 .orderByDesc(MpTagDO::getId));
18 } 20 }
19 21
  22 + default List<MpTagDO> selectListByAccountId(Long accountId) {
  23 + return selectList(MpTagDO::getAccountId, accountId);
  24 + }
  25 +
20 } 26 }
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/account/MpAccountService.java
@@ -9,6 +9,9 @@ import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO; @@ -9,6 +9,9 @@ import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
9 import javax.validation.Valid; 9 import javax.validation.Valid;
10 import java.util.List; 10 import java.util.List;
11 11
  12 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  13 +import static cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants.ACCOUNT_NOT_EXISTS;
  14 +
12 /** 15 /**
13 * 公众号账号 Service 接口 16 * 公众号账号 Service 接口
14 * 17 *
@@ -52,6 +55,20 @@ public interface MpAccountService { @@ -52,6 +55,20 @@ public interface MpAccountService {
52 MpAccountDO getAccount(Long id); 55 MpAccountDO getAccount(Long id);
53 56
54 /** 57 /**
  58 + * 获得公众号账号。若不存在,则抛出业务异常
  59 + *
  60 + * @param id 编号
  61 + * @return 公众号账号
  62 + */
  63 + default MpAccountDO getRequiredAccount(Long id) {
  64 + MpAccountDO account = getAccount(id);
  65 + if (account == null) {
  66 + throw exception(ACCOUNT_NOT_EXISTS);
  67 + }
  68 + return account;
  69 + }
  70 +
  71 + /**
55 * 从缓存中,获得公众号账号 72 * 从缓存中,获得公众号账号
56 * 73 *
57 * @param appId 微信公众号 appId 74 * @param appId 微信公众号 appId
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/tag/MpTagService.java
@@ -45,4 +45,11 @@ public interface MpTagService { @@ -45,4 +45,11 @@ public interface MpTagService {
45 */ 45 */
46 PageResult<MpTagDO> getTagPage(MpTagPageReqVO pageReqVO); 46 PageResult<MpTagDO> getTagPage(MpTagPageReqVO pageReqVO);
47 47
  48 + /**
  49 + * 同步公众号标签
  50 + *
  51 + * @param accountId 公众号账号的编号
  52 + */
  53 + void syncTag(Long accountId);
  54 +
48 } 55 }
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/tag/MpTagServiceImpl.java
1 package cn.iocoder.yudao.module.mp.service.tag; 1 package cn.iocoder.yudao.module.mp.service.tag;
2 2
  3 +import cn.hutool.core.collection.CollUtil;
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.tag.vo.MpTagCreateReqVO; 5 import cn.iocoder.yudao.module.mp.controller.admin.tag.vo.MpTagCreateReqVO;
5 import cn.iocoder.yudao.module.mp.controller.admin.tag.vo.MpTagPageReqVO; 6 import cn.iocoder.yudao.module.mp.controller.admin.tag.vo.MpTagPageReqVO;
6 import cn.iocoder.yudao.module.mp.controller.admin.tag.vo.MpTagUpdateReqVO; 7 import cn.iocoder.yudao.module.mp.controller.admin.tag.vo.MpTagUpdateReqVO;
  8 +import cn.iocoder.yudao.module.mp.convert.tag.MpTagConvert;
  9 +import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
7 import cn.iocoder.yudao.module.mp.dal.dataobject.tag.MpTagDO; 10 import cn.iocoder.yudao.module.mp.dal.dataobject.tag.MpTagDO;
8 import cn.iocoder.yudao.module.mp.dal.mysql.tag.MpTagMapper; 11 import cn.iocoder.yudao.module.mp.dal.mysql.tag.MpTagMapper;
9 import cn.iocoder.yudao.module.mp.framework.mp.core.MpServiceFactory; 12 import cn.iocoder.yudao.module.mp.framework.mp.core.MpServiceFactory;
  13 +import cn.iocoder.yudao.module.mp.service.account.MpAccountService;
10 import lombok.extern.slf4j.Slf4j; 14 import lombok.extern.slf4j.Slf4j;
  15 +import me.chanjar.weixin.common.error.WxErrorException;
  16 +import me.chanjar.weixin.mp.api.WxMpService;
  17 +import me.chanjar.weixin.mp.bean.tag.WxUserTag;
11 import org.springframework.context.annotation.Lazy; 18 import org.springframework.context.annotation.Lazy;
12 import org.springframework.stereotype.Service; 19 import org.springframework.stereotype.Service;
  20 +import org.springframework.transaction.annotation.Transactional;
13 import org.springframework.validation.annotation.Validated; 21 import org.springframework.validation.annotation.Validated;
14 22
15 import javax.annotation.Resource; 23 import javax.annotation.Resource;
  24 +import java.util.List;
  25 +import java.util.Map;
  26 +
  27 +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
  28 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
  29 +import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertMap;
  30 +import static cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants.*;
16 31
17 /** 32 /**
18 * 公众号标签 Service 实现类 33 * 公众号标签 Service 实现类
@@ -28,28 +43,112 @@ public class MpTagServiceImpl implements MpTagService { @@ -28,28 +43,112 @@ public class MpTagServiceImpl implements MpTagService {
28 private MpTagMapper mpTagMapper; 43 private MpTagMapper mpTagMapper;
29 44
30 @Resource 45 @Resource
  46 + private MpAccountService mpAccountService;
  47 +
  48 + @Resource
31 @Lazy // 延迟加载,为了解决延迟加载 49 @Lazy // 延迟加载,为了解决延迟加载
32 private MpServiceFactory mpServiceFactory; 50 private MpServiceFactory mpServiceFactory;
33 51
34 @Override 52 @Override
35 public Long createTag(MpTagCreateReqVO createReqVO) { 53 public Long createTag(MpTagCreateReqVO createReqVO) {
36 -// return wxMpService.getUserTagService().tagCreate(createReqVO.getName());  
37 - return null; 54 + // 获得公众号账号
  55 + MpAccountDO account = mpAccountService.getRequiredAccount(createReqVO.getAccountId());
  56 +
  57 + // 第一步,新增标签到公众号平台。标签名的唯一,交给公众号平台
  58 + WxMpService mpService = mpServiceFactory.getRequiredMpService(createReqVO.getAccountId());
  59 + WxUserTag wxTag;
  60 + try {
  61 + wxTag = mpService.getUserTagService().tagCreate(createReqVO.getName());
  62 + } catch (WxErrorException e) {
  63 + throw exception(TAG_CREATE_FAIL, e.getError().getErrorMsg());
  64 + }
  65 +
  66 + // 第二步,新增标签到数据库
  67 + MpTagDO tag = MpTagConvert.INSTANCE.convert(wxTag, account);
  68 + mpTagMapper.insert(tag);
  69 + return tag.getId();
38 } 70 }
39 71
40 @Override 72 @Override
41 public void updateTag(MpTagUpdateReqVO updateReqVO) { 73 public void updateTag(MpTagUpdateReqVO updateReqVO) {
42 -// return wxMpService.getUserTagService().tagUpdate(updateReqVO.getId(), updateReqVO.getName()); 74 + // 校验标签存在
  75 + MpTagDO tag = validateTagExists(updateReqVO.getId());
  76 +
  77 + // 第一步,更新标签到公众号平台。标签名的唯一,交给公众号平台
  78 + WxMpService mpService = mpServiceFactory.getRequiredMpService(tag.getAccountId());
  79 + try {
  80 + mpService.getUserTagService().tagUpdate(tag.getTagId(), updateReqVO.getName());
  81 + } catch (WxErrorException e) {
  82 + throw exception(TAG_UPDATE_FAIL, e.getError().getErrorMsg());
  83 + }
  84 +
  85 + // 第二步,更新标签到数据库
  86 + mpTagMapper.updateById(new MpTagDO().setId(tag.getId()).setName(updateReqVO.getName()));
43 } 87 }
44 88
45 @Override 89 @Override
46 public void deleteTag(Long id) { 90 public void deleteTag(Long id) {
47 -// return wxMpService.getUserTagService().tagDelete(id); 91 + // 校验标签存在
  92 + MpTagDO tag = validateTagExists(id);
  93 +
  94 + // 第一步,删除标签到公众号平台。
  95 + WxMpService mpService = mpServiceFactory.getRequiredMpService(tag.getAccountId());
  96 + try {
  97 + mpService.getUserTagService().tagDelete(tag.getTagId());
  98 + } catch (WxErrorException e) {
  99 + throw exception(TAG_DELETE_FAIL, e.getError().getErrorMsg());
  100 + }
  101 +
  102 + // 第二步,删除标签到数据库
  103 + mpTagMapper.deleteById(tag.getId());
  104 + }
  105 +
  106 + private MpTagDO validateTagExists(Long id) {
  107 + MpTagDO tag = mpTagMapper.selectById(id);
  108 + if (tag == null) {
  109 + throw exception(TAG_NOT_EXISTS);
  110 + }
  111 + return tag;
48 } 112 }
49 113
50 @Override 114 @Override
51 public PageResult<MpTagDO> getTagPage(MpTagPageReqVO pageReqVO) { 115 public PageResult<MpTagDO> getTagPage(MpTagPageReqVO pageReqVO) {
52 - return null; 116 + return mpTagMapper.selectPage(pageReqVO);
  117 + }
  118 +
  119 + @Override
  120 + @Transactional(rollbackFor = Exception.class)
  121 + public void syncTag(Long accountId) {
  122 + MpAccountDO account = mpAccountService.getRequiredAccount(accountId);
  123 +
  124 + // 第一步,从公众号平台获取最新的标签列表
  125 + WxMpService mpService = mpServiceFactory.getRequiredMpService(accountId);
  126 + List<WxUserTag> wxTags;
  127 + try {
  128 + wxTags = mpService.getUserTagService().tagGet();
  129 + } catch (WxErrorException e) {
  130 + throw new RuntimeException(e);
  131 + }
  132 +
  133 + // 第二步,合并更新回自己的数据库;由于标签只有 100 个,所以直接 for 循环操作
  134 + Map<Long, MpTagDO> tagMap = convertMap(mpTagMapper.selectListByAccountId(accountId),
  135 + MpTagDO::getTagId);
  136 + wxTags.forEach(wxTag -> {
  137 + MpTagDO tag = tagMap.remove(wxTag.getId());
  138 + // 情况一,不存在,新增
  139 + if (tag == null) {
  140 + tag = MpTagConvert.INSTANCE.convert(wxTag, account);
  141 + mpTagMapper.insert(tag);
  142 + return;
  143 + }
  144 + // 情况二,存在,则更新
  145 + mpTagMapper.updateById(new MpTagDO().setId(tag.getId())
  146 + .setName(wxTag.getName()).setCount(wxTag.getCount()));
  147 + });
  148 + // 情况三,部分标签已经不存在了,删除
  149 + if (CollUtil.isNotEmpty(tagMap)) {
  150 + mpTagMapper.deleteBatchIds(convertList(tagMap.values(), MpTagDO::getId));
  151 + }
53 } 152 }
54 153
55 } 154 }