Merge remote-tracking branch 'origin/master'

This commit is contained in:
李京通 2026-01-20 14:15:57 +08:00
commit e62fdd9e34
9 changed files with 110 additions and 29 deletions

View File

@ -182,10 +182,7 @@ public class SmallProgramController extends BaseController {
public AjaxResult payFees(@RequestBody PayFees payFees,HttpServletRequest request){ public AjaxResult payFees(@RequestBody PayFees payFees,HttpServletRequest request){
LoginUserByPhone loginUserByPhone = tokenService.getLoginUserByPhone(request); LoginUserByPhone loginUserByPhone = tokenService.getLoginUserByPhone(request);
ParkingBillInfo one = parkingBillInfoService.lambdaQuery() ParkingBillInfo one = parkingBillInfoService.getById(payFees.getId());
.eq(ParkingBillInfo::getBillCode, payFees.getBillCode())
.last("limit 1")
.one();
if (one == null) { if (one == null) {
return AjaxResult.error("停车记录查询失败"); return AjaxResult.error("停车记录查询失败");
} }
@ -202,17 +199,19 @@ public class SmallProgramController extends BaseController {
return AjaxResult.error("用户信息出错"); return AjaxResult.error("用户信息出错");
} }
String openId = null; String openId = null;
String userId = null;
PayType payType = PayType.getByCode(payFees.getPayType()); PayType payType = PayType.getByCode(payFees.getPayType());
switch (payType) { switch (payType) {
case WECHAT: case WECHAT:
openId = one1.getOpenId(); openId = one1.getOpenId();
break; break;
case ALIPAY: case ALIPAY:
openId = one1.getAlipayUserId(); openId = one1.getAlipayOpenId();
userId = one1.getAlipayUserId();
break; break;
} }
String clientIp = wechatMiniProgramPayService.getClientIpAddress(request); String clientIp = wechatMiniProgramPayService.getClientIpAddress(request);
Map<String, Object> order = createOrder(payFees, generate, openId, one, clientIp); Map<String, Object> order = createOrder(payFees, generate, openId, one, clientIp, userId);
ParkingBillPaymentInfo parkingBillPaymentInfo = new ParkingBillPaymentInfo(); ParkingBillPaymentInfo parkingBillPaymentInfo = new ParkingBillPaymentInfo();
parkingBillPaymentInfo.setBillCode(one.getBillCode()); parkingBillPaymentInfo.setBillCode(one.getBillCode());
@ -249,7 +248,8 @@ public class SmallProgramController extends BaseController {
String orderId, String orderId,
String openId, String openId,
ParkingBillInfo parkingBillInfo, ParkingBillInfo parkingBillInfo,
String clientIp) { String clientIp,
String userId) {
PayType payType = PayType.getByCode(payFees.getPayType()); PayType payType = PayType.getByCode(payFees.getPayType());
switch (payType) { switch (payType) {
@ -260,7 +260,7 @@ public class SmallProgramController extends BaseController {
case ALIPAY: case ALIPAY:
return alipayService.createOrder(orderId, return alipayService.createOrder(orderId,
parkingBillInfo.getPayMoneyYuan().toString(), parkingBillInfo.getPayMoneyYuan().toString(),
"常客隆智慧停车缴费",openId); "常客隆智慧停车缴费",openId,userId);
default: default:
throw new IllegalArgumentException("不支持的登录方式: " + payType); throw new IllegalArgumentException("不支持的登录方式: " + payType);

View File

@ -78,6 +78,12 @@ public class BaseCustomerInfo {
@Excel(name = "支付宝用户ID") @Excel(name = "支付宝用户ID")
private String alipayUserId; private String alipayUserId;
@ApiModelProperty("支付宝openID")
@Excel(name = "支付宝openID")
private String alipayOpenId;
/** /**
* 手机号 * 手机号
*/ */

View File

@ -8,9 +8,9 @@ import javax.validation.constraints.NotBlank;
@Data @Data
public class PayFees { public class PayFees {
@ApiModelProperty("账单编号") @ApiModelProperty("账单id")
@NotBlank(message = "账单编号不能为空") @NotBlank(message = "账单id不能为空")
private String billCode; private Long id;
@ApiModelProperty("支付方式: wechat 或 alipay") @ApiModelProperty("支付方式: wechat 或 alipay")
@NotBlank(message = "支付方式不能为空") @NotBlank(message = "支付方式不能为空")

View File

@ -4,9 +4,14 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.parser.Feature; import com.alibaba.fastjson.parser.Feature;
import com.alipay.api.AlipayApiException; import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipayEncrypt; import com.alipay.api.internal.util.AlipayEncrypt;
import com.alipay.api.internal.util.AlipaySignature; import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayUserInfoShareRequest;
import com.alipay.api.response.AlipayUserInfoShareResponse;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.config.AlipayRYConfig;
import com.ruoyi.database.exception.BusinessException; import com.ruoyi.database.exception.BusinessException;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.A; import org.checkerframework.checker.units.qual.A;
@ -46,6 +51,8 @@ public class AlipayPhoneService {
@Value("${alipay.gateway}") @Value("${alipay.gateway}")
private String gateway; private String gateway;
@Value("${alipay.publicKey}")
private String publicKey;
private final String AES_STR = "LoKBapEj35+bRnC/Rrhe8g=="; private final String AES_STR = "LoKBapEj35+bRnC/Rrhe8g==";
@ -84,7 +91,7 @@ public class AlipayPhoneService {
/** /**
* 获取用户id * 获取用户id
*/ */
private String getOpenId(String authCode) { private Map<String,String> getOpenId(String authCode) {
try { try {
Map<String, String> params = buildBaseParams(); Map<String, String> params = buildBaseParams();
params.put("method", "alipay.system.oauth.token"); params.put("method", "alipay.system.oauth.token");
@ -113,13 +120,31 @@ public class AlipayPhoneService {
throw new BusinessException("ALIPAY_ACCESS_TOKEN_ERROR", "获取access_token失败: 响应格式错误"); throw new BusinessException("ALIPAY_ACCESS_TOKEN_ERROR", "获取access_token失败: 响应格式错误");
} }
String accessToken = (String) tokenResponse.get("open_id"); String openId = (String) tokenResponse.get("open_id");
String accessToken = (String) tokenResponse.get("access_token");
if (accessToken == null || accessToken.trim().isEmpty()) { if (accessToken == null || accessToken.trim().isEmpty()) {
throw new BusinessException("ALIPAY_ACCESS_TOKEN_ERROR", "获取access_token失败: access_token为空"); throw new BusinessException("ALIPAY_ACCESS_TOKEN_ERROR", "获取access_token失败: access_token为空");
} }
log.info("成功获取access_token: {}", accessToken); log.info("成功获取access_token: {}", accessToken);
return accessToken; AlipayClient alipayClient = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",
appId,
privateKey,
"json",
"GBK",
publicKey,
"RSA2");
AlipayUserInfoShareRequest request = new AlipayUserInfoShareRequest();
AlipayUserInfoShareResponse response = alipayClient.execute(request,accessToken);
if(response.isSuccess()){
Map<String, String> map = new HashMap<>();
map.put("openId",openId);
map.put("userId",response.getUserId());
return map;
}else {
return null;
}
} catch (Exception e) { } catch (Exception e) {
log.error("获取access_token异常", e); log.error("获取access_token异常", e);
@ -324,12 +349,10 @@ public class AlipayPhoneService {
return phoneNumber.matches("^1[3-9]\\d{9}$"); return phoneNumber.matches("^1[3-9]\\d{9}$");
} }
/**
* 获取支付宝用户ID (如果需要) public Map<String,String> getAlipayOpenId(String authCode) {
*/
public String getAlipayUserId(String authCode) {
try { try {
String openId = getOpenId(authCode); Map<String,String> openId = getOpenId(authCode);
// 在实际业务中你可能需要根据手机号关联用户ID // 在实际业务中你可能需要根据手机号关联用户ID
// 这里返回手机号作为示例实际应该返回支付宝用户ID // 这里返回手机号作为示例实际应该返回支付宝用户ID

View File

@ -31,7 +31,7 @@ public class AlipayService {
* @param buyerId 支付宝用户ID相当于OpenID * @param buyerId 支付宝用户ID相当于OpenID
* @return 支付订单字符串用于小程序前端调起支付 * @return 支付订单字符串用于小程序前端调起支付
*/ */
public Map<String, Object> createOrder(String orderId, String amount, String subject, String buyerId) { public Map<String, Object> createOrder(String orderId, String amount, String subject, String buyerId,String userId) {
try { try {
AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig()); AlipayClient alipayClient = new DefaultAlipayClient(getAlipayConfig());
// 构造请求参数以调用接口 // 构造请求参数以调用接口
@ -51,6 +51,7 @@ public class AlipayService {
model.setBody(subject); model.setBody(subject);
// 设置买家支付宝用户唯一标识 // 设置买家支付宝用户唯一标识
model.setBuyerOpenId(buyerId); model.setBuyerOpenId(buyerId);
// model.setBuyerId(userId);
request.setBizModel(model); request.setBizModel(model);
AlipayTradeCreateResponse response = alipayClient.execute(request); AlipayTradeCreateResponse response = alipayClient.execute(request);
System.out.println(response.getBody()); System.out.println(response.getBody());

View File

@ -154,7 +154,7 @@ public class WechatPhoneService {
/** /**
* 获取微信用户openid (如果需要) * 获取微信用户openid (如果需要)
*/ */
public String getOpenId(String jsCode) { public Map<String,String> getOpenId(String jsCode) {
try { try {
String url = String.format( String url = String.format(
"https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code", "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
@ -174,7 +174,9 @@ public class WechatPhoneService {
if (openid != null) { if (openid != null) {
log.info("成功获取微信openid"); log.info("成功获取微信openid");
return openid; Map<String,String> map = new HashMap<>();
map.put("openId",openid);
return map;
} else if (errcode != null) { } else if (errcode != null) {
String errmsg = (String) result.get("errmsg"); String errmsg = (String) result.get("errmsg");
throw new BusinessException("WECHAT_OPENID_ERROR", throw new BusinessException("WECHAT_OPENID_ERROR",

View File

@ -51,7 +51,10 @@ public class ParkingBillInfoServiceImpl extends ServiceImpl<ParkingBillInfoMappe
updateWrapper.eq(ParkingBillInfo::getInUnid,parkingBillInfo.getInUnid()); updateWrapper.eq(ParkingBillInfo::getInUnid,parkingBillInfo.getInUnid());
boolean b = saveOrUpdate(parkingBillInfo, updateWrapper); boolean b = saveOrUpdate(parkingBillInfo, updateWrapper);
if (b) { if (b) {
return parkingBillInfo; ParkingBillInfo one = lambdaQuery().eq(ParkingBillInfo::getInUnid, parkingBillInfo.getInUnid())
.last("LIMIT 1")
.one();
return one;
}else { }else {
return null; return null;
} }

View File

@ -0,0 +1,45 @@
package com.ruoyi.database.util;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Util {
/**
* 生成MD5加密字符串32位小写
*/
public static String md5(String input) {
try {
MessageDigest md = MessageDigest.getInstance("MD5");
byte[] digest = md.digest(input.getBytes());
return bytesToHex(digest);
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
/**
* 字节数组转十六进制字符串
*/
private static String bytesToHex(byte[] bytes) {
StringBuilder hexString = new StringBuilder();
for (byte b : bytes) {
String hex = Integer.toHexString(0xff & b);
if (hex.length() == 1) {
hexString.append('0');
}
hexString.append(hex);
}
return hexString.toString();
}
// 使用示例
public static void main(String[] args) {
long l = System.currentTimeMillis() / 1000L;
System.out.println(l + "");
String text = "15599026928" + l + "VAR21UEUjhHmeMqiAvA7VYvQLPn5rO2z";
String md5Hash = md5(text);
System.out.println("MD5加密结果: " + md5Hash);
// 输出: b10a8db164e0754105b7a99be72e3fe5
}
}

View File

@ -31,6 +31,7 @@ import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid; import javax.validation.Valid;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Set; import java.util.Set;
/** /**
@ -101,8 +102,7 @@ public class SysLoginController {
String phoneNumber = getPhoneNumberByLoginType(request); String phoneNumber = getPhoneNumberByLoginType(request);
LoginBodyByPhone loginBodyByPhone = new LoginBodyByPhone(); LoginBodyByPhone loginBodyByPhone = new LoginBodyByPhone();
loginBodyByPhone.setPhone(phoneNumber); loginBodyByPhone.setPhone(phoneNumber);
String openId = getOpenId(request); Map<String,String> openId = getOpenId(request);
LoginType loginType = LoginType.getByCode(request.getLoginType()); LoginType loginType = LoginType.getByCode(request.getLoginType());
AjaxResult ajax = AjaxResult.success(); AjaxResult ajax = AjaxResult.success();
// 生成令牌 // 生成令牌
@ -112,10 +112,11 @@ public class SysLoginController {
.one(); .one();
switch (loginType) { switch (loginType) {
case WECHAT: case WECHAT:
one.setOpenId(openId); one.setOpenId(openId.get("openId"));
break; break;
case ALIPAY: case ALIPAY:
one.setAlipayUserId(openId); one.setAlipayUserId(openId.get("userId"));
one.setAlipayOpenId(openId.get("openId"));
break; break;
} }
if (one == null) { if (one == null) {
@ -172,7 +173,7 @@ public class SysLoginController {
* @param request * @param request
* @return * @return
*/ */
private String getOpenId(LoginRequest request) { private Map<String,String> getOpenId(LoginRequest request) {
LoginType loginType = LoginType.getByCode(request.getLoginType()); LoginType loginType = LoginType.getByCode(request.getLoginType());
switch (loginType) { switch (loginType) {
@ -180,7 +181,7 @@ public class SysLoginController {
return wechatPhoneService.getOpenId(request.getAuthCode()); return wechatPhoneService.getOpenId(request.getAuthCode());
case ALIPAY: case ALIPAY:
return alipayPhoneService.getAlipayUserId(request.getAuthCode()); return alipayPhoneService.getAlipayOpenId(request.getAuthCode());
default: default:
throw new IllegalArgumentException("不支持的登录方式: " + loginType); throw new IllegalArgumentException("不支持的登录方式: " + loginType);