1.3.3新增 后台微信图文发送功能,小程序配置,增加小程序授权等,修复一些bug等
This commit is contained in:
@ -23,16 +23,16 @@
|
||||
<artifactId>wx-java-pay-spring-boot-starter</artifactId>
|
||||
<version>3.5.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.binarywang</groupId>
|
||||
<artifactId>wx-java-miniapp-spring-boot-starter</artifactId>
|
||||
<version>3.5.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>co.yixiang</groupId>
|
||||
<artifactId>yshop-common</artifactId>
|
||||
<version>1.3</version>
|
||||
</dependency>
|
||||
<!-- <dependency>-->
|
||||
<!-- <groupId>com.github.binarywang</groupId>-->
|
||||
<!-- <artifactId>wx-java-miniapp-spring-boot-starter</artifactId>-->
|
||||
<!-- <version>3.5.0</version>-->
|
||||
<!-- </dependency>-->
|
||||
</dependencies>
|
||||
|
||||
|
||||
|
@ -1,15 +1,19 @@
|
||||
package co.yixiang.mp.config;
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import co.yixiang.mp.handler.*;
|
||||
import co.yixiang.utils.RedisUtil;
|
||||
import lombok.AllArgsConstructor;
|
||||
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
|
||||
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
|
||||
import org.apache.poi.util.StringUtil;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ -41,13 +45,40 @@ public class WxMpConfiguration {
|
||||
private final SubscribeHandler subscribeHandler;
|
||||
private final ScanHandler scanHandler;
|
||||
private final WxMpProperties properties;
|
||||
private final RedisHandler redisHandler;
|
||||
|
||||
@Bean
|
||||
public WxMpService wxMpService() {
|
||||
// 代码里 getConfigs()处报错的同学,请注意仔细阅读项目说明,你的IDE需要引入lombok插件!!!!
|
||||
final List<WxMpProperties.MpConfig> configs = this.properties.getConfigs();
|
||||
System.out.println(configs);
|
||||
if (configs == null) {
|
||||
|
||||
final List<WxMpProperties.MpConfig> configs = new ArrayList<>();
|
||||
WxMpProperties.MpConfig mpConfig = new WxMpProperties.MpConfig();
|
||||
String appId = redisHandler.getVal("wechat_appid");
|
||||
String secret = redisHandler.getVal("wechat_appsecret");
|
||||
String token = redisHandler.getVal("wechat_token");
|
||||
String aesKey = redisHandler.getVal("wechat_encodingaeskey");
|
||||
|
||||
|
||||
if(StrUtil.isNotBlank(appId) && StrUtil.isNotBlank(secret)
|
||||
&& StrUtil.isNotBlank(token) && StrUtil.isNotBlank(aesKey)) {
|
||||
mpConfig.setAppId(appId);
|
||||
mpConfig.setSecret(secret);
|
||||
mpConfig.setToken(token);
|
||||
mpConfig.setAesKey(aesKey);
|
||||
System.out.println(mpConfig);
|
||||
|
||||
configs.add(mpConfig);
|
||||
}else{
|
||||
mpConfig.setAppId("111111");
|
||||
mpConfig.setSecret("111111");
|
||||
mpConfig.setToken("111111");
|
||||
mpConfig.setAesKey("111111");
|
||||
|
||||
configs.add(mpConfig);
|
||||
}
|
||||
|
||||
//System.out.println("configs:"+configs);
|
||||
|
||||
if (configs.isEmpty()) {
|
||||
throw new RuntimeException("请先配置!");
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,11 @@
|
||||
package co.yixiang.mp.controller;
|
||||
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import co.yixiang.exception.BadRequestException;
|
||||
import co.yixiang.mp.domain.YxArticle;
|
||||
import co.yixiang.mp.service.YxArticleService;
|
||||
import co.yixiang.mp.service.dto.YxArticleDTO;
|
||||
import co.yixiang.mp.service.dto.YxArticleQueryCriteria;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
@ -57,6 +60,7 @@ public class YxArticleController {
|
||||
@DeleteMapping(value = "/yxArticle/{id}")
|
||||
@PreAuthorize("hasAnyRole('ADMIN','YXARTICLE_ALL','YXARTICLE_DELETE')")
|
||||
public ResponseEntity delete(@PathVariable Integer id){
|
||||
//if(id > 0) throw new BadRequestException("演示环境禁止操作");
|
||||
yxArticleService.delete(id);
|
||||
return new ResponseEntity(HttpStatus.OK);
|
||||
}
|
||||
@ -64,8 +68,10 @@ public class YxArticleController {
|
||||
@ApiOperation(value = "发布文章")
|
||||
@GetMapping(value = "/yxArticle/publish/{id}")
|
||||
@PreAuthorize("hasAnyRole('ADMIN','YXARTICLE_ALL','YXARTICLE_DELETE')")
|
||||
public ResponseEntity publish(@PathVariable Integer id){
|
||||
//todo
|
||||
public ResponseEntity publish(@PathVariable Integer id) throws Exception{
|
||||
//if(id > 0) throw new BadRequestException("演示环境禁止操作");
|
||||
YxArticleDTO yxArticleDTO= yxArticleService.findById(id);
|
||||
yxArticleService.uploadNews(yxArticleDTO);
|
||||
return new ResponseEntity(HttpStatus.OK);
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
package co.yixiang.mp.controller;
|
||||
|
||||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import co.yixiang.exception.BadRequestException;
|
||||
import co.yixiang.mp.domain.YxCache;
|
||||
import co.yixiang.mp.service.YxCacheService;
|
||||
import co.yixiang.utils.OrderUtil;
|
||||
@ -62,6 +64,7 @@ public class YxCacheController {
|
||||
yxCacheService.create(yxCache);
|
||||
}
|
||||
|
||||
System.out.println("menu:"+menu);
|
||||
|
||||
//创建菜单
|
||||
try {
|
||||
|
@ -1,6 +1,8 @@
|
||||
package co.yixiang.mp.controller;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import co.yixiang.exception.BadRequestException;
|
||||
import co.yixiang.mp.domain.YxWechatReply;
|
||||
import co.yixiang.mp.service.YxWechatReplyService;
|
||||
import com.alibaba.fastjson.JSON;
|
||||
@ -39,6 +41,7 @@ public class YxWechatReplyController {
|
||||
@PostMapping(value = "/yxWechatReply")
|
||||
@PreAuthorize("hasAnyRole('ADMIN','YXWECHATREPLY_ALL','YXWECHATREPLY_CREATE')")
|
||||
public ResponseEntity create(@RequestBody String jsonStr){
|
||||
//if(StrUtil.isNotEmpty(jsonStr)) throw new BadRequestException("演示环境禁止操作");
|
||||
JSONObject jsonObject = JSON.parseObject(jsonStr);
|
||||
YxWechatReply yxWechatReply = new YxWechatReply();
|
||||
YxWechatReply isExist = yxWechatReplyService.isExist(jsonObject.get("key").toString());
|
||||
|
@ -0,0 +1,31 @@
|
||||
package co.yixiang.mp.handler;
|
||||
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
||||
@Component
|
||||
public class RedisHandler{
|
||||
|
||||
@Autowired
|
||||
RedisTemplate redisTemplate;
|
||||
|
||||
|
||||
public String getVal(String key) {
|
||||
try {
|
||||
String value = redisTemplate.opsForValue().get(key).toString();
|
||||
return value;
|
||||
}catch (Exception e){
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Object getObj(String key) {
|
||||
return redisTemplate.opsForValue().get(key);
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -31,9 +31,6 @@ public class SubscribeHandler extends AbstractHandler {
|
||||
WxSessionManager sessionManager) throws WxErrorException {
|
||||
|
||||
|
||||
//System.out.println("wxMessage:"+wxMessage);
|
||||
//System.out.println("context:"+context);
|
||||
|
||||
YxWechatReply wechatReply = yxWechatReplyService.isExist("subscribe");
|
||||
if(ObjectUtil.isNull(wechatReply)){
|
||||
|
||||
@ -42,15 +39,12 @@ public class SubscribeHandler extends AbstractHandler {
|
||||
|
||||
String str = JSONObject.parseObject(wechatReply.getData()).getString("content");
|
||||
try {
|
||||
//String str = new String(wechatReply.getData().getBytes(),"utf-8");
|
||||
WxMpXmlOutMessage msg= WxMpXmlOutMessage.TEXT()
|
||||
.content(str)
|
||||
.fromUser(wxMessage.getToUser())
|
||||
.toUser(wxMessage.getFromUser())
|
||||
.build();
|
||||
//System.out.println(msg);
|
||||
return msg;
|
||||
//return new TextBuilder().build(str, wxMessage, weixinService);
|
||||
} catch (Exception e) {
|
||||
this.logger.error(e.getMessage(), e);
|
||||
}
|
||||
|
@ -62,4 +62,7 @@ public interface YxArticleService {
|
||||
*/
|
||||
//@CacheEvict(allEntries = true)
|
||||
void delete(Integer id);
|
||||
|
||||
void uploadNews(YxArticleDTO yxArticleDTO) throws Exception;
|
||||
|
||||
}
|
@ -70,4 +70,6 @@ public class YxArticleDTO implements Serializable {
|
||||
|
||||
// 是否轮播图(小程序)
|
||||
private Integer isBanner;
|
||||
|
||||
private String thumbMediaId;
|
||||
}
|
@ -1,23 +1,42 @@
|
||||
package co.yixiang.mp.service.impl;
|
||||
|
||||
|
||||
import cn.hutool.core.io.FileUtil;
|
||||
import cn.hutool.core.util.ReUtil;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import cn.hutool.json.JSONUtil;
|
||||
import co.yixiang.exception.ErrorRequestException;
|
||||
import co.yixiang.mp.domain.YxArticle;
|
||||
import co.yixiang.mp.repository.YxArticleRepository;
|
||||
import co.yixiang.mp.service.YxArticleService;
|
||||
import co.yixiang.mp.service.dto.YxArticleDTO;
|
||||
import co.yixiang.mp.service.dto.YxArticleQueryCriteria;
|
||||
import co.yixiang.mp.service.mapper.YxArticleMapper;
|
||||
import co.yixiang.mp.utils.URLUtils;
|
||||
import co.yixiang.utils.OrderUtil;
|
||||
import co.yixiang.utils.PageUtil;
|
||||
import co.yixiang.utils.QueryHelp;
|
||||
import co.yixiang.utils.ValidationUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import me.chanjar.weixin.common.api.WxConsts;
|
||||
import me.chanjar.weixin.common.error.WxErrorException;
|
||||
import me.chanjar.weixin.mp.api.WxMpService;
|
||||
import me.chanjar.weixin.mp.bean.WxMpMassTagMessage;
|
||||
import me.chanjar.weixin.mp.bean.material.WxMediaImgUploadResult;
|
||||
import me.chanjar.weixin.mp.bean.material.WxMpMaterial;
|
||||
import me.chanjar.weixin.mp.bean.material.WxMpMaterialNews;
|
||||
import me.chanjar.weixin.mp.bean.material.WxMpMaterialUploadResult;
|
||||
import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Propagation;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@ -26,6 +45,7 @@ import java.util.Optional;
|
||||
* @author hupeng
|
||||
* @date 2019-10-07
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
|
||||
public class YxArticleServiceImpl implements YxArticleService {
|
||||
@ -36,6 +56,12 @@ public class YxArticleServiceImpl implements YxArticleService {
|
||||
@Autowired
|
||||
private YxArticleMapper yxArticleMapper;
|
||||
|
||||
@Autowired
|
||||
private WxMpService wxMpService;
|
||||
|
||||
@Value("${file.path}")
|
||||
private String uploadDirStr;
|
||||
|
||||
@Override
|
||||
public Map<String,Object> queryAll(YxArticleQueryCriteria criteria, Pageable pageable){
|
||||
Page<YxArticle> page = yxArticleRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
|
||||
@ -76,4 +102,97 @@ public class YxArticleServiceImpl implements YxArticleService {
|
||||
public void delete(Integer id) {
|
||||
yxArticleRepository.deleteById(id);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void uploadNews(YxArticleDTO wxNewsArticleItem) throws Exception {
|
||||
|
||||
WxMpMaterialNews wxMpMaterialNews = new WxMpMaterialNews();
|
||||
|
||||
|
||||
WxMpMaterialNews.WxMpMaterialNewsArticle article = new WxMpMaterialNews.WxMpMaterialNewsArticle();
|
||||
|
||||
WxMpMaterialUploadResult wxMpMaterialUploadResult = uploadPhotoToWx( wxMpService,
|
||||
wxNewsArticleItem.getImageInput() );
|
||||
wxNewsArticleItem.setThumbMediaId( wxMpMaterialUploadResult.getMediaId() );
|
||||
|
||||
article.setAuthor( wxNewsArticleItem.getAuthor() );
|
||||
|
||||
System.out.println(wxNewsArticleItem.getContent());
|
||||
|
||||
//处理content
|
||||
String content = processContent(wxMpService, wxNewsArticleItem.getContent());
|
||||
System.out.println(content);
|
||||
article.setContent( content );
|
||||
article.setContentSourceUrl( wxNewsArticleItem.getUrl() );
|
||||
article.setDigest( wxNewsArticleItem.getSynopsis() );
|
||||
article.setShowCoverPic( true );
|
||||
article.setThumbMediaId( wxNewsArticleItem.getThumbMediaId() );
|
||||
article.setTitle( wxNewsArticleItem.getTitle() );
|
||||
//TODO 暂时注释掉,测试号没有留言权限
|
||||
//article.setNeedOpenComment( wxNewsArticleItem );
|
||||
//article.setOnlyFansCanComment( wxNewsArticleItem );
|
||||
wxMpMaterialNews.addArticle( article );
|
||||
|
||||
log.info( "wxMpMaterialNews : {}", JSONUtil.toJsonStr( wxMpMaterialNews ) );
|
||||
|
||||
WxMpMaterialUploadResult wxMpMaterialUploadResult1 = wxMpService.getMaterialService()
|
||||
.materialNewsUpload( wxMpMaterialNews );
|
||||
|
||||
//推送开始
|
||||
WxMpMassTagMessage massMessage = new WxMpMassTagMessage();
|
||||
massMessage.setMsgType(WxConsts.MassMsgType.MPNEWS);
|
||||
massMessage.setMediaId(wxMpMaterialUploadResult1.getMediaId());
|
||||
massMessage.setSendAll(true);
|
||||
|
||||
WxMpMassSendResult massResult = wxMpService.getMassMessageService()
|
||||
.massGroupMessageSend(massMessage);
|
||||
if(!massResult.getErrorCode().equals("0")) {
|
||||
log.info("error:"+massResult.getErrorMsg());
|
||||
throw new ErrorRequestException("发送失败");
|
||||
}
|
||||
|
||||
log.info( "massResult : {}", JSONUtil.toJsonStr( massResult ) );
|
||||
|
||||
log.info( "wxMpMaterialUploadResult : {}", JSONUtil.toJsonStr( wxMpMaterialUploadResult1 ) );
|
||||
}
|
||||
|
||||
|
||||
private WxMpMaterialUploadResult uploadPhotoToWx(WxMpService wxMpService, String picPath) throws WxErrorException {
|
||||
WxMpMaterial wxMpMaterial = new WxMpMaterial();
|
||||
|
||||
String filename = String.valueOf( System.currentTimeMillis() ) + ".png";
|
||||
String downloadPath = uploadDirStr + filename;
|
||||
long size = HttpUtil.downloadFile(picPath, FileUtil.file(downloadPath));
|
||||
picPath = downloadPath;
|
||||
File picFile = new File( picPath );
|
||||
wxMpMaterial.setFile( picFile );
|
||||
wxMpMaterial.setName( picFile.getName() );
|
||||
log.info( "picFile name : {}", picFile.getName() );
|
||||
WxMpMaterialUploadResult wxMpMaterialUploadResult = wxMpService.getMaterialService().materialFileUpload( WxConsts.MediaFileType.IMAGE, wxMpMaterial );
|
||||
log.info( "wxMpMaterialUploadResult : {}", JSONUtil.toJsonStr( wxMpMaterialUploadResult ) );
|
||||
return wxMpMaterialUploadResult;
|
||||
}
|
||||
|
||||
private String processContent(WxMpService wxMpService,String content) throws WxErrorException {
|
||||
if(StringUtils.isBlank( content )){
|
||||
return content;
|
||||
}
|
||||
String imgReg = "<img[^>]+src\\s*=\\s*['\"]([^'\"]+)['\"][^>]*>";
|
||||
List<String> imgList = ReUtil.findAllGroup1( imgReg,content);
|
||||
for (int j = 0; j < imgList.size(); j++) {
|
||||
String imgSrc = imgList.get( j );
|
||||
String filepath = URLUtils.getParam( imgSrc,"filepath" );
|
||||
|
||||
if(StringUtils.isBlank( filepath )){//网络图片URL,需下载到本地
|
||||
String filename = String.valueOf( System.currentTimeMillis() ) + ".png";
|
||||
String downloadPath = uploadDirStr + filename;
|
||||
long size = HttpUtil.downloadFile(imgSrc, FileUtil.file(downloadPath));
|
||||
filepath = downloadPath;
|
||||
}
|
||||
WxMediaImgUploadResult wxMediaImgUploadResult = wxMpService.getMaterialService().mediaImgUpload( new File(filepath) );
|
||||
content = StringUtils.replace( content,imgList.get( j ),wxMediaImgUploadResult.getUrl());
|
||||
}
|
||||
return content;
|
||||
}
|
||||
}
|
76
yshop-mp/src/main/java/co/yixiang/mp/utils/URLUtils.java
Normal file
76
yshop-mp/src/main/java/co/yixiang/mp/utils/URLUtils.java
Normal file
@ -0,0 +1,76 @@
|
||||
package co.yixiang.mp.utils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* URLUtils
|
||||
* @author Kevin
|
||||
* @date 2019-03-20 13:39
|
||||
*/
|
||||
public class URLUtils {
|
||||
|
||||
/**
|
||||
* 获取URL中的某个参数
|
||||
* @param url
|
||||
* @param name
|
||||
* @return
|
||||
*/
|
||||
public static String getParam(String url, String name) {
|
||||
return urlSplit(url).get( name );
|
||||
}
|
||||
|
||||
/**
|
||||
* 去掉url中的路径,留下请求参数部分
|
||||
* @param strURL url地址
|
||||
* @return url请求参数部分
|
||||
*/
|
||||
private static String truncateUrlPage(String strURL){
|
||||
String strAllParam=null;
|
||||
String[] arrSplit=null;
|
||||
strURL=strURL.trim().toLowerCase();
|
||||
arrSplit=strURL.split("[?]");
|
||||
if(strURL.length()>1){
|
||||
if(arrSplit.length>1){
|
||||
for (int i=1;i<arrSplit.length;i++){
|
||||
strAllParam = arrSplit[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
return strAllParam;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析出url参数中的键值对
|
||||
* 如 "index.jsp?Action=del&id=123",解析出Action:del,id:123存入map中
|
||||
* @param URL url地址
|
||||
* @return url请求参数部分
|
||||
*/
|
||||
public static Map<String, String> urlSplit(String URL){
|
||||
Map<String, String> mapRequest = new HashMap<String, String>();
|
||||
String[] arrSplit=null;
|
||||
String strUrlParam= truncateUrlPage(URL);
|
||||
if(strUrlParam==null){
|
||||
return mapRequest;
|
||||
}
|
||||
arrSplit=strUrlParam.split("[&]");
|
||||
for(String strSplit:arrSplit){
|
||||
String[] arrSplitEqual=null;
|
||||
arrSplitEqual= strSplit.split("[=]");
|
||||
//解析出键值
|
||||
if(arrSplitEqual.length>1){
|
||||
//正确解析
|
||||
mapRequest.put(arrSplitEqual[0], arrSplitEqual[1]);
|
||||
}else{
|
||||
if(arrSplitEqual[0]!=""){
|
||||
//只有参数没有值,不加入
|
||||
mapRequest.put(arrSplitEqual[0], "");
|
||||
}
|
||||
}
|
||||
}
|
||||
return mapRequest;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
Reference in New Issue
Block a user