1.在小程序公众平台选择消息模板
2.uni-app前端调用代码
a.小程序登录代码
loginUser() {
var me = this;
if (!me.name) {
uni.showToast({
title: '用户名不能为空!'
});
return;
}
if (!me.password) {
uni.showToast({
title: '密码不能为空!'
});
return;
}
uni.showLoading({
title: '加载中'
});
uni.request({
url: config.api.login,
method: 'POST',
header: {
'content-type': 'application/json'
},
data: {
name: me.name,
password: me.password
},
success: res => {
console.log(res.data);
if (res.data.code == 0) {
var id = res.data.data.id;
var name = res.data.data.name;
var nickName = res.data.data.nickName;
var token = res.data.data.token;
var headImage = res.data.data.headImage;
var userEmail = res.data.data.userEmail;
//本地存储用户信息
uni.setStorage({
key: 'userId',
data: {
id: id,
token: token
},
success: function() {
console.log('success');
}
});
//-----
let user = res.data.data;
if (user == undefined || user.uid <= 0 || user.token == '') {
util.toastError('登录失败:未知错误')
return
}
util.setUser(user);
//-----
uni.showToast({
title: '登录成功'
});
uni.navigateBack();
} else if (res.data.code == -1) {
uni.showToast({
title: res.data.msg
});
}
},
complete() {
uni.hideLoading();
}
});
},
getUserProfile() {
uni.getUserProfile({
desc: "获取你的昵称、头像、地区及性别",
success: res => {
var rawData = res.rawData; //用户非敏感信息
const signature = res.signature; //签名
var encrypteData = res.encryptedData; //用户敏感信息
var iv = res.iv; //解密算法的向量
console.log("用户数据==>" + rawData)
console.log("临时登录凭证==signature>" + signature)
uni.request({
url: config.api.wxLogin,
method: 'POST',
header: {
'content-type': 'application/x-www-form-urlencoded'
},
data: {
code: this.code, //临时登录凭证
rawData: rawData, //用户非敏感信息
signature: signature, //签名
encrypteData: encrypteData, //用户敏感信息
iv: iv //解密算法的向量
},
success: function(res) {
},
fail: res => {
console.log("微信授权登录失败数据==>" + res)
}
})
}
})
}
wxLogin(e) {
var me = this;
var userInfo = e.detail.userInfo;
var rawData = e.detail.rawData; //用户非敏感信息
var signature = e.detail.signature; //签名
var encrypteData = e.detail.encryptedData; //用户敏感信息
var iv = e.detail.iv; //解密算法的向量
console.log(e);
uni.login({
provider: 'weixin',
success(loginResult) {
console.log(loginResult);
var code = loginResult.code; //临时登录凭证
uni.request({
url: config.api.wxLogin,
method: 'POST',
header: {
'content-type': 'application/x-www-form-urlencoded'
},
data: {
code: code, //临时登录凭证
rawData: rawData, //用户非敏感信息
signature: signature, //签名
encrypteData: encrypteData, //用户敏感信息
iv: iv //解密算法的向量
},
success: function(res) {
if (res.data.code == 0) {
console.log(res);
console.log('userInfo=====>' + userInfo);
console.log('skey=========>' + res.data.data);
var id = res.data.data.id;
var name = res.data.data.name;
var nickName = res.data.data.nickName;
var token = res.data.data.token;
var headImage = res.data.data.headImage;
var userEmail = res.data.data.userEmail;
//本地存储用户信息
uni.setStorage({
key: 'userId',
data: {
id: id,
token: token
},
success: function() {
console.log('success');
}
});
//-----
let user = res.data.data;
if (user == undefined || user.uid <= 0 || user.token == '') {
util.toastError('登录失败:未知错误')
return
}
util.setUser(user);
//-----
uni.showToast({
title: '登录成功'
});
uni.navigateBack();
} else if (res.data.code == -1) {
uni.showToast({
title: res.data.msg
});
}
}
});
}
});
}
b.调用订阅消息的前端代码
getMsg() {
uni.requestSubscribeMessage({
tmplIds: ['模板ID'],
complete:(res)=>{
console.log(res)
}
});
},
3.java 后台代码
a.登录代码:
@Log(title = "微信登录", businessType = BusinessType.OTHER)
@PostMapping("wx/login")
@ResponseBody
public BaseResult wxLogin(@RequestParam(value = "code", required = false) String code,
@RequestParam(value = "rawData", required = false) String rawData,
@RequestParam(value = "signature", required = false) String signature,
@RequestParam(value = "encrypteData", required = false) String encrypteData,
@RequestParam(value = "iv", required = false) String iv) {
// 用户非敏感信息:rawData
// 签名:signature
JSONObject rawDataJson = JSON.parseObject(rawData);
// 1.接收小程序发送的code
// 2.开发者服务器 登录凭证校验接口 appi + appsecret + code
JSONObject SessionKeyOpenId = WechatUtil.getSessionKeyOrOpenId(code);
// 3.接收微信接口服务 获取返回的参数
String openid = SessionKeyOpenId.getString("openid");
String sessionKey = SessionKeyOpenId.getString("session_key");
// 4.校验签名 小程序发送的签名signature与服务器端生成的签名signature2 = sha1(rawData + sessionKey)
String signature2 = DigestUtils.sha1Hex(rawData + sessionKey);
// log.info("小程序传来的rawData: {}", rawData);
// log.info("小程序传来的code: {}", code);
// log.info("服务器生产的sessionKey: {}", sessionKey);
// log.info("小程序传来的signature: {}", signature);
// log.info("服务器生产的signature: {}", signature2);
// log.info("服务器生产的openid: {}", openid);
if (!signature.equals(signature2)) {
return BaseResult.error("登陆失败,签名校验失败!");
}
// 5.根据返回的User实体类,判断用户是否是新用户,是的话,将用户信息存到数据库;不是的话,更新最新登录时间
SysUser sysUser = userService.selectUserByOpenId(openid);
if (sysUser == null) {
log.info("用户信息入库");
// 用户信息入库
String nickName = rawDataJson.getString("nickName");
String avatarUrl = rawDataJson.getString("avatarUrl");
String gender = rawDataJson.getString("gender");//0.未知 1.男 2.女
sysUser = new SysUser();
sysUser.setUserName(nickName);
sysUser.setNickName(nickName);
sysUser.setAvatar(avatarUrl);
//保持与数据库设计一致
if (null != gender) {
switch (gender) {
case "0":
sysUser.setSex("2");//用户性别(0男 1女 2未知)
break;
case "1":
sysUser.setSex("0");//用户性别(0男 1女 2未知)
break;
case "2":
sysUser.setSex("1");//用户性别(0男 1女 2未知)
break;
}
}
sysUser.setOpenId(openid);
sysUser.setCreateBy(nickName);
sysUser.setPassword(SecurityUtils.encryptPassword(openid));//小程序默认密码为 openid
userService.insertUser(sysUser);
} else {
sysUser.setUpdateBy(sysUser.getNickName());
// 已存在,更新用户登录时间
userService.updateUserProfile(sysUser);
}
BaseResult ajax = BaseResult.success("登录成功");
// 生成令牌
String token = loginService.login(rawDataJson.getString("nickName"), openid, "",
"");
ajax.put(Constants.TOKEN, token);
return ajax;
}
b.发送订阅消息的java代码
@Log(title = "微信消息", businessType = BusinessType.OTHER)
@GetMapping("wx/msg")
@ResponseBody
public BaseResult user_login(){
String url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="
+ "小程序的appid"
+ "&secret="
+ "小程序的secret";
String result = HttpClientUtil.doGet(url);
JSONObject object=JSON.parseObject(result);
String Access_Token = object.getString("access_token");
Template template=new Template();
template.setTemplate_id("模板id");
template.setTouser("小程序用户登录的openid");//登录后返回取
template.setPage("pages/index/index");
List<TemplateParam> paras=new ArrayList<TemplateParam>();
// paras.add(new TemplateParam("character_string2","000001"));
// paras.add(new TemplateParam("amount1","888.88"));
paras.add(new TemplateParam("time2","2015年01月05日"));
paras.add(new TemplateParam("thing3","请进入小程序查1看"));
template.setTemplateParamList(paras);
String requestUrl="https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=ACCESS_TOKEN";
requestUrl=requestUrl.replace("ACCESS_TOKEN", Access_Token);
System.out.println(template.toJSON());
String jsonResult=HttpClientUtil.doPostJson(requestUrl, template.toJSON());
if(jsonResult!=null){
return BaseResult.success("订阅消息发送成功!");
}else {
return BaseResult.error("订阅消息发送失败!");
}
}
注意: paras.add(new TemplateParam(“time2”,“2015年01月05日”));中的"time2","thing3"对应模板中的字段名称
其他工具类:
HttpClientUtil.java
/**
* 发起Http请求 【用于小程序登录】
*/
public class HttpClientUtil {
public static String doGet(String url, Map<String, String> param) {
// 创建Httpclient对象
CloseableHttpClient httpclient = HttpClients.createDefault();
String resultString = "";
CloseableHttpResponse response = null;
try {
// 创建uri
URIBuilder builder = new URIBuilder(url);
if (param != null) {
for (String key : param.keySet()) {
builder.addParameter(key, param.get(key));
}
}
URI uri = builder.build();
// 创建http GET请求
HttpGet httpGet = new HttpGet(uri);
// 执行请求
response = httpclient.execute(httpGet);
// 判断返回状态是否为200
if (response.getStatusLine().getStatusCode() == 200) {
resultString = EntityUtils.toString(response.getEntity(), "UTF-8");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (response != null) {
response.close();
}
httpclient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
public static String doGet(String url) {
return doGet(url, null);
}
public static String doPost(String url, Map<String, String> param) {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
// 创建参数列表
if (param != null) {
List<NameValuePair> paramList = new ArrayList<>();
for (String key : param.keySet()) {
paramList.add(new BasicNameValuePair(key, param.get(key)));
}
// 模拟表单
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(paramList);
httpPost.setEntity(entity);
}
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
public static String doPost(String url) {
return doPost(url, null);
}
public static String doPostJson(String url, String json) {
// 创建Httpclient对象
CloseableHttpClient httpClient = HttpClients.createDefault();
CloseableHttpResponse response = null;
String resultString = "";
try {
// 创建Http Post请求
HttpPost httpPost = new HttpPost(url);
// 创建请求内容
StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
httpPost.setEntity(entity);
// 执行http请求
response = httpClient.execute(httpPost);
resultString = EntityUtils.toString(response.getEntity(), "utf-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
response.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return resultString;
}
}
Template.java
public class Template {
private String touser;
private String template_id;
private String page;
private List<TemplateParam> templateParamList;
public String getTouser() {
return touser;
}
public void setTouser(String touser) {
this.touser = touser;
}
public String getTemplate_id() {
return template_id;
}
public void setTemplate_id(String template_id) {
this.template_id = template_id;
}
public String getPage() {
return page;
}
public void setPage(String page) {
this.page = page;
}
public List<TemplateParam> getTemplateParamList() {
return templateParamList;
}
public void setTemplateParamList(List<TemplateParam> templateParamList) {
this.templateParamList = templateParamList;
}
public String toJSON() {
StringBuffer buffer = new StringBuffer();
buffer.append("{");
buffer.append(String.format("\"touser\":\"%s\"", this.touser)).append(",");
buffer.append(String.format("\"template_id\":\"%s\"", this.template_id)).append(",");
buffer.append(String.format("\"page\":\"%s\"", this.page)).append(",");
buffer.append("\"data\":{");
TemplateParam param = null;
for (int i = 0; i < this.templateParamList.size(); i++) {
param = templateParamList.get(i);
// 判断是否追加逗号
if (i < this.templateParamList.size() - 1){
buffer.append(String.format("\"%s\": {\"value\":\"%s\"},", param.getKey(), param.getValue()));
}else{
buffer.append(String.format("\"%s\": {\"value\":\"%s\"}", param.getKey(), param.getValue()));
}
}
buffer.append("}");
buffer.append("}");
return buffer.toString();
}
}
TemplateParam.java
public class TemplateParam {
private String key;
private String value;
public TemplateParam(String key,String value){
this.key=key;
this.value=value;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
注意:maven 引入:
<!-- http请求工具包依赖 [微信登录需要]-->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>