diff --git a/bin/build-server.sh b/bin/build-server.sh index 2f704019a..aa4dc468b 100755 --- a/bin/build-server.sh +++ b/bin/build-server.sh @@ -1,6 +1,6 @@ #!/usr/bin/sh cd /home/workspace/ShengTangManage -git pull origin master +git pull mvn clean package -Dmaven.test.skip=true -P prod rm -f /home/api/manage.shengtangdiet.com/st-manage.jar cp -f ./stdiet-admin/target/stdiet-admin.jar /home/api/manage.shengtangdiet.com/st-manage.jar diff --git a/bin/build-test-web.sh b/bin/build-test-web.sh index d6dc7f1c5..21c481e00 100755 --- a/bin/build-test-web.sh +++ b/bin/build-test-web.sh @@ -1,6 +1,6 @@ #!/usr/bin/sh cd /home/workspace/ShengTangManage/stdiet-ui -git pull origin master +git pull yarn yarn build:stage rm -rf /home/web/test.stdiet/dist diff --git a/bin/build-web.sh b/bin/build-web.sh index eba494e1d..bb40b3628 100755 --- a/bin/build-web.sh +++ b/bin/build-web.sh @@ -1,6 +1,6 @@ #!/usr/bin/sh cd /home/workspace/ShengTangManage/stdiet-ui -git pull origin master +git pull yarn yarn build:prod rm -rf /home/web/manage.shengtangdiet.com/dist 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/CusWxController.java b/stdiet-admin/src/main/java/com/stdiet/web/controller/custom/CusWxController.java index 30728d62a..d04cb42e2 100644 --- a/stdiet-admin/src/main/java/com/stdiet/web/controller/custom/CusWxController.java +++ b/stdiet-admin/src/main/java/com/stdiet/web/controller/custom/CusWxController.java @@ -2,14 +2,11 @@ package com.stdiet.web.controller.custom; import com.stdiet.common.core.controller.BaseController; import com.stdiet.common.core.domain.AjaxResult; -import com.stdiet.custom.domain.WxXmlData; import com.stdiet.custom.service.ISysWxService; -import com.thoughtworks.xstream.XStream; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; -import javax.xml.bind.annotation.XmlMimeType; @RestController @RequestMapping("/wx") @@ -24,8 +21,13 @@ public class CusWxController extends BaseController { } @PostMapping("/checkSign") - public String autoResonse(HttpServletRequest request){ + public String autoResponse(HttpServletRequest request) { return sysWxService.autoResponse(request); } + @GetMapping("/accessToken") + public AjaxResult getAccessToken() { + return sysWxService.getAccessToken(); + } + } 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 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 list = sysWxSaleAccountService.selectSysWxSaleAccountList(sysWxSaleAccount); + ExcelUtil util = new ExcelUtil(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 void setCacheObject(final String key, final T value) - { + public 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 void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) - { + public 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 getCacheObject(final String key) - { + public T getCacheObject(final String key) { ValueOperations 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 long setCacheList(final String key, final List dataList) - { + public long setCacheList(final String key, final List dataList) { Long count = redisTemplate.opsForList().rightPushAll(key, dataList); return count == null ? 0 : count; } @@ -124,20 +117,18 @@ public class RedisCache * @param key 缓存的键值 * @return 缓存键值对应的数据 */ - public List getCacheList(final String key) - { + public List getCacheList(final String key) { return redisTemplate.opsForList().range(key, 0, -1); } /** * 缓存Set * - * @param key 缓存键值 + * @param key 缓存键值 * @param dataSet 缓存的数据 * @return 缓存数据的对象 */ - public long setCacheSet(final String key, final Set dataSet) - { + public long setCacheSet(final String key, final Set dataSet) { Long count = redisTemplate.opsForSet().add(key, dataSet); return count == null ? 0 : count; } @@ -148,8 +139,7 @@ public class RedisCache * @param key * @return */ - public Set getCacheSet(final String key) - { + public Set getCacheSet(final String key) { return redisTemplate.opsForSet().members(key); } @@ -159,8 +149,7 @@ public class RedisCache * @param key * @param dataMap */ - public void setCacheMap(final String key, final Map dataMap) - { + public void setCacheMap(final String key, final Map dataMap) { if (dataMap != null) { redisTemplate.opsForHash().putAll(key, dataMap); } @@ -172,32 +161,29 @@ public class RedisCache * @param key * @return */ - public Map getCacheMap(final String key) - { + public Map 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 void setCacheMapValue(final String key, final String hKey, final T value) - { + public 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 getCacheMapValue(final String key, final String hKey) - { + public T getCacheMapValue(final String key, final String hKey) { HashOperations 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 List getMultiCacheMapValue(final String key, final Collection hKeys) - { + public List getMultiCacheMapValue(final String key, final Collection hKeys) { return redisTemplate.opsForHash().multiGet(key, hKeys); } @@ -220,8 +205,7 @@ public class RedisCache * @param pattern 字符串前缀 * @return 对象列表 */ - public Collection keys(final String pattern) - { + public Collection 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/domain/wechat/WxAccessToken.java b/stdiet-custom/src/main/java/com/stdiet/custom/domain/wechat/WxAccessToken.java new file mode 100644 index 000000000..079dcf14e --- /dev/null +++ b/stdiet-custom/src/main/java/com/stdiet/custom/domain/wechat/WxAccessToken.java @@ -0,0 +1,15 @@ +package com.stdiet.custom.domain.wechat; + +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Data; + +import java.io.Serializable; + +@Data +public class WxAccessToken implements Serializable { + @JSONField(name = "access_token") + private String accessToken; + + @JSONField(name = "expires_in") + private Integer expiresIn; +} diff --git a/stdiet-custom/src/main/java/com/stdiet/custom/domain/wechat/WxFileUploadResult.java b/stdiet-custom/src/main/java/com/stdiet/custom/domain/wechat/WxFileUploadResult.java new file mode 100644 index 000000000..53632c655 --- /dev/null +++ b/stdiet-custom/src/main/java/com/stdiet/custom/domain/wechat/WxFileUploadResult.java @@ -0,0 +1,16 @@ +package com.stdiet.custom.domain.wechat; + +import com.alibaba.fastjson.annotation.JSONField; +import lombok.Data; + +import java.io.Serializable; + +@Data +public class WxFileUploadResult implements Serializable { + + @JSONField(name = "media_id") + private String mediaId; + + @JSONField(name = "url") + private String url; +} 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 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 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/ISysWxService.java b/stdiet-custom/src/main/java/com/stdiet/custom/service/ISysWxService.java index 50a87eec6..d45fc3f63 100644 --- a/stdiet-custom/src/main/java/com/stdiet/custom/service/ISysWxService.java +++ b/stdiet-custom/src/main/java/com/stdiet/custom/service/ISysWxService.java @@ -1,5 +1,6 @@ package com.stdiet.custom.service; +import com.stdiet.common.core.domain.AjaxResult; import com.stdiet.custom.domain.WxXmlData; import javax.servlet.http.HttpServletRequest; @@ -16,4 +17,6 @@ public interface ISysWxService { public String wxCheckAuth(String signature, String timestamp, String nonce, String echostr); public String autoResponse(HttpServletRequest request); + + public AjaxResult getAccessToken(); } 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 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/service/impl/SysWxServiceImpl.java b/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysWxServiceImpl.java index 382eea3e9..d860fdb79 100644 --- a/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysWxServiceImpl.java +++ b/stdiet-custom/src/main/java/com/stdiet/custom/service/impl/SysWxServiceImpl.java @@ -1,5 +1,6 @@ package com.stdiet.custom.service.impl; +import com.stdiet.common.core.domain.AjaxResult; import com.stdiet.common.utils.StringUtils; import com.stdiet.custom.domain.WxXmlData; import com.stdiet.custom.service.ISysWxService; @@ -29,7 +30,7 @@ public class SysWxServiceImpl implements ISysWxService { WxXmlData resultXmlData = new WxXmlData(); resultXmlData.setToUserName(wxData.getFromUserName()); //收到的消息是谁发来的再发给谁 resultXmlData.setFromUserName(wxData.getToUserName()); // - if (!StringUtils.isEmpty(wxData.getEvent())) { + if (wxData.getMsgType().equals(WechatMessageUtil.MESSAGE_EVENT)) { if (wxData.getEvent().equals(WechatMessageUtil.MESSAGE_EVENT_SUBSCRIBE)) { resultXmlData.setMsgType("text"); resultXmlData.setCreateTime(System.currentTimeMillis()); @@ -37,7 +38,7 @@ public class SysWxServiceImpl implements ISysWxService { } else if (wxData.getEvent().equals(WechatMessageUtil.MESSAGE_EVENT_UNSUBSCRIBE)) { } - } else if (wxData.getContent().equalsIgnoreCase("vip")) { + } else if (wxData.getMsgType().equals(WechatMessageUtil.MESSAGE_TEXT)) { resultXmlData.setMsgType("text"); resultXmlData.setCreateTime(System.currentTimeMillis()); resultXmlData.setContent("点击该链接,获取博客解锁验证码"); @@ -55,4 +56,10 @@ public class SysWxServiceImpl implements ISysWxService { } } + @Override + public AjaxResult getAccessToken() { + return AjaxResult.success(WxTokenUtils.fetchAccessToken()); + } + + } 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 textParams = new HashMap(); + private HashMap fileparams = new HashMap(); + 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 keySet = textParams.keySet(); + for (Iterator 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 keySet = fileparams.keySet(); + for (Iterator 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 8d1599e02..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,9 +1,17 @@ package com.stdiet.custom.utils; +import com.alibaba.fastjson.JSONObject; +import com.stdiet.common.core.redis.RedisCache; +import com.stdiet.common.utils.StringUtils; +import com.stdiet.common.utils.http.HttpUtils; import com.stdiet.custom.domain.WxXmlData; +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; @@ -11,8 +19,48 @@ import java.security.NoSuchAlgorithmException; 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 appSecret = "fff029ade5d3575df755f4cf9e52f8da"; + 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 { + String resStr = HttpUtils.sendGet(tokenUrl, "grant_type=client_credential&appid=" + appId + "&secret=" + appSecret); + if (StringUtils.isEmpty(resStr)) { + return null; + } + JSONObject obj = JSONObject.parseObject(resStr); + + WxAccessToken token = JSONObject.toJavaObject(obj, WxAccessToken.class); + return token; + } catch (Exception e) { + return null; + } + } + + 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 @@ + + + + + + + + + + + + + + + + + + select id, nick_name, account_id, wx_id, phone, remark, img_url, count, media_id from sys_wx_sale_account + + + + + + + + insert into sys_wx_sale_account + + nick_name, + account_id, + wx_id, + phone, + remark, + img_url, + count, + media_id, + + + #{nickName}, + #{accountId}, + #{wxId}, + #{phone}, + #{remark}, + #{imgUrl}, + #{count}, + #{mediaId}, + + + + + update sys_wx_sale_account + + nick_name = #{nickName}, + account_id = #{accountId}, + wx_id = #{wxId}, + phone = #{phone}, + remark = #{remark}, + img_url = #{imgUrl}, + count = #{count}, + media_id = #{mediaId}, + + where id = #{id} + + + + delete from sys_wx_sale_account where id = #{id} + + + + delete from sys_wx_sale_account where id in + + #{id} + + + + \ 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 @@ + + +