Compare commits
No commits in common. "1f6b6e78f9176933d786691e5668d2b9394ef124" and "de971ca31286aec70e86c9307020f972c03e7ae6" have entirely different histories.
1f6b6e78f9
...
de971ca312
|
|
@ -46,9 +46,4 @@ public class MyResult extends UserDetail {
|
||||||
*/
|
*/
|
||||||
private String wechatOpenid;
|
private String wechatOpenid;
|
||||||
|
|
||||||
/**
|
|
||||||
* 微信授权地址
|
|
||||||
*/
|
|
||||||
private String wxAuthUrl;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,14 +15,11 @@ import com.njzscloud.supervisory.sys.auth.pojo.result.MyResult;
|
||||||
import com.njzscloud.supervisory.sys.user.pojo.entity.UserEntity;
|
import com.njzscloud.supervisory.sys.user.pojo.entity.UserEntity;
|
||||||
import com.njzscloud.supervisory.sys.user.pojo.param.UserRegisterParam;
|
import com.njzscloud.supervisory.sys.user.pojo.param.UserRegisterParam;
|
||||||
import com.njzscloud.supervisory.sys.user.service.UserService;
|
import com.njzscloud.supervisory.sys.user.service.UserService;
|
||||||
import com.njzscloud.supervisory.wxPay.contant.WxApiConfig;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
|
||||||
import java.net.URLEncoder;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
|
@ -95,27 +92,7 @@ public class AuthService implements IUserService, IRoleService {
|
||||||
.setEndpoints(endpointResources)
|
.setEndpoints(endpointResources)
|
||||||
.setCompany(company)
|
.setCompany(company)
|
||||||
.setDriver(driver)
|
.setDriver(driver)
|
||||||
.setWechatOpenid(wechatOpenid != null ? wechatOpenid : "")
|
.setWechatOpenid(wechatOpenid != null ? wechatOpenid : "");
|
||||||
.setWxAuthUrl(wxAuthUrl());
|
|
||||||
}
|
|
||||||
|
|
||||||
public String wxAuthUrl() {
|
|
||||||
// 参数说明
|
|
||||||
// 对回调地址进行URL编码至关重要[citation:1]
|
|
||||||
String redirectUri = null;
|
|
||||||
try {
|
|
||||||
redirectUri = URLEncoder.encode(WxApiConfig.REDIRECT_URI, WxApiConfig.ENC);
|
|
||||||
} catch (UnsupportedEncodingException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 将authUrl返回给前端,引导用户跳转
|
|
||||||
return "https://open.weixin.qq.com/connect/oauth2/authorize?" +
|
|
||||||
"appid=" + WxApiConfig.APP_ID +
|
|
||||||
"&redirect_uri=" + redirectUri +
|
|
||||||
"&response_type=code" +
|
|
||||||
"&scope=" + WxApiConfig.SCOPE +
|
|
||||||
"&state=STATE#wechat_redirect";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -86,9 +86,4 @@ public class UserEntity {
|
||||||
@TableLogic
|
@TableLogic
|
||||||
private Boolean deleted;
|
private Boolean deleted;
|
||||||
|
|
||||||
/**
|
|
||||||
* 微信 公众号openid
|
|
||||||
*/
|
|
||||||
private String openid;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,23 +0,0 @@
|
||||||
package com.njzscloud.supervisory.wxPay.contant;
|
|
||||||
|
|
||||||
public class WxApiConfig {
|
|
||||||
|
|
||||||
public static final String APP_ID = "wxcf5b818c19c51c07";
|
|
||||||
|
|
||||||
public static final String APP_SECRET = "35f72f3d49a9e24c618b82eb624538c8";
|
|
||||||
|
|
||||||
public static final String REDIRECT_URI = "https://supervisory.njzscloud.com/test/payment/wechat/callback";
|
|
||||||
|
|
||||||
public static final String SCOPE = "snsapi_base"; // 静默授权,仅获取OpenID
|
|
||||||
// String scope = "snsapi_userinfo"; // 非静默授权,可获取用户昵称、头像等更多信息[citation:1]
|
|
||||||
|
|
||||||
public static final String ENC = "UTF-8";
|
|
||||||
|
|
||||||
public static final String OAUTH_URL = "https://api.weixin.qq.com/sns/oauth2/access_token?";
|
|
||||||
|
|
||||||
public static final String GET_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=";
|
|
||||||
|
|
||||||
public static final String SEND_TEMPLATE_MSG_URL = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=";
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
package com.njzscloud.supervisory.wxPay.controller;
|
|
||||||
|
|
||||||
import com.njzscloud.common.core.utils.R;
|
|
||||||
import com.njzscloud.supervisory.wxPay.dto.TemplateData;
|
|
||||||
import com.njzscloud.supervisory.wxPay.service.WechatTemplateMessageService;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 支付相关接口
|
|
||||||
* 使用微信支付官方SDK的生产级实现
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
@RestController
|
|
||||||
@RequestMapping("/wechatTemplateMessage")
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class WechatTemplateMessageController {
|
|
||||||
|
|
||||||
private final WechatTemplateMessageService wechatTemplateMessageService;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 绑定微信openid
|
|
||||||
*/
|
|
||||||
@GetMapping("/bind")
|
|
||||||
public R<?> detail(@RequestParam String code) {
|
|
||||||
wechatTemplateMessageService.bind(code);
|
|
||||||
return R.success();
|
|
||||||
}
|
|
||||||
|
|
||||||
@PostMapping("/send-order-notice")
|
|
||||||
public String sendOrderNotice(@RequestParam String openId) {
|
|
||||||
try {
|
|
||||||
// 构建模板数据
|
|
||||||
Map<String, TemplateData> data = new HashMap<>();
|
|
||||||
data.put("first", new TemplateData("下单待审核通知"));
|
|
||||||
data.put("character_string6", new TemplateData("202312010001"));
|
|
||||||
data.put("thing4", new TemplateData("LuanMa"));
|
|
||||||
data.put("time5", new TemplateData("2023-12-01 10:30:00"));
|
|
||||||
data.put("remark", new TemplateData("感谢您的购买!"));
|
|
||||||
|
|
||||||
// 发送模板消息
|
|
||||||
String templateId = "HXr8xxYERp2TrkdfBgdRJGSJeMT_8mXF7Yjz6NDBUFw"; // 在公众号后台获取
|
|
||||||
|
|
||||||
return wechatTemplateMessageService.sendTemplateMessage(openId, templateId, data,
|
|
||||||
null, null);
|
|
||||||
} catch (Exception e) {
|
|
||||||
return "发送失败: " + e.getMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
package com.njzscloud.supervisory.wxPay.dto;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 模板数据封装类
|
|
||||||
*/
|
|
||||||
@Data
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class TemplateData {
|
|
||||||
|
|
||||||
private String value;
|
|
||||||
private String color;
|
|
||||||
|
|
||||||
public TemplateData(String value) {
|
|
||||||
this.value = value;
|
|
||||||
this.color = "#173177";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,18 +0,0 @@
|
||||||
package com.njzscloud.supervisory.wxPay.service;
|
|
||||||
|
|
||||||
import com.njzscloud.supervisory.wxPay.dto.TemplateData;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 微信消息推送服务接口
|
|
||||||
*/
|
|
||||||
public interface WechatTemplateMessageService {
|
|
||||||
|
|
||||||
void bind(String code);
|
|
||||||
|
|
||||||
String sendTemplateMessage(String openId, String templateId,
|
|
||||||
Map<String, TemplateData> data,
|
|
||||||
String url, String miniProgram);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,138 +0,0 @@
|
||||||
package com.njzscloud.supervisory.wxPay.service.impl;
|
|
||||||
|
|
||||||
import com.alibaba.fastjson2.JSONObject;
|
|
||||||
import com.njzscloud.common.core.ex.Exceptions;
|
|
||||||
import com.njzscloud.common.security.util.SecurityUtil;
|
|
||||||
import com.njzscloud.supervisory.sys.user.pojo.entity.UserEntity;
|
|
||||||
import com.njzscloud.supervisory.sys.user.service.UserService;
|
|
||||||
import com.njzscloud.supervisory.wxPay.contant.WxApiConfig;
|
|
||||||
import com.njzscloud.supervisory.wxPay.dto.TemplateData;
|
|
||||||
import com.njzscloud.supervisory.wxPay.service.WechatTemplateMessageService;
|
|
||||||
import lombok.RequiredArgsConstructor;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
import org.springframework.web.client.RestTemplate;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 微信消息推送服务实现类
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
@Service
|
|
||||||
@RequiredArgsConstructor
|
|
||||||
public class WechatTemplateMessageServiceImpl implements WechatTemplateMessageService {
|
|
||||||
|
|
||||||
public final UserService userService;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void bind(String code) {
|
|
||||||
// 使用Code换取Access Token和OpenID
|
|
||||||
String tokenUrl = WxApiConfig.OAUTH_URL + "appid=" + WxApiConfig.APP_ID + "&secret=" + WxApiConfig.APP_SECRET +
|
|
||||||
"&code=" + code + "&grant_type=authorization_code";
|
|
||||||
|
|
||||||
// 使用HTTP客户端发起请求
|
|
||||||
RestTemplate restTemplate = new RestTemplate();
|
|
||||||
String response = restTemplate.getForObject(tokenUrl, String.class);
|
|
||||||
|
|
||||||
// 解析微信返回的JSON数据
|
|
||||||
JSONObject jsonObject = JSONObject.parseObject(response);
|
|
||||||
if (null == jsonObject) {
|
|
||||||
throw Exceptions.clierr("获取openid失败");
|
|
||||||
}
|
|
||||||
String openId = jsonObject.getString("openid");
|
|
||||||
// String accessToken = jsonObject.getString("access_token");
|
|
||||||
// 返回中通常还包含 expires_in, refresh_token等字段[citation:1]
|
|
||||||
|
|
||||||
if (openId == null || openId.isEmpty()) {
|
|
||||||
// 错误处理
|
|
||||||
String errCode = (String) jsonObject.get("errcode");
|
|
||||||
String errMsg = (String) jsonObject.get("errmsg");
|
|
||||||
log.info("获取OpenID失败: " + errCode + " - " + errMsg);
|
|
||||||
throw Exceptions.clierr("获取openid失败");
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info("用户的OpenID是: " + openId);
|
|
||||||
|
|
||||||
// 将openId与你的系统用户关联
|
|
||||||
UserEntity userEntity = new UserEntity();
|
|
||||||
userEntity.setId(SecurityUtil.currentUserId());
|
|
||||||
userEntity.setOpenid(openId);
|
|
||||||
userService.updateById(userEntity);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送模板消息
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public String sendTemplateMessage(String openId, String templateId,
|
|
||||||
Map<String, TemplateData> data,
|
|
||||||
String url, String miniProgram) {
|
|
||||||
// 1. 获取Access Token
|
|
||||||
String accessToken = getAccessToken();
|
|
||||||
|
|
||||||
// 2. 构建请求数据
|
|
||||||
JSONObject requestData = new JSONObject();
|
|
||||||
requestData.put("touser", openId);
|
|
||||||
requestData.put("template_id", templateId);
|
|
||||||
|
|
||||||
if (url != null) {
|
|
||||||
requestData.put("url", url); // 点击消息跳转的URL
|
|
||||||
}
|
|
||||||
|
|
||||||
if (miniProgram != null) {
|
|
||||||
JSONObject miniProgramObj = new JSONObject();
|
|
||||||
miniProgramObj.put("appid", miniProgram);
|
|
||||||
miniProgramObj.put("pagepath", "pages/index/index");
|
|
||||||
requestData.put("miniprogram", miniProgramObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 构建模板数据
|
|
||||||
JSONObject dataObj = new JSONObject();
|
|
||||||
for (Map.Entry<String, TemplateData> entry : data.entrySet()) {
|
|
||||||
JSONObject item = new JSONObject();
|
|
||||||
item.put("value", entry.getValue().getValue());
|
|
||||||
if (entry.getValue().getColor() != null) {
|
|
||||||
item.put("color", entry.getValue().getColor());
|
|
||||||
}
|
|
||||||
dataObj.put(entry.getKey(), item);
|
|
||||||
}
|
|
||||||
requestData.put("data", dataObj);
|
|
||||||
log.info(JSONObject.toJSONString(requestData));
|
|
||||||
|
|
||||||
// 4. 发送请求
|
|
||||||
RestTemplate restTemplate = new RestTemplate();
|
|
||||||
String response = restTemplate.postForObject(WxApiConfig.SEND_TEMPLATE_MSG_URL + accessToken, JSONObject.toJSONString(requestData), String.class);
|
|
||||||
|
|
||||||
// 5. 处理响应
|
|
||||||
JSONObject jsonResponse = JSONObject.parseObject(response);
|
|
||||||
if (null == jsonResponse) {
|
|
||||||
throw Exceptions.clierr("发送模板消息失败,jsonResponse为null");
|
|
||||||
}
|
|
||||||
if (jsonResponse.getIntValue("errcode") == 0) {
|
|
||||||
return "发送成功";
|
|
||||||
} else {
|
|
||||||
throw Exceptions.clierr("发送模板消息失败: " + jsonResponse.getString("errmsg"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取Access Token
|
|
||||||
*/
|
|
||||||
private String getAccessToken() {
|
|
||||||
String tokenUrl = WxApiConfig.GET_TOKEN_URL + WxApiConfig.APP_ID + "&secret=" + WxApiConfig.APP_SECRET;
|
|
||||||
|
|
||||||
RestTemplate restTemplate = new RestTemplate();
|
|
||||||
String response = restTemplate.getForObject(tokenUrl, String.class);
|
|
||||||
JSONObject jsonResponse = JSONObject.parseObject(response);
|
|
||||||
if (null == jsonResponse) {
|
|
||||||
throw Exceptions.clierr("获取Access Token失败");
|
|
||||||
}
|
|
||||||
if (jsonResponse.getIntValue("errcode") != 0) {
|
|
||||||
throw Exceptions.clierr("发送模板消息失败: " + jsonResponse.getString("errmsg"));
|
|
||||||
}
|
|
||||||
return jsonResponse.getString("access_token");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue