完成小程序消息订阅

This commit is contained in:
huangdeliang 2021-05-18 14:02:56 +08:00
parent 2e83c4be3c
commit 55a7e5e54f
22 changed files with 231 additions and 658 deletions

11
pom.xml
View File

@ -204,6 +204,17 @@
<artifactId>vod20170321</artifactId> <artifactId>vod20170321</artifactId>
<version>2.0.0</version> <version>2.0.0</version>
</dependency> </dependency>
<!-- 阿里云短信-->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.0.6</version> <!-- 注:如提示报错,先升级基础包版,无法解决可联系技术支持 -->
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-dysmsapi</artifactId>
<version>1.1.0</version>
</dependency>
</dependencies> </dependencies>
<modules> <modules>

View File

@ -7,11 +7,7 @@ import com.stdiet.common.core.redis.RedisCache;
import com.stdiet.common.utils.StringUtils; import com.stdiet.common.utils.StringUtils;
import com.stdiet.common.utils.file.FileUploadUtils; import com.stdiet.common.utils.file.FileUploadUtils;
import com.stdiet.common.utils.file.FileUtils; 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 com.stdiet.framework.config.ServerConfig;
import org.aspectj.weaver.loadtime.Aj;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -23,7 +19,6 @@ import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.net.URLDecoder; import java.net.URLDecoder;
import java.util.concurrent.TimeUnit;
/** /**
* 通用请求处理 * 通用请求处理

View File

@ -1,43 +0,0 @@
package com.stdiet.web.controller.custom;
import com.stdiet.common.core.controller.BaseController;
import com.stdiet.common.core.domain.AjaxResult;
import com.stdiet.common.core.redis.RedisCache;
import com.stdiet.custom.service.ISysWxService;
import com.stdiet.custom.utils.WxTokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
@RestController
@RequestMapping("/wx")
public class CusWxController extends BaseController {
@Autowired
public ISysWxService sysWxService;
@Autowired
public RedisCache redisCache;
@GetMapping("/checkSign")
public String wxCheckAuth(@RequestParam String signature, @RequestParam String timestamp, @RequestParam String nonce, @RequestParam String echostr) {
return sysWxService.wxCheckAuth(signature, timestamp, nonce, echostr);
}
@PostMapping("/checkSign")
public String autoResponse(HttpServletRequest request) {
return sysWxService.autoResponse(request);
}
@GetMapping("/accessToken")
public AjaxResult getAccessToken() {
return sysWxService.getAccessToken();
}
@GetMapping("/clearAccessToken")
public AjaxResult clearAccessToken() {
redisCache.deleteObject(WxTokenUtils.KEY_ACCESS_TOKEN);
return AjaxResult.success();
}
}

View File

@ -576,7 +576,7 @@ public class WechatAppletController extends BaseController {
@GetMapping("/subscribe/post") @GetMapping("/subscribe/post")
public AjaxResult subscribePost(@RequestParam Long cusId, @RequestParam Long planId, @RequestParam String name, @RequestParam String startDate, @RequestParam String endDate, @RequestParam String remark) { public AjaxResult subscribePost(@RequestParam Long cusId, @RequestParam Long planId, @RequestParam String name, @RequestParam String startDate, @RequestParam String endDate, @RequestParam String remark) {
return AjaxResult.success(iWechatAppletService.postRecipesMessage(cusId, planId, name, startDate, endDate, remark)); return AjaxResult.success(iWechatAppletService.postSubscribeMessage(cusId, planId, name, startDate, endDate, remark));
} }

Binary file not shown.

Binary file not shown.

View File

@ -155,4 +155,8 @@ public class SysRecipesPlan {
private Integer subscribed; private Integer subscribed;
private String remark; private String remark;
private Integer subSend;
private Integer smsSend;
} }

View File

@ -1,9 +0,0 @@
package com.stdiet.custom.domain;
import java.io.Serializable;
public class WxPush implements Serializable {
private static final long serialVersionUID = 1L;
}

View File

@ -1,39 +0,0 @@
package com.stdiet.custom.domain;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import lombok.Data;
import java.io.Serializable;
@Data
@XStreamAlias("xml")
public class WxXmlData implements Serializable {
@XStreamAlias("ToUserName")
private String toUserName;
@XStreamAlias("FromUserName")
private String fromUserName;
@XStreamAlias("CreateTime")
private Long createTime;
@XStreamAlias("MsgType")
private String msgType;
@XStreamAlias("Content")
private String content;
@XStreamAlias("MsgId")
private String msgId;
//
@XStreamAlias("Title")
private String title;
@XStreamAlias("Description")
private String description;
@XStreamAlias("Url")
private String url;
/**
* 订阅或者取消订阅的事件
*/
@XStreamAlias("Event")
private String event;
@XStreamAlias("EventKey")
private String eventkey;
}

