perf: 优化支付宝支付流程

This commit is contained in:
xiongxiaoyang 2024-02-04 12:25:26 +08:00
parent 4665b5c4b9
commit 4c82c2d720
6 changed files with 161 additions and 145 deletions

View File

@ -121,7 +121,7 @@ public class PayController extends BaseController {
PrintWriter out = httpResponse.getWriter();
//获取支付宝POST过来反馈信息
//获取支付宝POST过来信息
Map<String, String> params = new HashMap<>();
Map<String, String[]> requestParams = request.getParameterMap();
for (String name : requestParams.keySet()) {
@ -134,18 +134,10 @@ public class PayController extends BaseController {
params.put(name, valueStr);
}
//调用SDK验证签名
//验证签名
boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayConfig.getPublicKey(),
alipayConfig.getCharset(), alipayConfig.getSignType());
//请在这里编写您的程序以下代码仅作参考
/* 实际验证过程建议商户务必添加以下校验
1需要验证该通知数据中的out_trade_no是否为商户系统中创建的订单号
2判断total_amount是否确实为该订单的实际金额即商户订单创建时的金额
3校验通知中的seller_id或者seller_email) 是否为out_trade_no这笔单据的对应的操作方有的时候一个商户可能有多个seller_id/seller_email
4验证app_id是否为该商户本身
*/
if (signVerified) {
//验证成功
//商户订单号
@ -160,21 +152,18 @@ public class PayController extends BaseController {
String tradeStatus = new String(request.getParameter("trade_status").getBytes(StandardCharsets.ISO_8859_1),
StandardCharsets.UTF_8);
//更新订单状态
orderService.updatePayOrder(Long.parseLong(outTradeNo), tradeNo, tradeStatus);
if ("TRADE_SUCCESS".equals(tradeStatus)) {
//支付成功
orderService.updatePayOrder(Long.parseLong(outTradeNo), tradeNo, 1);
}
out.println("success");
} else {//验证失败
out.println("fail");
//调试用写文本函数记录程序运行情况是否正常
//String sWord = AlipaySignature.getSignCheckContentV1(params);
//AlipayConfig.logResult(sWord);
}
}
}

View File

@ -0,0 +1,15 @@
package com.java2nb.novel.mapper;
import org.apache.ibatis.annotations.Param;
/**
* @author Administrator
*/
public interface FrontUserMapper extends UserMapper {
void addUserBalance(@Param("userId") Long userId, @Param("amount") Integer amount);
}

View File

@ -1,7 +1,6 @@
package com.java2nb.novel.service;
/**
* @author 11797
*/
@ -12,18 +11,19 @@ public interface OrderService {
* 创建充值订单
*
* @param payChannel 支付渠道
* @param payAmount 支付金额
* @param userId 用户ID
* @param payAmount 支付金额
* @param userId 用户ID
* @return 商户订单号
* */
*/
Long createPayOrder(Byte payChannel, Integer payAmount, Long userId);
/**
* 更新订单状态
*
* @param outTradeNo 商户订单号
* @param tradeNo 支付宝/微信 订单号
* @param tradeStatus 支付状态
* */
void updatePayOrder(Long outTradeNo, String tradeNo, String tradeStatus);
* @param tradeNo 支付宝/微信 订单号
* @param payStatus 支付状态
*/
void updatePayOrder(Long outTradeNo, String tradeNo, int payStatus);
}

View File

