Procházet zdrojové kódy

mp:实现 user 的 ui 界面

YunaiV před 2 roky
rodič
revize
2ac2af64d4
21 změnil soubory, kde provedl 505 přidání a 476 odebrání
  1. 2 2
      yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/DefaultDatabaseQueryTest.java
  2. 4 0
      yudao-module-mp/yudao-module-mp-api/src/main/java/cn/iocoder/yudao/module/mp/enums/ErrorCodeConstants.java
  3. 10 4
      yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/MpTagController.java
  4. 20 0
      yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagSimpleRespVO.java
  5. 13 0
      yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/MpUserController.http
  6. 21 3
      yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/MpUserController.java
  7. 0 58
      yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/vo/MpUserBaseVO.java
  8. 14 8
      yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/vo/MpUserPageReqVO.java
  9. 43 8
      yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/vo/MpUserRespVO.java
  10. 27 0
      yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/vo/MpUserUpdateReqVO.java
  11. 3 0
      yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/convert/tag/MpTagConvert.java
  12. 3 0
      yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/convert/user/MpUserConvert.java
  13. 3 0
      yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/tag/MpTagService.java
  14. 6 1
      yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/tag/MpTagServiceImpl.java
  15. 8 0
      yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/user/MpUserService.java
  16. 50 4
      yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/user/MpUserServiceImpl.java
  17. 8 0
      yudao-ui-admin/src/api/mp/tag.js
  18. 35 0
      yudao-ui-admin/src/api/mp/user.js
  19. 0 54
      yudao-ui-admin/src/api/wechatMp/wxAccountFans.js
  20. 235 0
      yudao-ui-admin/src/views/mp/user/index.vue
  21. 0 334
      yudao-ui-admin/src/views/wechatMp/wxAccountFans/index.vue

+ 2 - 2
yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/service/DefaultDatabaseQueryTest.java

@@ -1,10 +1,10 @@
 package cn.iocoder.yudao.module.infra.service;
 
 import cn.hutool.core.util.StrUtil;
-import com.baomidou.mybatisplus.generator.IDatabaseQuery.DefaultDatabaseQuery;
 import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
 import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
 import com.baomidou.mybatisplus.generator.config.po.TableInfo;
+import com.baomidou.mybatisplus.generator.query.DefaultQuery;
 
 import java.util.List;
 