View File

@ -1,6 +1,6 @@
package com.stdiet.custom.domain.wechat; package com.stdiet.custom.domain.wechat;
import com.google.gson.JsonObject; import com.alibaba.fastjson.JSONObject;
import lombok.Data; import lombok.Data;
import java.util.Date; import java.util.Date;
@ -10,9 +10,10 @@ public class WxSubscribePostLog {
Long id; Long id;
String appid; String appid;
String openid; String openid;
String phone;
Long planId; Long planId;
Date sendTime; Date sendTime;
Integer errcode; JSONObject result;
String errmsg; JSONObject data;
JsonObject data; Integer type;
} }

View File

@ -1,22 +0,0 @@
package com.stdiet.custom.service;
import com.stdiet.common.core.domain.AjaxResult;
import com.stdiet.custom.domain.WxXmlData;
import javax.servlet.http.HttpServletRequest;
public interface ISysWxService {
/**
* 微信token验证
*
* @param signature
* @param timestamp
* @param nonce
* @return
*/
public String wxCheckAuth(String signature, String timestamp, String nonce, String echostr);
public String autoResponse(HttpServletRequest request);
public AjaxResult getAccessToken();
}

View File

@ -4,5 +4,7 @@ public interface IWechatAppletService {
public String getAccessToken(String appId); public String getAccessToken(String appId);
public String postRecipesMessage(Long cusId, Long planId, String name, String startDate, String endDate, String remark); public Integer postSubscribeMessage(Long cusId, Long planId, String name, String startDate, String endDate, String remark);
public Integer postSms(Long cusId, Long planId, String plan);
} }

View File

