提交修改

This commit is contained in:
quyixiao 2025-11-11 20:52:35 +08:00
parent b9cf1c8b56
commit c4b1253fb3
8 changed files with 266 additions and 7 deletions

View File

@ -0,0 +1,17 @@
package com.heyu.api.data.dto;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@Data
public class AccessTokenDTO {
@JsonProperty("access_token")
private String accessToken;
@JsonProperty("expires_in")
private Integer expiresIn;
}

View File

@ -24,9 +24,10 @@ import org.apache.http.util.EntityUtils;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
@ -65,6 +66,46 @@ public class HttpUtils {
return httpClient.execute(request);
}
// 原生HttpURLConnection方式
public static byte[] getWechatQrcodeByHttpURL(String url, Map<String, Object> body) {
HttpURLConnection httpURLConnection = null;
try {
httpURLConnection = (HttpURLConnection) new URL(url).openConnection();
httpURLConnection.setRequestMethod("POST");
// 发送POST请求必须设置如下两行
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
// 获取URLConnection对象对应的输出流
PrintWriter printWriter = new PrintWriter(httpURLConnection.getOutputStream());
// 发送请求参数
printWriter.write(JSONObject.toJSONString(body));
// flush输出流的缓冲
printWriter.flush();
//开始获取数据
try (InputStream inputStream = httpURLConnection.getInputStream();
ByteArrayOutputStream out = new ByteArrayOutputStream()) {
byte[] buffer = new byte[1024];
int len = -1;
while ((len = inputStream.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
return out.toByteArray();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (httpURLConnection != null) {
httpURLConnection.disconnect();
}
}
return null;
}
/**
* 发送POST方式请求
*
@ -169,6 +210,13 @@ public class HttpUtils {
.setSocketTimeout(TIMEOUT_MSEC).build();
}
public static String doGet(String url) {
return doGet(url,null);
}
/**
* 发送GET方式请求
*
@ -219,6 +267,7 @@ public class HttpUtils {
}
/**
* post form

View File

@ -61,6 +61,13 @@ public class RedisUtils {
public final static long thirty_minute = 30 * 60;
/**
* 默认过期时长单位
*/
public final static long one_hours = 1* 60 * 60;
/**
* 不设置过期时长
*/

View File

@ -94,4 +94,8 @@ public interface OssFileUploadService {
public List<Map<String, Object>> uploadImages(MultipartFile[] files);
OssUploadResult uploadImageToOss(InputStream inputStream,String oss_buccket, String fileName, int fileSize);
OssUploadResult uploadImageByBytes(byte[] bytes);
}

View File

@ -48,7 +48,7 @@ public class OssFileUploadServiceImpl implements OssFileUploadService {
public OssUploadResult uploadToOss(MultipartFile imageFile) {
String fileName = imageFile.getOriginalFilename();
String contextType = this.getImageFileContentType(fileName);
String path = env + "/";
String path = env + "/" ;
String fileNameSuffix = DigestUtil.MD5_16(UUID.randomUUID().toString());
if (StringUtils.isNotBlank(contextType)) {
fileNameSuffix = fileNameSuffix + fileName.substring(fileName.lastIndexOf("."));
@ -96,6 +96,51 @@ public class OssFileUploadServiceImpl implements OssFileUploadService {
return this.uploadFileToOss(imageFile, contextType, path, fileNameSuffix);
}
@Override
public OssUploadResult uploadImageByBytes(byte[] bytes) {
InputStream inputStream = null;
OssUploadResult result = new OssUploadResult();
try {
String suffix = ".jpeg";
// 步骤 2: 使用字节数组创建 InputStream
inputStream = new ByteArrayInputStream(bytes);
// 生成文件名称
String path = env + "/";
String fileName = DigestUtil.MD5_16(UUID.randomUUID().toString()) + suffix;
//3 获取文件信息为了上传
// meta设置请求头
ObjectMetadata meta = new ObjectMetadata();
meta.setContentType(MimeTypeEnums.getContentType(suffix));
//4 设置知道文件夹
PutObjectResult pubResult = ossClient.putObject(oss_buccket, path + fileName, inputStream, meta);
result.setSuccess(true);
result.setMsg("upload to oss succeed");
result.setFileMd5(pubResult.getETag());
result.setUrl(oss_url + path + fileName);
return result;
} catch (Exception e) {
log.error("upload to oss error", e);
} finally {
if(inputStream !=null){
try {
inputStream.close();
} catch (IOException e) {
log.error("inputStream to close error", e);
}
}
}
return null;
}
@Override
public OssUploadResult uploadImageToOss(InputStream inputStream, String fileName, int fileSize) {
OssUploadResult result = new OssUploadResult();

View File

@ -0,0 +1,113 @@
package com.heyu.api.controller.vv;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.heyu.api.alibaba.request.vv.AppPromoterRequest;
import com.heyu.api.common.annotation.Describe;
import com.heyu.api.data.dto.AccessTokenDTO;
import com.heyu.api.data.utils.HttpUtils;
import com.heyu.api.data.utils.R;
import com.heyu.api.data.utils.RedisUtils;
import com.heyu.api.data.utils.StringUtils;
import com.heyu.api.oss.OssFileUploadService;
import com.heyu.api.oss.OssUploadResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@Slf4j
@RestController
@RequestMapping("/app/qrcode")
public class AppQrCodeController {
public static final String wechatQrcodeUrl = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=";
public static final String wechatAccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?appid=%s&secret=%s&grant_type=client_credential";
@Value("${eb.config.weixin.pay.appid}")
private String appid;
@Value("${eb.config.weixin.pay.appSecret}")
private String appSecret;
// 自行配置正式版为 "release"体验版为 "trial"开发版为 "develop"默认是正式版
private String envVersion = "trial";
@Autowired
private RedisUtils redisUtils;
public static final String jsapi_acessToken = "jsapi_acessToken";
@Autowired
private OssFileUploadService ossFileUploadService;
/***
* 列表
* http://localhost:8888/app/qrcode/create
*
* https://developers.weixin.qq.com/miniprogram/dev/OpenApiDoc/qrcode-link/qr-code/getUnlimitedQRCode.html
*
*/
@Describe("生成二维码")
@RequestMapping("/create")
public R create(@RequestBody AppPromoterRequest request) {
// 当前登录账号
String accountId = "123456";
AccessTokenDTO accessTokenDTO = null;
String acessTokenJson = redisUtils.get(jsapi_acessToken);
if (StringUtils.isNotEmpty(acessTokenJson)) {
accessTokenDTO = JSONObject.parseObject(acessTokenJson, AccessTokenDTO.class);
} else {
accessTokenDTO = getAccessToken(appid, appSecret);
redisUtils.set(jsapi_acessToken, JSON.toJSONString(accessTokenDTO), RedisUtils.one_hours);
}
String accessToken = accessTokenDTO.getAccessToken();
String url = wechatQrcodeUrl + accessToken;
Map<String, Object> body = new HashMap<>();
// 场景码请根据业务场景与前端约定
// 最大32个可见字符只支持数字大小写英文以及部分特殊字符!#$&'()*+,/:;=?@-._~其它字符请自行编码为合法字符因不支持%中文无法使用 urlencode 处理请使用其他编码方式
body.put("scene", String.format("a=%s", accountId));
body.put("env_version", envVersion);
// body.put("page", envVersion); 默认是主页页面 page例如 pages/index/index根路径前不要填加 /不能携带参数参数请放在scene字段里如果不填写这个字段默认跳主页面scancode_time为系统保留参数不允许配置
// 透明
body.put("is_hyaline", true); // 默认是false是否需要透明底色 true 生成透明底色的小程序
byte[] bytes = HttpUtils.getWechatQrcodeByHttpURL(url, body);
if (bytes == null) {
return R.error("bytes is null");
}
String error = new String(bytes);
if (error.contains("errcode")) {
return R.error(error);
}
OssUploadResult ossUploadResult = ossFileUploadService.uploadImageByBytes(bytes);
return R.ok().setData(ossUploadResult);
}
// 获取access_token
public AccessTokenDTO getAccessToken(String appid, String appSecret) {
String url = String.format(wechatAccessTokenUrl, appid, appSecret);
String responseBody = HttpUtils.doGet(url);
log.info("getAccessToken responseBody:{}", responseBody);
AccessTokenDTO accessTokenDTO = JSONObject.parseObject(responseBody, AccessTokenDTO.class);
return accessTokenDTO;
}
}

View File

@ -2,6 +2,7 @@ package com.heyu.api.controller.vv;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.heyu.api.alibaba.request.mm.VvAnonymousUserLoginRequest;
import com.heyu.api.alibaba.request.mm.VvAppLoginRequest;
import com.heyu.api.alibaba.request.vv.AppUserLoginRequest;
@ -41,6 +42,7 @@ public class AppUserLoginController {
if (weiChatLoginDTO == null) {
return R.error("code 失效");
}
VvBuyerEntity target = vvBuyerDao.selectVvBuyerOpenId(weiChatLoginDTO.getOpenid());
if (target == null) {
target = new VvBuyerEntity();
@ -48,6 +50,7 @@ public class AppUserLoginController {
target.setIsTest(0);
target.setCreateTimestamp(System.currentTimeMillis());
}
target.setSessionKey(weiChatLoginDTO.getSessionKey());
vvBuyerDao.insertOrUpdateVvBuyer(target);
BuyerDTO buyerDTO = new BuyerDTO();
@ -57,7 +60,7 @@ public class AppUserLoginController {
String token = TokenUtils.generateToken(target.getId());
buyerDTO.setToken(token);
// 默认24 小时
redisUtils.set(token, JSON.toJSON(buyerDTO), RedisUtils.DEFAULT_EXPIRE);
redisUtils.set(token, JSON.toJSONString(buyerDTO), RedisUtils.DEFAULT_EXPIRE);
return R.ok().put("buyer", buyerDTO);
}
@ -77,7 +80,7 @@ public class AppUserLoginController {
Random random = new Random(1000000L);
String token = TokenUtils.generateToken(random.nextLong());
buyerDTO.setToken(token);
redisUtils.set(token, JSON.toJSON(buyerDTO), RedisUtils.thirty_minute);
redisUtils.set(token, JSON.toJSONString(buyerDTO), RedisUtils.thirty_minute);
return R.ok().put("buyer", buyerDTO);
}
@ -101,8 +104,28 @@ public class AppUserLoginController {
String token = TokenUtils.generateToken(target.getId());
buyerDTO.setToken(token);
// 默认24 小时
redisUtils.set(token, JSON.toJSON(buyerDTO), RedisUtils.DEFAULT_EXPIRE);
redisUtils.set(token, JSON.toJSONString(buyerDTO), RedisUtils.DEFAULT_EXPIRE);
return R.ok().put("buyer", buyerDTO);
}
@RequestMapping("/getPhoneNumber")
public Object getPhoneNumber(@RequestBody VvAppLoginRequest request) {
// String sessionKey = userRepository.findByOpenId(request.getOpenId()).getSessionKey(); // 从数据库中获取 sessionKey
// JSONObject phoneInfo = JSONObject.parseObject(WxMaCryptUtils.decrypt(sessionKey, request.getEncryptedData(), request.getIv())); // 解密获取手机号信息
// String phoneNumber = phoneInfo.getString("phoneNumber");
// 更新用户信息并存储到数据库
// 返回给前端的手机号信息
JSONObject result = new JSONObject();
result.put("phoneNumber", null);
return result;
}
}

View File

@ -66,12 +66,13 @@ eb:
weixin:
pay:
appid: wx75fa59c097bd3dfd
appSecret: 1837c382de696013a2dfc64591e6b854
mchid: 1731491745
certificateSerialNo: 793D48CCEB62C6B227E0A4F46AD90279B149A7BE
privateKeyFilePath: MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCzn74aYlkoD1lOrcbpqW9aIE/IiH/lAea+nFmmmao5ggxrXhnvkGDQ3e+59Cf59jTikKxmMc+aj36maxrd/OYDM27j0q5b7t8fWPD4qqyMR2uqiImc622BpQIxaPUeLeDHwsHq4C6g0UzZ6DXJppHpb6xn0gEFHS87Na0hhElCbEpjEnbyhRmOC1yDPDmnDTGMX2LP0Cxx6U1pX4JmYToQ0/iOFeD8F9sLrQElGelJnDS6QY+L+qKe7SecNv0axvbwyGXuSUef2+GWgBCnBeWTZhhHNPNAFo6fQR9+zaQmZEksg9HxmAKLxG1w6YSMXQWk8psSiCSoiQfu39m3pN13AgMBAAECggEAbhvoPug22xW9mztvieDxf3/7KGR0cf+eYQ4a7sOX07TixBZlM7N/hcnmoEkJEHNaq+Afrm2uY4K/EmjpiVbz8NZgjYuiknx1jhPJc8W8DCnj2B/mq6it8iEinQNH7v4Uop/Cm6ZdLvvebl2oSzquiziHqQTU1zuyrksTHE6pUetj6ci2AgyKOpyZ3nJ8ivgUSFuvQjlEQ1aJFrFg6nm52MTdJqB9JaQEcBYxw21JCfl1zNZ7EO4eFBqzNO0ttu3EJckYDKClhcesNrJJGUHvPFGo2hfOd2ZzfA4UnaL7yaraAJxQbqwnXOoaV14ka9HYNfakmz59348AxrIbPtHj0QKBgQDskdn7Cut/1DV2EhW26rNj9zaXt55COujHf5+0htj9JrZ6u9s4sCHuzPo8rLiAw7/Pvksfa7Oq+BHE65rMds88KluLyW84b1Wd4annyI+anjtDyz3Chmx7NGQyaHg7lfOqJ09S/0T6WwSViZJz3Fp6p39+1ROyhWZaFRQIwrA6UwKBgQDCYIrAYFnqBaXMk5wFoDg2kc7H6/SL9wgxTo5EwV/ccqFirbScjuM9IkylcIx02gKUH9y+3aDccNPr7PqIreLip9sX+DdFqDa5yEtY4XNR9zAf0aSgo+qSCAtgMqrWwyV+fKUjbzEbEjD7STPXLy+r1YC0g0Z7WeszLG0f4MYTzQKBgQCkCFW+7klwrzIKlmucE40jqYyfEmCXx8UUX3fbcw0OK0OoQo209tvwewyf+ZtNHW3onCf2t3Uy/SNFCaCiWVdEfpJPkPKfjQMuoARxhO2d5k1tqoU+VnrtytwW371Og6EawHsOL5Yiie3ZyjRURdwu4+lRhmlMBZd8qtTjZitPpQKBgQCVrMOLKWZzRxAJvOxahKpkkthYp//yOzHqzePNW95WIUrWco3uNDUVITFF/6mYXTu5FePkcULqHFODi0LMNqHMCJc0GOVu1P33Bx3F/izPw/kht0v+itoYwusHk1xr7W8UvCRpabi1cMeY6CBsJaCev9PQrHl8iJwNFruc3XeJTQKBgFt31iujP7W2FHaT6uyO1gKSlqCcZILD2F15Q52OYQoV6I5Tq152ITyMyE4EiYPOqnqVWUc+ej1m+AuvYljRqlvVCmp91QtYwLGguuHFYNVcE2V3WftKKbIIPT2qEFaS5eUb6hB+kl02E1EmjCtApwssCVJj81yu/DsBP0580zBL
wechatPayPublicKeyId: PUB_KEY_ID_0117314917452025110400382304001401
wechatPayPublicKeyFilePath: MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx/QqdSnkS8wd7xFH0LHVpZTFVI+eWL383eAP7RaxHfRwXNDfZYrdi/Bt8Enko+1Wkr2FGY2kS4Hol5NCvuZ7UY28/L4r95dBEgXtflkrxeVbiNbWHtiIdNXZSgkrpUkZEFoh7ks5Ou3pAlpG+94/Nnc//D/yckM7AuD85G1foZMSO5niyVeFAed6z7CeBMAhRVdnOIDUqsI/NaHruT4fvWNzPnn5SQKoKum00vRHckxftUqMkZ1D/YxHiAycEc9H0hCgLW7ZM6UV88Loa6SPvhM0fmXIuk6p277ldlxFl6Bcxd5jOcCTjdpWaB3CeSXnSIBl6KsZNcV3vPC3xey1WwIDAQAB
appid: wx75fa59c097bd3dfd
notifyUrl: https://api.1024api.com/api-interface/app/weixin/payNotify
apiv3key: E938F17ABF6843743F49688269F73B7D
refundNotifyUrl: https://api.1024api.com/api-interface/app/weixin/refundNotify