@@ -19,7 +19,7 @@ public class DefaultDatabaseQueryTest {
 
         ConfigBuilder builder = new ConfigBuilder(null, dataSourceConfig, null, null, null, null);
 
-        DefaultDatabaseQuery query = new DefaultDatabaseQuery(builder);
+        DefaultQuery query = new DefaultQuery(builder);
 
         long time = System.currentTimeMillis();
         List<TableInfo> tableInfos = query.queryTables();

+ 4 - 0
yudao-module-mp/yudao-module-mp-api/src/main/java/cn/iocoder/yudao/module/mp/enums/ErrorCodeConstants.java

@@ -27,6 +27,10 @@ public interface ErrorCodeConstants {
     ErrorCode TAG_DELETE_FAIL = new ErrorCode(1006002001, "删除标签失败,原因:{}");
     ErrorCode TAG_GET_FAIL = new ErrorCode(1006002001, "获得标签失败,原因:{}");
 
+    // ========== 公众号标签 1006003000============
+    ErrorCode USER_NOT_EXISTS = new ErrorCode(1006003000, "用户不存在");
+    ErrorCode USER_UPDATE_TAG_FAIL = new ErrorCode(1006003001, "更新用户标签失败,原因:{}");
+
     // TODO 要处理下
     ErrorCode COMMON_NOT_EXISTS = new ErrorCode(1006001002, "用户不存在");
 

+ 10 - 4
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/MpTagController.java

@@ -2,10 +2,7 @@ package cn.iocoder.yudao.module.mp.controller.admin.tag;
 
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.mp.controller.admin.tag.vo.MpTagCreateReqVO;
-import cn.iocoder.yudao.module.mp.controller.admin.tag.vo.MpTagPageReqVO;
-import cn.iocoder.yudao.module.mp.controller.admin.tag.vo.MpTagRespVO;
-import cn.iocoder.yudao.module.mp.controller.admin.tag.vo.MpTagUpdateReqVO;
+import cn.iocoder.yudao.module.mp.controller.admin.tag.vo.*;
 import cn.iocoder.yudao.module.mp.convert.tag.MpTagConvert;
 import cn.iocoder.yudao.module.mp.dal.dataobject.tag.MpTagDO;
 import cn.iocoder.yudao.module.mp.service.tag.MpTagService;
@@ -18,6 +15,7 @@ import org.springframework.web.bind.annotation.*;
 
 import javax.annotation.Resource;
 import javax.validation.Valid;
+import java.util.List;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 
@@ -62,6 +60,14 @@ public class MpTagController {
         return success(MpTagConvert.INSTANCE.convertPage(pageResult));
     }
 
+    @GetMapping("/list-all-simple")
+    @ApiOperation(value = "获取公众号账号精简信息列表")
+    @PreAuthorize("@ss.hasPermission('mp:account:query')")
+    public CommonResult<List<MpTagSimpleRespVO>> getSimpleTags() {
+        List<MpTagDO> list = mpTagService.getTagList();
+        return success(MpTagConvert.INSTANCE.convertList02(list));
+    }
+
     @PostMapping("/sync")
     @ApiOperation("同步公众号标签")
     @ApiImplicitParam(name = "accountId", value = "公众号账号的编号", required = true, dataTypeClass = Long.class)

+ 20 - 0
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/tag/vo/MpTagSimpleRespVO.java

@@ -0,0 +1,20 @@
+package cn.iocoder.yudao.module.mp.controller.admin.tag.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+@ApiModel("管理后台 - 公众号标签精简信息 Response VO")
+@Data
+public class MpTagSimpleRespVO {
+
+    @ApiModelProperty(value = "编号", required = true, example = "1024")
+    private Long id;
+
+    @ApiModelProperty(value = "公众号的标签编号", required = true, example = "2048")
+    private Long tagId;
+
+    @ApiModelProperty(value = "标签名称", required = true, example = "快乐")
+    private String name;
+
+}

+ 13 - 0
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/MpUserController.http

@@ -3,3 +3,16 @@ POST {{baseUrl}}/mp/user/sync?accountId=1
 Content-Type: application/json
 Authorization: Bearer {{token}}
 tenant-id: {{adminTenentId}}
+
+### 请求 /mp/user/update 接口 => 成功
+PUT {{baseUrl}}/mp/user/update
+Content-Type: application/json
+Authorization: Bearer {{token}}
+tenant-id: {{adminTenentId}}
+
+{
+  "id": "3",
+  "nickname": "test",
+  "remark": "测试备注",
+  "tagIds": [103, 104]
+}

+ 21 - 3
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/MpUserController.java

@@ -2,7 +2,9 @@ package cn.iocoder.yudao.module.mp.controller.admin.user;
 
 import cn.iocoder.yudao.framework.common.pojo.CommonResult;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
-import cn.iocoder.yudao.module.mp.controller.admin.user.vo.*;
+import cn.iocoder.yudao.module.mp.controller.admin.user.vo.MpUserPageReqVO;
+import cn.iocoder.yudao.module.mp.controller.admin.user.vo.MpUserRespVO;
+import cn.iocoder.yudao.module.mp.controller.admin.user.vo.MpUserUpdateReqVO;
 import cn.iocoder.yudao.module.mp.convert.user.MpUserConvert;
 import cn.iocoder.yudao.module.mp.dal.dataobject.user.MpUserDO;
 import cn.iocoder.yudao.module.mp.service.user.MpUserService;
@@ -18,7 +20,7 @@ import javax.validation.Valid;
 
 import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
 
-@Api(tags = "管理后台 - 微信公众号粉丝")
+@Api(tags = "管理后台 - 公众号粉丝")
 @RestController
 @RequestMapping("/mp/user")
 @Validated
@@ -28,13 +30,29 @@ public class MpUserController {
     private MpUserService mpUserService;
 
     @GetMapping("/page")
-    @ApiOperation("获得微信公众号粉丝分页")
+    @ApiOperation("获得公众号粉丝分页")
     @PreAuthorize("@ss.hasPermission('mp:user:query')")
     public CommonResult<PageResult<MpUserRespVO>> getUserPage(@Valid MpUserPageReqVO pageVO) {
         PageResult<MpUserDO> pageResult = mpUserService.getUserPage(pageVO);
         return success(MpUserConvert.INSTANCE.convertPage(pageResult));
     }
 
+    @GetMapping("/get")
+    @ApiOperation("获得公众号粉丝")
+    @ApiImplicitParam(name = "id", value = "编号", required = true, example = "1024", dataTypeClass = Long.class)
+    @PreAuthorize("@ss.hasPermission('mp:user:query')")
+    public CommonResult<MpUserRespVO> getUser(@RequestParam("id") Long id) {
+        return success(MpUserConvert.INSTANCE.convert(mpUserService.getUser(id)));
+    }
+
+    @PutMapping("/update")
+    @ApiOperation("更新公众号粉丝")
+    @PreAuthorize("@ss.hasPermission('mp:user:update')")
+    public CommonResult<Boolean> updateUser(@Valid @RequestBody MpUserUpdateReqVO updateReqVO) {
+        mpUserService.updateUser(updateReqVO);
+        return success(true);
+    }
+
     @PostMapping("/sync")
     @ApiOperation("同步公众号粉丝")
     @ApiImplicitParam(name = "accountId", value = "公众号账号的编号", required = true, dataTypeClass = Long.class)

+ 0 - 58
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/vo/MpUserBaseVO.java

@@ -1,58 +0,0 @@
-package cn.iocoder.yudao.module.mp.controller.admin.user.vo;
-
-import lombok.*;
-import java.util.*;
-import io.swagger.annotations.*;
-import org.springframework.format.annotation.DateTimeFormat;
-
-import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
-
-/**
-* 微信公众号粉丝 Base VO,提供给添加、修改、详细的子 VO 使用
-* 如果子 VO 存在差异的字段,请不要添加到这里,影响 Swagger 文档生成
-*/
-@Data
-public class MpUserBaseVO {
-
-    @ApiModelProperty(value = "用户标识")
-    private String openid;
-
-    @ApiModelProperty(value = "订阅状态,0未关注,1已关注")
-    private Integer subscribeStatus;
-
-    @ApiModelProperty(value = "订阅时间")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    private Date subscribeTime;
-
-    @ApiModelProperty(value = "订阅时间")
-    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
-    private Date unsubscribeTime;
-
-    @ApiModelProperty(value = "昵称")
-    private String nickname;
-
-    @ApiModelProperty(value = "语言")
-    private String language;
-
-    @ApiModelProperty(value = "国家")
-    private String country;
-
-    @ApiModelProperty(value = "省份")
-    private String province;
-
-    @ApiModelProperty(value = "城市")
-    private String city;
-
-    @ApiModelProperty(value = "头像地址")
-    private String headImageUrl;
-
-    @ApiModelProperty(value = "备注")
-    private String remark;
-
-    @ApiModelProperty(value = "微信公众号ID")
-    private Long accountId;
-
-    @ApiModelProperty(value = "微信公众号appid")
-    private String appId;
-
-}

+ 14 - 8
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/vo/MpUserPageReqVO.java

@@ -1,22 +1,28 @@
 package cn.iocoder.yudao.module.mp.controller.admin.user.vo;
 
-import lombok.*;
-import io.swagger.annotations.*;
 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;
 
-@ApiModel("管理后台 - 微信公众号粉丝分页 Request VO")
+import javax.validation.constraints.NotNull;
+
+@ApiModel("管理后台 - 公众号粉丝分页 Request VO")
 @Data
 @EqualsAndHashCode(callSuper = true)
 @ToString(callSuper = true)
 public class MpUserPageReqVO extends PageParam {
 
-    @ApiModelProperty(value = "用户标识")
+    @ApiModelProperty(value = "公众号账号的编号", required = true, example = "2048")
+    @NotNull(message = "公众号账号的编号不能为空")
+    private Long accountId;
+
+    @ApiModelProperty(value = "公众号用户标识", example = "o6_bmjrPTlm6_2sgVt7hMZOPfL2M", notes = "模糊匹配")
     private String openid;
 
-    @ApiModelProperty(value = "昵称")
+    @ApiModelProperty(value = "公众号用户昵称", example = "芋艿", notes = "模糊匹配")
     private String nickname;
 
-    @ApiModelProperty(value = "微信公众号 ID")
-    private Long accountId;
-
 }

+ 43 - 8
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/vo/MpUserRespVO.java

@@ -1,18 +1,53 @@
 package cn.iocoder.yudao.module.mp.controller.admin.user.vo;
 
-import lombok.*;
-import java.util.*;
-import io.swagger.annotations.*;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
 
-@ApiModel("管理后台 - 微信公众号粉丝 Response VO")
+import java.time.LocalDateTime;
+import java.util.Date;
+import java.util.List;
+
+@ApiModel("管理后台 - 公众号粉丝 Response VO")
 @Data
-@EqualsAndHashCode(callSuper = true)
-@ToString(callSuper = true)
-public class MpUserRespVO extends MpUserBaseVO {
+public class MpUserRespVO  {
 
-    @ApiModelProperty(value = "编号", required = true)
+    @ApiModelProperty(value = "编号", required = true, example = "1024")
     private Long id;
 
+    @ApiModelProperty(value = "公众号用户标识", required = true, example = "o6_bmjrPTlm6_2sgVt7hMZOPfL2M")
+    private String openid;
+
+    @ApiModelProperty(value = "关注状态", required = true, example = "1", notes = "参见 CommonStatusEnum 枚举")
+    private Integer subscribeStatus;
+    @ApiModelProperty(value = "关注时间", required = true)
+    private LocalDateTime subscribeTime;
+    @ApiModelProperty(value = "取消关注时间")
+    private LocalDateTime unsubscribeTime;
+
+    @ApiModelProperty(value = "昵称", example = "芋道")
+    private String nickname;
+    @ApiModelProperty(value = "头像地址", example = "https://www.iocoder.cn/1.png")
+    private String headImageUrl;
+    @ApiModelProperty(value = "语言", example = "zh_CN")
+    private String language;
+    @ApiModelProperty(value = "国家", example = "中国")
+    private String country;
+    @ApiModelProperty(value = "省份", example = "广东省")
+    private String province;
+    @ApiModelProperty(value = "城市", example = "广州市")
+    private String city;
+    @ApiModelProperty(value = "备注", example = "你是一个芋头嘛")
+    private String remark;
+
+    @ApiModelProperty(value = "标签编号数组", example = "1,2,3")
+    private List<Long> tagIds;
+
+    @ApiModelProperty(value = "公众号账号的编号", required = true, example = "1")
+    private Long accountId;
+    @ApiModelProperty(value = "公众号账号的 appId", required = true, example = "wx1234567890")
+    private String appId;
+
     @ApiModelProperty(value = "创建时间", required = true)
     private Date createTime;
 

+ 27 - 0
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/controller/admin/user/vo/MpUserUpdateReqVO.java

@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.module.mp.controller.admin.user.vo;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+@ApiModel("管理后台 - 公众号粉丝更新 Request VO")
+@Data
+public class MpUserUpdateReqVO {
+
+    @ApiModelProperty(value = "编号", required = true, example = "1024")
+    @NotNull(message = "编号不能为空")
+    private Long id;
+
+    @ApiModelProperty(value = "昵称", example = "芋道")
+    private String nickname;
+
+    @ApiModelProperty(value = "备注", example = "你是一个芋头嘛")
+    private String remark;
+
+    @ApiModelProperty(value = "标签编号数组", example = "1,2,3")
+    private List<Long> tagIds;
+
+}

+ 3 - 0
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/convert/tag/MpTagConvert.java

@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.mp.convert.tag;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.mp.controller.admin.tag.vo.MpTagRespVO;
+import cn.iocoder.yudao.module.mp.controller.admin.tag.vo.MpTagSimpleRespVO;
 import cn.iocoder.yudao.module.mp.controller.admin.tag.vo.MpTagUpdateReqVO;
 import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
 import cn.iocoder.yudao.module.mp.dal.dataobject.tag.MpTagDO;
@@ -36,4 +37,6 @@ public interface MpTagConvert {
     })
     MpTagDO convert(WxUserTag tag, MpAccountDO account);
 
+    List<MpTagSimpleRespVO> convertList02(List<MpTagDO> list);
+
 }

+ 3 - 0
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/convert/user/MpUserConvert.java

@@ -5,6 +5,7 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.module.mp.controller.admin.user.vo.MpUserRespVO;
+import cn.iocoder.yudao.module.mp.controller.admin.user.vo.MpUserUpdateReqVO;
 import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
 import cn.iocoder.yudao.module.mp.dal.dataobject.user.MpUserDO;
 import me.chanjar.weixin.mp.bean.result.WxMpUser;
@@ -49,4 +50,6 @@ public interface MpUserConvert {
         return CollectionUtils.convertList(wxUsers, wxUser -> convert(account, wxUser));
     }
 
+    MpUserDO convert(MpUserUpdateReqVO bean);
+
 }

+ 3 - 0
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/tag/MpTagService.java

@@ -7,6 +7,7 @@ import cn.iocoder.yudao.module.mp.controller.admin.tag.vo.MpTagUpdateReqVO;
 import cn.iocoder.yudao.module.mp.dal.dataobject.tag.MpTagDO;
 
 import javax.validation.Valid;
+import java.util.List;
 
 /**
  * 公众号标签 Service 接口
@@ -45,6 +46,8 @@ public interface MpTagService {
      */
     PageResult<MpTagDO> getTagPage(MpTagPageReqVO pageReqVO);
 
+    List<MpTagDO> getTagList();
+
     /**
      * 同步公众号标签
      *

+ 6 - 1
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/tag/MpTagServiceImpl.java

@@ -116,6 +116,11 @@ public class MpTagServiceImpl implements MpTagService {
         return mpTagMapper.selectPage(pageReqVO);
     }
 
+    @Override
+    public List<MpTagDO> getTagList() {
+        return mpTagMapper.selectList();
+    }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public void syncTag(Long accountId) {
@@ -127,7 +132,7 @@ public class MpTagServiceImpl implements MpTagService {
         try {
             wxTags = mpService.getUserTagService().tagGet();
         } catch (WxErrorException e) {
-            throw new RuntimeException(e);
+            throw exception(TAG_GET_FAIL, e.getError().getErrorMsg());
         }
 
         // 第二步,合并更新回自己的数据库;由于标签只有 100 个,所以直接 for 循环操作

+ 8 - 0
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/user/MpUserService.java

@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.mp.service.user;
 
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.module.mp.controller.admin.user.vo.MpUserPageReqVO;
+import cn.iocoder.yudao.module.mp.controller.admin.user.vo.MpUserUpdateReqVO;
 import cn.iocoder.yudao.module.mp.dal.dataobject.user.MpUserDO;
 import me.chanjar.weixin.mp.bean.result.WxMpUser;
 
@@ -74,4 +75,11 @@ public interface MpUserService {
      */
     void updateUserUnsubscribe(String appId, String openId);
 
+    /**
+     * 更新公众号粉丝
+     *
+     * @param updateReqVO 更新信息
+     */
+    void updateUser(MpUserUpdateReqVO updateReqVO);
+
 }

+ 50 - 4
yudao-module-mp/yudao-module-mp-biz/src/main/java/cn/iocoder/yudao/module/mp/service/user/MpUserServiceImpl.java

@@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
 import cn.iocoder.yudao.framework.common.pojo.PageResult;
 import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
 import cn.iocoder.yudao.module.mp.controller.admin.user.vo.MpUserPageReqVO;
+import cn.iocoder.yudao.module.mp.controller.admin.user.vo.MpUserUpdateReqVO;
 import cn.iocoder.yudao.module.mp.convert.user.MpUserConvert;
 import cn.iocoder.yudao.module.mp.dal.dataobject.account.MpAccountDO;
 import cn.iocoder.yudao.module.mp.dal.dataobject.user.MpUserDO;
@@ -29,6 +30,10 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 
+import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
+import static cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants.USER_NOT_EXISTS;
+import static cn.iocoder.yudao.module.mp.enums.ErrorCodeConstants.USER_UPDATE_TAG_FAIL;
+
 /**
  * 微信公众号粉丝 Service 实现类
  *
@@ -156,14 +161,55 @@ public class MpUserServiceImpl implements MpUserService {
     }
 
     @Override
-    public void updateUserUnsubscribe(String appId, String openId) {
-        MpUserDO dbUser = mpUserMapper.selectByAppIdAndOpenid(appId, openId);
+    public void updateUserUnsubscribe(String appId, String openid) {
+        MpUserDO dbUser = mpUserMapper.selectByAppIdAndOpenid(appId, openid);
         if (dbUser == null) {
-            log.error("[updateUserUnsubscribe][微信公众号粉丝 appId({}) openId({}) 不存在]", appId, openId);
+            log.error("[updateUserUnsubscribe][微信公众号粉丝 appId({}) openid({}) 不存在]", appId, openid);
             return;
         }
         mpUserMapper.updateById(new MpUserDO().setId(dbUser.getId()).setSubscribeStatus(CommonStatusEnum.DISABLE.getStatus())
-                .setSubscribeTime(LocalDateTime.now()));
+                .setUnsubscribeTime(LocalDateTime.now()));
+    }
+
+    @Override
+    public void updateUser(MpUserUpdateReqVO updateReqVO) {
+        // 校验存在
+        MpUserDO user = validateUserExists(updateReqVO.getId());
+
+        // 第一步,更新标签到公众号
+        updateUserTag(user.getAppId(), user.getOpenid(), updateReqVO.getTagIds());
+
+        // 第二步,更新基本信息到数据库
+        MpUserDO updateObj = MpUserConvert.INSTANCE.convert(updateReqVO).setId(user.getId());
+        mpUserMapper.updateById(updateObj);
+    }
+
+    private MpUserDO validateUserExists(Long id) {
+        MpUserDO user = mpUserMapper.selectById(id);
+        if (user == null) {
+            throw exception(USER_NOT_EXISTS);
+        }
+        return user;
+    }
+
+    private void updateUserTag(String appId, String openid, List<Long> tagIds) {
+        WxMpService mpService = mpServiceFactory.getRequiredMpService(appId);
+        try {
+            // 第一步,先取消原来的标签
+            List<Long> oldTagIds = mpService.getUserTagService().userTagList(openid);
+            for (Long tagId : oldTagIds) {
+                mpService.getUserTagService().batchUntagging(tagId, new String[]{openid});
+            }
+            // 第二步,再设置新的标签
+            if (CollUtil.isEmpty(tagIds)) {
+                return;
+            }
+            for (Long tagId: tagIds) {
+                mpService.getUserTagService().batchTagging(tagId, new String[]{openid});
+            }
+        } catch (WxErrorException e) {
+            throw exception(USER_UPDATE_TAG_FAIL, e.getError().getErrorMsg());
+        }
     }
 
 }

+ 8 - 0
yudao-ui-admin/src/api/mp/tag.js

@@ -43,6 +43,14 @@ export function getTagPage(query) {
   })
 }
 
+// 获取公众号标签精简信息列表
+export function getSimpleTags() {
+  return request({
+    url: '/mp/tag/list-all-simple',
+    method: 'get',
+  })
+}
+
 // 同步公众号标签
 export function syncTag(accountId) {
   return request({

+ 35 - 0
yudao-ui-admin/src/api/mp/user.js

@@ -0,0 +1,35 @@
+import request from '@/utils/request'
+
+// 更新公众号粉丝
+export function updateUser(data) {
+  return request({
+    url: '/mp/user/update',
+    method: 'put',
+    data: data
+  })
+}
+
+// 获得公众号粉丝
+export function getUser(id) {
+  return request({
+    url: '/mp/user/get?id=' + id,
+    method: 'get'
+  })
+}
+
+// 获得公众号粉丝分页
+export function getUserPage(query) {
+  return request({
+    url: '/mp/user/page',
+    method: 'get',
+    params: query
+  })
+}
+
+// 同步公众号粉丝
+export function syncUser(accountId) {
+  return request({
+    url: '/mp/tag/sync?accountId=' + accountId,
+    method: 'post'
+  })
+}

+ 0 - 54
yudao-ui-admin/src/api/wechatMp/wxAccountFans.js

@@ -1,54 +0,0 @@
-import request from '@/utils/request'
-
-// 创建微信公众号粉丝
-export function createWxAccountFans(data) {
-  return request({
-    url: '/wechatMp/wx-account-fans/create',
-    method: 'post',
-    data: data
-  })
-}
-
-// 更新微信公众号粉丝
-export function updateWxAccountFans(data) {
-  return request({
-    url: '/wechatMp/wx-account-fans/update',
-    method: 'put',
-    data: data
-  })
-}
-
-// 删除微信公众号粉丝
-export function deleteWxAccountFans(id) {
-  return request({
-    url: '/wechatMp/wx-account-fans/delete?id=' + id,
-    method: 'delete'
-  })
-}
-
-// 获得微信公众号粉丝
-export function getWxAccountFans(id) {
-  return request({
-    url: '/wechatMp/wx-account-fans/get?id=' + id,
-    method: 'get'
-  })
-}
-
-// 获得微信公众号粉丝分页
-export function getWxAccountFansPage(query) {
-  return request({
-    url: '/wechatMp/wx-account-fans/page',
-    method: 'get',
-    params: query
-  })
-}
-
-// 导出微信公众号粉丝 Excel
-export function exportWxAccountFansExcel(query) {
-  return request({
-    url: '/wechatMp/wx-account-fans/export-excel',
-    method: 'get',
-    params: query,
-    responseType: 'blob'
-  })
-}

+ 235 - 0
yudao-ui-admin/src/views/mp/user/index.vue

@@ -0,0 +1,235 @@
+<template>
+  <div class="app-container">
+
+    <!-- 搜索工作栏 -->
+    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="公众号" prop="accountId">
+        <el-select v-model="queryParams.accountId" placeholder="请选择公众号">
+          <el-option v-for="item in accounts" :key="parseInt(item.id)" :label="item.name" :value="parseInt(item.id)" />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="用户标识" prop="openid">
+        <el-input v-model="queryParams.openid" placeholder="请输入用户标识" clearable @keyup.enter.native="handleQuery"/>
+      </el-form-item>
+      <el-form-item label="昵称" prop="nickname">
+        <el-input v-model="queryParams.nickname" placeholder="请输入昵称" clearable @keyup.enter.native="handleQuery"/>
+      </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>
+      </el-form-item>
+    </el-form>
+
+    <!-- 操作工具栏 -->
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button type="info" plain icon="el-icon-refresh" size="mini" @click="handleSync"
+                   v-hasPermi="['mp:user:sync']">同步
+        </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="openid" width="260" />
+      <el-table-column label="昵称" align="center" prop="nickname" />
+      <el-table-column label="备注" align="center" prop="remark" />
+      <el-table-column label="标签" align="center" prop="tagIds" width="200">
+        <template slot-scope="scope">
+          <span v-for="(tagId, index) in scope.row.tagIds" :key="index">
+            <el-tag>{{ tags.find(tag => tag.tagId === tagId)?.name }} </el-tag>&nbsp;
+          </span>
+        </template>
+      </el-table-column>
+      <el-table-column label="订阅状态" align="center" prop="subscribeStatus">
+        <template slot-scope="scope">
+          <el-tag v-if="scope.row.subscribeStatus === 0" type="success">已订阅</el-tag>
+          <el-tag v-else type="danger">未订阅</el-tag>
+        </template>
+      </el-table-column>
+      <el-table-column label="订阅时间" align="center" prop="subscribeTime" width="180">
+        <template slot-scope="scope">
+          <span>{{ parseTime(scope.row.subscribeTime) }}</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="['mp:user:update']">修改</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>
+      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
+        <el-form-item label="昵称" prop="nickname">
+          <el-input v-model="form.nickname" placeholder="请输入昵称" />
+        </el-form-item>
+        <el-form-item label="备注" prop="remark">
+          <el-input v-model="form.remark" placeholder="请输入备注" />
+        </el-form-item>
+        <el-form-item label="标签" prop="tagIds">
+          <el-select v-model="form.tagIds" multiple clearable placeholder="请选择标签">
+            <el-option v-for="item in tags" :key="parseInt(item.tagId)" :label="item.name" :value="parseInt(item.tagId)" />
+          </el-select>
+        </el-form-item>
+      </el-form>
+      <div slot="footer" class="dialog-footer">
+        <el-button type="primary" @click="submitForm">确 定</el-button>
+        <el-button @click="cancel">取 消</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import { updateUser, getUser, getUserPage, syncUser } from "@/api/mp/user";
+import { getSimpleAccounts } from "@/api/mp/account";
+import { getSimpleTags } from "@/api/mp/tag";
+
+export default {
+  name: "WxAccountFans",
+  components: {
+  },
+  data() {
+    return {
+      // 遮罩层
+      loading: true,
+      // 显示搜索条件
+      showSearch: true,
+      // 总条数
+      total: 0,
+      // 微信公众号粉丝列表
+      list: [],
+      // 弹出层标题
+      title: "",
+      // 是否显示弹出层
+      open: false,
+      // 查询参数
+      queryParams: {
+        pageNo: 1,
+        pageSize: 10,
+        accountId: null,
+        openid: null,
+        nickname: null,
+      },
+      // 表单参数
+      form: {},
+      // 表单校验
+      rules: {},
+
+      // 公众号账号列表
+      accounts: [],
+      // 公众号标签列表
+      tags: [],
+    };
+  },
+  created() {
+    getSimpleAccounts().then(response => {
+      this.accounts = response.data;
+      // 默认选中第一个
+      if (this.accounts.length > 0) {
+        this.queryParams.accountId = this.accounts[0].id;
+      }
+      // 加载数据
+      this.getList();
+    })
+
+    // 加载标签
+    getSimpleTags().then(response => {
+      this.tags = response.data;
+    })
+  },
+  methods: {
+    /** 查询列表 */
+    getList() {
+      // 如果没有选中公众号账号,则进行提示。
+      if (!this.queryParams.accountId) {
+        this.$message.error('未选中公众号,无法查询用户')
+        return false
+      }
+
+      this.loading = true;
+      // 处理查询参数
+      let params = {...this.queryParams};
+      // 执行查询
+      getUserPage(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,
+        nickname: undefined,
+        remark: undefined,
+        tagIds: [],
+      };
+      this.resetForm("form");
+    },
+    /** 搜索按钮操作 */
+    handleQuery() {
+      this.queryParams.pageNo = 1;
+      this.getList();
+    },
+    /** 重置按钮操作 */
+    resetQuery() {
+      this.resetForm("queryForm");
+      // 默认选中第一个
+      if (this.accounts.length > 0) {
+        this.queryParams.accountId = this.accounts[0].id;
+      }
+      this.handleQuery();
+    },
+    /** 修改按钮操作 */
+    handleUpdate(row) {
+      this.reset();
+      const id = row.id;
+      getUser(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) {
+          updateUser(this.form).then(response => {
+            this.$modal.msgSuccess("修改成功");
+            this.open = false;
+            this.getList();
+          });
+        }
+      });
+    },
+    /** 同步标签 */
+    handleSync() {
+      const accountId = this.queryParams.accountId
+      this.$modal.confirm('是否确认同步粉丝?').then(function () {
+        return syncUser(accountId)
+      }).then(() => {
+        this.$modal.msgSuccess('开始从微信公众号同步粉丝信息,同步需要一段时间,建议稍后再查询')
+      }).catch(() => {
+      })
+    },
+  }
+};
+</script>