@ -9,15 +9,13 @@ import com.stdiet.custom.domain.SysOrderPause;
import com.stdiet.custom.domain.SysRecipesPlan; import com.stdiet.custom.domain.SysRecipesPlan;
import com.stdiet.custom.domain.SysRecipesPlanListInfo; import com.stdiet.custom.domain.SysRecipesPlanListInfo;
import com.stdiet.custom.mapper.SysRecipesPlanMapper; import com.stdiet.custom.mapper.SysRecipesPlanMapper;
import com.stdiet.custom.service.ISysOrderPauseService; import com.stdiet.custom.service.*;
import com.stdiet.custom.service.ISysOrderService;
import com.stdiet.custom.service.ISysRecipesPlanService;
import com.stdiet.custom.service.IWechatAppletService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async; import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.text.SimpleDateFormat;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.temporal.ChronoUnit; import java.time.temporal.ChronoUnit;
import java.util.*; import java.util.*;
@ -31,8 +29,8 @@ import java.util.*;
@Service("sysRecipesPlanService") @Service("sysRecipesPlanService")
@Transactional @Transactional
public class SysRecipesPlanServiceImpl implements ISysRecipesPlanService { public class SysRecipesPlanServiceImpl implements ISysRecipesPlanService {
public static final String generateRecipesPlanLockKey = "generateRecipesPlanLock::%s"; public static final String generateRecipesPlanLockKey = "generateRecipesPlanLock::%s";
static final SimpleDateFormat ft = new SimpleDateFormat("yyyy-MM-dd");
@Autowired @Autowired
private SysRecipesPlanMapper sysRecipesPlanMapper; private SysRecipesPlanMapper sysRecipesPlanMapper;
@Autowired @Autowired
@ -43,6 +41,8 @@ public class SysRecipesPlanServiceImpl implements ISysRecipesPlanService {
private SynchrolockUtil synchrolockUtil; private SynchrolockUtil synchrolockUtil;
@Autowired @Autowired
private IWechatAppletService wechatAppletService; private IWechatAppletService wechatAppletService;
@Autowired
private ISysCustomerService sysCustomerService;
/** /**
* 查询食谱计划 * 查询食谱计划
@ -86,7 +86,6 @@ public class SysRecipesPlanServiceImpl implements ISysRecipesPlanService {
*/ */
@Override @Override
public int updateSysRecipesPlan(SysRecipesPlan sysRecipesPlan) { public int updateSysRecipesPlan(SysRecipesPlan sysRecipesPlan) {
SysRecipesPlan recipesPlan = null;
sysRecipesPlan.setUpdateTime(DateUtils.getNowDate()); sysRecipesPlan.setUpdateTime(DateUtils.getNowDate());
if (StringUtils.isNotNull(sysRecipesPlan.getSubscribed())) { if (StringUtils.isNotNull(sysRecipesPlan.getSubscribed())) {
@ -94,17 +93,30 @@ public class SysRecipesPlanServiceImpl implements ISysRecipesPlanService {
} else if (StringUtils.isNotNull(sysRecipesPlan.getSendFlag())) { } else if (StringUtils.isNotNull(sysRecipesPlan.getSendFlag())) {
// 后台修改发送状态 // 后台修改发送状态
sysRecipesPlan.setSendTime(DateUtils.getNowDate()); sysRecipesPlan.setSendTime(DateUtils.getNowDate());
recipesPlan = sysRecipesPlanMapper.selectSysRecipesPlanById(sysRecipesPlan.getId()); SysRecipesPlan recipesPlan = sysRecipesPlanMapper.selectSysRecipesPlanById(sysRecipesPlan.getId());
} if (StringUtils.isNotNull(sysRecipesPlan.getSendFlag()) && sysRecipesPlan.getSendFlag() == 1) {
int row = sysRecipesPlanMapper.updateSysRecipesPlan(sysRecipesPlan);
if (row > 0 && StringUtils.isNotNull(sysRecipesPlan.getSendFlag()) && sysRecipesPlan.getSendFlag() == 1 && StringUtils.isNotNull(recipesPlan) && StringUtils.isNull(recipesPlan.getSendTime())) {
// 未发送过 // 未发送过
String name = "" + recipesPlan.getStartNumDay() + "" + recipesPlan.getEndNumDay() + ""; String name = "" + recipesPlan.getStartNumDay() + "" + recipesPlan.getEndNumDay() + "";
String startDate = recipesPlan.getStartDate().toString(); String startDate = ft.format(recipesPlan.getStartDate());
String endDate = recipesPlan.getEndDate().toString(); String endDate = ft.format(recipesPlan.getEndDate());
wechatAppletService.postRecipesMessage(sysRecipesPlan.getCusId(), sysRecipesPlan.getId(), name, startDate, endDate, recipesPlan.getRemark()); // 发送微信订阅
if (StringUtils.isNotNull(recipesPlan) && recipesPlan.getSubSend() == 0) {
Integer code = wechatAppletService.postSubscribeMessage(recipesPlan.getCusId(), recipesPlan.getId(), name, startDate, endDate, recipesPlan.getRemark());
if (code == 0) {
sysRecipesPlan.setSubSend(1);
} }
return row; }
// 发送通知短信
if(StringUtils.isNotNull(recipesPlan) && recipesPlan.getSmsSend() == 0) {
Integer smsCode = wechatAppletService.postSms(recipesPlan.getCusId(), recipesPlan.getId(), name);
if (smsCode == 0) {
sysRecipesPlan.setSmsSend(1);
}
}
}
}
return sysRecipesPlanMapper.updateSysRecipesPlan(sysRecipesPlan);
} }
/** /**

View File

@ -1,65 +0,0 @@
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;
import com.stdiet.custom.utils.WechatMessageUtil;
import com.stdiet.custom.utils.WxTokenUtils;
import com.thoughtworks.xstream.XStream;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
@Service
@Transactional
public class SysWxServiceImpl implements ISysWxService {
@Override
public String wxCheckAuth(String signature, String timestamp, String nonce, String echostr) {
return WxTokenUtils.checkSignature(signature, timestamp, nonce) ? echostr : null;
}
@Override
public String autoResponse(HttpServletRequest request) {
try {
WxXmlData wxData = WxTokenUtils.resolveXmlData(request.getInputStream());
WxXmlData resultXmlData = new WxXmlData();
resultXmlData.setToUserName(wxData.getFromUserName()); //收到的消息是谁发来的再发给谁
resultXmlData.setFromUserName(wxData.getToUserName()); //
if (wxData.getMsgType().equals(WechatMessageUtil.MESSAGE_EVENT)) {
if (wxData.getEvent().equals(WechatMessageUtil.MESSAGE_EVENT_SUBSCRIBE)) {
resultXmlData.setMsgType("text");
resultXmlData.setCreateTime(System.currentTimeMillis());
resultXmlData.setContent("欢迎来到胜唐体控,这是一条测试用的关注信息");
} else if (wxData.getEvent().equals(WechatMessageUtil.MESSAGE_EVENT_UNSUBSCRIBE)) {
}
} else if (wxData.getMsgType().equals(WechatMessageUtil.MESSAGE_TEXT)) {
resultXmlData.setMsgType("text");
resultXmlData.setCreateTime(System.currentTimeMillis());
resultXmlData.setContent("<a href=\"https://my.openwrite.cn/code/generate?blogId=18931-1576559666626-322\">点击该链接,获取博客解锁验证码</a>");
} else {
resultXmlData.setMsgType("text");
resultXmlData.setCreateTime(System.currentTimeMillis());
resultXmlData.setContent("公众号正在开发中。后期请多多关注!");
}
XStream xstream = new XStream();
xstream.processAnnotations(WxXmlData.class);
xstream.setClassLoader(WxXmlData.class.getClassLoader());
return xstream.toXML(resultXmlData); //XStream的方法直接将对象转换成 xml数据
} catch (IOException e) {
return null;
}
}
@Override
public AjaxResult getAccessToken() {
return AjaxResult.success(WxTokenUtils.fetchAccessToken());
}
}

View File

@ -1,26 +1,36 @@
package com.stdiet.custom.service.impl; package com.stdiet.custom.service.impl;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonObject; import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.stdiet.common.core.redis.RedisCache; import com.stdiet.common.core.redis.RedisCache;
import com.stdiet.common.utils.DateUtils; import com.stdiet.common.utils.DateUtils;
import com.stdiet.common.utils.StringUtils; import com.stdiet.common.utils.StringUtils;
import com.stdiet.custom.domain.SysCustomer;
import com.stdiet.custom.domain.SysWxUserInfo; import com.stdiet.custom.domain.SysWxUserInfo;
import com.stdiet.custom.domain.wechat.WxSubscribePostLog; import com.stdiet.custom.domain.wechat.WxSubscribePostLog;
import com.stdiet.custom.service.ISysCustomerService;
import com.stdiet.custom.service.ISysWxUserInfoService; import com.stdiet.custom.service.ISysWxUserInfoService;
import com.stdiet.custom.service.IWechatAppletService; import com.stdiet.custom.service.IWechatAppletService;
import com.stdiet.custom.service.IWxSubscribePostLogService; import com.stdiet.custom.service.IWxSubscribePostLogService;
import com.stdiet.custom.utils.SmsUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate; import org.springframework.web.client.RestTemplate;
import java.nio.charset.StandardCharsets;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
@Service @Service
public class WeChartAppletServiceImp implements IWechatAppletService { public class WeChartAppletServiceImp implements IWechatAppletService {
static final String WX_TEM_ID = "Ow0j0Jt4OJhjy6GruBstOMLTGjAVagM4hTZRLAaxqJo";
static final String SMS_TEM_ID = "SMS_216839183";
static final String SMS_SIGN_NAME = "胜唐体控";
@Autowired @Autowired
private RedisCache redisCache; private RedisCache redisCache;
@ -34,6 +44,9 @@ public class WeChartAppletServiceImp implements IWechatAppletService {
@Autowired @Autowired
private IWxSubscribePostLogService wxSubscribePostLogService; private IWxSubscribePostLogService wxSubscribePostLogService;
@Autowired
private ISysCustomerService sysCustomerService;
@Override @Override
public String getAccessToken(String appId) { public String getAccessToken(String appId) {
String accessToken = redisCache.getCacheObject(appId); String accessToken = redisCache.getCacheObject(appId);
@ -60,7 +73,7 @@ public class WeChartAppletServiceImp implements IWechatAppletService {
} }
@Override @Override
public String postRecipesMessage(Long cusId, Long planId, String name, String startDate, String endDate, String remark) { public Integer postSubscribeMessage(Long cusId, Long planId, String name, String startDate, String endDate, String remark) {
SysWxUserInfo sysWxUserInfo = sysWxUserInfoService.selectSysWxUserInfoByCusId(cusId); SysWxUserInfo sysWxUserInfo = sysWxUserInfoService.selectSysWxUserInfoByCusId(cusId);
if (StringUtils.isNull(sysWxUserInfo)) { if (StringUtils.isNull(sysWxUserInfo)) {
return null; return null;
@ -68,42 +81,80 @@ public class WeChartAppletServiceImp implements IWechatAppletService {
String accessToken = getAccessToken(sysWxUserInfo.getAppid()); String accessToken = getAccessToken(sysWxUserInfo.getAppid());
if (StringUtils.isNull(accessToken)) { if (StringUtils.isNull(accessToken)) {
return ""; return -1;
} }
String tmpId = "EWeha9m0ggpnhMANDLHtl2ezLfPWKY_9PsJubbG_6eA";
String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken; String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=" + accessToken;
JsonObject param = new JsonObject(); JSONObject param = new JSONObject();
param.addProperty("access_token", accessToken); param.put("access_token", accessToken);
param.addProperty("touser", sysWxUserInfo.getOpenid()); param.put("touser", sysWxUserInfo.getOpenid());
param.addProperty("template_id", tmpId); param.put("template_id", WX_TEM_ID);
param.addProperty("page", "pages/recipes/index"); param.put("page", "pages/recipes/index");
JsonObject dataParam = new JsonObject();
dataParam.addProperty("phrase1", name);
dataParam.addProperty("date3", startDate);
dataParam.addProperty("thing6", endDate);
// dataParam.addProperty("thing6", remark);
param.add("data", dataParam); JSONObject dataParam = new JSONObject();
dataParam.put("thing1", JSONObject.parse("{\"value\":\"" + name + "\"}"));
dataParam.put("time2", JSONObject.parse("{\"value\":\"" + startDate + "\"}"));
dataParam.put("time3", JSONObject.parse("{\"value\":\"" + endDate + "\"}"));
String mRemark = StringUtils.isNull(remark) ? "" : remark;
dataParam.put("thing4", JSONObject.parse("{\"value\":\"" + mRemark + "\"}"));
ResponseEntity<String> entity = restTemplate.postForEntity(url, param, String.class); param.put("data", dataParam);
restTemplate.getMessageConverters()
.add(0, new StringHttpMessageConverter(StandardCharsets.UTF_8));
ResponseEntity<String> entity = restTemplate.postForEntity(url, param.toJSONString(), String.class);
JSONObject resultObj = JSONObject.parseObject(entity.getBody()); JSONObject resultObj = JSONObject.parseObject(entity.getBody());
WxSubscribePostLog postLog = new WxSubscribePostLog(); WxSubscribePostLog postLog = new WxSubscribePostLog();
postLog.setAppid(sysWxUserInfo.getAppid()); postLog.setAppid(sysWxUserInfo.getAppid());
postLog.setOpenid(sysWxUserInfo.getOpenid()); postLog.setOpenid(sysWxUserInfo.getOpenid());
postLog.setErrcode(resultObj.getInteger("errcode")); int errCode = resultObj.getInteger("errcode");
postLog.setErrmsg(resultObj.getString("errmsg")); postLog.setType(0);
postLog.setResult(resultObj);
postLog.setSendTime(DateUtils.getNowDate()); postLog.setSendTime(DateUtils.getNowDate());
postLog.setPlanId(planId); postLog.setPlanId(planId);
//
dataParam.put("tmpId", WX_TEM_ID);
postLog.setData(dataParam); postLog.setData(dataParam);
wxSubscribePostLogService.insertWxSubscribePostLog(postLog); wxSubscribePostLogService.insertWxSubscribePostLog(postLog);
return resultObj.toJSONString(); return errCode;
// Integer errcode = resultObj.getInteger("errcode");
} }
@Override
public Integer postSms(Long cusId, Long planId, String plan) {
try {
SysCustomer customer = sysCustomerService.selectSysCustomerById(cusId);
SendSmsResponse response = SmsUtils.sendSms(customer.getPhone(), plan, SMS_TEM_ID, SMS_SIGN_NAME);
WxSubscribePostLog postLog = new WxSubscribePostLog();
postLog.setPhone(customer.getPhone());
postLog.setPlanId(planId);
JSONObject resultObj = new JSONObject();
resultObj.put("requestId", response.getRequestId());
resultObj.put("bizId", response.getBizId());
resultObj.put("code", response.getCode());
resultObj.put("message", response.getMessage());
postLog.setResult(resultObj);
JSONObject dataParam = new JSONObject();
dataParam.put("phone", customer.getPhone());
dataParam.put("plan", plan);
dataParam.put("tmpCode", SMS_TEM_ID);
dataParam.put("signName", SMS_SIGN_NAME);
postLog.setData(dataParam);
postLog.setSendTime(DateUtils.getNowDate());
postLog.setType(1);
wxSubscribePostLogService.insertWxSubscribePostLog(postLog);
return response.getCode().equals("OK") ? 0 : -1;
} catch (Exception e) {
System.out.println(e);
}
return -1;
}
} }

View File

@ -1,193 +0,0 @@
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");
}
}

View File

@ -0,0 +1,91 @@
package com.stdiet.custom.utils;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.QuerySendDetailsResponse;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsRequest;
import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.profile.DefaultProfile;
import com.aliyuncs.profile.IClientProfile;
import com.stdiet.common.config.AliyunOSSConfig;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SmsUtils {
//产品名称:云通信短信API产品,开发者无需替换
static final String product = "Dysmsapi";
//产品域名,开发者无需替换
static final String domain = "dysmsapi.aliyuncs.com";
public static SendSmsResponse sendSms(String phone, String plan, String tmpCode, String signName) throws ClientException {
//可自助调整超时时间
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
//初始化acsClient,暂不支持region化
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", AliyunOSSConfig.AccessKeyID, AliyunOSSConfig.AccessKeySecret);
DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
IAcsClient acsClient = new DefaultAcsClient(profile);
//组装请求对象-具体描述见控制台-文档部分内容
SendSmsRequest request = new SendSmsRequest();
//必填:待发送手机号
request.setPhoneNumbers(phone);
//必填:短信签名-可在短信控制台中找到
request.setSignName(signName);
//必填:短信模板-可在短信控制台中找到
request.setTemplateCode(tmpCode);
//可选:模板中的变量替换JSON串,如模板内容为"亲爱的${name},您的验证码为${code}",此处的值为
JSONObject paramObj = new JSONObject();
paramObj.put("plan", plan);
request.setTemplateParam(paramObj.toJSONString());
//选填-上行短信扩展码(无特殊需求用户请忽略此字段)
//request.setSmsUpExtendCode("90997");
//可选:outId为提供给业务方扩展字段,最终在短信回执消息中将此值带回给调用者
request.setOutId("yourOutId");
//hint 此处可能会抛出异常注意catch
SendSmsResponse sendSmsResponse = acsClient.getAcsResponse(request);
return sendSmsResponse;
}
public static QuerySendDetailsResponse querySendDetails(String bizId) throws ClientException {
//可自助调整超时时间
System.setProperty("sun.net.client.defaultConnectTimeout", "10000");
System.setProperty("sun.net.client.defaultReadTimeout", "10000");
//初始化acsClient,暂不支持region化
IClientProfile profile = DefaultProfile.getProfile("cn-hangzhou", AliyunOSSConfig.AccessKeyID, AliyunOSSConfig.AccessKeySecret);
DefaultProfile.addEndpoint("cn-hangzhou", "cn-hangzhou", product, domain);
IAcsClient acsClient = new DefaultAcsClient(profile);
//组装请求对象
QuerySendDetailsRequest request = new QuerySendDetailsRequest();
//必填-号码
request.setPhoneNumber("15000000000");
//可选-流水号
request.setBizId(bizId);
//必填-发送日期 支持30天内记录查询格式yyyyMMdd
SimpleDateFormat ft = new SimpleDateFormat("yyyyMMdd");
request.setSendDate(ft.format(new Date()));
//必填-页大小
request.setPageSize(10L);
//必填-当前页码从1开始计数
request.setCurrentPage(1L);
//hint 此处可能会抛出异常注意catch
QuerySendDetailsResponse querySendDetailsResponse = acsClient.getAcsResponse(request);
return querySendDetailsResponse;
}
}

View File

@ -1,63 +0,0 @@
package com.stdiet.custom.utils;
public class WechatMessageUtil {
// 各种消息类型,除了扫带二维码事件
/**
* 文本消息
*/
public static final String MESSAGE_TEXT = "text";
/**
* 图片消息
*/
public static final String MESSAtGE_IMAGE = "image";
/**
* 图文消息
*/
public static final String MESSAGE_NEWS = "news";
/**
* 语音消息
*/
public static final String MESSAGE_VOICE = "voice";
/**
* 视频消息
*/
public static final String MESSAGE_VIDEO = "video";
/**
* 小视频消息
*/
public static final String MESSAGE_SHORTVIDEO = "shortvideo";
/**
* 地理位置消息
*/
public static final String MESSAGE_LOCATION = "location";
/**
* 链接消息
*/
public static final String MESSAGE_LINK = "link";
/**
* 事件推送消息
*/
public static final String MESSAGE_EVENT = "event";
/**
* 事件推送消息中,事件类型subscribe(订阅)
*/
public static final String MESSAGE_EVENT_SUBSCRIBE = "subscribe";
/**
* 事件推送消息中,事件类型unsubscribe(取消订阅)
*/
public static final String MESSAGE_EVENT_UNSUBSCRIBE = "unsubscribe";
/**
* 事件推送消息中,上报地理位置事件
*/
public static final String MESSAGE_EVENT_LOCATION_UP = "LOCATION";
/**
* 事件推送消息中,自定义菜单事件,点击菜单拉取消息时的事件推送
*/
public static final String MESSAGE_EVENT_CLICK = "CLICK";
/**
* 事件推送消息中,自定义菜单事件,点击菜单跳转链接时的事件推送
*/
public static final String MESSAGE_EVENT_VIEW = "VIEW";
}

View File

@ -1,166 +0,0 @@
package com.stdiet.custom.utils;
import com.alibaba.fastjson.JSONObject;
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 java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
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?access_token=ACCESS_TOKEN&type=image";
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;
}
}
/**
* 模拟form表单的形式 上传文件 以输出流的形式把文件写入到url中然后用输入流来获取url的响应
*
* @return String url的响应信息返回值
* @throws IOException
*/
public static WxFileUploadResult uploadImage(String filePath, String fileName, String accessToken) throws Exception {
String[] cmds = {"curl", uploadMaterialUrl.replaceAll("ACCESS_TOKEN", accessToken), "-F"
, "media=@" + filePath + ";filename=" + fileName};//必须分开写不能有空格
ProcessBuilder process = new ProcessBuilder(cmds);
Process p = process.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
StringBuilder builder = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
builder.append(line);
builder.append(System.getProperty("line.separator"));
}
JSONObject obj = JSONObject.parseObject(builder.toString());
return JSONObject.toJavaObject(obj, WxFileUploadResult.class);
}
/**
* 验证签名
*
* @param signature
* @param timestamp
* @param nonce
* @return
*/
public static boolean checkSignature(String signature, String timestamp, String nonce) {
String[] arr = new String[]{token, timestamp, nonce};
// 将tokentimestampnonce三个参数进行字典序排序
// Arrays.sort(arr);
sort(arr);
StringBuilder content = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
content.append(arr[i]);
}
MessageDigest md = null;
String tmpStr = null;
try {
md = MessageDigest.getInstance("SHA-1");
// 将三个参数字符串拼接成一个字符串进行sha1加密
byte[] digest = md.digest(content.toString().getBytes());
tmpStr = byteToStr(digest);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
content = null;
// 将sha1加密后的字符串可与signature对比标识该请求来源于微信
return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false;
}
/**
* 将字节数组转换为十六进制字符串
*
* @param byteArray
* @return
*/
private static String byteToStr(byte[] byteArray) {
String strDigest = "";
for (int i = 0; i < byteArray.length; i++) {
strDigest += byteToHexStr(byteArray[i]);
}
return strDigest;
}
/**
* 将字节转换为十六进制字符串
*
* @param mByte
* @return
*/
private static String byteToHexStr(byte mByte) {
char[] Digit = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
char[] tempArr = new char[2];
tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
tempArr[1] = Digit[mByte & 0X0F];
String s = new String(tempArr);
return s;
}
public static void sort(String a[]) {
for (int i = 0; i < a.length - 1; i++) {
for (int j = i + 1; j < a.length; j++) {
if (a[j].compareTo(a[i]) < 0) {
String temp = a[i];
a[i] = a[j];
a[j] = temp;
}
}
}
}
public static WxXmlData resolveXmlData(InputStream in) {
WxXmlData wxXmlData = null;
try {
String xmlData = IOUtils.toString(in, StandardCharsets.UTF_8.name());
XStream xstream = new XStream();
//这个必须要加 不然无法转换成WxXmlData对象
xstream.setClassLoader(WxXmlData.class.getClassLoader());
xstream.processAnnotations(WxXmlData.class);
xstream.alias("xml", WxXmlData.class);
wxXmlData = (WxXmlData) xstream.fromXML(xmlData);
// log.info("【wxXmlData: {}】 ", wxXmlData);
} catch (Exception e) {
// log.error("【error】{}", e.getMessage());
}
return wxXmlData;
}
}