@ -9,6 +9,7 @@ import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.mybatis.dynamic.sql.render.RenderingStrategies;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import org.mybatis.dynamic.sql.update.render.UpdateStatementProvider;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -17,6 +18,7 @@ import java.util.Date;
import java.util.Random;
import static org.mybatis.dynamic.sql.SqlBuilder.isEqualTo;
import static org.mybatis.dynamic.sql.SqlBuilder.update;
import static org.mybatis.dynamic.sql.select.SelectDSL.select;
/**
@ -50,7 +52,7 @@ public class OrderServiceImpl implements OrderService {
@Transactional(rollbackFor = Exception.class)
@Override
public void updatePayOrder(Long outTradeNo, String tradeNo, String tradeStatus) {
public void updatePayOrder(Long outTradeNo, String tradeNo, int payStatus) {
SelectStatementProvider selectStatement = select(OrderPayDynamicSqlSupport.id,
OrderPayDynamicSqlSupport.payStatus, OrderPayDynamicSqlSupport.totalAmount,
OrderPayDynamicSqlSupport.userId)
@ -59,25 +61,30 @@ public class OrderServiceImpl implements OrderService {
.build()
.render(RenderingStrategies.MYBATIS3);
OrderPay orderPay = orderPayMapper.selectMany(selectStatement).get(0);
OrderPay orderPay = orderPayMapper.selectOne(selectStatement).orElse(null);
if (orderPay.getPayStatus().intValue() != 1) {
//此订单还未处理过
if (tradeStatus.equals("TRADE_SUCCESS") || tradeStatus.equals("TRADE_FINISHED")) {
if (orderPay.getPayStatus().intValue() == 2) {
//待支付订单处理
if (payStatus == 1) {
//支付成功
//1.更新订单状态为成功
orderPay.setPayStatus((byte) 1);
orderPay.setUpdateTime(new Date());
orderPayMapper.updateByPrimaryKeySelective(orderPay);
//2.增加用户余额
userService.addAmount(orderPay.getUserId(), orderPay.getTotalAmount() * 100);
UpdateStatementProvider updateStatement = update(OrderPayDynamicSqlSupport.orderPay)
.set(OrderPayDynamicSqlSupport.tradeNo).equalTo(tradeNo)
.set(OrderPayDynamicSqlSupport.payStatus).equalTo((byte) 1)
.set(OrderPayDynamicSqlSupport.updateTime).equalTo(new Date())
.where(OrderPayDynamicSqlSupport.id, isEqualTo(orderPay.getId()))
.and(OrderPayDynamicSqlSupport.payStatus, isEqualTo((byte) 2))
.build()
.render(RenderingStrategies.MYBATIS3);
int updateRow = orderPayMapper.update(updateStatement);
if (updateRow > 0) {
//更新成功
//2.增加用户余额
userService.addAmount(orderPay.getUserId(), orderPay.getTotalAmount() * 100);
}
}
}
}
}

View File

@ -1,20 +1,20 @@
package com.java2nb.novel.service.impl;
import com.github.pagehelper.PageHelper;
import io.github.xxyopen.model.page.PageBean;
import com.java2nb.novel.core.bean.UserDetails;
import com.java2nb.novel.entity.*;
import com.java2nb.novel.entity.User;
import com.java2nb.novel.service.UserService;
import com.java2nb.novel.core.enums.ResponseStatus;
import com.java2nb.novel.entity.User;
import com.java2nb.novel.entity.*;
import com.java2nb.novel.mapper.*;
import com.java2nb.novel.service.UserService;
import com.java2nb.novel.vo.BookReadHistoryVO;
import com.java2nb.novel.vo.BookShelfVO;
import com.java2nb.novel.vo.UserFeedbackVO;
import io.github.xxyopen.model.page.PageBean;
import io.github.xxyopen.model.page.builder.pagehelper.PageBuilder;
import io.github.xxyopen.util.IdWorker;
import io.github.xxyopen.util.MD5Util;
import io.github.xxyopen.web.exception.BusinessException;
import com.java2nb.novel.mapper.*;
import com.java2nb.novel.vo.BookReadHistoryVO;
import com.java2nb.novel.vo.BookShelfVO;
import com.java2nb.novel.vo.UserFeedbackVO;
import io.github.xxyopen.web.util.BeanUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@ -46,7 +46,7 @@ import static org.mybatis.dynamic.sql.select.SelectDSL.select;
@RequiredArgsConstructor
public class UserServiceImpl implements UserService {
private final UserMapper userMapper;
private final FrontUserMapper userMapper;
private final FrontUserBookshelfMapper userBookshelfMapper;
@ -63,17 +63,17 @@ public class UserServiceImpl implements UserService {
public UserDetails register(User user) {
//查询用户名是否已注册
SelectStatementProvider selectStatement = select(count(id))
.from(UserDynamicSqlSupport.user)
.where(username, isEqualTo(user.getUsername()))
.build()
.render(RenderingStrategies.MYBATIS3);
.from(UserDynamicSqlSupport.user)
.where(username, isEqualTo(user.getUsername()))
.build()
.render(RenderingStrategies.MYBATIS3);
long count = userMapper.count(selectStatement);
if (count > 0) {
//用户名已注册
throw new BusinessException(ResponseStatus.USERNAME_EXIST);
}
User entity = new User();
BeanUtils.copyProperties(user,entity);
BeanUtils.copyProperties(user, entity);
//数据库生成注册记录
Long id = idWorker.nextId();
entity.setId(id);
@ -94,12 +94,12 @@ public class UserServiceImpl implements UserService {
@Override
public UserDetails login(User user) {
//根据用户名密码查询记录
SelectStatementProvider selectStatement = select(id, username,nickName)
.from(UserDynamicSqlSupport.user)
.where(username, isEqualTo(user.getUsername()))
.and(password, isEqualTo(MD5Util.MD5Encode(user.getPassword(), Charsets.UTF_8.name())))
.build()
.render(RenderingStrategies.MYBATIS3);
SelectStatementProvider selectStatement = select(id, username, nickName)
.from(UserDynamicSqlSupport.user)
.where(username, isEqualTo(user.getUsername()))
.and(password, isEqualTo(MD5Util.MD5Encode(user.getPassword(), Charsets.UTF_8.name())))
.build()
.render(RenderingStrategies.MYBATIS3);
List<User> users = userMapper.selectMany(selectStatement);
if (users.size() == 0) {
throw new BusinessException(ResponseStatus.USERNAME_PASS_ERROR);
@ -116,11 +116,11 @@ public class UserServiceImpl implements UserService {
@Override
public Boolean queryIsInShelf(Long userId, Long bookId) {
SelectStatementProvider selectStatement = select(count(UserBookshelfDynamicSqlSupport.id))
.from(userBookshelf)
.where(UserBookshelfDynamicSqlSupport.userId, isEqualTo(userId))
.and(UserBookshelfDynamicSqlSupport.bookId, isEqualTo(bookId))
.build()
.render(RenderingStrategies.MYBATIS3);
.from(userBookshelf)
.where(UserBookshelfDynamicSqlSupport.userId, isEqualTo(userId))
.and(UserBookshelfDynamicSqlSupport.bookId, isEqualTo(bookId))
.build()
.render(RenderingStrategies.MYBATIS3);
return userBookshelfMapper.count(selectStatement) > 0;
}
@ -141,10 +141,10 @@ public class UserServiceImpl implements UserService {
@Override
public void removeFromBookShelf(Long userId, Long bookId) {
DeleteStatementProvider deleteStatement = deleteFrom(userBookshelf)
.where(UserBookshelfDynamicSqlSupport.userId, isEqualTo(userId))
.and(UserBookshelfDynamicSqlSupport.bookId, isEqualTo(bookId))
.build()
.render(RenderingStrategies.MYBATIS3);
.where(UserBookshelfDynamicSqlSupport.userId, isEqualTo(userId))
.and(UserBookshelfDynamicSqlSupport.bookId, isEqualTo(bookId))
.build()
.render(RenderingStrategies.MYBATIS3);
userBookshelfMapper.delete(deleteStatement);
}
@ -162,10 +162,10 @@ public class UserServiceImpl implements UserService {
Date currentDate = new Date();
//删除该书以前的历史记录
DeleteStatementProvider deleteStatement = deleteFrom(userReadHistory)
.where(UserReadHistoryDynamicSqlSupport.bookId, isEqualTo(bookId))
.and(UserReadHistoryDynamicSqlSupport.userId, isEqualTo(userId))
.build()
.render(RenderingStrategies.MYBATIS3);
.where(UserReadHistoryDynamicSqlSupport.bookId, isEqualTo(bookId))
.and(UserReadHistoryDynamicSqlSupport.userId, isEqualTo(userId))
.build()
.render(RenderingStrategies.MYBATIS3);
userReadHistoryMapper.delete(deleteStatement);
//插入该书新的历史记录
@ -177,17 +177,16 @@ public class UserServiceImpl implements UserService {
userReadHistory.setUpdateTime(currentDate);
userReadHistoryMapper.insertSelective(userReadHistory);
//更新书架的阅读历史
UpdateStatementProvider updateStatement = update(userBookshelf)
.set(UserBookshelfDynamicSqlSupport.preContentId)
.equalTo(preContentId)
.set(UserBookshelfDynamicSqlSupport.updateTime)
.equalTo(currentDate)
.where(UserBookshelfDynamicSqlSupport.userId, isEqualTo(userId))
.and(UserBookshelfDynamicSqlSupport.bookId, isEqualTo(bookId))
.build()
.render(RenderingStrategies.MYBATIS3);
.set(UserBookshelfDynamicSqlSupport.preContentId)
.equalTo(preContentId)
.set(UserBookshelfDynamicSqlSupport.updateTime)
.equalTo(currentDate)
.where(UserBookshelfDynamicSqlSupport.userId, isEqualTo(userId))
.and(UserBookshelfDynamicSqlSupport.bookId, isEqualTo(bookId))
.build()
.render(RenderingStrategies.MYBATIS3);
userBookshelfMapper.update(updateStatement);
@ -206,25 +205,26 @@ public class UserServiceImpl implements UserService {
@Override
public PageBean<UserFeedback> listUserFeedBackByPage(Long userId, int page, int pageSize) {
PageHelper.startPage(page, pageSize);
SelectStatementProvider selectStatement = select(UserFeedbackDynamicSqlSupport.content, UserFeedbackDynamicSqlSupport.createTime)
.from(userFeedback)
.where(UserFeedbackDynamicSqlSupport.userId, isEqualTo(userId))
.orderBy(UserFeedbackDynamicSqlSupport.id.descending())
.build()
.render(RenderingStrategies.MYBATIS3);
SelectStatementProvider selectStatement = select(UserFeedbackDynamicSqlSupport.content,
UserFeedbackDynamicSqlSupport.createTime)
.from(userFeedback)
.where(UserFeedbackDynamicSqlSupport.userId, isEqualTo(userId))
.orderBy(UserFeedbackDynamicSqlSupport.id.descending())
.build()
.render(RenderingStrategies.MYBATIS3);
List<UserFeedback> userFeedbacks = userFeedbackMapper.selectMany(selectStatement);
PageBean<UserFeedback> pageBean = PageBuilder.build(userFeedbacks);
pageBean.setList(BeanUtil.copyList(userFeedbacks,UserFeedbackVO.class));
pageBean.setList(BeanUtil.copyList(userFeedbacks, UserFeedbackVO.class));
return pageBean;
}
@Override
public User userInfo(Long userId) {
SelectStatementProvider selectStatement = select(username, nickName, userPhoto,userSex,accountBalance)
.from(user)
.where(id, isEqualTo(userId))
.build()
.render(RenderingStrategies.MYBATIS3);
SelectStatementProvider selectStatement = select(username, nickName, userPhoto, userSex, accountBalance)
.from(user)
.where(id, isEqualTo(userId))
.build()
.render(RenderingStrategies.MYBATIS3);
return userMapper.selectMany(selectStatement).get(0);
}
@ -245,39 +245,35 @@ public class UserServiceImpl implements UserService {
@Override
public void updatePassword(Long userId, String oldPassword, String newPassword) {
SelectStatementProvider selectStatement = select(password)
.from(user)
.where(id,isEqualTo(userId))
.build()
.render(RenderingStrategies.MYBATIS3);
if(!userMapper.selectMany(selectStatement).get(0).getPassword().equals(MD5Util.MD5Encode(oldPassword, Charsets.UTF_8.name()))){
.from(user)
.where(id, isEqualTo(userId))
.build()
.render(RenderingStrategies.MYBATIS3);
if (!userMapper.selectMany(selectStatement).get(0).getPassword()
.equals(MD5Util.MD5Encode(oldPassword, Charsets.UTF_8.name()))) {
throw new BusinessException(ResponseStatus.OLD_PASSWORD_ERROR);
}
UpdateStatementProvider updateStatement = update(user)
.set(password)
.equalTo(MD5Util.MD5Encode(newPassword, Charsets.UTF_8.name()))
.where(id,isEqualTo(userId))
.build()
.render(RenderingStrategies.MYBATIS3);
.set(password)
.equalTo(MD5Util.MD5Encode(newPassword, Charsets.UTF_8.name()))
.where(id, isEqualTo(userId))
.build()
.render(RenderingStrategies.MYBATIS3);
userMapper.update(updateStatement);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void addAmount(Long userId, int amount) {
User user = this.userInfo(userId);
user.setId(userId);
user.setAccountBalance(user.getAccountBalance()+amount);
userMapper.updateByPrimaryKeySelective(user);
userMapper.addUserBalance(userId, amount);
}
@Override
public boolean queryIsBuyBookIndex(Long userId, Long bookIndexId) {
return userBuyRecordMapper.count(c ->
c.where(UserBuyRecordDynamicSqlSupport.userId, isEqualTo(userId))
.and(UserBuyRecordDynamicSqlSupport.bookIndexId,isEqualTo(bookIndexId))) > 0;
c.where(UserBuyRecordDynamicSqlSupport.userId, isEqualTo(userId))
.and(UserBuyRecordDynamicSqlSupport.bookIndexId, isEqualTo(bookIndexId))) > 0;
}
@Transactional(rollbackFor = Exception.class)
@ -285,7 +281,7 @@ public class UserServiceImpl implements UserService {
public void buyBookIndex(Long userId, UserBuyRecord buyRecord) {
//查询用户余额
long balance = userInfo(userId).getAccountBalance();
if(balance<buyRecord.getBuyAmount()){
if (balance < buyRecord.getBuyAmount()) {
//余额不足
throw new BusinessException(ResponseStatus.USER_NO_BALANCE);
}
@ -296,60 +292,56 @@ public class UserServiceImpl implements UserService {
//减少用户余额
userMapper.update(update(user)
.set(UserDynamicSqlSupport.accountBalance)
.equalTo(balance-buyRecord.getBuyAmount())
.where(id,isEqualTo(userId))
.build()
.render(RenderingStrategies.MYBATIS3));
.set(UserDynamicSqlSupport.accountBalance)
.equalTo(balance - buyRecord.getBuyAmount())
.where(id, isEqualTo(userId))
.build()
.render(RenderingStrategies.MYBATIS3));
}
@Override
public int queryBuyMember(Long bookId, Date startTime, Date endTime) {
return userMapper.selectStatistic(select(countDistinct(UserBuyRecordDynamicSqlSupport.userId))
.from(UserBuyRecordDynamicSqlSupport.userBuyRecord)
.where(UserBuyRecordDynamicSqlSupport.bookId,isEqualTo(bookId))
.and(UserBuyRecordDynamicSqlSupport.createTime,isGreaterThanOrEqualTo(startTime))
.and(UserBuyRecordDynamicSqlSupport.createTime,isLessThanOrEqualTo(endTime))
.build()
.render(RenderingStrategies.MYBATIS3));
.from(UserBuyRecordDynamicSqlSupport.userBuyRecord)
.where(UserBuyRecordDynamicSqlSupport.bookId, isEqualTo(bookId))
.and(UserBuyRecordDynamicSqlSupport.createTime, isGreaterThanOrEqualTo(startTime))
.and(UserBuyRecordDynamicSqlSupport.createTime, isLessThanOrEqualTo(endTime))
.build()
.render(RenderingStrategies.MYBATIS3));
}
@Override
public int queryBuyCount(Long bookId, Date startTime, Date endTime) {
return userMapper.selectStatistic(select(count(UserBuyRecordDynamicSqlSupport.id))
.from(UserBuyRecordDynamicSqlSupport.userBuyRecord)
.where(UserBuyRecordDynamicSqlSupport.bookId,isEqualTo(bookId))
.and(UserBuyRecordDynamicSqlSupport.createTime,isGreaterThanOrEqualTo(startTime))
.and(UserBuyRecordDynamicSqlSupport.createTime,isLessThanOrEqualTo(endTime))
.build()
.render(RenderingStrategies.MYBATIS3));
.from(UserBuyRecordDynamicSqlSupport.userBuyRecord)
.where(UserBuyRecordDynamicSqlSupport.bookId, isEqualTo(bookId))
.and(UserBuyRecordDynamicSqlSupport.createTime, isGreaterThanOrEqualTo(startTime))
.and(UserBuyRecordDynamicSqlSupport.createTime, isLessThanOrEqualTo(endTime))
.build()
.render(RenderingStrategies.MYBATIS3));
}
@Override
public int queryBuyAccount(Long bookId, Date startTime, Date endTime) {
return userMapper.selectStatistic(select(sum(UserBuyRecordDynamicSqlSupport.buyAmount))
.from(UserBuyRecordDynamicSqlSupport.userBuyRecord)
.where(UserBuyRecordDynamicSqlSupport.bookId,isEqualTo(bookId))
.and(UserBuyRecordDynamicSqlSupport.createTime,isGreaterThanOrEqualTo(startTime))
.and(UserBuyRecordDynamicSqlSupport.createTime,isLessThanOrEqualTo(endTime))
.build()
.render(RenderingStrategies.MYBATIS3));
.from(UserBuyRecordDynamicSqlSupport.userBuyRecord)
.where(UserBuyRecordDynamicSqlSupport.bookId, isEqualTo(bookId))
.and(UserBuyRecordDynamicSqlSupport.createTime, isGreaterThanOrEqualTo(startTime))
.and(UserBuyRecordDynamicSqlSupport.createTime, isLessThanOrEqualTo(endTime))
.build()
.render(RenderingStrategies.MYBATIS3));
}
@Override
public int queryBuyTotalMember(List<Long> bookIds, Date startTime, Date endTime) {
return userMapper.selectStatistic(select(countDistinct(UserBuyRecordDynamicSqlSupport.userId))
.from(UserBuyRecordDynamicSqlSupport.userBuyRecord)
.where(UserBuyRecordDynamicSqlSupport.bookId,isIn(bookIds))
.and(UserBuyRecordDynamicSqlSupport.createTime,isGreaterThanOrEqualTo(startTime))
.and(UserBuyRecordDynamicSqlSupport.createTime,isLessThanOrEqualTo(endTime))
.build()
.render(RenderingStrategies.MYBATIS3));
.from(UserBuyRecordDynamicSqlSupport.userBuyRecord)
.where(UserBuyRecordDynamicSqlSupport.bookId, isIn(bookIds))
.and(UserBuyRecordDynamicSqlSupport.createTime, isGreaterThanOrEqualTo(startTime))
.and(UserBuyRecordDynamicSqlSupport.createTime, isLessThanOrEqualTo(endTime))
.build()
.render(RenderingStrategies.MYBATIS3));
}
}

View File

@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.java2nb.novel.mapper.FrontUserMapper">
<update id="addUserBalance" >
update user set account_balance = account_balance + ${amount}
where id = #{userId}
</update>
</mapper>