Browse Source

!204 微信模块:公众号账号管理、粉丝标签管理(前端页面待优化)
Merge pull request !204 from fengdan/wechat-mp-fengdan

芋道源码 2 years ago
parent
commit
3f68c25540
52 changed files with 10444 additions and 10241 deletions
  1. 2 2
      http-client.env.json
  2. 3 3
      yudao-dependencies/pom.xml
  3. 0 2
      yudao-framework/yudao-spring-boot-starter-biz-weixin/pom.xml
  4. 5 7
      yudao-module-wechat/yudao-module-mp-api/src/main/java/cn/iocoder/yudao/module/mp/enums/ErrorCodeConstants.java
  5. 0 5
      yudao-module-wechat/yudao-module-mp-biz/pom.xml
  6. 0 165
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/config/WxMpConfig.java
  7. 0 47
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/config/WxMpProperties.java
  8. 11 9
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/WxAccountController.java
  9. 20 12
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/WxAccountBaseVO.java
  10. 7 2
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/WxAccountCreateReqVO.java
  11. 6 9
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/WxAccountExcelVO.java
  12. 4 1
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/WxAccountExportReqVO.java
  13. 4 3
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/WxAccountPageReqVO.java
  14. 12 3
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/WxAccountRespVO.java
  15. 3 0
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/WxAccountUpdateReqVO.java
  16. 98 0
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/fanstag/FansTagController.java
  17. 0 103
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/fanstag/WxFansTagController.java
  18. 20 0
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/fanstag/vo/FansTagBaseVO.java
  19. 22 0
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/fanstag/vo/FansTagCreateReqVO.java
  20. 1 4
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/fanstag/vo/WxFansTagExcelVO.java
  21. 1 1
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/fanstag/vo/WxFansTagExportReqVO.java
  22. 25 0
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/fanstag/vo/FansTagPageReqVO.java
  23. 3 3
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/fanstag/vo/WxFansTagRespVO.java
  24. 10 3
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/fanstag/vo/WxFansTagUpdateReqVO.java
  25. 0 22
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/fanstag/vo/WxFansTagBaseVO.java
  26. 0 12
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/fanstag/vo/WxFansTagCreateReqVO.java
  27. 0 36
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/fanstag/vo/WxFansTagPageReqVO.java
  28. 8 8
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/convert/fanstag/WxFansTagConvert.java
  29. 12 0
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/dataobject/account/WxAccountDO.java
  30. 0 43
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/dataobject/fanstag/WxFansTagDO.java
  31. 5 5
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/dataobject/texttemplate/WxTextTemplateDO.java
  32. 2 2
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/mysql/account/WxAccountMapper.java
  33. 0 38
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/mysql/fanstag/WxFansTagMapper.java
  34. 6 0
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/framework/package-info.java
  35. 106 0
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/framework/weixin/WxMpMessageRouterConfiguration.java
  36. 2 16
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/handler/MsgHandler.java
  37. 5 5
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/mq/costomer/WxConfigDataRefreshConsumer.java
  38. 1 1
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/mq/message/WxConfigDataRefreshMessage.java
  39. 2 2
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/mq/producer/WxMpConfigDataProducer.java
  40. 5 0
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/account/WxAccountService.java
  41. 65 3
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/account/WxAccountServiceImpl.java
  42. 0 71
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/fanstag/WxFansTagService.java
  43. 0 85
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/fanstag/WxFansTagServiceImpl.java
  44. 74 0
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/tag/FansTagService.java
  45. 67 0
      yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/tag/FansTagServiceImpl.java
  46. 1 1
      yudao-server/src/main/resources/application-dev.yaml
  47. 3 3
      yudao-server/src/main/resources/application-local.yaml
  48. 12 12
      yudao-ui-admin/src/api/wechatMp/wxAccount.js
  49. 7 7
      yudao-ui-admin/src/api/wechatMp/wxFansTag.js
  50. 134 103
      yudao-ui-admin/src/views/wechatMp/wxAccount/index.vue
  51. 208 188
      yudao-ui-admin/src/views/wechatMp/wxFansTag/index.vue
  52. 9462 9194
      yudao-ui-admin/yarn.lock

+ 2 - 2
http-client.env.json

@@ -2,10 +2,10 @@
   "local": {
     "baseUrl": "http://127.0.0.1:48080/admin-api",
     "token": "test1",
-    "adminTenentId": "1",
+    "appTenantId": "1",
 
     "appApi": "http://127.0.0.1:48080/app-api",
     "appToken": "test1",
-    "appTenentId": "1"
+    "appTenantId": "1"
   }
 }

+ 3 - 3
yudao-dependencies/pom.xml

@@ -64,7 +64,7 @@
         <tencentcloud-sdk-java.version>3.1.471</tencentcloud-sdk-java.version>
         <yunpian-java-sdk.version>1.2.7</yunpian-java-sdk.version>
         <justauth.version>1.4.0</justauth.version>
-        <weixin-java-mp.version>4.3.0</weixin-java-mp.version>
+        <wx-java-mp.version>4.3.0</wx-java-mp.version>
     </properties>
 
     <dependencyManagement>
@@ -570,8 +570,8 @@
 
             <dependency>
                 <groupId>com.github.binarywang</groupId>
-                <artifactId>weixin-java-mp</artifactId>
-                <version>${weixin-java-mp.version}</version>
+                <artifactId>wx-java-mp-spring-boot-starter</artifactId>
+                <version>${wx-java-mp.version}</version>
             </dependency>
 
         </dependencies>

+ 0 - 2
yudao-framework/yudao-spring-boot-starter-biz-weixin/pom.xml

@@ -33,9 +33,7 @@
         <!-- 三方云服务相关 -->
         <dependency>
             <groupId>com.github.binarywang</groupId>
-<!--            <artifactId>weixin-java-mp</artifactId>-->
             <artifactId>wx-java-mp-spring-boot-starter</artifactId>
-            <version>4.1.9.B</version>
         </dependency>
         <!-- TODO 芋艿:清理 -->
     </dependencies>

+ 5 - 7
yudao-module-wechat/yudao-module-mp-api/src/main/java/cn/iocoder/yudao/module/mp/enums/ErrorCodeConstants.java

@@ -2,18 +2,16 @@ package cn.iocoder.yudao.module.mp.enums;
 
 import cn.iocoder.yudao.framework.common.exception.ErrorCode;
 
-// TODO @亚洲:错误码要避免和别人的模块分段重叠
 /**
- * MP 错误码枚举类
+ * Member 错误码枚举类
  *
- * mp 系统,使用 1-004-000-000 段
+ * wechatMp 系统,使用 1-004-000-000 段
  */
 public interface ErrorCodeConstants {
 
     // ========== 用户相关  1004001000============
-    ErrorCode WX_ACCOUNT_NOT_EXISTS = new ErrorCode(1004001000, "用户不存在");
-    ErrorCode WX_ACCOUNT_FANS_NOT_EXISTS = new ErrorCode(1004001000, "用户不存在");
-    // TODO @亚洲:需要前缀哈,错误码分段不要重复
-    ErrorCode COMMON_NOT_EXISTS = new ErrorCode(1004001000, "用户不存在");
+    ErrorCode WX_ACCOUNT_NOT_EXISTS = new ErrorCode(1004001000, "公众号账户不存在");
+    ErrorCode WX_ACCOUNT_FANS_NOT_EXISTS = new ErrorCode(1004001001, "粉丝账号不存在");
+    ErrorCode COMMON_NOT_EXISTS = new ErrorCode(1004001002, "用户不存在");
 
 }

+ 0 - 5
yudao-module-wechat/yudao-module-mp-biz/pom.xml

@@ -79,11 +79,6 @@
         </dependency>
 
         <!-- 工具类相关 -->
-
-        <dependency>
-            <groupId>com.github.binarywang</groupId>
-            <artifactId>weixin-java-mp</artifactId>
-        </dependency>
         <dependency>
             <groupId>cn.iocoder.boot</groupId>
             <artifactId>yudao-spring-boot-starter-excel</artifactId>

+ 0 - 165
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/config/WxMpConfig.java

@@ -1,165 +0,0 @@
-package cn.iocoder.yudao.module.mp.config;
-
-
-import cn.hutool.extra.spring.SpringUtil;
-import cn.iocoder.yudao.module.mp.controller.admin.account.vo.WxAccountExportReqVO;
-import cn.iocoder.yudao.module.mp.dal.dataobject.account.WxAccountDO;
-import cn.iocoder.yudao.module.mp.handler.*;
-import cn.iocoder.yudao.module.mp.service.account.WxAccountService;
-import com.google.common.collect.Maps;
-import lombok.extern.slf4j.Slf4j;
-import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.common.redis.JedisWxRedisOps;
-import me.chanjar.weixin.mp.api.WxMpMessageRouter;
-import me.chanjar.weixin.mp.api.WxMpService;
-import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
-import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
-import me.chanjar.weixin.mp.config.impl.WxMpRedisConfigImpl;
-import me.chanjar.weixin.mp.constant.WxMpEventConstants;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.boot.context.properties.EnableConfigurationProperties;
-import org.springframework.scheduling.annotation.Scheduled;
-import org.springframework.stereotype.Component;
-import org.springframework.util.CollectionUtils;
-import redis.clients.jedis.JedisPool;
-import redis.clients.jedis.JedisPoolConfig;
-
-import java.util.List;
-import java.util.Map;
-import java.util.stream.Collectors;
-
-// TODO @芋艿:思考有没更好的处理方式
-@Component
-@EnableConfigurationProperties(WxMpProperties.class)
-@Slf4j
-public class WxMpConfig implements InitializingBean {
-
-    private static Map<String, WxMpMessageRouter> routers = Maps.newHashMap();
-    private static Map<String, WxMpService> mpServices = Maps.newHashMap();
-
-    @Autowired
-    private WxAccountService wxAccountService;
-    @Autowired
-    private WxMpProperties wxMpProperties;
-
-    private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
-
-    /**
-     * 初始化公众号配置
-     */
-    public synchronized void initWxConfig() {
-        WxAccountExportReqVO req = new WxAccountExportReqVO();
-        List<WxAccountDO> wxAccountList = wxAccountService.getWxAccountList(req);
-        if (CollectionUtils.isEmpty(wxAccountList)) {
-            return;
-        }
-        WxMpConfig.init(wxAccountList, wxMpProperties);
-        log.info("加载公众号配置成功");
-    }
-
-
-    @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD)
-    public void schedulePeriodicRefresh() {
-        initWxConfig();
-    }
-
-    public static void init(List<WxAccountDO> wxAccountDOS, WxMpProperties properties) {
-        mpServices = wxAccountDOS.stream().map(wxAccountDO -> {
-            // TODO 亚洲:使用 WxMpInMemoryConfigStorage 的话,多节点会不会存在 accessToken 冲突
-
-            WxMpDefaultConfigImpl configStorage;
-            if (properties.isUseRedis()) {
-                final WxMpProperties.RedisConfig redisConfig = properties.getRedisConfig();
-                JedisPoolConfig poolConfig = new JedisPoolConfig();
-                JedisPool jedisPool = new JedisPool(poolConfig, redisConfig.getHost(), redisConfig.getPort(),
-                        redisConfig.getTimeout(), redisConfig.getPassword());
-                configStorage = new WxMpRedisConfigImpl(new JedisWxRedisOps(jedisPool), wxAccountDO.getAppId());
-            } else {
-                configStorage = new WxMpDefaultConfigImpl();
-            }
-
-            configStorage.setAppId(wxAccountDO.getAppId());
-            configStorage.setSecret(wxAccountDO.getAppSecret());
-            configStorage.setToken(wxAccountDO.getToken());
-            configStorage.setAesKey(wxAccountDO.getAesKey());
-
-            WxMpService service = new WxMpServiceImpl();
-            service.setWxMpConfigStorage(configStorage);
-            routers.put(wxAccountDO.getAppId(), newRouter(service));
-            return service;
-        }).collect(Collectors.toMap(s -> s.getWxMpConfigStorage().getAppId(), a -> a, (o, n) -> o));
-    }
-
-    public static Map<String, WxMpMessageRouter> getRouters() {
-        return routers;
-    }
-
-    public static Map<String, WxMpService> getMpServices() {
-        return mpServices;
-    }
-
-    private static WxMpMessageRouter newRouter(WxMpService wxMpService) {
-        final WxMpMessageRouter newRouter = new WxMpMessageRouter(wxMpService);
-        // 记录所有事件的日志 (异步执行)
-        newRouter.rule().handler(SpringUtil.getBean(LogHandler.class)).next();
-
-        // 接收客服会话管理事件
-        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
-                .event(WxMpEventConstants.CustomerService.KF_CREATE_SESSION)
-                .handler(SpringUtil.getBean(KfSessionHandler.class)).end();
-        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
-                .event(WxMpEventConstants.CustomerService.KF_CLOSE_SESSION)
-                .handler(SpringUtil.getBean(KfSessionHandler.class))
-                .end();
-        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
-                .event(WxMpEventConstants.CustomerService.KF_SWITCH_SESSION)
-                .handler(SpringUtil.getBean(KfSessionHandler.class)).end();
-
-        // 门店审核事件
-        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
-                .event(WxMpEventConstants.POI_CHECK_NOTIFY)
-                .handler(SpringUtil.getBean(StoreCheckNotifyHandler.class)).end();
-
-        // 自定义菜单事件
-        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
-                .event(WxConsts.MenuButtonType.CLICK).handler(SpringUtil.getBean(MenuHandler.class)).end();
-
-        // 点击菜单连接事件
-        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
-                .event(WxConsts.MenuButtonType.VIEW).handler(SpringUtil.getBean(NullHandler.class)).end();
-
-        // 关注事件
-        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
-                .event(WxConsts.EventType.SUBSCRIBE).handler(SpringUtil.getBean(SubscribeHandler.class))
-                .end();
-
-        // 取消关注事件
-        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
-                .event(WxConsts.EventType.UNSUBSCRIBE)
-                .handler(SpringUtil.getBean(UnsubscribeHandler.class)).end();
-
-        // 上报地理位置事件
-        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
-                .event(WxConsts.EventType.LOCATION).handler(SpringUtil.getBean(LocationHandler.class))
-                .end();
-
-        // 接收地理位置消息
-        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.LOCATION)
-                .handler(SpringUtil.getBean(LocationHandler.class)).end();
-
-        // 扫码事件
-        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
-                .event(WxConsts.EventType.SCAN).handler(SpringUtil.getBean(ScanHandler.class)).end();
-
-        // 默认
-        newRouter.rule().async(false).handler(SpringUtil.getBean(MsgHandler.class)).end();
-
-        return newRouter;
-    }
-
-    @Override
-    public void afterPropertiesSet() throws Exception {
-        initWxConfig();
-    }
-}