View File

@ -23,6 +23,8 @@
<result property="cusId" column="cus_id"/> <result property="cusId" column="cus_id"/>
<result property="outId" column="out_id"/> <result property="outId" column="out_id"/>
<result property="subscribed" column="subscribed"/> <result property="subscribed" column="subscribed"/>
<result property="subSend" column="sub_send"/>
<result property="smsSend" column="sms_send"/>
<!-- 非持久化字段 --> <!-- 非持久化字段 -->
<!-- <result property="customerId" column="cus_id"></result>&lt;!&ndash; 客户ID &ndash;&gt;--> <!-- <result property="customerId" column="cus_id"></result>&lt;!&ndash; 客户ID &ndash;&gt;-->
<result property="customer" column="customer"/><!-- 客户姓名 --> <result property="customer" column="customer"/><!-- 客户姓名 -->
@ -38,7 +40,7 @@
<sql id="selectSysRecipesPlanVo"> <sql id="selectSysRecipesPlanVo">
select id, order_id, cus_id, out_id, start_date, end_date, start_num_day, end_num_day, recipes_id, send_flag, send_time, pause_date, create_time, create_by, update_time, update_by, del_flag, review_status from sys_recipes_plan select id, order_id, cus_id, out_id, start_date, end_date, start_num_day, end_num_day, recipes_id, send_flag, send_time, pause_date, create_time, create_by, update_time, update_by, del_flag, review_status, sub_send, sms_send from sys_recipes_plan
</sql> </sql>
<select id="selectSysRecipesPlanList" parameterType="SysRecipesPlan" resultMap="SysRecipesPlanResult"> <select id="selectSysRecipesPlanList" parameterType="SysRecipesPlan" resultMap="SysRecipesPlanResult">
@ -137,6 +139,8 @@
<if test="delFlag != null">del_flag = #{delFlag},</if> <if test="delFlag != null">del_flag = #{delFlag},</if>
<if test="reviewStatus != null">review_status = #{reviewStatus},</if> <if test="reviewStatus != null">review_status = #{reviewStatus},</if>
<if test="subscribed != null">subscribed = #{subscribed},</if> <if test="subscribed != null">subscribed = #{subscribed},</if>
<if test="subSend != null">sub_send = #{subSend},</if>
<if test="smsSend != null">sms_send = #{smsSend},</if>
</trim> </trim>
where id = #{id} and del_flag = 0 where id = #{id} and del_flag = 0
</update> </update>

