From 200e222aed941bc52f2c9f76005f8afd636e8ac4 Mon Sep 17 00:00:00 2001
From: huangdeliang <huangdeliang@skieer.com>
Date: Mon, 1 Feb 2021 09:15:52 +0800
Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=B5=8B=E8=AF=95=E5=85=AC?=
 =?UTF-8?q?=E4=BC=97=E5=8F=B7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../controller/common/CommonController.java   |  42 ++
 .../custom/SysWxSaleAccountController.java    | 133 ++++++
 .../stdiet/common/core/redis/RedisCache.java  |  94 ++--
 .../custom/domain/SysWxSaleAccount.java       |  47 ++
 .../custom/mapper/SysWxSaleAccountMapper.java |  61 +++
 .../service/ISysWxSaleAccountService.java     |  64 +++
 .../impl/SysWxSaleAccountServiceImpl.java     |  93 ++++
 .../com/stdiet/custom/utils/HttpPostUtil.java | 193 ++++++++
 .../com/stdiet/custom/utils/WxTokenUtils.java |  32 +-
 .../mapper/custom/SysWxSaleAccountMapper.xml  |  87 ++++
 stdiet-ui/src/api/custom/WxAccount.js         |  55 +++
 .../src/views/custom/WxAccount/index.vue      | 420 ++++++++++++++++++
 12 files changed, 1258 insertions(+), 63 deletions(-)
 create mode 100644 stdiet-admin/src/main/java/com/stdiet/web/controller/custom/SysWxSaleAccountController.java
 create mode 100644 stdiet-custom/src/main/java/com/stdiet/custom/domain/SysWxSaleAccount.java
 create mode 100644 stdiet-custom/src/main/java/com/stdiet/custom/mapper/SysWxSaleAccountMapper.java
 create mode 100644 stdiet-custom/src/main/java/com/stdiet/custom/service/ISysWxSaleAccountService.java
 create mode 100644 stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysWxSaleAccountServiceImpl.java
 create mode 100644 stdiet-custom/src/main/java/com/stdiet/custom/utils/HttpPostUtil.java
 create mode 100644 stdiet-custom/src/main/resources/mapper/custom/SysWxSaleAccountMapper.xml
 create mode 100644 stdiet-ui/src/api/custom/WxAccount.js
 create mode 100644 stdiet-ui/src/views/custom/WxAccount/index.vue

diff --git a/stdiet-admin/src/main/java/com/stdiet/web/controller/common/CommonController.java b/stdiet-admin/src/main/java/com/stdiet/web/controller/common/CommonController.java
index f2636c7f5..a4f41dab1 100644
--- a/stdiet-admin/src/main/java/com/stdiet/web/controller/common/CommonController.java
+++ b/stdiet-admin/src/main/java/com/stdiet/web/controller/common/CommonController.java
@@ -3,10 +3,15 @@ package com.stdiet.web.controller.common;
 import com.stdiet.common.config.RuoYiConfig;
 import com.stdiet.common.constant.Constants;
 import com.stdiet.common.core.domain.AjaxResult;
+import com.stdiet.common.core.redis.RedisCache;
 import com.stdiet.common.utils.StringUtils;
 import com.stdiet.common.utils.file.FileUploadUtils;
 import com.stdiet.common.utils.file.FileUtils;
+import com.stdiet.custom.domain.wechat.WxAccessToken;
+import com.stdiet.custom.domain.wechat.WxFileUploadResult;
+import com.stdiet.custom.utils.WxTokenUtils;
 import com.stdiet.framework.config.ServerConfig;
+import org.aspectj.weaver.loadtime.Aj;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -17,6 +22,7 @@ import org.springframework.web.multipart.MultipartFile;
 
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
+import java.util.concurrent.TimeUnit;
 
 /**
  * 通用请求处理
@@ -30,6 +36,9 @@ public class CommonController {
     @Autowired
     private ServerConfig serverConfig;
 
+    @Autowired
+    private RedisCache redisCache;
+
     /**
      * 通用下载请求
      *
@@ -98,6 +107,39 @@ public class CommonController {
         }
     }
 
+    /**
+     * 通用上传请求(无需登录认证)
+     */
+    @PostMapping("/common/wxAccountUpload")
+    public AjaxResult wxAccountUpload(MultipartFile file) throws Exception {
+        try {
+            // 上传文件路径
+            String filePath = RuoYiConfig.getUploadPath();
+            // 上传并返回新文件名称
+            String fileName = FileUploadUtils.upload(filePath, file);
+            String url = serverConfig.getUrl() + fileName;
+
+            String accessToken = redisCache.getCacheObject(WxTokenUtils.KEY_ACCESS_TOKEN);
+            if (StringUtils.isEmpty(accessToken)) {
+                WxAccessToken wxAccessToken = WxTokenUtils.fetchAccessToken();
+                redisCache.setCacheObject(WxTokenUtils.KEY_ACCESS_TOKEN, wxAccessToken.getAccessToken(), wxAccessToken.getExpiresIn(), TimeUnit.SECONDS);
+            }
+
+            WxFileUploadResult result = WxTokenUtils.uploadImage(filePath, accessToken);
+            if(result == null) {
+                return AjaxResult.error("上传微信失败");
+            }
+
+            AjaxResult ajax = AjaxResult.success();
+            ajax.put("fileName", fileName);
+            ajax.put("mediaId", result.getMediaId());
+            ajax.put("url", url);
+            return ajax;
+        } catch (Exception e) {
+            return AjaxResult.error(e.getMessage());
+        }
+    }
+
     /**
      * 本地资源通用下载
      */