+ 0 - 47
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/config/WxMpProperties.java

@@ -1,47 +0,0 @@
-package cn.iocoder.yudao.module.mp.config;
-
-import lombok.Data;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-
-/**
- * wechat mp properties
- */
-@Data
-@ConfigurationProperties(prefix = "wx.mp")
-public class WxMpProperties {
-    /**
-     * 是否使用redis存储access token
-     */
-    private boolean useRedis;
-
-    private String defaultContent;
-
-    /**
-     * redis 配置
-     */
-    private RedisConfig redisConfig;
-
-    @Data
-    public static class RedisConfig {
-        /**
-         * redis服务器 主机地址
-         */
-        private String host;
-
-        /**
-         * redis服务器 端口号
-         */
-        private Integer port;
-
-        /**
-         * redis服务器 密码
-         */
-        private String password;
-
-        /**
-         * redis 服务连接超时时间
-         */
-        private Integer timeout;
-    }
-
-}

+ 11 - 9
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/WxAccountController.java

@@ -25,10 +25,12 @@ import java.util.List;
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
 
-// TODO @亚洲:/mp/account 即可
+/**
+ * @author fengdan
+ */
 @Api(tags = "管理后台 - 公众号账户")
 @RestController
-@RequestMapping("/wechatMp/wx-account")
+@RequestMapping("/wechatMp/account")
 @Validated
 public class WxAccountController {
 
@@ -37,14 +39,14 @@ public class WxAccountController {
 
     @PostMapping("/create")
     @ApiOperation("创建公众号账户")
-    @PreAuthorize("@ss.hasPermission('wechatMp:wx-account:create')")
+    @PreAuthorize("@ss.hasPermission('wechatMp:account:create')")
     public CommonResult<Long> createWxAccount(@Valid @RequestBody WxAccountCreateReqVO createReqVO) {
         return success(wxAccountService.createWxAccount(createReqVO));
     }
 
     @PutMapping("/update")
     @ApiOperation("更新公众号账户")
-    @PreAuthorize("@ss.hasPermission('wechatMp:wx-account:update')")
+    @PreAuthorize("@ss.hasPermission('wechatMp:account:update')")
     public CommonResult<Boolean> updateWxAccount(@Valid @RequestBody WxAccountUpdateReqVO updateReqVO) {
         wxAccountService.updateWxAccount(updateReqVO);
         return success(true);
@@ -53,7 +55,7 @@ public class WxAccountController {
     @DeleteMapping("/delete")
     @ApiOperation("删除公众号账户")
     @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Long.class)
-    @PreAuthorize("@ss.hasPermission('wechatMp:wx-account:delete')")
+    @PreAuthorize("@ss.hasPermission('wechatMp:account:delete')")
     public CommonResult<Boolean> deleteWxAccount(@RequestParam("id") Long id) {
         wxAccountService.deleteWxAccount(id);
         return success(true);
@@ -62,7 +64,7 @@ public class WxAccountController {
     @GetMapping("/get")
     @ApiOperation("获得公众号账户")
     @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
-    @PreAuthorize("@ss.hasPermission('wechatMp:wx-account:query')")
+    @PreAuthorize("@ss.hasPermission('wechatMp:account:query')")
     public CommonResult<WxAccountRespVO> getWxAccount(@RequestParam("id") Long id) {
         WxAccountDO wxAccount = wxAccountService.getWxAccount(id);
         return success(WxAccountConvert.INSTANCE.convert(wxAccount));
@@ -71,7 +73,7 @@ public class WxAccountController {
     @GetMapping("/list")
     @ApiOperation("获得公众号账户列表")
     @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
-    @PreAuthorize("@ss.hasPermission('wechatMp:wx-account:query')")
+    @PreAuthorize("@ss.hasPermission('wechatMp:account:query')")
     public CommonResult<List<WxAccountRespVO>> getWxAccountList(@RequestParam("ids") Collection<Long> ids) {
         List<WxAccountDO> list = wxAccountService.getWxAccountList(ids);
         return success(WxAccountConvert.INSTANCE.convertList(list));
@@ -79,7 +81,7 @@ public class WxAccountController {
 
     @GetMapping("/page")
     @ApiOperation("获得公众号账户分页")
-    @PreAuthorize("@ss.hasPermission('wechatMp:wx-account:query')")
+    @PreAuthorize("@ss.hasPermission('wechatMp:account:query')")
     public CommonResult<PageResult<WxAccountRespVO>> getWxAccountPage(@Valid WxAccountPageReqVO pageVO) {
         PageResult<WxAccountDO> pageResult = wxAccountService.getWxAccountPage(pageVO);
         return success(WxAccountConvert.INSTANCE.convertPage(pageResult));
@@ -87,7 +89,7 @@ public class WxAccountController {
 
     @GetMapping("/export-excel")
     @ApiOperation("导出公众号账户 Excel")
-    @PreAuthorize("@ss.hasPermission('wechatMp:wx-account:export')")
+    @PreAuthorize("@ss.hasPermission('wechatMp:account:export')")
     @OperateLog(type = EXPORT)
     public void exportWxAccountExcel(@Valid WxAccountExportReqVO exportReqVO,
                                      HttpServletResponse response) throws IOException {

+ 20 - 12
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/WxAccountBaseVO.java

@@ -1,32 +1,40 @@
 package cn.iocoder.yudao.module.mp.controller.admin.account.vo;
 
-import lombok.*;
-import io.swagger.annotations.*;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
 
 /**
-* 公众号账户 Base VO,提供给添加、修改、详细的子 VO 使用
-* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
-*/
+ * 公众号账户 Base VO,提供给添加、修改、详细的子 VO 使用
+ * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
+ *
+ * @author fengdan
+ */
 @Data
 public class WxAccountBaseVO {
 
-    @ApiModelProperty(value = "公众号名称")
+    @ApiModelProperty(value = "公众号名称", required = true)
+    @NotNull(message = "公众号名称不能为空")
     private String name;
 
-    @ApiModelProperty(value = "公众号账户")
+    @ApiModelProperty(value = "公众号账户", required = true)
+    @NotNull(message = "公众号账户不能为空")
     private String account;
 
-    @ApiModelProperty(value = "公众号appid")
-    private String appid;
+    @ApiModelProperty(value = "公众号appid", required = true)
+    @NotNull(message = "公众号appid不能为空")
+    private String appId;
 
-    @ApiModelProperty(value = "公众号密钥")
-    private String appsecret;
+    @ApiModelProperty(value = "公众号密钥", required = true)
+    @NotNull(message = "公众号密钥不能为空")
+    private String appSecret;
 
     @ApiModelProperty(value = "公众号token")
     private String token;
 
     @ApiModelProperty(value = "加密密钥")
-    private String aeskey;
+    private String aesKey;
 
     @ApiModelProperty(value = "备注")
     private String remark;

+ 7 - 2
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/WxAccountCreateReqVO.java

@@ -1,8 +1,13 @@
 package cn.iocoder.yudao.module.mp.controller.admin.account.vo;
 
-import lombok.*;
-import io.swagger.annotations.*;
+import io.swagger.annotations.ApiModel;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
 
+/**
+ * @author fengdan
+ */
 @ApiModel("管理后台 - 公众号账户创建 Request VO")
 @Data
 @EqualsAndHashCode(callSuper = true)

+ 6 - 9
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/WxAccountExcelVO.java

@@ -1,9 +1,10 @@
 package cn.iocoder.yudao.module.mp.controller.admin.account.vo;
 
-import lombok.*;
-import java.util.*;
-
 import com.alibaba.excel.annotation.ExcelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
 
 /**
  * 公众号账户 Excel VO
@@ -23,10 +24,7 @@ public class WxAccountExcelVO {
     private String account;
 
     @ExcelProperty("公众号appid")
-    private String appid;
-
-    @ExcelProperty("公众号密钥")
-    private String appsecret;
+    private String appId;
 
     @ExcelProperty("公众号url")
     private String url;
@@ -35,7 +33,7 @@ public class WxAccountExcelVO {
     private String token;
 
     @ExcelProperty("加密密钥")
-    private String aeskey;
+    private String aesKey;
 
     @ExcelProperty("二维码图片URL")
     private String qrCodeUrl;
@@ -45,5 +43,4 @@ public class WxAccountExcelVO {
 
     @ExcelProperty("创建时间")
     private Date createTime;
-
 }

+ 4 - 1
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/WxAccountExportReqVO.java

@@ -7,6 +7,9 @@ import org.springframework.format.annotation.DateTimeFormat;
 
 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 
+/**
+ * @author fengdan
+ */
 @ApiModel(value = "管理后台 - 公众号账户 Excel 导出 Request VO", description = "参数和 WxAccountPageReqVO 是一致的")
 @Data
 public class WxAccountExportReqVO {
@@ -18,7 +21,7 @@ public class WxAccountExportReqVO {
     private String account;
 
     @ApiModelProperty(value = "公众号appid")
-    private String appid;
+    private String appId;
 
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
     @ApiModelProperty(value = "开始创建时间")

+ 4 - 3
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/WxAccountPageReqVO.java

@@ -8,12 +8,14 @@ import org.springframework.format.annotation.DateTimeFormat;
 
 import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
 
+/**
+ * @author fengdan
+ */
 @ApiModel("管理后台 - 公众号账户分页 Request VO")
 @Data
 @EqualsAndHashCode(callSuper = true)
 @ToString(callSuper = true)
 public class WxAccountPageReqVO extends PageParam {
-
     @ApiModelProperty(value = "公众号名称")
     private String name;
 
@@ -21,7 +23,7 @@ public class WxAccountPageReqVO extends PageParam {
     private String account;
 
     @ApiModelProperty(value = "公众号appid")
-    private String appid;
+    private String appId;
 
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
     @ApiModelProperty(value = "开始创建时间")
@@ -30,5 +32,4 @@ public class WxAccountPageReqVO extends PageParam {
     @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
     @ApiModelProperty(value = "结束创建时间")
     private Date endCreateTime;
-
 }

+ 12 - 3
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/WxAccountRespVO.java

@@ -1,9 +1,16 @@
 package cn.iocoder.yudao.module.mp.controller.admin.account.vo;
 
-import lombok.*;
-import java.util.*;
-import io.swagger.annotations.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
 
+import java.util.Date;
+
+/**
+ * @author fengdan
+ */
 @ApiModel("管理后台 - 公众号账户 Response VO")
 @Data
 @EqualsAndHashCode(callSuper = true)
@@ -22,4 +29,6 @@ public class WxAccountRespVO extends WxAccountBaseVO {
     @ApiModelProperty(value = "创建时间", required = true)
     private Date createTime;
 
+    @ApiModelProperty(value = "公众号密钥", required = true)
+    private String appSecret;
 }

+ 3 - 0
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/account/vo/WxAccountUpdateReqVO.java

@@ -4,6 +4,9 @@ import lombok.*;
 import io.swagger.annotations.*;
 import javax.validation.constraints.*;
 
+/**
+ * @author fengdan
+ */
 @ApiModel("管理后台 - 公众号账户更新 Request VO")
 @Data
 @EqualsAndHashCode(callSuper = true)

+ 98 - 0
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/fanstag/FansTagController.java

@@ -0,0 +1,98 @@
+package cn.iocoder.yudao.module.mp.controller.admin.fanstag;
+
+import cn.iocoder.yudao.framework.common.pojo.CommonResult;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
+import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
+import cn.iocoder.yudao.module.mp.controller.admin.fanstag.vo.*;
+import cn.iocoder.yudao.module.mp.convert.fanstag.WxFansTagConvert;
+import cn.iocoder.yudao.module.mp.service.tag.FansTagService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.mp.bean.tag.WxUserTag;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletResponse;
+import javax.validation.Valid;
+import javax.validation.constraints.NotEmpty;
+import java.io.IOException;
+import java.util.List;
+
+import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
+import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.EXPORT;
+
+/**
+ * @author fengdan
+ */
+@Api(tags = "管理后台 - 粉丝标签")
+@RestController
+@RequestMapping("/wechatMp/fans-tag")
+@Validated
+public class FansTagController {
+
+    @Resource
+    private FansTagService fansTagService;
+
+    @PostMapping("/create")
+    @ApiOperation("创建粉丝标签")
+    @PreAuthorize("@ss.hasPermission('wechatMp:fans-tag:create')")
+    public CommonResult<WxUserTag> createWxFansTag(@Valid @RequestBody FansTagCreateReqVO createReqVO) throws WxErrorException {
+        return success(fansTagService.createWxFansTag(createReqVO));
+    }
+
+    @PutMapping("/update")
+    @ApiOperation("更新粉丝标签")
+    @PreAuthorize("@ss.hasPermission('wechatMp:fans-tag:update')")
+    public CommonResult<Boolean> updateWxFansTag(@Valid @RequestBody FansTagUpdateReqVO updateReqVO) throws WxErrorException {
+        return success(fansTagService.updateWxFansTag(updateReqVO));
+    }
+
+    @DeleteMapping("/delete")
+    @ApiOperation("删除粉丝标签")
+    @PreAuthorize("@ss.hasPermission('wechatMp:fans-tag:delete')")
+    public CommonResult<Boolean> deleteWxFansTag(@RequestParam("id") Long id,
+                                                 @RequestParam("appId") String appId) throws WxErrorException {
+        return success(fansTagService.deleteWxFansTag(id, appId));
+    }
+
+    @GetMapping("/list")
+    @ApiOperation("获取公众号已创建的标签")
+    @PreAuthorize("@ss.hasPermission('wechatMp:fans-tag:query')")
+    public CommonResult<List<FansTagRespVO>> getWxFansTagList(@NotEmpty(message = "公众号appId不能为空")
+                                                              @RequestParam("appId") String appId) throws WxErrorException {
+        List<WxUserTag> list = fansTagService.getWxFansTagList(appId);
+        return success(WxFansTagConvert.INSTANCE.convertList(list));
+    }
+
+    @GetMapping("/page")
+    @ApiOperation("获取公众号已创建的标签")
+    @PreAuthorize("@ss.hasPermission('wechatMp:fans-tag:query')")
+    public CommonResult<PageResult<FansTagRespVO>> page() throws WxErrorException {
+        PageResult<WxUserTag> page = new PageResult<>();
+        return success(WxFansTagConvert.INSTANCE.convertPage(page));
+    }
+
+    @GetMapping("/tagListUser")
+    @ApiOperation("获取标签下粉丝列表")
+    @PreAuthorize("@ss.hasPermission('wechatMp:fans-tag:query')")
+    public CommonResult<String> tagListUser(@Valid FansTagPageReqVO pageVO) {
+        return success("");
+    }
+
+    @GetMapping("/export-excel")
+    @ApiOperation("导出粉丝标签 Excel")
+    @PreAuthorize("@ss.hasPermission('wechatMp:fans-tag:export')")
+    @OperateLog(type = EXPORT)
+    public void exportWxFansTagExcel(@Valid FansTagExportReqVO exportReqVO,
+                                     HttpServletResponse response) throws IOException {
+        List<WxUserTag> list = fansTagService.getWxFansTagList(exportReqVO);
+        // 导出 Excel
+        List<FansTagExcelVO> datas = WxFansTagConvert.INSTANCE.convertList02(list);
+        ExcelUtils.write(response, "粉丝标签.xls", "数据", FansTagExcelVO.class, datas);
+    }
+
+}

+ 0 - 103
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/fanstag/WxFansTagController.java

@@ -1,103 +0,0 @@
-package cn.iocoder.yudao.module.mp.controller.admin.fanstag;
-
-import org.springframework.web.bind.annotation.*;
-
-import javax.annotation.Resource;
-
-import org.springframework.validation.annotation.Validated;
-import org.springframework.security.access.prepost.PreAuthorize;
-import io.swagger.annotations.*;
-
-import javax.validation.*;
-import javax.servlet.http.*;
-import java.util.*;
-import java.io.IOException;
-
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.common.pojo.CommonResult;
-
-import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
-
-import cn.iocoder.yudao.framework.excel.core.util.ExcelUtils;
-
-import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
-
-import static cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum.*;
-
-import cn.iocoder.yudao.module.mp.controller.admin.fanstag.vo.*;
-import cn.iocoder.yudao.module.mp.dal.dataobject.fanstag.WxFansTagDO;
-import cn.iocoder.yudao.module.mp.convert.fanstag.WxFansTagConvert;
-import cn.iocoder.yudao.module.mp.service.fanstag.WxFansTagService;
-
-@Api(tags = "管理后台 - 粉丝标签")
-@RestController
-@RequestMapping("/wechatMp/wx-fans-tag")
-@Validated
-public class WxFansTagController {
-
-    @Resource
-    private WxFansTagService wxFansTagService;
-
-    @PostMapping("/create")
-    @ApiOperation("创建粉丝标签")
-    @PreAuthorize("@ss.hasPermission('wechatMp:wx-fans-tag:create')")
-    public CommonResult<Integer> createWxFansTag(@Valid @RequestBody WxFansTagCreateReqVO createReqVO) {
-        return success(wxFansTagService.createWxFansTag(createReqVO));
-    }
-
-    @PutMapping("/update")
-    @ApiOperation("更新粉丝标签")
-    @PreAuthorize("@ss.hasPermission('wechatMp:wx-fans-tag:update')")
-    public CommonResult<Boolean> updateWxFansTag(@Valid @RequestBody WxFansTagUpdateReqVO updateReqVO) {
-        wxFansTagService.updateWxFansTag(updateReqVO);
-        return success(true);
-    }
-
-    @DeleteMapping("/delete")
-    @ApiOperation("删除粉丝标签")
-    @ApiImplicitParam(name = "id", value = "编号", required = true, dataTypeClass = Integer.class)
-    @PreAuthorize("@ss.hasPermission('wechatMp:wx-fans-tag:delete')")
-    public CommonResult<Boolean> deleteWxFansTag(@RequestParam("id") Integer id) {
-        wxFansTagService.deleteWxFansTag(id);
-        return success(true);
-    }
-
-    @GetMapping("/get")
-    @ApiOperation("获得粉丝标签")
-    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Integer.class)
-    @PreAuthorize("@ss.hasPermission('wechatMp:wx-fans-tag:query')")
-    public CommonResult<WxFansTagRespVO> getWxFansTag(@RequestParam("id") Integer id) {
-        WxFansTagDO wxFansTag = wxFansTagService.getWxFansTag(id);
-        return success(WxFansTagConvert.INSTANCE.convert(wxFansTag));
-    }
-
-    @GetMapping("/list")
-    @ApiOperation("获得粉丝标签列表")
-    @ApiImplicitParam(name = "ids", value = "编号列表", required = true, example = "1024,2048", dataTypeClass = List.class)
-    @PreAuthorize("@ss.hasPermission('wechatMp:wx-fans-tag:query')")
-    public CommonResult<List<WxFansTagRespVO>> getWxFansTagList(@RequestParam("ids") Collection<Integer> ids) {
-        List<WxFansTagDO> list = wxFansTagService.getWxFansTagList(ids);
-        return success(WxFansTagConvert.INSTANCE.convertList(list));
-    }
-
-    @GetMapping("/page")
-    @ApiOperation("获得粉丝标签分页")
-    @PreAuthorize("@ss.hasPermission('wechatMp:wx-fans-tag:query')")
-    public CommonResult<PageResult<WxFansTagRespVO>> getWxFansTagPage(@Valid WxFansTagPageReqVO pageVO) {
-        PageResult<WxFansTagDO> pageResult = wxFansTagService.getWxFansTagPage(pageVO);
-        return success(WxFansTagConvert.INSTANCE.convertPage(pageResult));
-    }
-
-    @GetMapping("/export-excel")
-    @ApiOperation("导出粉丝标签 Excel")
-    @PreAuthorize("@ss.hasPermission('wechatMp:wx-fans-tag:export')")
-    @OperateLog(type = EXPORT)
-    public void exportWxFansTagExcel(@Valid WxFansTagExportReqVO exportReqVO,
-                                     HttpServletResponse response) throws IOException {
-        List<WxFansTagDO> list = wxFansTagService.getWxFansTagList(exportReqVO);
-        // 导出 Excel
-        List<WxFansTagExcelVO> datas = WxFansTagConvert.INSTANCE.convertList02(list);
-        ExcelUtils.write(response, "粉丝标签.xls", "数据", WxFansTagExcelVO.class, datas);
-    }
-
-}

+ 20 - 0
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/fanstag/vo/FansTagBaseVO.java

@@ -0,0 +1,20 @@
+package cn.iocoder.yudao.module.mp.controller.admin.fanstag.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * 粉丝标签 Base VO,提供给添加、修改、详细的子 VO 使用
+ * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
+ *
+ * @author fengdan
+ */
+@Data
+public class FansTagBaseVO {
+
+    @NotBlank(message = "标签名不能为空")
+    @ApiModelProperty(value = "标签名,UTF8编码")
+    private String name;
+}

+ 22 - 0
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/fanstag/vo/FansTagCreateReqVO.java

@@ -0,0 +1,22 @@
+package cn.iocoder.yudao.module.mp.controller.admin.fanstag.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * @author fengdan
+ */
+@ApiModel("管理后台 - 粉丝标签创建 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class FansTagCreateReqVO extends FansTagBaseVO {
+    @NotBlank(message = "公众号appId不能为空")
+    @ApiModelProperty("微信公众号appId")
+    private String appId;
+}

+ 1 - 4
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/fanstag/vo/WxFansTagExcelVO.java

@@ -12,7 +12,7 @@ import com.alibaba.excel.annotation.ExcelProperty;
  * @author 芋道源码
  */
 @Data
-public class WxFansTagExcelVO {
+public class FansTagExcelVO {
 
     @ExcelProperty("主键")
     private Integer id;
@@ -23,9 +23,6 @@ public class WxFansTagExcelVO {
     @ExcelProperty("粉丝数量")
     private Integer count;
 
-    @ExcelProperty("微信账号ID")
-    private String wxAccountId;
-
     @ExcelProperty("创建时间")
     private Date createTime;
 

+ 1 - 1
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/fanstag/vo/WxFansTagExportReqVO.java

@@ -11,7 +11,7 @@ import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_
 
 @ApiModel(value = "管理后台 - 粉丝标签 Excel 导出 Request VO", description = "参数和 WxFansTagPageReqVO 是一致的")
 @Data
-public class WxFansTagExportReqVO {
+public class FansTagExportReqVO {
 
     @ApiModelProperty(value = "标签名称")
     private String name;

+ 25 - 0
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/fanstag/vo/FansTagPageReqVO.java

@@ -0,0 +1,25 @@
+package cn.iocoder.yudao.module.mp.controller.admin.fanstag.vo;
+
+import cn.iocoder.yudao.framework.common.pojo.PageParam;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.ToString;
+
+import javax.validation.constraints.NotEmpty;
+
+/**
+ * @author fengdan
+ */
+@ApiModel("管理后台 - 粉丝标签分页 Request VO")
+@Data
+@EqualsAndHashCode(callSuper = true)
+@ToString(callSuper = true)
+public class FansTagPageReqVO extends PageParam {
+
+    @NotEmpty(message = "公众号appId不能为空")
+    @ApiModelProperty("微信公众号appId")
+    private String appId;
+
+}

+ 3 - 3
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/fanstag/vo/WxFansTagRespVO.java

@@ -10,10 +10,10 @@ import io.swagger.annotations.*;
 @Data
 @EqualsAndHashCode(callSuper = true)
 @ToString(callSuper = true)
-public class WxFansTagRespVO extends WxFansTagBaseVO {
+public class FansTagRespVO extends FansTagBaseVO {
 
-    @ApiModelProperty(value = "主键", required = true)
-    private Integer id;
+    @ApiModelProperty(value = "标签id,由微信分配.")
+    private Long id;
 
     @ApiModelProperty(value = "创建时间", required = true)
     private Date createTime;

+ 10 - 3
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/fanstag/vo/WxFansTagUpdateReqVO.java

@@ -5,14 +5,21 @@ import io.swagger.annotations.*;
 
 import javax.validation.constraints.*;
 
+/**
+ * @author fengdan
+ */
 @ApiModel("管理后台 - 粉丝标签更新 Request VO")
 @Data
 @EqualsAndHashCode(callSuper = true)
 @ToString(callSuper = true)
-public class WxFansTagUpdateReqVO extends WxFansTagBaseVO {
+public class FansTagUpdateReqVO extends FansTagBaseVO {
 
-    @ApiModelProperty(value = "主键", required = true)
+    @ApiModelProperty(value = "标签id,由微信分配", required = true)
     @NotNull(message = "主键不能为空")
-    private Integer id;
+    private Long id;
+
+    @NotBlank(message = "公众号appId不能为空")
+    @ApiModelProperty("微信公众号appId")
+    private String appId;
 
 }

+ 0 - 22
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/fanstag/vo/WxFansTagBaseVO.java

@@ -1,22 +0,0 @@
-package cn.iocoder.yudao.module.mp.controller.admin.fanstag.vo;
-
-import lombok.*;
-import io.swagger.annotations.*;
-
-/**
- * 粉丝标签 Base VO,提供给添加、修改、详细的子 VO 使用
- * 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
- */
-@Data
-public class WxFansTagBaseVO {
-
-    @ApiModelProperty(value = "标签名称")
-    private String name;
-
-    @ApiModelProperty(value = "粉丝数量")
-    private Integer count;
-
-    @ApiModelProperty(value = "微信账号ID")
-    private String wxAccountId;
-
-}

+ 0 - 12
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/fanstag/vo/WxFansTagCreateReqVO.java

@@ -1,12 +0,0 @@
-package cn.iocoder.yudao.module.mp.controller.admin.fanstag.vo;
-
-import lombok.*;
-import io.swagger.annotations.*;
-
-@ApiModel("管理后台 - 粉丝标签创建 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class WxFansTagCreateReqVO extends WxFansTagBaseVO {
-
-}

+ 0 - 36
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/fanstag/vo/WxFansTagPageReqVO.java

@@ -1,36 +0,0 @@
-package cn.iocoder.yudao.module.mp.controller.admin.fanstag.vo;
-
-import lombok.*;
-
-import java.util.*;
-
-import io.swagger.annotations.*;
-import cn.iocoder.yudao.framework.common.pojo.PageParam;
-import org.springframework.format.annotation.DateTimeFormat;
-
-import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
-
-@ApiModel("管理后台 - 粉丝标签分页 Request VO")
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class WxFansTagPageReqVO extends PageParam {
-
-    @ApiModelProperty(value = "标签名称")
-    private String name;
-
-    @ApiModelProperty(value = "粉丝数量")
-    private Integer count;
-
-    @ApiModelProperty(value = "微信账号ID")
-    private String wxAccountId;
-
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    @ApiModelProperty(value = "开始创建时间")
-    private Date beginCreateTime;
-
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    @ApiModelProperty(value = "结束创建时间")
-    private Date endCreateTime;
-
-}

+ 8 - 8
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/convert/fanstag/WxFansTagConvert.java

@@ -4,31 +4,31 @@ import java.util.*;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 
+import me.chanjar.weixin.mp.bean.tag.WxUserTag;
 import org.mapstruct.Mapper;
 import org.mapstruct.factory.Mappers;
 import cn.iocoder.yudao.module.mp.controller.admin.fanstag.vo.*;
-import cn.iocoder.yudao.module.mp.dal.dataobject.fanstag.WxFansTagDO;
 
 /**
  * 粉丝标签 Convert
  *
- * @author 芋道源码
+ * @author fengdan
  */
 @Mapper
 public interface WxFansTagConvert {
 
     WxFansTagConvert INSTANCE = Mappers.getMapper(WxFansTagConvert.class);
 
-    WxFansTagDO convert(WxFansTagCreateReqVO bean);
+    WxUserTag convert(FansTagCreateReqVO bean);
 
-    WxFansTagDO convert(WxFansTagUpdateReqVO bean);
+    WxUserTag convert(FansTagUpdateReqVO bean);
 
-    WxFansTagRespVO convert(WxFansTagDO bean);
+    FansTagRespVO convert(WxUserTag bean);
 
-    List<WxFansTagRespVO> convertList(List<WxFansTagDO> list);
+    List<FansTagRespVO> convertList(List<WxUserTag> list);
 
-    PageResult<WxFansTagRespVO> convertPage(PageResult<WxFansTagDO> page);
+    PageResult<FansTagRespVO> convertPage(PageResult<WxUserTag> page);
 
-    List<WxFansTagExcelVO> convertList02(List<WxFansTagDO> list);
+    List<FansTagExcelVO> convertList02(List<WxUserTag> list);
 
 }

+ 12 - 0
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/dataobject/account/WxAccountDO.java

@@ -4,7 +4,11 @@ import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
 import com.baomidou.mybatisplus.annotation.KeySequence;
 import com.baomidou.mybatisplus.annotation.TableId;
 import com.baomidou.mybatisplus.annotation.TableName;
+import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties;
 import lombok.*;
+import me.chanjar.weixin.common.redis.RedisTemplateWxRedisOps;
+import me.chanjar.weixin.mp.config.WxMpConfigStorage;
+import me.chanjar.weixin.mp.config.impl.WxMpRedisConfigImpl;
 
 // TODO 亚洲:这个模块的相关类,使用 Mp 作为前缀哈
 /**
@@ -64,4 +68,12 @@ public class WxAccountDO extends BaseDO {
      */
     private String remark;
 
+    public WxMpConfigStorage toWxMpConfigStorage(RedisTemplateWxRedisOps redisTemplateWxRedisOps, WxMpProperties wxMpProperties) {
+        WxMpRedisConfigImpl wxMpRedisConfig = new WxMpRedisConfigImpl(redisTemplateWxRedisOps, wxMpProperties.getConfigStorage().getKeyPrefix());
+        wxMpRedisConfig.setAppId(appId);
+        wxMpRedisConfig.setSecret(appSecret);
+        wxMpRedisConfig.setToken(token);
+        wxMpRedisConfig.setAesKey(aesKey);
+        return wxMpRedisConfig;
+    }
 }

+ 0 - 43
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/dataobject/fanstag/WxFansTagDO.java

@@ -1,43 +0,0 @@
-package cn.iocoder.yudao.module.mp.dal.dataobject.fanstag;
-
-import lombok.*;
-
-import java.util.*;
-
-import com.baomidou.mybatisplus.annotation.*;
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
-
-/**
- * 粉丝标签 DO
- *
- * @author 芋道源码
- */
-@TableName("wx_fans_tag")
-@KeySequence("wx_fans_tag_seq") // 用于 Oracle、PostgreSQL、Kingbase、DB2、H2 数据库的主键自增。如果是 MySQL 等数据库,可不写。
-@Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-@Builder
-@NoArgsConstructor
-@AllArgsConstructor
-public class WxFansTagDO extends BaseDO {
-
-    /**
-     * 主键
-     */
-    @TableId
-    private Integer id;
-    /**
-     * 标签名称
-     */
-    private String name;
-    /**
-     * 粉丝数量
-     */
-    private Integer count;
-    /**
-     * 微信账号ID
-     */
-    private String wxAccountId;
-
-}

+ 5 - 5
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/dataobject/texttemplate/WxTextTemplateDO.java

@@ -1,12 +1,12 @@
 package cn.iocoder.yudao.module.mp.dal.dataobject.texttemplate;
 
-import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
-import com.baomidou.mybatisplus.annotation.KeySequence;
-import com.baomidou.mybatisplus.annotation.TableId;
-import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.*;
 
-// TODO @亚洲:消息使用统一的表存储,思考下咋做哈。
+import java.util.*;
+
+import com.baomidou.mybatisplus.annotation.*;
+import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
+
 /**
  * 文本模板 DO
  *

+ 2 - 2
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/mysql/account/WxAccountMapper.java

@@ -22,7 +22,7 @@ public interface WxAccountMapper extends BaseMapperX<WxAccountDO> {
         return selectPage(reqVO, new LambdaQueryWrapperX<WxAccountDO>()
                 .likeIfPresent(WxAccountDO::getName, reqVO.getName())
                 .eqIfPresent(WxAccountDO::getAccount, reqVO.getAccount())
-                .eqIfPresent(WxAccountDO::getAppId, reqVO.getAppid())
+                .eqIfPresent(WxAccountDO::getAppId, reqVO.getAppId())
                 .betweenIfPresent(WxAccountDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
                 .orderByDesc(WxAccountDO::getId));
     }
@@ -31,7 +31,7 @@ public interface WxAccountMapper extends BaseMapperX<WxAccountDO> {
         return selectList(new LambdaQueryWrapperX<WxAccountDO>()
                 .likeIfPresent(WxAccountDO::getName, reqVO.getName())
                 .eqIfPresent(WxAccountDO::getAccount, reqVO.getAccount())
-                .eqIfPresent(WxAccountDO::getAppId, reqVO.getAppid())
+                .eqIfPresent(WxAccountDO::getAppId, reqVO.getAppId())
                 .betweenIfPresent(WxAccountDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
                 .orderByDesc(WxAccountDO::getId));
     }

+ 0 - 38
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/dal/mysql/fanstag/WxFansTagMapper.java

@@ -1,38 +0,0 @@
-package cn.iocoder.yudao.module.mp.dal.mysql.fanstag;
-
-import java.util.*;
-
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
-import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
-import cn.iocoder.yudao.module.mp.dal.dataobject.fanstag.WxFansTagDO;
-import org.apache.ibatis.annotations.Mapper;
-import cn.iocoder.yudao.module.mp.controller.admin.fanstag.vo.*;
-
-/**
- * 粉丝标签 Mapper
- *
- * @author 芋道源码
- */
-@Mapper
-public interface WxFansTagMapper extends BaseMapperX<WxFansTagDO> {
-
-    default PageResult<WxFansTagDO> selectPage(WxFansTagPageReqVO reqVO) {
-        return selectPage(reqVO, new LambdaQueryWrapperX<WxFansTagDO>()
-                .likeIfPresent(WxFansTagDO::getName, reqVO.getName())
-                .eqIfPresent(WxFansTagDO::getCount, reqVO.getCount())
-                .eqIfPresent(WxFansTagDO::getWxAccountId, reqVO.getWxAccountId())
-                .betweenIfPresent(WxFansTagDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
-                .orderByDesc(WxFansTagDO::getId));
-    }
-
-    default List<WxFansTagDO> selectList(WxFansTagExportReqVO reqVO) {
-        return selectList(new LambdaQueryWrapperX<WxFansTagDO>()
-                .likeIfPresent(WxFansTagDO::getName, reqVO.getName())
-                .eqIfPresent(WxFansTagDO::getCount, reqVO.getCount())
-                .eqIfPresent(WxFansTagDO::getWxAccountId, reqVO.getWxAccountId())
-                .betweenIfPresent(WxFansTagDO::getCreateTime, reqVO.getBeginCreateTime(), reqVO.getEndCreateTime())
-                .orderByDesc(WxFansTagDO::getId));
-    }
-
-}

+ 6 - 0
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/framework/package-info.java

@@ -0,0 +1,6 @@
+/**
+ * @date 2022/6/20
+ * @author feng-dan
+ * @version 1.0
+ */
+package cn.iocoder.yudao.module.mp.framework;

+ 106 - 0
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/framework/weixin/WxMpMessageRouterConfiguration.java

@@ -0,0 +1,106 @@
+package cn.iocoder.yudao.module.mp.framework.weixin;
+
+
+import cn.iocoder.yudao.module.mp.handler.*;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.common.api.WxConsts;
+import me.chanjar.weixin.mp.api.WxMpMessageRouter;
+import me.chanjar.weixin.mp.api.WxMpService;
+import me.chanjar.weixin.mp.constant.WxMpEventConstants;
+import org.springframework.context.annotation.Bean;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.Resource;
+
+/**
+ * @author fengdan
+ */
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class WxMpMessageRouterConfiguration {
+
+    @Resource
+    private WxMpService wxMpService;
+    @Resource
+    private LogHandler logHandler;
+    @Resource
+    private KfSessionHandler kfSessionHandler;
+    @Resource
+    private StoreCheckNotifyHandler storeCheckNotifyHandler;
+    @Resource
+    private MenuHandler menuHandler;
+    @Resource
+    private NullHandler nullHandler;
+    @Resource
+    private SubscribeHandler subscribeHandler;
+    @Resource
+    private UnsubscribeHandler unsubscribeHandler;
+    @Resource
+    private LocationHandler locationHandler;
+    @Resource
+    private ScanHandler scanHandler;
+    @Resource
+    private MsgHandler msgHandler;
+
+    @Bean
+    public WxMpMessageRouter messageRouter() {
+        final WxMpMessageRouter newRouter = new WxMpMessageRouter(wxMpService);
+        // 记录所有事件的日志 (异步执行)
+        newRouter.rule().handler(logHandler).next();
+
+        // 接收客服会话管理事件
+        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
+                .event(WxMpEventConstants.CustomerService.KF_CREATE_SESSION)
+                .handler(kfSessionHandler).end();
+        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
+                .event(WxMpEventConstants.CustomerService.KF_CLOSE_SESSION)
+                .handler(kfSessionHandler)
+                .end();
+        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
+                .event(WxMpEventConstants.CustomerService.KF_SWITCH_SESSION)
+                .handler(kfSessionHandler).end();
+
+        // 门店审核事件
+        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
+                .event(WxMpEventConstants.POI_CHECK_NOTIFY)
+                .handler(storeCheckNotifyHandler).end();
+
+        // 自定义菜单事件
+        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
+                .event(WxConsts.MenuButtonType.CLICK).handler(menuHandler).end();
+
+        // 点击菜单连接事件
+        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
+                .event(WxConsts.MenuButtonType.VIEW).handler(nullHandler).end();
+
+        // 关注事件
+        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
+                .event(WxConsts.EventType.SUBSCRIBE).handler(subscribeHandler)
+                .end();
+
+        // 取消关注事件
+        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
+                .event(WxConsts.EventType.UNSUBSCRIBE)
+                .handler(unsubscribeHandler).end();
+
+        // 上报地理位置事件
+        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
+                .event(WxConsts.EventType.LOCATION).handler(locationHandler)
+                .end();
+
+        // 接收地理位置消息
+        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.LOCATION)
+                .handler(locationHandler).end();
+
+        // 扫码事件
+        newRouter.rule().async(false).msgType(WxConsts.XmlMsgType.EVENT)
+                .event(WxConsts.EventType.SCAN).handler(scanHandler).end();
+
+        // 默认
+        newRouter.rule().async(false).handler(msgHandler).end();
+
+        return newRouter;
+    }
+}

+ 2 - 16
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/handler/MsgHandler.java

@@ -6,13 +6,10 @@ import cn.hutool.http.HttpUtil;
 import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
 import cn.iocoder.yudao.module.infra.api.file.FileApi;
 import cn.iocoder.yudao.module.mp.builder.TextBuilder;
-import cn.iocoder.yudao.module.mp.config.WxMpProperties;
 import cn.iocoder.yudao.module.mp.controller.admin.fansmsg.vo.WxFansMsgCreateReqVO;
 import cn.iocoder.yudao.module.mp.dal.dataobject.account.WxAccountDO;
 import cn.iocoder.yudao.module.mp.service.account.WxAccountService;
 import cn.iocoder.yudao.module.mp.service.fansmsg.WxFansMsgService;
-import cn.iocoder.yudao.module.mp.service.receivetext.WxReceiveTextService;
-import cn.iocoder.yudao.module.mp.service.texttemplate.WxTextTemplateService;
 import lombok.extern.slf4j.Slf4j;
 import me.chanjar.weixin.common.api.WxConsts;
 import me.chanjar.weixin.common.error.WxErrorException;
@@ -34,13 +31,6 @@ import java.util.Map;
 @Component
 @Slf4j
 public class MsgHandler implements WxMpMessageHandler {
-
-    @Autowired
-    private WxReceiveTextService wxReceiveTextService;
-
-    @Autowired
-    private WxTextTemplateService wxTextTemplateService;
-
     @Autowired
     private WxAccountService wxAccountService;
 
@@ -50,9 +40,6 @@ public class MsgHandler implements WxMpMessageHandler {
     @Resource
     private FileApi fileApi;
 
-    @Autowired
-    private WxMpProperties wxMpProperties;
-
     @Override
     public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
                                     Map<String, Object> context, WxMpService weixinService,
@@ -112,7 +99,7 @@ public class MsgHandler implements WxMpMessageHandler {
                             if (!downloadDir.exists()) {
                                 downloadDir.mkdirs();
                             }
-                            String filepath = downloadDirStr + String.valueOf(System.currentTimeMillis()) + ".png";
+                            String filepath = downloadDirStr + System.currentTimeMillis() + ".png";
                             //微信pic url下载到本地,防止失效
                             long size = HttpUtil.downloadFile(wxMessage.getPicUrl(), FileUtil.file(filepath));
                             log.info("download pic size : {}", size);
@@ -147,8 +134,7 @@ public class MsgHandler implements WxMpMessageHandler {
         }
 
         //组装默认回复消息
-        String content = wxMpProperties.getDefaultContent();//默认
-        return new TextBuilder().build(content, wxMessage, weixinService);
+        return new TextBuilder().build("测试", wxMessage, weixinService);
     }
 
 

+ 5 - 5
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/mq/costomer/WxConfigDataRefreshConsumer.java

@@ -1,8 +1,8 @@
-package cn.iocoder.yudao.module.mp.mq.costomer.dict;
+package cn.iocoder.yudao.module.mp.mq.costomer;
 
 import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessageListener;
-import cn.iocoder.yudao.module.mp.config.WxMpConfig;
-import cn.iocoder.yudao.module.mp.mq.message.dict.WxConfigDataRefreshMessage;
+import cn.iocoder.yudao.module.mp.mq.message.WxConfigDataRefreshMessage;
+import cn.iocoder.yudao.module.mp.service.account.WxAccountService;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Component;
 
@@ -18,12 +18,12 @@ import javax.annotation.Resource;
 public class WxConfigDataRefreshConsumer extends AbstractChannelMessageListener<WxConfigDataRefreshMessage> {
 
     @Resource
-    private WxMpConfig wxMpConfig;
+    private WxAccountService wxAccountService;
 
     @Override
     public void onMessage(WxConfigDataRefreshMessage message) {
         log.info("[onMessage][收到 WxConfigData 刷新消息]");
-        wxMpConfig.initWxConfig();
+        wxAccountService.initLoadWxMpConfigStorages();
     }
 
 }

+ 1 - 1
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/mq/message/WxConfigDataRefreshMessage.java

@@ -1,4 +1,4 @@
-package cn.iocoder.yudao.module.mp.mq.message.dict;
+package cn.iocoder.yudao.module.mp.mq.message;
 
 import cn.iocoder.yudao.framework.mq.core.pubsub.AbstractChannelMessage;
 import lombok.Data;

+ 2 - 2
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/mq/producer/WxMpConfigDataProducer.java

@@ -1,7 +1,7 @@
-package cn.iocoder.yudao.module.mp.mq.producer.dict;
+package cn.iocoder.yudao.module.mp.mq.producer;
 
 import cn.iocoder.yudao.framework.mq.core.RedisMQTemplate;
-import cn.iocoder.yudao.module.mp.mq.message.dict.WxConfigDataRefreshMessage;
+import cn.iocoder.yudao.module.mp.mq.message.WxConfigDataRefreshMessage;
 import org.springframework.stereotype.Component;
 
 import javax.annotation.Resource;

+ 5 - 0
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/account/WxAccountService.java

@@ -81,4 +81,9 @@ public interface WxAccountService {
      * @return
      */
     WxAccountDO findBy(SFunction<WxAccountDO, ?> field, Object val);
+
+    /**
+     * 初始化
+     */
+    void initLoadWxMpConfigStorages();
 }

+ 65 - 3
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/account/WxAccountServiceImpl.java

@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.mp.service.account;
 
 import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
 import cn.iocoder.yudao.module.mp.controller.admin.account.vo.WxAccountCreateReqVO;
 import cn.iocoder.yudao.module.mp.controller.admin.account.vo.WxAccountExportReqVO;
 import cn.iocoder.yudao.module.mp.controller.admin.account.vo.WxAccountPageReqVO;
@@ -10,30 +11,52 @@ import cn.iocoder.yudao.module.mp.convert.account.WxAccountConvert;
 import cn.iocoder.yudao.module.mp.dal.dataobject.account.WxAccountDO;
 import cn.iocoder.yudao.module.mp.dal.mysql.account.WxAccountMapper;
 import cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants;
-import cn.iocoder.yudao.module.mp.mq.producer.dict.WxMpConfigDataProducer;
+import cn.iocoder.yudao.module.mp.mq.producer.WxMpConfigDataProducer;
 import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
+import com.binarywang.spring.starter.wxjava.mp.properties.WxMpProperties;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.common.redis.RedisTemplateWxRedisOps;
+import me.chanjar.weixin.mp.api.WxMpService;
+import me.chanjar.weixin.mp.config.WxMpConfigStorage;
+import org.springframework.context.annotation.Lazy;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.scheduling.annotation.Scheduled;
 import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
 import org.springframework.validation.annotation.Validated;
 
+import javax.annotation.PostConstruct;
 import javax.annotation.Resource;
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 
 /**
  * 公众号账户 Service 实现类
  *
- * @author 芋道源码
+ * @author fengdan
  */
+@Slf4j
 @Service
 @Validated
 public class WxAccountServiceImpl implements WxAccountService {
 
+    private static final long SCHEDULER_PERIOD = 5 * 60 * 1000L;
     @Resource
     private WxAccountMapper wxAccountMapper;
-
     @Resource
     private WxMpConfigDataProducer wxMpConfigDataProducer;
+    @Resource
+    private StringRedisTemplate stringRedisTemplate;
+    @Resource
+    private WxMpService wxMpService;
+    @Resource
+    private WxMpProperties wxMpProperties;
+    @Resource
+    @Lazy // 注入自己,所以延迟加载
+    private WxAccountService self;
 
     @Override
     public Long createWxAccount(WxAccountCreateReqVO createReqVO) {
@@ -94,4 +117,43 @@ public class WxAccountServiceImpl implements WxAccountService {
     public WxAccountDO findBy(SFunction<WxAccountDO, ?> field, Object val) {
         return wxAccountMapper.selectOne(field, val);
     }
+
+    @PostConstruct
+    @TenantIgnore
+    @Override
+    public void initLoadWxMpConfigStorages() {
+        List<WxAccountDO> wxAccountList = this.wxAccountMapper.selectList();
+        if (CollectionUtils.isEmpty(wxAccountList)) {
+            log.info("未读取到公众号配置,请在管理后台添加");
+            return;
+        }
+        log.info("加载到{}条公众号配置", wxAccountList.size());
+        wxAccountList.forEach(account -> addAccountToRuntime(account, new RedisTemplateWxRedisOps(stringRedisTemplate)));
+        log.info("公众号配置加载完成");
+    }
+
+    /**
+     * 添加账号到当前程序,如首次添加需初始化configStorageMap
+     *
+     * @param account 公众号
+     */
+    private synchronized void addAccountToRuntime(WxAccountDO account, RedisTemplateWxRedisOps redisOps) {
+        String appId = account.getAppId();
+        WxMpConfigStorage wxMpRedisConfig = account.toWxMpConfigStorage(redisOps, wxMpProperties);
+        try {
+            wxMpService.addConfigStorage(appId, wxMpRedisConfig);
+        } catch (NullPointerException e) {
+            log.info("需初始化configStorageMap...");
+            Map<String, WxMpConfigStorage> configStorages = new HashMap<>(4);
+            configStorages.put(appId, wxMpRedisConfig);
+            wxMpService.setMultiConfigStorages(configStorages, appId);
+        }
+    }
+
+    @Scheduled(fixedDelay = SCHEDULER_PERIOD, initialDelay = SCHEDULER_PERIOD)
+    public void schedulePeriodicRefresh() {
+        self.initLoadWxMpConfigStorages();
+    }
+
+
 }

+ 0 - 71
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/fanstag/WxFansTagService.java

@@ -1,71 +0,0 @@
-package cn.iocoder.yudao.module.mp.service.fanstag;
-
-import java.util.*;
-import javax.validation.*;
-
-import cn.iocoder.yudao.module.mp.controller.admin.fanstag.vo.*;
-import cn.iocoder.yudao.module.mp.dal.dataobject.fanstag.WxFansTagDO;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-
-/**
- * 粉丝标签 Service 接口
- *
- * @author 芋道源码
- */
-public interface WxFansTagService {
-
-    /**
-     * 创建粉丝标签
-     *
-     * @param createReqVO 创建信息
-     * @return 编号
-     */
-    Integer createWxFansTag(@Valid WxFansTagCreateReqVO createReqVO);
-
-    /**
-     * 更新粉丝标签
-     *
-     * @param updateReqVO 更新信息
-     */
-    void updateWxFansTag(@Valid WxFansTagUpdateReqVO updateReqVO);
-
-    /**
-     * 删除粉丝标签
-     *
-     * @param id 编号
-     */
-    void deleteWxFansTag(Integer id);
-
-    /**
-     * 获得粉丝标签
-     *
-     * @param id 编号
-     * @return 粉丝标签
-     */
-    WxFansTagDO getWxFansTag(Integer id);
-
-    /**
-     * 获得粉丝标签列表
-     *
-     * @param ids 编号
-     * @return 粉丝标签列表
-     */
-    List<WxFansTagDO> getWxFansTagList(Collection<Integer> ids);
-
-    /**
-     * 获得粉丝标签分页
-     *
-     * @param pageReqVO 分页查询
-     * @return 粉丝标签分页
-     */
-    PageResult<WxFansTagDO> getWxFansTagPage(WxFansTagPageReqVO pageReqVO);
-
-    /**
-     * 获得粉丝标签列表, 用于 Excel 导出
-     *
-     * @param exportReqVO 查询条件
-     * @return 粉丝标签列表
-     */
-    List<WxFansTagDO> getWxFansTagList(WxFansTagExportReqVO exportReqVO);
-
-}

+ 0 - 85
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/fanstag/WxFansTagServiceImpl.java

@@ -1,85 +0,0 @@
-package cn.iocoder.yudao.module.mp.service.fanstag;
-
-import org.springframework.stereotype.Service;
-
-import javax.annotation.Resource;
-
-import org.springframework.validation.annotation.Validated;
-
-import java.util.*;
-
-import cn.iocoder.yudao.module.mp.controller.admin.fanstag.vo.*;
-import cn.iocoder.yudao.module.mp.dal.dataobject.fanstag.WxFansTagDO;
-import cn.iocoder.yudao.framework.common.pojo.PageResult;
-
-import cn.iocoder.yudao.module.mp.convert.fanstag.WxFansTagConvert;
-import cn.iocoder.yudao.module.mp.dal.mysql.fanstag.WxFansTagMapper;
-
-import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
-import static cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants.*;
-
-/**
- * 粉丝标签 Service 实现类
- *
- * @author 芋道源码
- */
-@Service
-@Validated
-public class WxFansTagServiceImpl implements WxFansTagService {
-
-    @Resource
-    private WxFansTagMapper wxFansTagMapper;
-
-    @Override
-    public Integer createWxFansTag(WxFansTagCreateReqVO createReqVO) {
-        // 插入
-        WxFansTagDO wxFansTag = WxFansTagConvert.INSTANCE.convert(createReqVO);
-        wxFansTagMapper.insert(wxFansTag);
-        // 返回
-        return wxFansTag.getId();
-    }
-
-    @Override
-    public void updateWxFansTag(WxFansTagUpdateReqVO updateReqVO) {
-        // 校验存在
-        this.validateWxFansTagExists(updateReqVO.getId());
-        // 更新
-        WxFansTagDO updateObj = WxFansTagConvert.INSTANCE.convert(updateReqVO);
-        wxFansTagMapper.updateById(updateObj);
-    }
-
-    @Override
-    public void deleteWxFansTag(Integer id) {
-        // 校验存在
-        this.validateWxFansTagExists(id);
-        // 删除
-        wxFansTagMapper.deleteById(id);
-    }
-
-    private void validateWxFansTagExists(Integer id) {
-        if (wxFansTagMapper.selectById(id) == null) {
-            throw exception(COMMON_NOT_EXISTS);
-        }
-    }
-
-    @Override
-    public WxFansTagDO getWxFansTag(Integer id) {
-        return wxFansTagMapper.selectById(id);
-    }
-
-    @Override
-    public List<WxFansTagDO> getWxFansTagList(Collection<Integer> ids) {
-        return wxFansTagMapper.selectBatchIds(ids);
-    }
-
-    @Override
-    public PageResult<WxFansTagDO> getWxFansTagPage(WxFansTagPageReqVO pageReqVO) {
-        return wxFansTagMapper.selectPage(pageReqVO);
-    }
-
-    @Override
-    public List<WxFansTagDO> getWxFansTagList(WxFansTagExportReqVO exportReqVO) {
-        return wxFansTagMapper.selectList(exportReqVO);
-    }
-
-}

+ 74 - 0
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/tag/FansTagService.java

@@ -0,0 +1,74 @@
+package cn.iocoder.yudao.module.mp.service.tag;
+
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.mp.controller.admin.fanstag.vo.FansTagCreateReqVO;
+import cn.iocoder.yudao.module.mp.controller.admin.fanstag.vo.FansTagExportReqVO;
+import cn.iocoder.yudao.module.mp.controller.admin.fanstag.vo.FansTagPageReqVO;
+import cn.iocoder.yudao.module.mp.controller.admin.fanstag.vo.FansTagUpdateReqVO;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.mp.bean.tag.WxUserTag;
+
+import javax.validation.Valid;
+import java.util.List;
+
+/**
+ * 粉丝标签 Service 接口
+ *
+ * @author fengdan
+ */
+public interface FansTagService {
+
+    /**
+     * 创建粉丝标签
+     *
+     * @param createReqVO 创建标签信息
+     * @return {@link WxUserTag}  用户标签对象
+     * @throws WxErrorException 微信异常
+     */
+    WxUserTag createWxFansTag(FansTagCreateReqVO createReqVO) throws WxErrorException;
+
+    /**
+     * 更新粉丝标签
+     *
+     * @param updateReqVO 更新信息
+     * @return {@link         Boolean}
+     * @throws WxErrorException 微信异常
+     */
+    Boolean updateWxFansTag(@Valid FansTagUpdateReqVO updateReqVO) throws WxErrorException;
+
+    /**
+     * 删除粉丝标签
+     *
+     * @param id    编号
+     * @param appId 公众号appId
+     * @return {@link         Boolean}
+     * @throws WxErrorException 微信异常
+     */
+    Boolean deleteWxFansTag(Long id, String appId) throws WxErrorException;
+
+    /**
+     * 获取公众号已创建的标签
+     *
+     * @param appId 公众号appId
+     * @return 粉丝标签列表
+     * @throws WxErrorException 微信异常
+     */
+    List<WxUserTag> getWxFansTagList(String appId) throws WxErrorException;
+
+    /**
+     * 获得粉丝标签分页
+     *
+     * @param pageReqVO 分页查询
+     * @return 粉丝标签分页
+     */
+    PageResult<WxUserTag> getWxFansTagPage(FansTagPageReqVO pageReqVO);
+
+    /**
+     * 获得粉丝标签列表, 用于 Excel 导出
+     *
+     * @param exportReqVO 查询条件
+     * @return 粉丝标签列表
+     */
+    List<WxUserTag> getWxFansTagList(FansTagExportReqVO exportReqVO);
+
+}

+ 67 - 0
yudao-module-wechat/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/tag/FansTagServiceImpl.java

@@ -0,0 +1,67 @@
+package cn.iocoder.yudao.module.mp.service.tag;
+
+import cn.hutool.core.util.ReUtil;
+import cn.iocoder.yudao.framework.common.pojo.PageResult;
+import cn.iocoder.yudao.module.mp.controller.admin.fanstag.vo.FansTagCreateReqVO;
+import cn.iocoder.yudao.module.mp.controller.admin.fanstag.vo.FansTagExportReqVO;
+import cn.iocoder.yudao.module.mp.controller.admin.fanstag.vo.FansTagPageReqVO;
+import cn.iocoder.yudao.module.mp.controller.admin.fanstag.vo.FansTagUpdateReqVO;
+import lombok.extern.slf4j.Slf4j;
+import me.chanjar.weixin.common.error.WxErrorException;
+import me.chanjar.weixin.mp.api.WxMpService;
+import me.chanjar.weixin.mp.bean.tag.WxUserTag;
+import org.springframework.stereotype.Service;
+import org.springframework.validation.annotation.Validated;
+
+import javax.annotation.Resource;
+import java.util.List;
+
+/**
+ * 粉丝标签 Service 实现类
+ *
+ * @author fengdan
+ */
+@Slf4j
+@Service
+@Validated
+public class FansTagServiceImpl implements FansTagService {
+    @Resource
+    private WxMpService wxMpService;
+
+    @Override
+    public WxUserTag createWxFansTag(FansTagCreateReqVO createReqVO) throws WxErrorException {
+        // TODO 切换公众号操作 调整为 aop 或者 过滤器\拦截器 处理
+        wxMpService.switchover(createReqVO.getAppId());
+        return wxMpService.getUserTagService().tagCreate(createReqVO.getName());
+    }
+
+    @Override
+    public Boolean updateWxFansTag(FansTagUpdateReqVO updateReqVO) throws WxErrorException {
+        wxMpService.switchover(updateReqVO.getAppId());
+        return wxMpService.getUserTagService().tagUpdate(updateReqVO.getId(), updateReqVO.getName());
+    }
+
+    @Override
+    public Boolean deleteWxFansTag(Long id, String appId) throws WxErrorException {
+        wxMpService.switchover(appId);
+        return wxMpService.getUserTagService().tagDelete(id);
+    }
+
+
+    @Override
+    public List<WxUserTag> getWxFansTagList(String appId) throws WxErrorException {
+        wxMpService.switchover(appId);
+        return wxMpService.getUserTagService().tagGet();
+    }
+
+    @Override
+    public PageResult<WxUserTag> getWxFansTagPage(FansTagPageReqVO pageReqVO) {
+        return null;
+    }
+
+    @Override
+    public List<WxUserTag> getWxFansTagList(FansTagExportReqVO exportReqVO) {
+        return null;
+    }
+
+}

+ 1 - 1
yudao-server/src/main/resources/application-dev.yaml

@@ -204,7 +204,7 @@ justauth:
     timeout: 24h # 超时时长,目前只对 Redis 缓存生效,默认 3 分钟
 wx:
   mp:
-    useRedis: false # TODO @亚洲:要使用 redis 哈,和默认的 redis 使用同一个
+    useRedis: false
     defaultContent: \u60A8\u597D\uFF0C\u6709\u4EC0\u4E48\u95EE\u9898\uFF1F
     redisConfig:
       host: 127.0.0.1

+ 3 - 3
yudao-server/src/main/resources/application-local.yaml

@@ -177,13 +177,13 @@ logging:
 wx: # 参见 https://github.com/Wechat-Group/WxJava/blob/develop/spring-boot-starters/wx-java-mp-spring-boot-starter/README.md 文档
   mp:
     # 公众号配置(必填)
-    app-id: wx041349c6f39b268b
+    appId: wx041349c6f39b268b
     secret: 5abee519483bc9f8cb37ce280e814bd0
     # 存储配置,解决 AccessToken 的跨节点的共享
     config-storage:
-      type: RedisTemplate # 采用 RedisTemplate 操作 Redis,会自动从 Spring 中获取
+      type: RedisTemplate  # 配置类型: Memory(默认), Jedis, RedisTemplate
       key-prefix: wx # Redis Key 的前缀 TODO 芋艿:解决下 Redis key 管理的配置
-      http-client-type: HttpClient # 采用 HttpClient 请求微信公众号平台
+      http-client-type: HttpClient # http客户端类型: HttpClient(默认), OkHttp, JoddHttp
 
 --- #################### 芋道相关配置 ####################
 

+ 12 - 12
yudao-ui-admin/src/api/wechatMp/wxAccount.js

@@ -1,52 +1,52 @@
 import request from '@/utils/request'
 
 // 创建公众号账户
-export function createWxAccount(data) {
+export function createAccount(data) {
   return request({
-    url: '/wechatMp/wx-account/create',
+    url: '/wechatMp/account/create',
     method: 'post',
     data: data
   })
 }
 
 // 更新公众号账户
-export function updateWxAccount(data) {
+export function updateAccount(data) {
   return request({
-    url: '/wechatMp/wx-account/update',
+    url: '/wechatMp/account/update',
     method: 'put',
     data: data
   })
 }
 
 // 删除公众号账户
-export function deleteWxAccount(id) {
+export function deleteAccount(id) {
   return request({
-    url: '/wechatMp/wx-account/delete?id=' + id,
+    url: '/wechatMp/account/delete?id=' + id,
     method: 'delete'
   })
 }
 
 // 获得公众号账户
-export function getWxAccount(id) {
+export function getAccount(id) {
   return request({
-    url: '/wechatMp/wx-account/get?id=' + id,
+    url: '/wechatMp/account/get?id=' + id,
     method: 'get'
   })
 }
 
 // 获得公众号账户分页
-export function getWxAccountPage(query) {
+export function getAccountPage(query) {
   return request({
-    url: '/wechatMp/wx-account/page',
+    url: '/wechatMp/account/page',
     method: 'get',
     params: query
   })
 }
 
 // 导出公众号账户 Excel
-export function exportWxAccountExcel(query) {
+export function exportAccountExcel(query) {
   return request({
-    url: '/wechatMp/wx-account/export-excel',
+    url: '/wechatMp/account/export-excel',
     method: 'get',
     params: query,
     responseType: 'blob'

+ 7 - 7
yudao-ui-admin/src/api/wechatMp/wxFansTag.js

@@ -3,7 +3,7 @@ import request from '@/utils/request'
 // 创建粉丝标签
 export function createWxFansTag(data) {
   return request({
-    url: '/wechatMp/wx-fans-tag/create',
+    url: '/wechatMp/fans-tag/create',
     method: 'post',
     data: data
   })
@@ -12,7 +12,7 @@ export function createWxFansTag(data) {
 // 更新粉丝标签
 export function updateWxFansTag(data) {
   return request({
-    url: '/wechatMp/wx-fans-tag/update',
+    url: '/wechatMp/fans-tag/update',
     method: 'put',
     data: data
   })
@@ -21,7 +21,7 @@ export function updateWxFansTag(data) {
 // 删除粉丝标签
 export function deleteWxFansTag(id) {
   return request({
-    url: '/wechatMp/wx-fans-tag/delete?id=' + id,
+    url: '/wechatMp/fans-tag/delete?id=' + id,
     method: 'delete'
   })
 }
@@ -29,15 +29,15 @@ export function deleteWxFansTag(id) {
 // 获得粉丝标签
 export function getWxFansTag(id) {
   return request({
-    url: '/wechatMp/wx-fans-tag/get?id=' + id,
+    url: '/wechatMp/fans-tag/get?id=' + id,
     method: 'get'
   })
 }
 
 // 获得粉丝标签分页
-export function getWxFansTagPage(query) {
+export function getWxFansTagList(query) {
   return request({
-    url: '/wechatMp/wx-fans-tag/page',
+    url: '/wechatMp/fans-tag/list',
     method: 'get',
     params: query
   })
@@ -46,7 +46,7 @@ export function getWxFansTagPage(query) {
 // 导出粉丝标签 Excel
 export function exportWxFansTagExcel(query) {
   return request({
-    url: '/wechatMp/wx-fans-tag/export-excel',
+    url: '/wechatMp/fans-tag/export-excel',
     method: 'get',
     params: query,
     responseType: 'blob'

+ 134 - 103
yudao-ui-admin/src/views/wechatMp/wxAccount/index.vue

@@ -3,18 +3,13 @@
 
     <!-- 搜索工作栏 -->
     <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
-      <el-form-item label="公众号名称" prop="name">
-        <el-input v-model="queryParams.name" placeholder="请输入公众号名称" clearable @keyup.enter.native="handleQuery"/>
-      </el-form-item>
-      <el-form-item label="公众号账户" prop="account">
-        <el-input v-model="queryParams.account" placeholder="请输入公众号账户" clearable @keyup.enter.native="handleQuery"/>
-      </el-form-item>
-      <el-form-item label="公众号appId" prop="appId">
-        <el-input v-model="queryParams.appId" placeholder="请输入公众号appId" clearable @keyup.enter.native="handleQuery"/>
+      <el-form-item label="名称" prop="name">
+        <el-input v-model="queryParams.name" placeholder="请输入公众号名称" clearable
+                  @keyup.enter.native="handleQuery"/>
       </el-form-item>
       <el-form-item label="创建时间">
         <el-date-picker v-model="dateRangeCreateTime" style="width: 240px" value-format="yyyy-MM-dd"
-                        type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" />
+                        type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"/>
       </el-form-item>
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
@@ -26,27 +21,29 @@
     <el-row :gutter="10" class="mb8">
       <el-col :span="1.5">
         <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
-                   v-hasPermi="['wechatMp:wx-account:create']">新增</el-button>
+                   v-hasPermi="['wechatMp:account:create']">新增
+        </el-button>
       </el-col>
       <el-col :span="1.5">
-        <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport" :loading="exportLoading"
-                   v-hasPermi="['wechatMp:wx-account:export']">导出</el-button>
+        <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport"
+                   :loading="exportLoading"
+                   v-hasPermi="['wechatMp:account:export']">导出
+        </el-button>
       </el-col>
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
     </el-row>
 
     <!-- 列表 -->
     <el-table v-loading="loading" :data="list">
-      <el-table-column label="编号" align="center" prop="id" />
-      <el-table-column label="公众号名称" align="center" prop="name" />
-      <el-table-column label="公众号账户" align="center" prop="account" />
-      <el-table-column label="公众号appId" align="center" prop="appId"/>
-      <el-table-column label="公众号密钥" align="center" prop="appSecret"/>
-      <el-table-column label="公众号url" align="center" prop="url" />
-      <el-table-column label="公众号token" align="center" prop="token" />
+      <el-table-column label="编号" align="center" prop="id"/>
+      <el-table-column label="名称" align="center" prop="name"/>
+      <el-table-column label="微信原始ID" align="center" prop="account"/>
+      <el-table-column label="appId" align="center" prop="appId"/>
+      <el-table-column label="url" align="center" prop="url"/>
+      <el-table-column label="Token" align="center" prop="token"/>
       <el-table-column label="加密密钥" align="center" prop="aesKey"/>
-      <el-table-column label="二维码图片URL" align="center" prop="qrCodeUrl"/>
-      <el-table-column label="备注" align="center" prop="remark" />
+      <el-table-column label="二维码" align="center" prop="qrCodeUrl"/>
+      <el-table-column label="备注" align="center" prop="remark"/>
       <el-table-column label="创建时间" align="center" prop="createTime" width="180">
         <template slot-scope="scope">
           <span>{{ parseTime(scope.row.createTime) }}</span>
@@ -55,9 +52,11 @@
       <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
         <template slot-scope="scope">
           <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
-                     v-hasPermi="['wechatMp:wx-account:update']">修改</el-button>
+                     v-hasPermi="['wechatMp:account:update']">修改
+          </el-button>
           <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
-                     v-hasPermi="['wechatMp:wx-account:delete']">删除</el-button>
+                     v-hasPermi="['wechatMp:account:delete']">删除
+          </el-button>
         </template>
       </el-table-column>
     </el-table>
@@ -69,25 +68,41 @@
     <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
       <el-form ref="form" :model="form" :rules="rules" label-width="80px">
         <el-form-item label="公众号名称" prop="name">
-          <el-input v-model="form.name" placeholder="请输入公众号名称" />
-        </el-form-item>
-        <el-form-item label="公众号账户" prop="account">
-          <el-input v-model="form.account" placeholder="请输入公众号账户" />
-        </el-form-item>
-        <el-form-item label="公众号appId" prop="appId">
-          <el-input v-model="form.appId" placeholder="请输入公众号appId"/>
+          <el-input v-model="form.name" placeholder="请输入公众号名称"/>
         </el-form-item>
-        <el-form-item label="公众号密钥" prop="appSecret">
-          <el-input v-model="form.appSecret" placeholder="请输入公众号密钥"/>
-        </el-form-item>
-        <el-form-item label="公众号token" prop="token">
-          <el-input v-model="form.token" placeholder="请输入公众号token" />
+
+        <el-tooltip class="item" effect="dark"
+                    content="在微信公众平台(mp.weixin.qq.com)的菜单【设置】-【公众号设置】-【帐号详情】中能找到原始ID"
+                    placement="right">
+          <el-form-item label="微信原始ID" prop="account">
+            <el-input v-model="form.account" placeholder="请输入微信原始ID" :disabled='disabled'/>
+          </el-form-item>
+        </el-tooltip>
+
+        <el-tooltip class="item" effect="dark"
+                    content="在微信公众平台(mp.weixin.qq.com)的菜单【开发】-【基本配置】中能找到AppID "
+                    placement="right">
+          <el-form-item label="AppID" prop="appId">
+            <el-input v-model="form.appId" placeholder="请输入公众号appId" :disabled='disabled'/>
+          </el-form-item>
+        </el-tooltip>
+
+        <el-tooltip class="item" effect="dark"
+                    content="在微信公众平台(mp.weixin.qq.com)的菜单【开发】-【基本配置】中能找到AppSecret"
+                    placement="right">
+          <el-form-item label="AppSecret" prop="appSecret">
+            <el-input v-model="form.appSecret" placeholder="请输入公众号密钥" :disabled='disabled'/>
+          </el-form-item>
+        </el-tooltip>
+
+        <el-form-item label="token" prop="token">
+          <el-input v-model="form.token" placeholder="请输入公众号token"/>
         </el-form-item>
         <el-form-item label="加密密钥" prop="aesKey">
           <el-input v-model="form.aesKey" placeholder="请输入加密密钥"/>
         </el-form-item>
         <el-form-item label="备注" prop="remark">
-          <el-input v-model="form.remark" placeholder="请输入备注" />
+          <el-input v-model="form.remark" placeholder="请输入备注"/>
         </el-form-item>
       </el-form>
       <div slot="footer" class="dialog-footer">
@@ -99,12 +114,18 @@
 </template>
 
 <script>
-import { createWxAccount, updateWxAccount, deleteWxAccount, getWxAccount, getWxAccountPage, exportWxAccountExcel } from "@/api/wechatMp/wxAccount";
+import {
+  createAccount,
+  deleteAccount,
+  exportAccountExcel,
+  getAccount,
+  getAccountPage,
+  updateAccount
+} from '@/api/wechatMp/wxAccount'
 
 export default {
-  name: "WxAccount",
-  components: {
-  },
+  name: 'wxAccount',
+  components: {},
   data() {
     return {
       // 遮罩层
@@ -118,7 +139,7 @@ export default {
       // 公众号账户列表
       list: [],
       // 弹出层标题
-      title: "",
+      title: '',
       // 是否显示弹出层
       open: false,
       dateRangeCreateTime: [],
@@ -134,30 +155,37 @@ export default {
       form: {},
       // 表单校验
       rules: {
-      }
-    };
+        name: [{required: true, message: '公众号名称不能为空', trigger: 'blur'}],
+        account: [{required: true, message: '公众号账户不能为空', trigger: 'blur'}],
+        appId: [{required: true, message: '公众号appid不能为空', trigger: 'blur'}],
+        appSecret: [{required: true, message: '公众号密钥不能为空', trigger: 'blur'}],
+      },
+      // 禁用属性
+      disabled: false,
+    }
   },
   created() {
-    this.getList();
+    this.getList()
   },
   methods: {
     /** 查询列表 */
     getList() {
-      this.loading = true;
+      this.loading = true
       // 处理查询参数
-      let params = {...this.queryParams};
-      this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime');
+      let params = {...this.queryParams}
+      this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime')
       // 执行查询
-      getWxAccountPage(params).then(response => {
-        this.list = response.data.list;
-        this.total = response.data.total;
-        this.loading = false;
-      });
+      getAccountPage(params).then(response => {
+        this.list = response.data.list
+        this.total = response.data.total
+        this.loading = false
+      })
     },
     /** 取消按钮 */
     cancel() {
-      this.open = false;
-      this.reset();
+      this.open = false
+      this.disabled = false
+      this.reset()
     },
     /** 表单重置 */
     reset() {
@@ -170,85 +198,88 @@ export default {
         token: undefined,
         aesKey: undefined,
         remark: undefined,
-      };
-      this.resetForm("form");
+      }
+      this.resetForm('form')
     },
     /** 搜索按钮操作 */
     handleQuery() {
-      this.queryParams.pageNo = 1;
-      this.getList();
+      this.queryParams.pageNo = 1
+      this.getList()
     },
     /** 重置按钮操作 */
     resetQuery() {
-      this.dateRangeCreateTime = [];
-      this.resetForm("queryForm");
-      this.handleQuery();
+      this.dateRangeCreateTime = []
+      this.resetForm('queryForm')
+      this.handleQuery()
     },
     /** 新增按钮操作 */
     handleAdd() {
-      this.reset();
-      this.open = true;
-      this.title = "添加公众号账户";
+      this.reset()
+      this.open = true
+      this.title = '添加公众号账户'
     },
     /** 修改按钮操作 */
     handleUpdate(row) {
-      this.reset();
-      const id = row.id;
-      getWxAccount(id).then(response => {
-        this.form = response.data;
-        this.open = true;
-        this.title = "修改公众号账户";
-      });
+      this.reset()
+      const id = row.id
+      getAccount(id).then(response => {
+        this.form = response.data
+        this.open = true
+        this.title = '修改公众号账户'
+        this.disabled = true
+      })
     },
     /** 提交按钮 */
     submitForm() {
-      this.$refs["form"].validate(valid => {
+      this.$refs['form'].validate(valid => {
         if (!valid) {
-          return;
+          return
         }
         // 修改的提交
         if (this.form.id != null) {
-          updateWxAccount(this.form).then(response => {
-            this.$modal.msgSuccess("修改成功");
-            this.open = false;
-            this.getList();
-          });
-          return;
+          updateAccount(this.form).then(response => {
+            this.$modal.msgSuccess('修改成功')
+            this.open = false
+            this.getList()
+          })
+          return
         }
         // 添加的提交
-        createWxAccount(this.form).then(response => {
-          this.$modal.msgSuccess("新增成功");
-          this.open = false;
-          this.getList();
-        });
-      });
+        createAccount(this.form).then(response => {
+          this.$modal.msgSuccess('新增成功')
+          this.open = false
+          this.getList()
+        })
+      })
     },
     /** 删除按钮操作 */
     handleDelete(row) {
-      const id = row.id;
-      this.$modal.confirm('是否确认删除公众号账户编号为"' + id + '"的数据项?').then(function() {
-          return deleteWxAccount(id);
-        }).then(() => {
-          this.getList();
-          this.$modal.msgSuccess("删除成功");
-        }).catch(() => {});
+      const id = row.id
+      this.$modal.confirm('是否确认删除公众号账户编号为"' + id + '"的数据项?').then(function () {
+        return deleteAccount(id)
+      }).then(() => {
+        this.getList()
+        this.$modal.msgSuccess('删除成功')
+      }).catch(() => {
+      })
     },
     /** 导出按钮操作 */
     handleExport() {
       // 处理查询参数
-      let params = {...this.queryParams};
-      params.pageNo = undefined;
-      params.pageSize = undefined;
-      this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime');
+      let params = {...this.queryParams}
+      params.pageNo = undefined
+      params.pageSize = undefined
+      this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime')
       // 执行导出
       this.$modal.confirm('是否确认导出所有公众号账户数据项?').then(() => {
-          this.exportLoading = true;
-          return exportWxAccountExcel(params);
-        }).then(response => {
-          this.$download.excel(response, '公众号账户.xls');
-          this.exportLoading = false;
-        }).catch(() => {});
+        this.exportLoading = true
+        return exportAccountExcel(params)
+      }).then(response => {
+        this.$download.excel(response, '公众号账户.xls')
+        this.exportLoading = false
+      }).catch(() => {
+      })
     }
   }
-};
+}
 </script>

+ 208 - 188
yudao-ui-admin/src/views/wechatMp/wxFansTag/index.vue

@@ -6,17 +6,7 @@
       <el-form-item label="标签名称" prop="name">
         <el-input v-model="queryParams.name" placeholder="请输入标签名称" clearable @keyup.enter.native="handleQuery"/>
       </el-form-item>
-      <el-form-item label="粉丝数量" prop="count">
-        <el-input v-model="queryParams.count" placeholder="请输入粉丝数量" clearable @keyup.enter.native="handleQuery"/>
-      </el-form-item>
-      <el-form-item label="微信账号ID" prop="wxAccountId">
-        <el-input v-model="queryParams.wxAccountId" placeholder="请输入微信账号ID" clearable
-                  @keyup.enter.native="handleQuery"/>
-      </el-form-item>
-      <el-form-item label="创建时间">
-        <el-date-picker v-model="dateRangeCreateTime" style="width: 240px" value-format="yyyy-MM-dd"
-                        type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"/>
-      </el-form-item>
+
       <el-form-item>
         <el-button type="primary" icon="el-icon-search" @click="handleQuery">搜索</el-button>
         <el-button icon="el-icon-refresh" @click="resetQuery">重置</el-button>
@@ -27,43 +17,54 @@
     <el-row :gutter="10" class="mb8">
       <el-col :span="1.5">
         <el-button type="primary" plain icon="el-icon-plus" size="mini" @click="handleAdd"
-                   v-hasPermi="['wechatMp:wx-fans-tag:create']">新增
+                   v-hasPermi="['wechatMp:fans-tag:create']">新增
         </el-button>
       </el-col>
       <el-col :span="1.5">
         <el-button type="warning" plain icon="el-icon-download" size="mini" @click="handleExport"
                    :loading="exportLoading"
-                   v-hasPermi="['wechatMp:wx-fans-tag:export']">导出
+                   v-hasPermi="['wechatMp:fans-tag:export']">导出
         </el-button>
       </el-col>
       <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
     </el-row>
+    <div style="display: flex;width: auto">
+      <div class="left_column" style="border: 1px solid #EBEEF5FF; width: 15%;height: auto">
+        <div style="padding: 10px 20px; border-bottom: 1px solid #ebeef5; box-sizing: border-box;"><span
+          style="font-size: 16px">公众号名称</span></div>
+
+        <div style="margin-top: 10px;margin-right: 5px;margin-left: 5px">
+          <input type="text" placeholder="输入关键字进行过滤"
+                 class="el-input__inner"/>
+        </div>
+
+        <div style="margin-top: 10px;margin-right: 5px;margin-left: 5px">
+          <div style="margin-right: 5px;margin-left: 5px" v-for="(account,index) in accountList" @click="getAccountTag(account.appId)">{{ account.name }}</div>
+        </div>
+      </div>
+      <div class="right_column" style="width: 85%">
+        <!-- 列表 -->
+        <el-table v-loading="loading" :data="list">
+          <el-table-column label="编号" align="center" prop="id"/>
+          <el-table-column label="标签名称" align="center" prop="name"/>
+          <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+            <template slot-scope="scope">
+              <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
+                         v-hasPermi="['wechatMp:fans-tag:update']">修改
+              </el-button>
+              <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
+                         v-hasPermi="['wechatMp:fans-tag:delete']">删除
+              </el-button>
+            </template>
+          </el-table-column>
+        </el-table>
+        <!-- 分页组件 -->
+        <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
+                    @pagination="getList"/>
+
+      </div>
+    </div>
 
-    <!-- 列表 -->
-    <el-table v-loading="loading" :data="list">
-      <el-table-column label="主键" align="center" prop="id"/>
-      <el-table-column label="标签名称" align="center" prop="name"/>
-      <el-table-column label="粉丝数量" align="center" prop="count"/>
-      <el-table-column label="微信账号ID" align="center" prop="wxAccountId"/>
-      <el-table-column label="创建时间" align="center" prop="createTime" width="180">
-        <template slot-scope="scope">
-          <span>{{ parseTime(scope.row.createTime) }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
-        <template slot-scope="scope">
-          <el-button size="mini" type="text" icon="el-icon-edit" @click="handleUpdate(scope.row)"
-                     v-hasPermi="['wechatMp:wx-fans-tag:update']">修改
-          </el-button>
-          <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
-                     v-hasPermi="['wechatMp:wx-fans-tag:delete']">删除
-          </el-button>
-        </template>
-      </el-table-column>
-    </el-table>
-    <!-- 分页组件 -->
-    <pagination v-show="total > 0" :total="total" :page.sync="queryParams.pageNo" :limit.sync="queryParams.pageSize"
-                @pagination="getList"/>
 
     <!-- 对话框(添加 / 修改) -->
     <el-dialog :title="title" :visible.sync="open" width="500px" append-to-body>
@@ -86,160 +87,179 @@
   </div>
 </template>
 
+<style>
+.left_column {
+  height: 100%;
+  position: relative;
+  overflow: auto;
+}
+</style>
+
 <script>
-  import {
-    createWxFansTag,
-    updateWxFansTag,
-    deleteWxFansTag,
-    getWxFansTag,
-    getWxFansTagPage,
-    exportWxFansTagExcel
-  } from "@/api/wechatMp/wxFansTag";
+import {
+  createWxFansTag,
+  deleteWxFansTag,
+  exportWxFansTagExcel,
+  getWxFansTag,
+  getWxFansTagList,
+  updateWxFansTag
+} from '@/api/wechatMp/wxFansTag'
+import {getAccountPage} from '@/api/wechatMp/wxAccount'
 
-  export default {
-    name: "WxFansTag",
-    components: {},
-    data() {
-      return {
-        // 遮罩层
-        loading: true,
-        // 导出遮罩层
-        exportLoading: false,
-        // 显示搜索条件
-        showSearch: true,
-        // 总条数
-        total: 0,
-        // 粉丝标签列表
-        list: [],
-        // 弹出层标题
-        title: "",
-        // 是否显示弹出层
-        open: false,
-        dateRangeCreateTime: [],
-        // 查询参数
-        queryParams: {
-          pageNo: 1,
-          pageSize: 10,
-          name: null,
-          count: null,
-          wxAccountId: null,
-        },
-        // 表单参数
-        form: {},
-        // 表单校验
-        rules: {}
-      };
+export default {
+  name: 'WxFansTag',
+  components: {},
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 导出遮罩层
+      exportLoading: false,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 粉丝标签列表
+      list: [],
+      // 账号列表
+      accountList: [],
+      // 弹出层标题
+      title: '',
+      // 是否显示弹出层
+      open: false,
+      dateRangeCreateTime: [],
+      // 查询参数
+      queryParams: {
+        appId: null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {}
+    }
+  },
+  created() {
+    this.getAccountList()
+  },
+  methods: {
+    /** 查询列表 */
+    getList(appId) {
+      this.loading = false
+      this.queryParams.appId = appId
+      // 处理查询参数
+      let params = {...this.queryParams}
+      // 执行查询
+      getWxFansTagList(params).then(response => {
+        this.list = response.data
+        this.loading = false
+      })
     },
-    created() {
-      this.getList();
+    /** 查询列表 */
+    getAccountList() {
+      // 执行查询
+      getAccountPage().then(response => {
+        this.accountList = response.data.list
+      })
     },
-    methods: {
-      /** 查询列表 */
-      getList() {
-        this.loading = true;
-        // 处理查询参数
-        let params = {...this.queryParams};
-        this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime');
-        // 执行查询
-        getWxFansTagPage(params).then(response => {
-          this.list = response.data.list;
-          this.total = response.data.total;
-          this.loading = false;
-        });
-      },
-      /** 取消按钮 */
-      cancel() {
-        this.open = false;
-        this.reset();
-      },
-      /** 表单重置 */
-      reset() {
-        this.form = {
-          id: undefined,
-          name: undefined,
-          count: undefined,
-          wxAccountId: undefined,
-        };
-        this.resetForm("form");
-      },
-      /** 搜索按钮操作 */
-      handleQuery() {
-        this.queryParams.pageNo = 1;
-        this.getList();
-      },
-      /** 重置按钮操作 */
-      resetQuery() {
-        this.dateRangeCreateTime = [];
-        this.resetForm("queryForm");
-        this.handleQuery();
-      },
-      /** 新增按钮操作 */
-      handleAdd() {
-        this.reset();
-        this.open = true;
-        this.title = "添加粉丝标签";
-      },
-      /** 修改按钮操作 */
-      handleUpdate(row) {
-        this.reset();
-        const id = row.id;
-        getWxFansTag(id).then(response => {
-          this.form = response.data;
-          this.open = true;
-          this.title = "修改粉丝标签";
-        });
-      },
-      /** 提交按钮 */
-      submitForm() {
-        this.$refs["form"].validate(valid => {
-          if (!valid) {
-            return;
-          }
-          // 修改的提交
-          if (this.form.id != null) {
-            updateWxFansTag(this.form).then(response => {
-              this.$modal.msgSuccess("修改成功");
-              this.open = false;
-              this.getList();
-            });
-            return;
-          }
-          // 添加的提交
-          createWxFansTag(this.form).then(response => {
-            this.$modal.msgSuccess("新增成功");
-            this.open = false;
-            this.getList();
-          });
-        });
-      },
-      /** 删除按钮操作 */
-      handleDelete(row) {
-        const id = row.id;
-        this.$modal.confirm('是否确认删除粉丝标签编号为"' + id + '"的数据项?').then(function () {
-          return deleteWxFansTag(id);
-        }).then(() => {
-          this.getList();
-          this.$modal.msgSuccess("删除成功");
-        }).catch(() => {
-        });
-      },
-      /** 导出按钮操作 */
-      handleExport() {
-        // 处理查询参数
-        let params = {...this.queryParams};
-        params.pageNo = undefined;
-        params.pageSize = undefined;
-        this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime');
-        // 执行导出
-        this.$modal.confirm('是否确认导出所有粉丝标签数据项?').then(() => {
-          this.exportLoading = true;
-          return exportWxFansTagExcel(params);
-        }).then(response => {
-          this.$download.excel(response, '粉丝标签.xls');
-          this.exportLoading = false;
-        }).catch(() => {
-        });
+
+    /**
+     * 获取帐户标签
+     * @param appId 公众号appId
+     */
+    getAccountTag(appId) {
+      this.getList(appId)
+    },
+
+    /** 取消按钮 */
+    cancel() {
+      this.open = false
+      this.reset()
+    },
+    /** 表单重置 */
+    reset() {
+      this.form = {
+        appId: undefined,
       }
+      this.resetForm('form')
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNo = 1
+      this.getList()
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.dateRangeCreateTime = []
+      this.resetForm('queryForm')
+      this.handleQuery()
+    },
+    /** 新增按钮操作 */
+    handleAdd() {
+      this.reset()
+      this.open = true
+      this.title = '添加粉丝标签'
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset()
+      const id = row.id
+      getWxFansTag(id).then(response => {
+        this.form = response.data
+        this.open = true
+        this.title = '修改粉丝标签'
+      })
+    },
+    /** 提交按钮 */
+    submitForm() {
+      this.$refs['form'].validate(valid => {
+        if (!valid) {
+          return
+        }
+        // 修改的提交
+        if (this.form.id != null) {
+          updateWxFansTag(this.form).then(response => {
+            this.$modal.msgSuccess('修改成功')
+            this.open = false
+            this.getList()
+          })
+          return
+        }
+        // 添加的提交
+        createWxFansTag(this.form).then(response => {
+          this.$modal.msgSuccess('新增成功')
+          this.open = false
+          this.getList()
+        })
+      })
+    },
+    /** 删除按钮操作 */
+    handleDelete(row) {
+      const id = row.id
+      this.$modal.confirm('是否确认删除粉丝标签编号为"' + id + '"的数据项?').then(function () {
+        return deleteWxFansTag(id)
+      }).then(() => {
+        this.getList()
+        this.$modal.msgSuccess('删除成功')
+      }).catch(() => {
+      })
+    },
+    /** 导出按钮操作 */
+    handleExport() {
+      // 处理查询参数
+      let params = {...this.queryParams}
+      params.pageNo = undefined
+      params.pageSize = undefined
+      this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime')
+      // 执行导出
+      this.$modal.confirm('是否确认导出所有粉丝标签数据项?').then(() => {
+        this.exportLoading = true
+        return exportWxFansTagExcel(params)
+      }).then(response => {
+        this.$download.excel(response, '粉丝标签.xls')
+        this.exportLoading = false
+      }).catch(() => {
+      })
     }
-  };
+  }
+}
 </script>

File diff suppressed because it is too large
+ 9462 - 9194
yudao-ui-admin/yarn.lock