+ 0 - 334
yudao-ui-admin/src/views/wechatMp/wxAccountFans/index.vue

@@ -1,334 +0,0 @@
-<template>
-  <div class="app-container">
-
-    <!-- 搜索工作栏 -->
-    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
-      <el-form-item label="用户标识" prop="openid">
-        <el-input v-model="queryParams.openid" placeholder="请输入用户标识" clearable @keyup.enter.native="handleQuery"/>
-      </el-form-item>
-      <el-form-item label="订阅状态,0未关注,1已关注" prop="subscribeStatus">
-        <el-select v-model="queryParams.subscribeStatus" placeholder="请选择订阅状态,0未关注,1已关注" clearable size="small">
-          <el-option label="请选择字典生成" value="" />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="订阅时间">
-        <el-date-picker v-model="dateRangeSubscribeTime" style="width: 240px" value-format="yyyy-MM-dd"
-                        type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" />
-      </el-form-item>
-      <el-form-item label="昵称" prop="nickname">
-        <el-input v-model="queryParams.nickname" placeholder="请输入昵称" clearable @keyup.enter.native="handleQuery"/>
-      </el-form-item>
-      <el-form-item label="性别,1男,2女,0未知" prop="gender">
-        <el-input v-model="queryParams.gender" placeholder="请输入性别,1男,2女,0未知" clearable @keyup.enter.native="handleQuery"/>
-      </el-form-item>
-      <el-form-item label="语言" prop="language">
-        <el-input v-model="queryParams.language" placeholder="请输入语言" clearable @keyup.enter.native="handleQuery"/>
-      </el-form-item>
-      <el-form-item label="国家" prop="country">
-        <el-input v-model="queryParams.country" placeholder="请输入国家" clearable @keyup.enter.native="handleQuery"/>
-      </el-form-item>
-      <el-form-item label="省份" prop="province">
-        <el-input v-model="queryParams.province" placeholder="请输入省份" clearable @keyup.enter.native="handleQuery"/>
-      </el-form-item>
-      <el-form-item label="城市" prop="city">
-        <el-input v-model="queryParams.city" placeholder="请输入城市" clearable @keyup.enter.native="handleQuery"/>
-      </el-form-item>
-      <el-form-item label="头像地址" prop="headimgUrl">
-        <el-input v-model="queryParams.headimgUrl" placeholder="请输入头像地址" clearable @keyup.enter.native="handleQuery"/>
-      </el-form-item>
-      <el-form-item label="备注" prop="remark">
-        <el-input v-model="queryParams.remark" 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="微信公众号appid" prop="wxAccountAppid">
-        <el-input v-model="queryParams.wxAccountAppid" placeholder="请输入微信公众号appid" 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>
-      </el-form-item>
-    </el-form>
-
-    <!-- 操作工具栏 -->
-    <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-fans: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-fans: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="openid" />
-      <el-table-column label="订阅状态,0未关注,1已关注" align="center" prop="subscribeStatus" />
-      <el-table-column label="订阅时间" align="center" prop="subscribeTime" width="180">
-        <template slot-scope="scope">
-          <span>{{ parseTime(scope.row.subscribeTime) }}</span>
-        </template>
-      </el-table-column>
-      <el-table-column label="昵称" align="center" prop="nickname" />
-      <el-table-column label="性别,1男,2女,0未知" align="center" prop="gender" />
-      <el-table-column label="语言" align="center" prop="language" />
-      <el-table-column label="国家" align="center" prop="country" />
-      <el-table-column label="省份" align="center" prop="province" />
-      <el-table-column label="城市" align="center" prop="city" />
-      <el-table-column label="头像地址" align="center" prop="headimgUrl" />
-      <el-table-column label="备注" align="center" prop="remark" />
-      <el-table-column label="微信公众号ID" align="center" prop="wxAccountId" />
-      <el-table-column label="微信公众号appid" align="center" prop="wxAccountAppid" />
-      <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-account-fans:update']">修改</el-button>
-          <el-button size="mini" type="text" icon="el-icon-delete" @click="handleDelete(scope.row)"
-                     v-hasPermi="['wechatMp:wx-account-fans: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>
-      <el-form ref="form" :model="form" :rules="rules" label-width="80px">
-        <el-form-item label="用户标识" prop="openid">
-          <el-input v-model="form.openid" placeholder="请输入用户标识" />
-        </el-form-item>
-        <el-form-item label="订阅状态,0未关注,1已关注" prop="subscribeStatus">
-          <el-radio-group v-model="form.subscribeStatus">
-            <el-radio label="1">请选择字典生成</el-radio>
-          </el-radio-group>
-        </el-form-item>
-        <el-form-item label="订阅时间" prop="subscribeTime">
-          <el-date-picker clearable v-model="form.subscribeTime" type="date" value-format="timestamp" placeholder="选择订阅时间" />
-        </el-form-item>
-        <el-form-item label="昵称" prop="nickname">
-          <el-input v-model="form.nickname" placeholder="请输入昵称" />
-        </el-form-item>
-        <el-form-item label="性别,1男,2女,0未知" prop="gender">
-          <el-input v-model="form.gender" placeholder="请输入性别,1男,2女,0未知" />
-        </el-form-item>
-        <el-form-item label="语言" prop="language">
-          <el-input v-model="form.language" placeholder="请输入语言" />
-        </el-form-item>
-        <el-form-item label="国家" prop="country">
-          <el-input v-model="form.country" placeholder="请输入国家" />
-        </el-form-item>
-        <el-form-item label="省份" prop="province">
-          <el-input v-model="form.province" placeholder="请输入省份" />
-        </el-form-item>
-        <el-form-item label="城市" prop="city">
-          <el-input v-model="form.city" placeholder="请输入城市" />
-        </el-form-item>
-        <el-form-item label="头像地址" prop="headimgUrl">
-          <el-input v-model="form.headimgUrl" placeholder="请输入头像地址" />
-        </el-form-item>
-        <el-form-item label="备注" prop="remark">
-          <el-input v-model="form.remark" placeholder="请输入备注" />
-        </el-form-item>
-        <el-form-item label="微信公众号ID" prop="wxAccountId">
-          <el-input v-model="form.wxAccountId" placeholder="请输入微信公众号ID" />
-        </el-form-item>
-        <el-form-item label="微信公众号appid" prop="wxAccountAppid">
-          <el-input v-model="form.wxAccountAppid" placeholder="请输入微信公众号appid" />
-        </el-form-item>
-      </el-form>
-      <div slot="footer" class="dialog-footer">
-        <el-button type="primary" @click="submitForm">确 定</el-button>
-        <el-button @click="cancel">取 消</el-button>
-      </div>
-    </el-dialog>
-  </div>
-</template>
-
-<script>
-import { createWxAccountFans, updateWxAccountFans, deleteWxAccountFans, getWxAccountFans, getWxAccountFansPage, exportWxAccountFansExcel } from "@/api/wechatMp/wxAccountFans";
-
-export default {
-  name: "WxAccountFans",
-  components: {
-  },
-  data() {
-    return {
-      // 遮罩层
-      loading: true,
-      // 导出遮罩层
-      exportLoading: false,
-      // 显示搜索条件
-      showSearch: true,
-      // 总条数
-      total: 0,
-      // 微信公众号粉丝列表
-      list: [],
-      // 弹出层标题
-      title: "",
-      // 是否显示弹出层
-      open: false,
-      dateRangeSubscribeTime: [],
-      dateRangeCreateTime: [],
-      // 查询参数
-      queryParams: {
-        pageNo: 1,
-        pageSize: 10,
-        openid: null,
-        subscribeStatus: null,
-        nickname: null,
-        gender: null,
-        language: null,
-        country: null,
-        province: null,
-        city: null,
-        headimgUrl: null,
-        remark: null,
-        wxAccountId: null,
-        wxAccountAppid: null,
-      },
-      // 表单参数
-      form: {},
-      // 表单校验
-      rules: {
-      }
-    };
-  },
-  created() {
-    this.getList();
-  },
-  methods: {
-    /** 查询列表 */
-    getList() {
-      this.loading = true;
-      // 处理查询参数
-      let params = {...this.queryParams};
-      this.addBeginAndEndTime(params, this.dateRangeSubscribeTime, 'subscribeTime');
-      this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime');
-      // 执行查询
-      getWxAccountFansPage(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,
-        openid: undefined,
-        subscribeStatus: undefined,
-        subscribeTime: undefined,
-        nickname: undefined,
-        gender: undefined,
-        language: undefined,
-        country: undefined,
-        province: undefined,
-        city: undefined,
-        headimgUrl: undefined,
-        remark: undefined,
-        wxAccountId: undefined,
-        wxAccountAppid: undefined,
-      };
-      this.resetForm("form");
-    },
-    /** 搜索按钮操作 */
-    handleQuery() {
-      this.queryParams.pageNo = 1;
-      this.getList();
-    },
-    /** 重置按钮操作 */
-    resetQuery() {
-      this.dateRangeSubscribeTime = [];
-      this.dateRangeCreateTime = [];
-      this.resetForm("queryForm");
-      this.handleQuery();
-    },
-    /** 新增按钮操作 */
-    handleAdd() {
-      this.reset();
-      this.open = true;
-      this.title = "添加微信公众号粉丝";
-    },
-    /** 修改按钮操作 */
-    handleUpdate(row) {
-      this.reset();
-      const id = row.id;
-      getWxAccountFans(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) {
-          updateWxAccountFans(this.form).then(response => {
-            this.$modal.msgSuccess("修改成功");
-            this.open = false;
-            this.getList();
-          });
-          return;
-        }
-        // 添加的提交
-        createWxAccountFans(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 deleteWxAccountFans(id);
-        }).then(() => {
-          this.getList();
-          this.$modal.msgSuccess("删除成功");
-        }).catch(() => {});
-    },
-    /** 导出按钮操作 */
-    handleExport() {
-      // 处理查询参数
-      let params = {...this.queryParams};
-      params.pageNo = undefined;
-      params.pageSize = undefined;
-      this.addBeginAndEndTime(params, this.dateRangeSubscribeTime, 'subscribeTime');
-      this.addBeginAndEndTime(params, this.dateRangeCreateTime, 'createTime');
-      // 执行导出
-      this.$modal.confirm('是否确认导出所有微信公众号粉丝数据项?').then(() => {
-          this.exportLoading = true;
-          return exportWxAccountFansExcel(params);
-        }).then(response => {
-          this.$download.excel(response, '微信公众号粉丝.xls');
-          this.exportLoading = false;
-        }).catch(() => {});
-    }
-  }
-};
-</script>