diff --git a/stdiet-admin/src/main/java/com/stdiet/web/controller/custom/SysWxSaleAccountController.java b/stdiet-admin/src/main/java/com/stdiet/web/controller/custom/SysWxSaleAccountController.java
new file mode 100644
index 000000000..ac283eefb
--- /dev/null
+++ b/stdiet-admin/src/main/java/com/stdiet/web/controller/custom/SysWxSaleAccountController.java
@@ -0,0 +1,133 @@
+package com.stdiet.web.controller.custom;
+
+import com.stdiet.common.annotation.Log;
+import com.stdiet.common.config.RuoYiConfig;
+import com.stdiet.common.core.controller.BaseController;
+import com.stdiet.common.core.domain.AjaxResult;
+import com.stdiet.common.core.page.TableDataInfo;
+import com.stdiet.common.core.redis.RedisCache;
+import com.stdiet.common.enums.BusinessType;
+import com.stdiet.common.utils.StringUtils;
+import com.stdiet.common.utils.file.FileUploadUtils;
+import com.stdiet.common.utils.poi.ExcelUtil;
+import com.stdiet.custom.domain.SysWxSaleAccount;
+import com.stdiet.custom.domain.wechat.WxAccessToken;
+import com.stdiet.custom.domain.wechat.WxFileUploadResult;
+import com.stdiet.custom.service.ISysWxSaleAccountService;
+import com.stdiet.custom.utils.WxTokenUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.security.access.prepost.PreAuthorize;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * 微信销售账号Controller
+ *
+ * @author wonder
+ * @date 2021-01-29
+ */
+@RestController
+@RequestMapping("/custom/WxAccount")
+public class SysWxSaleAccountController extends BaseController {
+    @Autowired
+    private ISysWxSaleAccountService sysWxSaleAccountService;
+
+    @Autowired
+    private RedisCache redisCache;
+
+    /**
+     * 查询微信销售账号列表
+     */
+    @PreAuthorize("@ss.hasPermi('custom:WxAccount:list')")
+    @GetMapping("/list")
+    public TableDataInfo list(SysWxSaleAccount sysWxSaleAccount) {
+        startPage();
+        List<SysWxSaleAccount> list = sysWxSaleAccountService.selectSysWxSaleAccountList(sysWxSaleAccount);
+        return getDataTable(list);
+    }
+
+    /**
+     * 导出微信销售账号列表
+     */
+    @PreAuthorize("@ss.hasPermi('custom:WxAccount:export')")
+    @Log(title = "微信销售账号", businessType = BusinessType.EXPORT)
+    @GetMapping("/export")
+    public AjaxResult export(SysWxSaleAccount sysWxSaleAccount) {
+        List<SysWxSaleAccount> list = sysWxSaleAccountService.selectSysWxSaleAccountList(sysWxSaleAccount);
+        ExcelUtil<SysWxSaleAccount> util = new ExcelUtil<SysWxSaleAccount>(SysWxSaleAccount.class);
+        return util.exportExcel(list, "WxAccount");
+    }
+
+    /**
+     * 获取微信销售账号详细信息
+     */
+    @PreAuthorize("@ss.hasPermi('custom:WxAccount:query')")
+    @GetMapping(value = "/{id}")
+    public AjaxResult getInfo(@PathVariable("id") Long id) {
+        return AjaxResult.success(sysWxSaleAccountService.selectSysWxSaleAccountById(id));
+    }
+
+    /**
+     * 新增微信销售账号
+     */
+    @PreAuthorize("@ss.hasPermi('custom:WxAccount:add')")
+    @Log(title = "微信销售账号", businessType = BusinessType.INSERT)
+    @PostMapping
+    public AjaxResult add(@RequestBody SysWxSaleAccount sysWxSaleAccount) {
+        return toAjax(sysWxSaleAccountService.insertSysWxSaleAccount(sysWxSaleAccount));
+    }
+
+    /**
+     * 修改微信销售账号
+     */
+    @PreAuthorize("@ss.hasPermi('custom:WxAccount:edit')")
+    @Log(title = "微信销售账号", businessType = BusinessType.UPDATE)
+    @PutMapping
+    public AjaxResult edit(@RequestBody SysWxSaleAccount sysWxSaleAccount) {
+        return toAjax(sysWxSaleAccountService.updateSysWxSaleAccount(sysWxSaleAccount));
+    }
+
+    /**
+     * 删除微信销售账号
+     */
+    @PreAuthorize("@ss.hasPermi('custom:WxAccount:remove')")
+    @Log(title = "微信销售账号", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public AjaxResult remove(@PathVariable Long[] ids) {
+        return toAjax(sysWxSaleAccountService.deleteSysWxSaleAccountByIds(ids));
+    }
+
+    @PostMapping("/upload")
+    public AjaxResult uploadFile(@RequestParam("file") MultipartFile file, SysWxSaleAccount sysWxSaleAccount) throws Exception {
+        try {
+            // 上传文件路径
+            String filePath = RuoYiConfig.getUploadPath();
+            // 上传并返回新文件名称
+            String fileName = FileUploadUtils.upload(filePath, file);
+
+            sysWxSaleAccount.setImgUrl(fileName);
+
+            String accessToken = redisCache.getCacheObject(WxTokenUtils.KEY_ACCESS_TOKEN);
+            if (StringUtils.isEmpty(accessToken)) {
+                WxAccessToken wxAccessToken = WxTokenUtils.fetchAccessToken();
+                redisCache.setCacheObject(WxTokenUtils.KEY_ACCESS_TOKEN, wxAccessToken.getAccessToken(), wxAccessToken.getExpiresIn(), TimeUnit.SECONDS);
+            }
+
+            WxFileUploadResult result = WxTokenUtils.uploadImage(fileName, accessToken);
+            if (StringUtils.isNotNull(result)) {
+
+                sysWxSaleAccount.setMediaId(result.getMediaId());
+
+                return toAjax(sysWxSaleAccountService.insertSysWxSaleAccount(sysWxSaleAccount));
+
+            }
+            return AjaxResult.error("empty");
+
+        } catch (Exception e) {
+            return AjaxResult.error(e.getMessage());
+        }
+    }
+}
\ No newline at end of file
diff --git a/stdiet-common/src/main/java/com/stdiet/common/core/redis/RedisCache.java b/stdiet-common/src/main/java/com/stdiet/common/core/redis/RedisCache.java
index 4f5b0fc40..5978bb839 100644
--- a/stdiet-common/src/main/java/com/stdiet/common/core/redis/RedisCache.java
+++ b/stdiet-common/src/main/java/com/stdiet/common/core/redis/RedisCache.java
@@ -1,74 +1,71 @@
 package com.stdiet.common.core.redis;
 
-import java.util.Collection;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.HashOperations;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.data.redis.core.ValueOperations;
 import org.springframework.stereotype.Component;
 
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.TimeUnit;
+
 /**
  * spring redis 工具类
  *
  * @author stdiet
  **/
-@SuppressWarnings(value = { "unchecked", "rawtypes" })
+@SuppressWarnings(value = {"unchecked", "rawtypes"})
 @Component
-public class RedisCache
-{
+public class RedisCache {
     @Autowired
     public RedisTemplate redisTemplate;
 
+
     /**
      * 缓存基本的对象,Integer、String、实体类等
      *
-     * @param key 缓存的键值
+     * @param key   缓存的键值
      * @param value 缓存的值
      */
-    public <T> void setCacheObject(final String key, final T value)
-    {
+    public <T> void setCacheObject(final String key, final T value) {
         redisTemplate.opsForValue().set(key, value);
     }
 
     /**
      * 缓存基本的对象,Integer、String、实体类等
      *
-     * @param key 缓存的键值
-     * @param value 缓存的值
-     * @param timeout 时间
+     * @param key      缓存的键值
+     * @param value    缓存的值
+     * @param timeout  时间
      * @param timeUnit 时间颗粒度
      */
-    public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit)
-    {
+    public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) {
         redisTemplate.opsForValue().set(key, value, timeout, timeUnit);
     }
 
     /**
      * 设置有效时间
      *
-     * @param key Redis键
+     * @param key     Redis键
      * @param timeout 超时时间
      * @return true=设置成功;false=设置失败
      */
-    public boolean expire(final String key, final long timeout)
-    {
+    public boolean expire(final String key, final long timeout) {
         return expire(key, timeout, TimeUnit.SECONDS);
     }
 
     /**
      * 设置有效时间
      *
-     * @param key Redis键
+     * @param key     Redis键
      * @param timeout 超时时间
-     * @param unit 时间单位
+     * @param unit    时间单位
      * @return true=设置成功;false=设置失败
      */
-    public boolean expire(final String key, final long timeout, final TimeUnit unit)
-    {
+    public boolean expire(final String key, final long timeout, final TimeUnit unit) {
         return redisTemplate.expire(key, timeout, unit);
     }
 
@@ -78,8 +75,7 @@ public class RedisCache
      * @param key 缓存键值
      * @return 缓存键值对应的数据
      */
-    public <T> T getCacheObject(final String key)
-    {
+    public <T> T getCacheObject(final String key) {
         ValueOperations<String, T> operation = redisTemplate.opsForValue();
         return operation.get(key);
     }
@@ -89,8 +85,7 @@ public class RedisCache
      *
      * @param key
      */
-    public boolean deleteObject(final String key)
-    {
+    public boolean deleteObject(final String key) {
         return redisTemplate.delete(key);
     }
 
@@ -100,20 +95,18 @@ public class RedisCache
      * @param collection 多个对象
      * @return
      */
-    public long deleteObject(final Collection collection)
-    {
+    public long deleteObject(final Collection collection) {
         return redisTemplate.delete(collection);
     }
 
     /**
      * 缓存List数据
      *
-     * @param key 缓存的键值
+     * @param key      缓存的键值
      * @param dataList 待缓存的List数据
      * @return 缓存的对象
      */
-    public <T> long setCacheList(final String key, final List<T> dataList)
-    {
+    public <T> long setCacheList(final String key, final List<T> dataList) {
         Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
         return count == null ? 0 : count;
     }
@@ -124,20 +117,18 @@ public class RedisCache
      * @param key 缓存的键值
      * @return 缓存键值对应的数据
      */
-    public <T> List<T> getCacheList(final String key)
-    {
+    public <T> List<T> getCacheList(final String key) {
         return redisTemplate.opsForList().range(key, 0, -1);
     }
 
     /**
      * 缓存Set
      *
-     * @param key 缓存键值
+     * @param key     缓存键值
      * @param dataSet 缓存的数据
      * @return 缓存数据的对象
      */
-    public <T> long setCacheSet(final String key, final Set<T> dataSet)
-    {
+    public <T> long setCacheSet(final String key, final Set<T> dataSet) {
         Long count = redisTemplate.opsForSet().add(key, dataSet);
         return count == null ? 0 : count;
     }
@@ -148,8 +139,7 @@ public class RedisCache
      * @param key
      * @return
      */
-    public <T> Set<T> getCacheSet(final String key)
-    {
+    public <T> Set<T> getCacheSet(final String key) {
         return redisTemplate.opsForSet().members(key);
     }
 
@@ -159,8 +149,7 @@ public class RedisCache
      * @param key
      * @param dataMap
      */
-    public <T> void setCacheMap(final String key, final Map<String, T> dataMap)
-    {
+    public <T> void setCacheMap(final String key, final Map<String, T> dataMap) {
         if (dataMap != null) {
             redisTemplate.opsForHash().putAll(key, dataMap);
         }
@@ -172,32 +161,29 @@ public class RedisCache
      * @param key
      * @return
      */
-    public <T> Map<String, T> getCacheMap(final String key)
-    {
+    public <T> Map<String, T> getCacheMap(final String key) {
         return redisTemplate.opsForHash().entries(key);
     }
 
     /**
      * 往Hash中存入数据
      *
-     * @param key Redis键
-     * @param hKey Hash键
+     * @param key   Redis键
+     * @param hKey  Hash键
      * @param value 值
      */
-    public <T> void setCacheMapValue(final String key, final String hKey, final T value)
-    {
+    public <T> void setCacheMapValue(final String key, final String hKey, final T value) {
         redisTemplate.opsForHash().put(key, hKey, value);
     }
 
     /**
      * 获取Hash中的数据
      *
-     * @param key Redis键
+     * @param key  Redis键
      * @param hKey Hash键
      * @return Hash中的对象
      */
-    public <T> T getCacheMapValue(final String key, final String hKey)
-    {
+    public <T> T getCacheMapValue(final String key, final String hKey) {
         HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
         return opsForHash.get(key, hKey);
     }
@@ -205,12 +191,11 @@ public class RedisCache
     /**
      * 获取多个Hash中的数据
      *
-     * @param key Redis键
+     * @param key   Redis键
      * @param hKeys Hash键集合
      * @return Hash对象集合
      */
-    public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys)
-    {
+    public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys) {
         return redisTemplate.opsForHash().multiGet(key, hKeys);
     }
 
@@ -220,8 +205,7 @@ public class RedisCache
      * @param pattern 字符串前缀
      * @return 对象列表
      */
-    public Collection<String> keys(final String pattern)
-    {
+    public Collection<String> keys(final String pattern) {
         return redisTemplate.keys(pattern);
     }
 }
diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/domain/SysWxSaleAccount.java b/stdiet-custom/src/main/java/com/stdiet/custom/domain/SysWxSaleAccount.java
new file mode 100644
index 000000000..a034f8638
--- /dev/null
+++ b/stdiet-custom/src/main/java/com/stdiet/custom/domain/SysWxSaleAccount.java
@@ -0,0 +1,47 @@
+package com.stdiet.custom.domain;
+
+import lombok.Data;
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+import com.stdiet.common.annotation.Excel;
+import com.stdiet.common.core.domain.BaseEntity;
+
+/**
+ * 微信销售账号对象 sys_wx_sale_account
+ * 
+ * @author wonder
+ * @date 2021-01-29
+ */
+@Data
+public class SysWxSaleAccount extends BaseEntity
+{
+    private static final long serialVersionUID = 1L;
+
+    /** $column.columnComment */
+    private Long id;
+
+    /** 账号名称 */
+    @Excel(name = "账号名称")
+    private String nickName;
+
+    /** 账号id */
+    @Excel(name = "账号id")
+    private Long accountId;
+
+    /** 微信号 */
+    @Excel(name = "微信号")
+    private String wxId;
+
+    /** 手机号 */
+    @Excel(name = "手机号")
+    private String phone;
+
+    private String imgUrl;
+
+    private String mediaId;
+
+    private String remark;
+
+    private Integer count;
+
+}
\ No newline at end of file
diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/mapper/SysWxSaleAccountMapper.java b/stdiet-custom/src/main/java/com/stdiet/custom/mapper/SysWxSaleAccountMapper.java
new file mode 100644
index 000000000..63cb0aba5
--- /dev/null
+++ b/stdiet-custom/src/main/java/com/stdiet/custom/mapper/SysWxSaleAccountMapper.java
@@ -0,0 +1,61 @@
+package com.stdiet.custom.mapper;
+
+import java.util.List;
+import com.stdiet.custom.domain.SysWxSaleAccount;
+
+/**
+ * 微信销售账号Mapper接口
+ * 
+ * @author wonder
+ * @date 2021-01-29
+ */
+public interface SysWxSaleAccountMapper 
+{
+    /**
+     * 查询微信销售账号
+     * 
+     * @param id 微信销售账号ID
+     * @return 微信销售账号
+     */
+    public SysWxSaleAccount selectSysWxSaleAccountById(Long id);
+
+    /**
+     * 查询微信销售账号列表
+     * 
+     * @param sysWxSaleAccount 微信销售账号
+     * @return 微信销售账号集合
+     */
+    public List<SysWxSaleAccount> selectSysWxSaleAccountList(SysWxSaleAccount sysWxSaleAccount);
+
+    /**
+     * 新增微信销售账号
+     * 
+     * @param sysWxSaleAccount 微信销售账号
+     * @return 结果
+     */
+    public int insertSysWxSaleAccount(SysWxSaleAccount sysWxSaleAccount);
+
+    /**
+     * 修改微信销售账号
+     * 
+     * @param sysWxSaleAccount 微信销售账号
+     * @return 结果
+     */
+    public int updateSysWxSaleAccount(SysWxSaleAccount sysWxSaleAccount);
+
+    /**
+     * 删除微信销售账号
+     * 
+     * @param id 微信销售账号ID
+     * @return 结果
+     */
+    public int deleteSysWxSaleAccountById(Long id);
+
+    /**
+     * 批量删除微信销售账号
+     * 
+     * @param ids 需要删除的数据ID
+     * @return 结果
+     */
+    public int deleteSysWxSaleAccountByIds(Long[] ids);
+}
\ No newline at end of file
diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/service/ISysWxSaleAccountService.java b/stdiet-custom/src/main/java/com/stdiet/custom/service/ISysWxSaleAccountService.java
new file mode 100644
index 000000000..534b8392f
--- /dev/null
+++ b/stdiet-custom/src/main/java/com/stdiet/custom/service/ISysWxSaleAccountService.java
@@ -0,0 +1,64 @@
+package com.stdiet.custom.service;
+
+import java.util.List;
+
+import com.stdiet.common.core.domain.AjaxResult;
+import com.stdiet.custom.domain.SysWxSaleAccount;
+
+/**
+ * 微信销售账号Service接口
+ * 
+ * @author wonder
+ * @date 2021-01-29
+ */
+public interface ISysWxSaleAccountService 
+{
+    /**
+     * 查询微信销售账号
+     * 
+     * @param id 微信销售账号ID
+     * @return 微信销售账号
+     */
+    public SysWxSaleAccount selectSysWxSaleAccountById(Long id);
+
+    /**
+     * 查询微信销售账号列表
+     * 
+     * @param sysWxSaleAccount 微信销售账号
+     * @return 微信销售账号集合
+     */
+    public List<SysWxSaleAccount> selectSysWxSaleAccountList(SysWxSaleAccount sysWxSaleAccount);
+
+    /**
+     * 新增微信销售账号
+     * 
+     * @param sysWxSaleAccount 微信销售账号
+     * @return 结果
+     */
+    public int insertSysWxSaleAccount(SysWxSaleAccount sysWxSaleAccount);
+
+    /**
+     * 修改微信销售账号
+     * 
+     * @param sysWxSaleAccount 微信销售账号
+     * @return 结果
+     */
+    public int updateSysWxSaleAccount(SysWxSaleAccount sysWxSaleAccount);
+
+    /**
+     * 批量删除微信销售账号
+     * 
+     * @param ids 需要删除的微信销售账号ID
+     * @return 结果
+     */
+    public int deleteSysWxSaleAccountByIds(Long[] ids);
+
+    /**
+     * 删除微信销售账号信息
+     * 
+     * @param id 微信销售账号ID
+     * @return 结果
+     */
+    public int deleteSysWxSaleAccountById(Long id);
+
+}
\ No newline at end of file
diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysWxSaleAccountServiceImpl.java b/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysWxSaleAccountServiceImpl.java
new file mode 100644
index 000000000..0ff744f83
--- /dev/null
+++ b/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysWxSaleAccountServiceImpl.java
@@ -0,0 +1,93 @@
+package com.stdiet.custom.service.impl;
+
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import com.stdiet.custom.mapper.SysWxSaleAccountMapper;
+import com.stdiet.custom.domain.SysWxSaleAccount;
+import com.stdiet.custom.service.ISysWxSaleAccountService;
+
+/**
+ * 微信销售账号Service业务层处理
+ * 
+ * @author wonder
+ * @date 2021-01-29
+ */
+@Service
+public class SysWxSaleAccountServiceImpl implements ISysWxSaleAccountService 
+{
+    @Autowired
+    private SysWxSaleAccountMapper sysWxSaleAccountMapper;
+
+    /**
+     * 查询微信销售账号
+     * 
+     * @param id 微信销售账号ID
+     * @return 微信销售账号
+     */
+    @Override
+    public SysWxSaleAccount selectSysWxSaleAccountById(Long id)
+    {
+        return sysWxSaleAccountMapper.selectSysWxSaleAccountById(id);
+    }
+
+    /**
+     * 查询微信销售账号列表
+     * 
+     * @param sysWxSaleAccount 微信销售账号
+     * @return 微信销售账号
+     */
+    @Override
+    public List<SysWxSaleAccount> selectSysWxSaleAccountList(SysWxSaleAccount sysWxSaleAccount)
+    {
+        return sysWxSaleAccountMapper.selectSysWxSaleAccountList(sysWxSaleAccount);
+    }
+
+    /**
+     * 新增微信销售账号
+     * 
+     * @param sysWxSaleAccount 微信销售账号
+     * @return 结果
+     */
+    @Override
+    public int insertSysWxSaleAccount(SysWxSaleAccount sysWxSaleAccount)
+    {
+        return sysWxSaleAccountMapper.insertSysWxSaleAccount(sysWxSaleAccount);
+    }
+
+    /**
+     * 修改微信销售账号
+     * 
+     * @param sysWxSaleAccount 微信销售账号
+     * @return 结果
+     */
+    @Override
+    public int updateSysWxSaleAccount(SysWxSaleAccount sysWxSaleAccount)
+    {
+        return sysWxSaleAccountMapper.updateSysWxSaleAccount(sysWxSaleAccount);
+    }
+
+    /**
+     * 批量删除微信销售账号
+     * 
+     * @param ids 需要删除的微信销售账号ID
+     * @return 结果
+     */
+    @Override
+    public int deleteSysWxSaleAccountByIds(Long[] ids)
+    {
+        return sysWxSaleAccountMapper.deleteSysWxSaleAccountByIds(ids);
+    }
+
+    /**
+     * 删除微信销售账号信息
+     * 
+     * @param id 微信销售账号ID
+     * @return 结果
+     */
+    @Override
+    public int deleteSysWxSaleAccountById(Long id)
+    {
+        return sysWxSaleAccountMapper.deleteSysWxSaleAccountById(id);
+    }
+}
\ No newline at end of file
diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/utils/HttpPostUtil.java b/stdiet-custom/src/main/java/com/stdiet/custom/utils/HttpPostUtil.java
new file mode 100644
index 000000000..5a7e9f087
--- /dev/null
+++ b/stdiet-custom/src/main/java/com/stdiet/custom/utils/HttpPostUtil.java
@@ -0,0 +1,193 @@
+package com.stdiet.custom.utils;
+
+import java.io.*;
+import java.net.HttpURLConnection;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * [url=home.php?mod=space&uid=49329]@author[/url] Sunlight
+ */
+public class HttpPostUtil {
+    private URL url;
+    private HttpURLConnection conn;
+    private String boundary = "--------httppost123";
+    private HashMap<String, String> textParams = new HashMap<String, String>();
+    private HashMap<String, File> fileparams = new HashMap<String, File>();
+    private DataOutputStream outputStream;
+
+    public HttpPostUtil(String url) throws Exception {
+        this.url = new URL(url);
+    }
+
+    /**
+     * 重新设置要请求的服务器地址,即上传文件的地址。
+     *
+     * @param url
+     * @throws Exception
+     */
+    public void setUrl(String url) throws Exception {
+        this.url = new URL(url);
+    }
+
+    /**
+     * 增加一个普通字符串数据到form表单数据中
+     *
+     * @param name
+     * @param value
+     */
+    public void addParameter(String name, String value) {
+        textParams.put(name, value);
+    }
+
+    /**
+     * 增加一个文件到form表单数据中
+     *
+     * @param name
+     * @param value
+     */
+    public void addParameter(String name, File value) {
+        fileparams.put(name, value);
+    }
+
+    /**
+     * 清空所有已添加的form表单数据
+     */
+    public void clearAllParameters() {
+        textParams.clear();
+        fileparams.clear();
+    }
+
+    /**
+     * 发送数据到服务器,返回一个字节包含服务器的返回结果的数组
+     *
+     * @return
+     * @throws Exception
+     */
+    public String send() throws Exception {
+        initConnection();
+        conn.connect();
+        outputStream = new DataOutputStream(conn.getOutputStream());
+        writeFileParams();
+        writeStringParams();
+        paramsEnd();
+        int code = conn.getResponseCode();
+        if (code == 200) {
+            InputStream in = conn.getInputStream();
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            byte[] buf = new byte[1024 * 8];
+            int len;
+            while ((len = in.read(buf)) != -1) {
+                out.write(buf, 0, len);
+            }
+            conn.disconnect();
+            String s = new String(out.toByteArray(), "utf-8");
+            return s;
+        }
+        return null;
+    }
+
+    /**
+     * 文件上传的connection的一些必须设置
+     *
+     * @throws Exception
+     */
+    private void initConnection() throws Exception {
+        conn = (HttpURLConnection) this.url.openConnection();
+        conn.setDoOutput(true);
+        conn.setUseCaches(false);
+        conn.setConnectTimeout(10000); // 连接超时为10秒
+        conn.setRequestMethod("POST");
+        conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
+    }
+
+    /**
+     * 普通字符串数据
+     *
+     * @throws Exception
+     */
+    private void writeStringParams() throws Exception {
+        Set<String> keySet = textParams.keySet();
+        for (Iterator<String> it = keySet.iterator(); it.hasNext(); ) {
+            String name = it.next();
+            String value = textParams.get(name);
+            outputStream.writeBytes("--" + boundary + "\r\n");
+            outputStream.writeBytes("Content-Disposition: form-data; name=" + name + "\r\n");
+            outputStream.writeBytes("\r\n");
+            outputStream.writeBytes(encode(value) + "\r\n");
+        }
+    }
+
+    /**
+     * 文件数据
+     *
+     * @throws Exception
+     */
+    private void writeFileParams() throws Exception {
+        Set<String> keySet = fileparams.keySet();
+        for (Iterator<String> it = keySet.iterator(); it.hasNext(); ) {
+            String name = it.next();
+            File value = fileparams.get(name);
+            outputStream.writeBytes("--" + boundary + "\r\n");
+            outputStream.writeBytes("Content-Disposition: form-data; name=" + name + "; filename=" + encode(value.getName()) + "\r\n");
+            outputStream.writeBytes("Content-Type: " + getContentType(value) + "\r\n");
+            outputStream.writeBytes("\r\n");
+            outputStream.write(getBytes(value));
+            outputStream.writeBytes("\r\n");
+        }
+    }
+
+    /**
+     * 获取文件的上传类型,图片格式为image/png,image/jpeg等。非图片为application /octet-stream
+     *
+     * @param f
+     * @return
+     * @throws Exception
+     */
+    private String getContentType(File f) throws Exception {
+        return "application/octet-stream";
+    }
+
+    /**
+     * 把文件转换成字节数组
+     *
+     * @param f
+     * @return
+     * @throws Exception
+     */
+    private byte[] getBytes(File f) throws Exception {
+        FileInputStream in = new FileInputStream(f);
+        ByteArrayOutputStream out = new ByteArrayOutputStream();
+        byte[] b = new byte[1024];
+        int n;
+        while ((n = in.read(b)) != -1) {
+            out.write(b, 0, n);
+        }
+        in.close();
+        return out.toByteArray();
+    }
+
+    /**
+     * 添加结尾数据
+     *
+     * @throws Exception
+     */
+    private void paramsEnd() throws Exception {
+        outputStream.writeBytes("--" + boundary + "--" + "\r\n");
+        outputStream.writeBytes("\r\n");
+    }
+
+    /**
+     * 对包含中文的字符串进行转码,此为UTF-8。服务器那边要进行一次解码
+     *
+     * @param value
+     * @return
+     * @throws Exception
+     */
+    private String encode(String value) throws Exception {
+        return URLEncoder.encode(value, "UTF-8");
+    }
+}
\ No newline at end of file
diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/utils/WxTokenUtils.java b/stdiet-custom/src/main/java/com/stdiet/custom/utils/WxTokenUtils.java
index a36648bd7..a75365921 100644
--- a/stdiet-custom/src/main/java/com/stdiet/custom/utils/WxTokenUtils.java
+++ b/stdiet-custom/src/main/java/com/stdiet/custom/utils/WxTokenUtils.java
@@ -1,7 +1,6 @@
 package com.stdiet.custom.utils;
 
 import com.alibaba.fastjson.JSONObject;
-import com.stdiet.common.annotation.Log;
 import com.stdiet.common.core.redis.RedisCache;
 import com.stdiet.common.utils.StringUtils;
 import com.stdiet.common.utils.http.HttpUtils;
@@ -10,22 +9,29 @@ import com.stdiet.custom.domain.wechat.WxAccessToken;
 import com.stdiet.custom.domain.wechat.WxFileUploadResult;
 import com.thoughtworks.xstream.XStream;
 import org.apache.commons.io.IOUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 
+import java.io.File;
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
-import java.util.logging.Logger;
 
 public class WxTokenUtils {
 
+    public static final String KEY_ACCESS_TOKEN="wx:access_token";
+    public static final String KEY_ACCESS_TOKEN_WATHER="wx:access_token_watcher";
+
     // 与接口配置信息中的Token要一致
     private static String token = "shengtangdiet";
-//    private static String appId = "wx4a9c1fc9dba53202";
+    //    private static String appId = "wx4a9c1fc9dba53202";
 //    private static String appSecret = "fff029ade5d3575df755f4cf9e52f8da";
-private static String appId = "wxaf10fe560ea043a0";
-        private static String appSecret = "afb47e477337df23b7562c3c1f965826";
+    private static String appId = "wxaf10fe560ea043a0";
+    private static String appSecret = "afb47e477337df23b7562c3c1f965826";
     private static String tokenUrl = "https://api.weixin.qq.com/cgi-bin/token";
+    private static String uploadMaterialUrl = "https://api.weixin.qq.com/cgi-bin/material/add_material";
+
+
 
     public static WxAccessToken fetchAccessToken() {
         try {
@@ -42,9 +48,19 @@ private static String appId = "wxaf10fe560ea043a0";
         }
     }
 
-//    public static WxFileUploadResult uploadImage() {
-//
-//    }
+    public static WxFileUploadResult uploadImage(String filePath, String accessToken) {
+        try {
+            String url = uploadMaterialUrl + "?access_token" + accessToken + "&type=image";
+            HttpPostUtil post = new HttpPostUtil(url);
+            post.addParameter("media", new File(filePath));
+            String resultStr = post.send();
+            JSONObject obj = JSONObject.parseObject(resultStr);
+            WxFileUploadResult result = JSONObject.toJavaObject(obj, WxFileUploadResult.class);
+            return result;
+        } catch (Exception e) {
+            return null;
+        }
+    }
 
     /**
      * 验证签名
diff --git a/stdiet-custom/src/main/resources/mapper/custom/SysWxSaleAccountMapper.xml b/stdiet-custom/src/main/resources/mapper/custom/SysWxSaleAccountMapper.xml
new file mode 100644
index 000000000..26b992bdd
--- /dev/null
+++ b/stdiet-custom/src/main/resources/mapper/custom/SysWxSaleAccountMapper.xml
@@ -0,0 +1,87 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.stdiet.custom.mapper.SysWxSaleAccountMapper">
+
+    <resultMap type="SysWxSaleAccount" id="SysWxSaleAccountResult">
+        <result property="id"    column="id"    />
+        <result property="nickName"    column="nick_name"    />
+        <result property="accountId"    column="account_id"    />
+        <result property="wxId"    column="wx_id"    />
+        <result property="phone"    column="phone"    />
+        <result property="remark"    column="remark"    />
+        <result property="imgUrl"    column="img_url"    />
+        <result property="count"    column="count"    />
+        <result property="mediaId"    column="media_id"    />
+    </resultMap>
+
+    <sql id="selectSysWxSaleAccountVo">
+        select id, nick_name, account_id, wx_id, phone, remark, img_url, count, media_id from sys_wx_sale_account
+    </sql>
+
+    <select id="selectSysWxSaleAccountList" parameterType="SysWxSaleAccount" resultMap="SysWxSaleAccountResult">
+        <include refid="selectSysWxSaleAccountVo"/>
+        <where>
+            <if test="nickName != null  and nickName != ''"> and nick_name like concat('%', #{nickName}, '%')</if>
+            <if test="accountId != null "> and account_id = #{accountId}</if>
+            <if test="phone != null  and phone != ''"> and phone = #{phone}</if>
+        </where>
+    </select>
+
+    <select id="selectSysWxSaleAccountById" parameterType="Long" resultMap="SysWxSaleAccountResult">
+        <include refid="selectSysWxSaleAccountVo"/>
+        where id = #{id}
+    </select>
+
+    <insert id="insertSysWxSaleAccount" parameterType="SysWxSaleAccount" useGeneratedKeys="true" keyProperty="id">
+        insert into sys_wx_sale_account
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="nickName != null">nick_name,</if>
+            <if test="accountId != null">account_id,</if>
+            <if test="wxId != null">wx_id,</if>
+            <if test="phone != null">phone,</if>
+            <if test="remark != null">remark,</if>
+            <if test="imgUrl != null">img_url,</if>
+            <if test="count != null">count,</if>
+            <if test="mediaId != null">media_id,</if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="nickName != null">#{nickName},</if>
+            <if test="accountId != null">#{accountId},</if>
+            <if test="wxId != null">#{wxId},</if>
+            <if test="phone != null">#{phone},</if>
+            <if test="remark != null">#{remark},</if>
+            <if test="imgUrl != null">#{imgUrl},</if>
+            <if test="count != null">#{count},</if>
+            <if test="mediaId != null">#{mediaId},</if>
+        </trim>
+    </insert>
+
+    <update id="updateSysWxSaleAccount" parameterType="SysWxSaleAccount">
+        update sys_wx_sale_account
+        <trim prefix="SET" suffixOverrides=",">
+            <if test="nickName != null">nick_name = #{nickName},</if>
+            <if test="accountId != null">account_id = #{accountId},</if>
+            <if test="wxId != null">wx_id = #{wxId},</if>
+            <if test="phone != null">phone = #{phone},</if>
+            <if test="remark != null">remark = #{remark},</if>
+            <if test="imgUrl != null">img_url = #{imgUrl},</if>
+            <if test="count != null">count = #{count},</if>
+            <if test="mediaId != null">media_id = #{mediaId},</if>
+        </trim>
+        where id = #{id}
+    </update>
+
+    <delete id="deleteSysWxSaleAccountById" parameterType="Long">
+        delete from sys_wx_sale_account where id = #{id}
+    </delete>
+
+    <delete id="deleteSysWxSaleAccountByIds" parameterType="String">
+        delete from sys_wx_sale_account where id in
+        <foreach item="id" collection="array" open="(" separator="," close=")">
+            #{id}
+        </foreach>
+    </delete>
+
+</mapper>
\ No newline at end of file
diff --git a/stdiet-ui/src/api/custom/WxAccount.js b/stdiet-ui/src/api/custom/WxAccount.js
new file mode 100644
index 000000000..19bddf9b5
--- /dev/null
+++ b/stdiet-ui/src/api/custom/WxAccount.js
@@ -0,0 +1,55 @@
+import request from '@/utils/request'
+
+// 查询微信销售账号列表
+export function listWxAccount(query) {
+  return request({
+    url: '/custom/WxAccount/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 查询微信销售账号详细
+export function getWxAccount(id) {
+  return request({
+    url: '/custom/WxAccount/' + id,
+    method: 'get'
+  })
+}
+
+// 新增微信销售账号
+export function addWxAccount(data) {
+  return request({
+    url: '/custom/WxAccount',
+    method: 'post',
+    data: data
+  })
+}
+
+// 修改微信销售账号
+export function updateWxAccount(data) {
+  return request({
+    url: '/custom/WxAccount',
+    method: 'put',
+    data: data
+  })
+}
+
+// 删除微信销售账号
+export function delWxAccount(id) {
+  return request({
+    url: '/custom/WxAccount/' + id,
+    method: 'delete'
+  })
+}
+
+// 导出微信销售账号
+export function exportWxAccount(query) {
+  return request({
+    url: '/custom/WxAccount/export',
+    method: 'get',
+    params: query
+  })
+}
+
+
diff --git a/stdiet-ui/src/views/custom/WxAccount/index.vue b/stdiet-ui/src/views/custom/WxAccount/index.vue
new file mode 100644
index 000000000..cee94ed38
--- /dev/null
+++ b/stdiet-ui/src/views/custom/WxAccount/index.vue
@@ -0,0 +1,420 @@
+<template>
+  <div class="app-container">
+    <el-form :model="queryParams" ref="queryForm" :inline="true" v-show="showSearch" label-width="68px">
+      <el-form-item label="账号名称" prop="nickName">
+        <el-input
+          v-model="queryParams.nickName"
+          placeholder="请输入账号名称"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item label="账号id" prop="accountId">
+        <el-select v-model="queryParams.accountId" placeholder="请选择账号id" clearable size="small">
+          <el-option
+            v-for="dict in accountIdOptions"
+            :key="dict.dictValue"
+            :label="dict.dictLabel"
+            :value="dict.dictValue"
+          />
+        </el-select>
+      </el-form-item>
+      <el-form-item label="手机号" prop="phone">
+        <el-input
+          v-model="queryParams.phone"
+          placeholder="请输入手机号"
+          clearable
+          size="small"
+          @keyup.enter.native="handleQuery"
+        />
+      </el-form-item>
+      <el-form-item>
+        <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+      </el-form-item>
+    </el-form>
+
+    <el-row :gutter="10" class="mb8">
+      <el-col :span="1.5">
+        <el-button
+          type="primary"
+          icon="el-icon-plus"
+          size="mini"
+          @click="handleAdd"
+          v-hasPermi="['custom:WxAccount:add']"
+        >新增
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="success"
+          icon="el-icon-edit"
+          size="mini"
+          :disabled="single"
+          @click="handleUpdate"
+          v-hasPermi="['custom:WxAccount:edit']"
+        >修改
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="danger"
+          icon="el-icon-delete"
+          size="mini"
+          :disabled="multiple"
+          @click="handleDelete"
+          v-hasPermi="['custom:WxAccount:remove']"
+        >删除
+        </el-button>
+      </el-col>
+      <el-col :span="1.5">
+        <el-button
+          type="warning"
+          icon="el-icon-download"
+          size="mini"
+          @click="handleExport"
+          v-hasPermi="['custom:WxAccount:export']"
+        >导出
+        </el-button>
+      </el-col>
+      <right-toolbar :showSearch.sync="showSearch" @queryTable="getList"></right-toolbar>
+    </el-row>
+
+    <el-table v-loading="loading" :data="WxAccountList" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55" align="center"/>
+      <el-table-column label="手机号" align="center" prop="id"/>
+      <el-table-column label="账号名称" align="center" prop="nickName"/>
+      <el-table-column label="账号id" align="center" prop="accountId" :formatter="accountIdFormat"/>
+      <el-table-column label="微信号" align="center" prop="wxId"/>
+      <el-table-column label="手机号" align="center" prop="phone"/>
+      <el-table-column label="手机号" align="center" prop="remark"/>
+      <el-table-column label="二维码图片" align="center" prop="imgUrl"/>
+      <el-table-column label="使用次数" align="center" prop="count"/>
+      <el-table-column label="微信资源id" align="center" prop="mediaId"/>
+      <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="['custom:WxAccount:edit']"
+          >修改
+          </el-button>
+          <el-button
+            size="mini"
+            type="text"
+            icon="el-icon-delete"
+            @click="handleDelete(scope.row)"
+            v-hasPermi="['custom:WxAccount:remove']"
+          >删除
+          </el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+
+    <pagination
+      v-show="total>0"
+      :total="total"
+      :page.sync="queryParams.pageNum"
+      :limit.sync="queryParams.pageSize"
+      @pagination="getList"
+    />
+
+    <!-- 添加或修改微信销售账号对话框 -->
+    <el-dialog :title="title" :visible.sync="open" :close-on-click-modal="false" width="500px" append-to-body>
+      <el-form ref="form" :model="form" :rules="rules" label-width="90px">
+        <el-form-item label="账号昵称" prop="nickName">
+          <el-input v-model="form.nickName" placeholder="请输入账号名称"/>
+        </el-form-item>
+        <el-form-item label="账号id" prop="accountId">
+          <el-select v-model="form.accountId" placeholder="请选择账号id">
+            <el-option
+              v-for="dict in accountIdOptions"
+              :key="dict.dictValue"
+              :label="dict.dictLabel"
+              :value="parseInt(dict.dictValue)"
+            ></el-option>
+          </el-select>
+        </el-form-item>
+        <el-form-item label="微信号" prop="wxId">
+          <el-input v-model="form.wxId" placeholder="请输入微信号"/>
+        </el-form-item>
+        <el-form-item label="手机号" prop="phone">
+          <el-input v-model="form.phone" placeholder="请输入手机号"/>
+        </el-form-item>
+        <el-form-item label="二维码图片" prop="imgUrl">
+          <el-upload
+            class="upload-demo"
+            ref="upload"
+            drag
+            :action="upload.url"
+            :limit="upload.limit"
+            :disabled="upload.isUploading"
+            :file-list="upload.fileList"
+            :multiple="upload.multiple"
+            :on-change="handleFileChange"
+            :on-exceed="handleFileexceed"
+            :on-progress="handleFileUploadProgress"
+            :on-success="handleFileSuccess"
+            :on-error="handleFileFail"
+            :data="upload.data"
+            :auto-upload="true">
+            <i class="el-icon-upload"></i>
+            <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
+            <div class="el-upload__tip" slot="tip">只能上传jpg/png文件,且不超过500kb</div>
+          </el-upload>
+        </el-form-item>
+        <el-form-item label="备注" prop="remark">
+          <el-input v-model="form.remark" placeholder="请输入备注"/>
+        </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 {
+    addWxAccount,
+    delWxAccount,
+    exportWxAccount,
+    getWxAccount,
+    listWxAccount,
+    updateWxAccount
+  } from "@/api/custom/WxAccount";
+
+  export default {
+    name: "WxAccount",
+    data() {
+      return {
+        // 遮罩层
+        loading: true,
+        // 选中数组
+        ids: [],
+        // 非单个禁用
+        single: true,
+        // 非多个禁用
+        multiple: true,
+        // 显示搜索条件
+        showSearch: true,
+        // 总条数
+        total: 0,
+        // 微信销售账号表格数据
+        WxAccountList: [],
+        // 弹出层标题
+        title: "",
+        // 是否显示弹出层
+        open: false,
+        // 账号id字典
+        accountIdOptions: [],
+        // 查询参数
+        queryParams: {
+          pageNum: 1,
+          pageSize: 10,
+          nickName: null,
+          accountId: null,
+          phone: null,
+        },
+        upload: {
+          // 是否禁用上传
+          isUploading: false,
+          // 上传的地址
+          url: process.env.VUE_APP_BASE_API + "/common/wxAccountUpload",
+          // 设置上传的请求头部
+          headers: {},
+          // 其他需要携带的数据
+          data: {},
+          //文件列表
+          fileList: [],
+          //同时上传文件上限
+          limit: 1,
+          //每个文件大小
+          fileSize: 1024 * 500,
+          //是否支持同时选择多张
+          multiple: false
+        },
+        // 表单参数
+        form: {},
+        // 表单校验
+        rules: {}
+      };
+    },
+    created() {
+      this.getList();
+      this.getDicts("cus_account").then(response => {
+        this.accountIdOptions = response.data;
+      });
+    },
+    methods: {
+      /** 查询微信销售账号列表 */
+      getList() {
+        this.loading = true;
+        listWxAccount(this.queryParams).then(response => {
+          this.WxAccountList = response.rows;
+          this.total = response.total;
+          this.loading = false;
+        });
+      },
+      // 账号id字典翻译
+      accountIdFormat(row, column) {
+        return this.selectDictLabel(this.accountIdOptions, row.accountId);
+      },
+      // 取消按钮
+      cancel() {
+        this.open = false;
+        this.reset();
+      },
+      // 表单重置
+      reset() {
+        this.form = {
+          id: null,
+          nickName: null,
+          accountId: null,
+          wxId: null,
+          phone: null,
+          remark: null,
+          imgUrl: null,
+          count: null,
+          mediaId: null
+        };
+        this.resetForm("form");
+      },
+      /** 搜索按钮操作 */
+      handleQuery() {
+        this.queryParams.pageNum = 1;
+        this.getList();
+      },
+      /** 重置按钮操作 */
+      resetQuery() {
+        this.resetForm("queryForm");
+        this.handleQuery();
+      },
+      // 多选框选中数据
+      handleSelectionChange(selection) {
+        this.ids = selection.map(item => item.id)
+        this.single = selection.length !== 1
+        this.multiple = !selection.length
+      },
+      /** 新增按钮操作 */
+      handleAdd() {
+        this.reset();
+        this.open = true;
+        this.title = "添加微信销售账号";
+      },
+      /** 修改按钮操作 */
+      handleUpdate(row) {
+        this.reset();
+        const id = row.id || this.ids
+        getWxAccount(id).then(response => {
+          this.form = response.data;
+          this.open = true;
+          this.title = "修改微信销售账号";
+        });
+      },
+      /** 提交按钮 */
+      submitForm() {
+        this.$refs["form"].validate(valid => {
+          if (valid) {
+            if (this.form.id != null) {
+              updateWxAccount(this.form).then(response => {
+                if (response.code === 200) {
+                  this.msgSuccess("修改成功");
+                  this.open = false;
+                  this.getList();
+                }
+              });
+            } else {
+              addWxAccount(this.form).then(response => {
+                if (response.code === 200) {
+                  this.msgSuccess("新增成功");
+                  this.open = false;
+                  this.getList();
+                }
+              });
+            }
+          }
+        });
+      },
+      /** 删除按钮操作 */
+      handleDelete(row) {
+        const ids = row.id || this.ids;
+        this.$confirm('是否确认删除微信销售账号编号为"' + ids + '"的数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function () {
+          return delWxAccount(ids);
+        }).then(() => {
+          this.getList();
+          this.msgSuccess("删除成功");
+        }).catch(function () {
+        });
+      },
+      /** 导出按钮操作 */
+      handleExport() {
+        const queryParams = this.queryParams;
+        this.$confirm('是否确认导出所有微信销售账号数据项?', "警告", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning"
+        }).then(function () {
+          return exportWxAccount(queryParams);
+        }).then(response => {
+          this.download(response.msg);
+        }).catch(function () {
+        });
+      },
+      //监控上传文件列表
+      handleFileChange(file, fileList) {
+        let sizeFlag = file.size > this.upload.fileSize;
+        if (sizeFlag) {
+          this.$message({
+            message: "当前文件过大",
+            type: "warning",
+          });
+          fileList.pop();
+        }
+        this.upload.fileList = fileList;
+
+      },
+      // 文件数量超过限度
+      handleFileexceed(file, fileList) {
+        //console.log(this.upload.fileList.length);
+        this.$message({
+          message: "最多可上传" + this.upload.limit + "份文件",
+          type: "warning",
+        });
+      },
+      // 文件上传中处理
+      handleFileUploadProgress(event, file, fileList) {
+        this.upload.isUploading = true;
+      },
+      // 文件上传成功处理
+      handleFileSuccess(response, file, fileList) {
+        if (response != null && response.code === 200) {
+          this.form.imgUrl = response.fileName;
+          console.log(response)
+        } else {
+          this.fail();
+          this.$message.error(response.msg);
+        }
+      },
+      // 文件上传失败处理
+      handleFileFail(err, file, fileList) {
+        if (err) {
+          this.$message.error('文件上传失败,请检查文件格式');
+          this.fail();
+        }
+      },
+      fail() {
+        this.submitFlag = false;
+        this.upload.isUploading = false;
+      },
+    }
+  };
+</script>