View File

@ -10,8 +10,8 @@
<result property="openid" column="openid"/> <result property="openid" column="openid"/>
<result property="sendTime" column="send_time"/> <result property="sendTime" column="send_time"/>
<result property="planId" column="plan_id"/> <result property="planId" column="plan_id"/>
<result property="errcode" column="errcode"/> <result property="phone" column="phone"/>
<result property="errmsg" column="errmsg"/> <result property="result" column="result" typeHandler="com.stdiet.custom.typehandler.ObjectJsonHandler"/>
<result property="data" column="data" typeHandler="com.stdiet.custom.typehandler.ObjectJsonHandler"/> <result property="data" column="data" typeHandler="com.stdiet.custom.typehandler.ObjectJsonHandler"/>
</resultMap> </resultMap>
@ -22,18 +22,20 @@
<if test="openid != null">openid,</if> <if test="openid != null">openid,</if>
<if test="planId != null">plan_id,</if> <if test="planId != null">plan_id,</if>
<if test="sendTime != null">send_time,</if> <if test="sendTime != null">send_time,</if>
<if test="errcode != null">errcode,</if> <if test="result != null">result,</if>
<if test="errmsg != null">errmsg,</if> <if test="phone != null">phone,</if>
<if test="data != null">data,</if> <if test="data != null">data,</if>
<if test="type != null">type,</if>
</trim> </trim>
<trim prefix="values (" suffix=")" suffixOverrides=","> <trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="appid != null">#{appid},</if> <if test="appid != null">#{appid},</if>
<if test="openid != null">#{openid},</if> <if test="openid != null">#{openid},</if>
<if test="planId != null">#{planId},</if> <if test="planId != null">#{planId},</if>
<if test="sendTime != null">#{sendTime},</if> <if test="sendTime != null">#{sendTime},</if>
<if test="errcode != null">#{errcode},</if> <if test="result != null">#{result, jdbcType=OTHER, typeHandler=com.stdiet.custom.typehandler.ObjectJsonHandler},</if>
<if test="errmsg != null">#{errmsg},</if> <if test="phone != null">#{phone},</if>
<if test="data != null">#{data, jdbcType=OTHER, typeHandler=com.stdiet.custom.typehandler.ObjectJsonHandler},</if> <if test="data != null">#{data, jdbcType=OTHER, typeHandler=com.stdiet.custom.typehandler.ObjectJsonHandler},</if>
<if test="type != null">#{type},</if>
</trim> </trim>
</insert> </insert>
@ -45,8 +47,8 @@
<if test="openid != null">AND openid = #{openid}</if> <if test="openid != null">AND openid = #{openid}</if>
<if test="appid != null">AND appid = #{appid}</if> <if test="appid != null">AND appid = #{appid}</if>
<if test="planId != null">AND plan_id = #{planId}</if> <if test="planId != null">AND plan_id = #{planId}</if>
<if test="planId != null">AND plan_id = #{planId}</if> <if test="phone != null">AND phone = #{phone}</if>
<if test="errcode != null">AND errcode = #{errcode}</if> <if test="type != null">AND type = #{type}</if>
</where> </where>
</select> </select>

View File

@ -46,7 +46,7 @@
order by wxuser.update_time desc order by wxuser.update_time desc
</select> </select>
<select id="selectSysWxUserInfoByCusId" parameterType="String" resultMap="SysWxUserInfoResult"> <select id="selectSysWxUserInfoByCusId" parameterType="Long" resultMap="SysWxUserInfoResult">
<include refid="selectSysWxUserInfoVo"/> <include refid="selectSysWxUserInfoVo"/>
where cus_id = #{cusId} where cus_id = #{cusId}
</select> </select>