35302 字
约 117 分钟
39
appendix_G
2026-09-26
无标签
附录G 订单服务模块源码详解
模块概览(面向 0 基础读者):
- 负责课程付费订单创建、支付对接与结果通知。
- 通过消息任务表 + MQ 确保支付成功与学习开通幂等。
- 整合支付宝/微信支付 SDK,提供统一支付入口。
核心目录:
xuecheng-plus-orders/xuecheng-plus-orders-api/src/main/java/com/xuecheng/orders/apixuecheng-plus-orders/xuecheng-plus-orders-service/src/main/java/com/xuecheng/orders/servicexuecheng-plus-orders/xuecheng-plus-orders-service/src/main/java/com/xuecheng/orders/mapperxuecheng-plus-orders/xuecheng-plus-orders-service/src/main/java/com/xuecheng/orders/configxuecheng-plus-orders/xuecheng-plus-orders-model/src/main/java/com/xuecheng/orders/model
文件:xuecheng-plus-orders/api/main/com/xuecheng/orders/api/OrderController.java
package com.xuecheng.orders.api; // 声明类所在的包路径
import com.alipay.api.AlipayApiException; // 导入 AlipayApiException 类
import com.alipay.api.AlipayClient; // 导入 AlipayClient 类
import com.alipay.api.DefaultAlipayClient; // 导入 DefaultAlipayClient 类
import com.alipay.api.internal.util.AlipaySignature; // 导入 AlipaySignature 类
import com.alipay.api.request.AlipayTradeWapPayRequest; // 导入 AlipayTradeWapPayRequest 类
import com.xuecheng.base.exception.XueChengPlusException; // 导入 XueChengPlusException 类
import com.xuecheng.orders.config.AlipayConfig; // 导入 AlipayConfig 类
import com.xuecheng.orders.model.dto.AddOrderDto; // 导入 AddOrderDto 类
import com.xuecheng.orders.model.dto.PayRecordDto; // 导入 PayRecordDto 类
import com.xuecheng.orders.model.dto.PayStatusDto; // 导入 PayStatusDto 类
import com.xuecheng.orders.model.po.XcPayRecord; // 导入 XcPayRecord 类
import com.xuecheng.orders.service.OrderService; // 导入 OrderService 类
import com.xuecheng.orders.util.SecurityUtil; // 导入 SecurityUtil 类
import io.swagger.annotations.Api; // 导入 Api 类
import io.swagger.annotations.ApiOperation; // 导入 ApiOperation 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.beans.factory.annotation.Value; // 导入 Value 类
import org.springframework.stereotype.Controller; // 导入 Controller 类
import org.springframework.web.bind.annotation.GetMapping; // 导入 GetMapping 类
import org.springframework.web.bind.annotation.PostMapping; // 导入 PostMapping 类
import org.springframework.web.bind.annotation.RequestBody; // 导入 RequestBody 类
import org.springframework.web.bind.annotation.ResponseBody; // 导入 ResponseBody 类
import javax.servlet.http.HttpServletRequest; // 导入 HttpServletRequest 类
import javax.servlet.http.HttpServletResponse; // 导入 HttpServletResponse 类
import java.io.IOException; // 导入 IOException 类
import java.io.UnsupportedEncodingException; // 导入 UnsupportedEncodingException 类
import java.util.HashMap; // 导入 HashMap 类
import java.util.Iterator; // 导入 Iterator 类
import java.util.Map; // 导入 Map 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 订单相关的接口 // 保留原作者写的块注释
* @date 2023/2/26 10:09 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Api(value = "订单支付接口", tags = "订单支付接口") // 使用注解 @Api(value = "订单支付接口", tags = "订单支付接口")
@Slf4j // 使用注解 @Slf4j
@Controller // 使用注解 @Controller
public class OrderController { // 定义 class OrderController
@Autowired // 使用注解 @Autowired
OrderService orderService; // 执行语句
@Value("${pay.alipay.APP_ID}") // 使用注解 @Value("${pay.alipay.APP_ID}")
String APP_ID; // 执行语句
@Value("${pay.alipay.APP_PRIVATE_KEY}") // 使用注解 @Value("${pay.alipay.APP_PRIVATE_KEY}")
String APP_PRIVATE_KEY; // 执行语句
@Value("${pay.alipay.ALIPAY_PUBLIC_KEY}") // 使用注解 @Value("${pay.alipay.ALIPAY_PUBLIC_KEY}")
String ALIPAY_PUBLIC_KEY; // 执行语句
@ApiOperation("生成支付二维码") // 使用注解 @ApiOperation("生成支付二维码")
@PostMapping("/generatepaycode") // 使用注解 @PostMapping("/generatepaycode")
@ResponseBody // 使用注解 @ResponseBody
public PayRecordDto generatePayCode(@RequestBody AddOrderDto addOrderDto) { // 定义方法 generatePayCode(...)
SecurityUtil.XcUser user = SecurityUtil.getUser(); // 把 SecurityUtil.getUser() 的返回值赋给 user
String userId = user.getId(); // 把 user.getId() 的返回值赋给 userId
//调用service,完成插入订单信息、插入支付记录、生成支付二维码 // 保留原作者写的行内注释
PayRecordDto payRecordDto = orderService.createOrder(userId, addOrderDto); // 把 orderService.createOrder(userId, addOrderDto) 赋值给 payRecordDto
return payRecordDto; // 返回 payRecordDto
} // 代码块结束
@ApiOperation("扫码下单接口") // 使用注解 @ApiOperation("扫码下单接口")
@GetMapping("/requestpay") // 使用注解 @GetMapping("/requestpay")
public void requestpay(String payNo, HttpServletResponse httpResponse) throws IOException, AlipayApiException { // 定义方法 requestpay(...)
//传入了支付记录号,判断支付记录号是否存在 // 保留原作者写的行内注释
XcPayRecord payRecordByPayno = orderService.getPayRecordByPayno(payNo); // 把 orderService.getPayRecordByPayno(payNo) 赋值给 payRecordByPayno
if(payRecordByPayno == null){ // 定义方法 方法(...)
XueChengPlusException.cast("支付记录不存在"); // 执行语句
} // 代码块结束
//支付结果 // 保留原作者写的行内注释
String status = payRecordByPayno.getStatus(); // 把 payRecordByPayno.getStatus() 的返回值赋给 status
if ("601002".equals(status)) { // 定义方法 方法(...)
XueChengPlusException.cast("已支付,无需重复支付"); // 执行语句
} // 代码块结束
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, APP_ID, APP_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE); // 创建 DefaultAlipayClient 对象并赋值给 alipayClient
AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();//创建API对应的request // 创建 AlipayTradeWapPayRequest 对象并赋值给 alipayRequest
// alipayRequest.setReturnUrl("http://domain.com/CallBack/return_url.jsp"); // 保留原作者写的行内注释
alipayRequest.setNotifyUrl("http://tjxt-user-t.itheima.net/xuecheng/orders/paynotify");//在公共参数中设置回跳和通知地址 // 代码逻辑
alipayRequest.setBizContent("{" + // 代码逻辑
" \"out_trade_no\":\""+payNo+"\"," + // 代码逻辑
" \"total_amount\":"+payRecordByPayno.getTotalPrice()+"," + // 代码逻辑
" \"subject\":\""+payRecordByPayno.getOrderName()+"\"," + // 代码逻辑
" \"product_code\":\"QUICK_WAP_WAY\"" + // 代码逻辑
" }");//填充业务参数 // 执行语句
String form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK请求支付宝下单 // 把 alipayClient.pageExecute(alipayRequest).getBody() 的返回值赋给 form
httpResponse.setContentType("text/html;charset=" + AlipayConfig.CHARSET); // 把 " + AlipayConfig.CHARSET) 赋值给 httpResponse.setContentType("text/html;charset
httpResponse.getWriter().write(form);//直接将完整的表单html输出到页面 // 执行语句
httpResponse.getWriter().flush(); // 执行语句
} // 代码块结束
@ApiOperation("查询支付结果") // 使用注解 @ApiOperation("查询支付结果")
@GetMapping("/payresult") // 使用注解 @GetMapping("/payresult")
@ResponseBody // 使用注解 @ResponseBody
public PayRecordDto payresult(String payNo) throws IOException { // 定义方法 payresult(...)
//查询支付结果 // 保留原作者写的行内注释
PayRecordDto payRecordDto = orderService.queryPayResult(payNo); // 把 orderService.queryPayResult(payNo) 赋值给 payRecordDto
return payRecordDto; // 返回 payRecordDto
} // 代码块结束
//接收支付宝通知 // 保留原作者写的行内注释
@PostMapping("/paynotify") // 使用注解 @PostMapping("/paynotify")
public void paynotify(HttpServletRequest request, HttpServletResponse response) throws IOException, AlipayApiException { // 定义方法 paynotify(...)
//获取支付宝POST过来反馈信息 // 保留原作者写的行内注释
Map<String,String> params = new HashMap<String,String>(); // 创建 HashMap<String,String> 对象并赋值给 params
Map requestParams = request.getParameterMap(); // 把 request.getParameterMap() 的返回值赋给 requestParams
for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) { // 定义方法 方法(...)
String name = (String) iter.next(); // 把 (String) iter.next() 的返回值赋给 name
String[] values = (String[]) requestParams.get(name); // 把 (String[]) requestParams.get(name) 赋值给 values
String valueStr = ""; // 把 "" 赋值给 valueStr
for (int i = 0; i < values.length; i++) { // 定义方法 方法(...)
valueStr = (i == values.length - 1) ? valueStr + values[i] // 代码逻辑
: valueStr + values[i] + ","; // 执行语句
} // 代码块结束
params.put(name, valueStr); // 执行语句
} // 代码块结束
boolean verify_result = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2"); // 把 AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2") 赋值给 verify_result
if(verify_result){//验证成功 // 定义方法 方法(...)
//商户订单号 // 保留原作者写的行内注释
String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8"); // 创建 String 对象并赋值给 out_trade_no
//支付宝交易号 // 保留原作者写的行内注释
String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8"); // 创建 String 对象并赋值给 trade_no
//交易金额 // 保留原作者写的行内注释
String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"),"UTF-8"); // 创建 String 对象并赋值给 total_amount
//交易状态 // 保留原作者写的行内注释
String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8"); // 创建 String 对象并赋值给 trade_status
if (trade_status.equals("TRADE_SUCCESS")){ // 定义方法 方法(...)
//更新支付记录表的支付状态为成功,订单表的状态为成功 // 保留原作者写的行内注释
PayStatusDto payStatusDto = new PayStatusDto(); // 创建 PayStatusDto 对象并赋值给 payStatusDto
payStatusDto.setTrade_status(trade_status); // 执行语句
payStatusDto.setTrade_no(trade_no); // 执行语句
payStatusDto.setOut_trade_no(out_trade_no); // 执行语句
payStatusDto.setTotal_amount(total_amount); // 执行语句
payStatusDto.setApp_id(APP_ID); // 执行语句
orderService.saveAliPayStatus(payStatusDto); // 执行语句
} // 代码块结束
response.getWriter().write("success"); // 执行语句
}else{//验证失败 // 代码逻辑
response.getWriter().write("fail"); // 执行语句
} // 代码块结束
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-orders/api/main/com/xuecheng/orders/api/PayTestController.java
package com.xuecheng.orders.api; // 声明类所在的包路径
import com.alipay.api.AlipayApiException; // 导入 AlipayApiException 类
import com.alipay.api.AlipayClient; // 导入 AlipayClient 类
import com.alipay.api.DefaultAlipayClient; // 导入 DefaultAlipayClient 类
import com.alipay.api.internal.util.AlipaySignature; // 导入 AlipaySignature 类
import com.alipay.api.request.AlipayTradeWapPayRequest; // 导入 AlipayTradeWapPayRequest 类
import com.xuecheng.orders.config.AlipayConfig; // 导入 AlipayConfig 类
import org.springframework.beans.factory.annotation.Value; // 导入 Value 类
import org.springframework.stereotype.Controller; // 导入 Controller 类
import org.springframework.web.bind.annotation.PostMapping; // 导入 PostMapping 类
import org.springframework.web.bind.annotation.RequestMapping; // 导入 RequestMapping 类
import javax.servlet.ServletException; // 导入 ServletException 类
import javax.servlet.http.HttpServletRequest; // 导入 HttpServletRequest 类
import javax.servlet.http.HttpServletResponse; // 导入 HttpServletResponse 类
import java.io.IOException; // 导入 IOException 类
import java.io.UnsupportedEncodingException; // 导入 UnsupportedEncodingException 类
import java.util.HashMap; // 导入 HashMap 类
import java.util.Iterator; // 导入 Iterator 类
import java.util.Map; // 导入 Map 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 扫码支付的测试 // 保留原作者写的块注释
* @date 2023/2/25 16:17 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Controller // 使用注解 @Controller
public class PayTestController { // 定义 class PayTestController
@Value("${pay.alipay.APP_ID}") // 使用注解 @Value("${pay.alipay.APP_ID}")
String APP_ID; // 执行语句
@Value("${pay.alipay.APP_PRIVATE_KEY}") // 使用注解 @Value("${pay.alipay.APP_PRIVATE_KEY}")
String APP_PRIVATE_KEY; // 执行语句
@Value("${pay.alipay.ALIPAY_PUBLIC_KEY}") // 使用注解 @Value("${pay.alipay.ALIPAY_PUBLIC_KEY}")
String ALIPAY_PUBLIC_KEY; // 执行语句
//下单接口测试 // 保留原作者写的行内注释
@RequestMapping("/alipaytest") // 使用注解 @RequestMapping("/alipaytest")
public void doPost(HttpServletRequest httpRequest, // 代码逻辑
HttpServletResponse httpResponse) throws ServletException, IOException, AlipayApiException { // 代码逻辑
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, APP_ID, APP_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE); // 创建 DefaultAlipayClient 对象并赋值给 alipayClient
AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();//创建API对应的request // 创建 AlipayTradeWapPayRequest 对象并赋值给 alipayRequest
// alipayRequest.setReturnUrl("http://domain.com/CallBack/return_url.jsp"); // 保留原作者写的行内注释
alipayRequest.setNotifyUrl("http://tjxt-user-t.itheima.net/xuecheng/orders/paynotify");//在公共参数中设置回跳和通知地址 // 代码逻辑
alipayRequest.setBizContent("{" + // 代码逻辑
" \"out_trade_no\":\"202303200101020011\"," + // 代码逻辑
" \"total_amount\":0.1," + // 代码逻辑
" \"subject\":\"Iphone14 16G\"," + // 代码逻辑
" \"product_code\":\"QUICK_WAP_WAY\"" + // 代码逻辑
" }");//填充业务参数 // 执行语句
String form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单 // 把 alipayClient.pageExecute(alipayRequest).getBody() 的返回值赋给 form
httpResponse.setContentType("text/html;charset=" + AlipayConfig.CHARSET); // 把 " + AlipayConfig.CHARSET) 赋值给 httpResponse.setContentType("text/html;charset
httpResponse.getWriter().write(form);//直接将完整的表单html输出到页面 // 执行语句
httpResponse.getWriter().flush(); // 执行语句
} // 代码块结束
//支付结果通知 // 保留原作者写的行内注释
@PostMapping("/paynotifytest") // 使用注解 @PostMapping("/paynotifytest")
public void paynotify(HttpServletRequest request,HttpServletResponse response) throws IOException, AlipayApiException { // 定义方法 paynotify(...)
//获取支付宝POST过来反馈信息 // 保留原作者写的行内注释
Map<String,String> params = new HashMap<String,String>(); // 创建 HashMap<String,String> 对象并赋值给 params
Map requestParams = request.getParameterMap(); // 把 request.getParameterMap() 的返回值赋给 requestParams
for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) { // 定义方法 方法(...)
String name = (String) iter.next(); // 把 (String) iter.next() 的返回值赋给 name
String[] values = (String[]) requestParams.get(name); // 把 (String[]) requestParams.get(name) 赋值给 values
String valueStr = ""; // 把 "" 赋值给 valueStr
for (int i = 0; i < values.length; i++) { // 定义方法 方法(...)
valueStr = (i == values.length - 1) ? valueStr + values[i] // 代码逻辑
: valueStr + values[i] + ","; // 执行语句
} // 代码块结束
//乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化 // 保留原作者写的行内注释
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk"); // 保留原作者写的行内注释
params.put(name, valueStr); // 执行语句
} // 代码块结束
//获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)// // 保留原作者写的行内注释
//获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)// // 保留原作者写的行内注释
//计算得出通知验证结果 // 保留原作者写的行内注释
//boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type) // 保留原作者写的行内注释
boolean verify_result = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2"); // 把 AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2") 赋值给 verify_result
if(verify_result){//验证成功 // 定义方法 方法(...)
////////////////////////////////////////////////////////////////////////////////////////// // 保留原作者写的行内注释
//请在这里加上商户的业务逻辑程序代码 // 保留原作者写的行内注释
//商户订单号 // 保留原作者写的行内注释
String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8"); // 创建 String 对象并赋值给 out_trade_no
//支付宝交易号 // 保留原作者写的行内注释
String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8"); // 创建 String 对象并赋值给 trade_no
//交易状态 // 保留原作者写的行内注释
String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8"); // 创建 String 对象并赋值给 trade_status
//——请根据您的业务逻辑来编写程序(以下代码仅作参考)—— // 保留原作者写的行内注释
if(trade_status.equals("TRADE_FINISHED")){ // 定义方法 方法(...)
//判断该笔订单是否在商户网站中已经做过处理 // 保留原作者写的行内注释
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序 // 保留原作者写的行内注释
//请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的 // 保留原作者写的行内注释
//如果有做过处理,不执行商户的业务程序 // 保留原作者写的行内注释
//注意: // 保留原作者写的行内注释
//如果签约的是可退款协议,退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知 // 保留原作者写的行内注释
//如果没有签约可退款协议,那么付款完成后,支付宝系统发送该交易状态通知。 // 保留原作者写的行内注释
} else if (trade_status.equals("TRADE_SUCCESS")){ // 定义方法 if(...)
//判断该笔订单是否在商户网站中已经做过处理 // 保留原作者写的行内注释
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序 // 保留原作者写的行内注释
//请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的 // 保留原作者写的行内注释
//如果有做过处理,不执行商户的业务程序 // 保留原作者写的行内注释
System.out.println(trade_status); // 执行语句
//注意: // 保留原作者写的行内注释
//如果签约的是可退款协议,那么付款完成后,支付宝系统发送该交易状态通知。 // 保留原作者写的行内注释
} // 代码块结束
//——请根据您的业务逻辑来编写程序(以上代码仅作参考)—— // 保留原作者写的行内注释
response.getWriter().write("success"); // 执行语句
////////////////////////////////////////////////////////////////////////////////////////// // 保留原作者写的行内注释
}else{//验证失败 // 代码逻辑
response.getWriter().write("fail"); // 执行语句
} // 代码块结束
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-orders/api/main/com/xuecheng/orders/config/ResouceServerConfig.java
package com.xuecheng.orders.config; // 声明类所在的包路径
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.context.annotation.Configuration; // 导入 Configuration 类
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; // 导入 EnableGlobalMethodSecurity 类
import org.springframework.security.config.annotation.web.builders.HttpSecurity; // 导入 HttpSecurity 类
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; // 导入 EnableResourceServer 类
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; // 导入 ResourceServerConfigurerAdapter 类
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; // 导入 ResourceServerSecurityConfigurer 类
import org.springframework.security.oauth2.provider.token.TokenStore; // 导入 TokenStore 类
/** // 保留原作者写的块注释
* @author Administrator // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
**/ // 保留原作者写的块注释
@Configuration // 使用注解 @Configuration
@EnableResourceServer // 使用注解 @EnableResourceServer
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true) // 使用注解 @EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
public class ResouceServerConfig extends ResourceServerConfigurerAdapter { // 定义 class ResouceServerConfig
//资源服务标识 // 保留原作者写的行内注释
public static final String RESOURCE_ID = "xuecheng-plus"; // 把 "xuecheng-plus" 赋值给 RESOURCE_ID
@Autowired // 使用注解 @Autowired
TokenStore tokenStore; // 执行语句
@Override // 使用注解 @Override
public void configure(ResourceServerSecurityConfigurer resources) { // 定义方法 configure(...)
resources.resourceId(RESOURCE_ID)//资源 id // 代码逻辑
.tokenStore(tokenStore) // 代码逻辑
.stateless(true); // 执行语句
} // 代码块结束
@Override // 使用注解 @Override
public void configure(HttpSecurity http) throws Exception { // 定义方法 configure(...)
http.csrf().disable() // 代码逻辑
.authorizeRequests() // 代码逻辑
// .antMatchers("/r/**","/course/**").authenticated()//所有/r/**的请求必须认证通过 // 保留原作者写的行内注释
.anyRequest().permitAll() // 代码逻辑
; // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-orders/api/main/com/xuecheng/orders/config/TokenConfig.java
package com.xuecheng.orders.config; // 声明类所在的包路径
import org.springframework.context.annotation.Bean; // 导入 Bean 类
import org.springframework.context.annotation.Configuration; // 导入 Configuration 类
import org.springframework.security.oauth2.provider.token.TokenStore; // 导入 TokenStore 类
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; // 导入 JwtAccessTokenConverter 类
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; // 导入 JwtTokenStore 类
/** // 保留原作者写的块注释
* @author Administrator // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
**/ // 保留原作者写的块注释
@Configuration // 使用注解 @Configuration
public class TokenConfig { // 定义 class TokenConfig
//jwt签名密钥,与认证服务保持一致 // 保留原作者写的行内注释
private String SIGNING_KEY = "mq123"; // 把 "mq123" 赋值给 SIGNING_KEY
@Bean // 使用注解 @Bean
public TokenStore tokenStore() { // 定义方法 tokenStore(...)
//JWT令牌存储方案 // 保留原作者写的行内注释
return new JwtTokenStore(accessTokenConverter()); // 返回 new JwtTokenStore(accessTokenConverter())
} // 代码块结束
@Bean // 使用注解 @Bean
public JwtAccessTokenConverter accessTokenConverter() { // 定义方法 accessTokenConverter(...)
JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); // 创建 JwtAccessTokenConverter 对象并赋值给 converter
converter.setSigningKey(SIGNING_KEY); // 执行语句
return converter; // 返回 converter
} // 代码块结束
/* @Bean // 保留原作者写的块注释
public TokenStore tokenStore() { // 定义方法 tokenStore(...)
//使用内存存储令牌(普通令牌) // 保留原作者写的行内注释
return new InMemoryTokenStore(); // 返回 new InMemoryTokenStore()
}*/ // 代码逻辑
} // 代码块结束
文件:xuecheng-plus-orders/api/main/com/xuecheng/orders/util/SecurityUtil.java
package com.xuecheng.orders.util; // 声明类所在的包路径
import com.alibaba.fastjson.JSON; // 导入 JSON 类
import lombok.Data; // 导入 Data 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.security.core.context.SecurityContextHolder; // 导入 SecurityContextHolder 类
import java.io.Serializable; // 导入 Serializable 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
/*** // 保留原作者写的块注释
* 获取当前登录用户信息,使用解析jwt中的用户信息 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Slf4j // 使用注解 @Slf4j
public class SecurityUtil { // 定义 class SecurityUtil
public static XcUser getUser() { // 定义方法 getUser(...)
try { // 尝试执行可能抛出异常的代码
Object principalObj = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); // 把 SecurityContextHolder.getContext().getAuthentication().getPrincipal() 的返回值赋给 principalObj
if (principalObj instanceof String) { // 定义方法 方法(...)
//取出用户身份信息 // 保留原作者写的行内注释
String principal = principalObj.toString(); // 把 principalObj.toString() 的返回值赋给 principal
//将json转成对象 // 保留原作者写的行内注释
XcUser user = JSON.parseObject(principal, XcUser.class); // 把 JSON.parseObject(principal, XcUser.class) 赋值给 user
return user; // 返回 user
} // 代码块结束
} catch (Exception e) { // 定义方法 catch(...)
log.error("获取当前登录用户身份出错:{}", e.getMessage()); // 执行语句
e.printStackTrace(); // 执行语句
} // 代码块结束
return null; // 返回 null
} // 代码块结束
@Data // 使用注解 @Data
public static class XcUser implements Serializable { // 代码逻辑
private static final long serialVersionUID = 1L; // 把 1L 赋值给 serialVersionUID
private String id; // 执行语句
private String username; // 执行语句
private String password; // 执行语句
private String salt; // 执行语句
private String name; // 执行语句
private String nickname; // 执行语句
private String wxUnionid; // 执行语句
private String companyId; // 执行语句
/** // 保留原作者写的块注释
* 头像 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String userpic; // 执行语句
private String utype; // 执行语句
private LocalDateTime birthday; // 执行语句
private String sex; // 执行语句
private String email; // 执行语句
private String cellphone; // 执行语句
private String qq; // 执行语句
/** // 保留原作者写的块注释
* 用户状态 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String status; // 执行语句
private LocalDateTime createTime; // 执行语句
private LocalDateTime updateTime; // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-orders/api/main/com/xuecheng/OrdersApiApplication.java
package com.xuecheng; // 声明类所在的包路径
import org.springframework.boot.SpringApplication; // 导入 SpringApplication 类
import org.springframework.boot.autoconfigure.SpringBootApplication; // 导入 SpringBootApplication 类
@SpringBootApplication // 使用注解 @SpringBootApplication
public class OrdersApiApplication { // 定义 class OrdersApiApplication
public static void main(String[] args) { // 定义方法 main(...)
SpringApplication.run(OrdersApiApplication.class, args); // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-orders/api/resources/bootstrap.yml
#微服务配置
spring:
application:
name: orders-api
cloud:
nacos:
server-addr: 192.168.101.65:8848
discovery:
namespace: dev402
group: xuecheng-plus-project
config:
namespace: dev402
group: xuecheng-plus-project
file-extension: yaml
refresh-enabled: true
extension-configs:
- data-id: orders-service-${spring.profiles.active}.yaml
group: xuecheng-plus-project
refresh: true
shared-configs:
- data-id: swagger-${spring.profiles.active}.yaml
group: xuecheng-plus-common
refresh: true
- data-id: logging-${spring.profiles.active}.yaml
group: xuecheng-plus-common
refresh: true
- data-id: rabbitmq-${spring.profiles.active}.yaml
group: xuecheng-plus-common
refresh: true
profiles:
active: dev
文件:xuecheng-plus-orders/api/resources/log4j2-dev.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorInterval="180" packages="">
<properties>
<property name="logdir">logs</property>
<property name="PATTERN">%date{YYYY-MM-dd HH:mm:ss,SSS} %level [%thread][%file:%line] - %msg%n%throwable</property>
</properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${PATTERN}"/>
</Console>
<RollingFile name="ErrorAppender" fileName="${logdir}/error.log"
filePattern="${logdir}/$${date:yyyy-MM-dd}/error.%d{yyyy-MM-dd-HH}.log" append="true">
<PatternLayout pattern="${PATTERN}"/>
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
</RollingFile>
<RollingFile name="DebugAppender" fileName="${logdir}/info.log"
filePattern="${logdir}/$${date:yyyy-MM-dd}/info.%d{yyyy-MM-dd-HH}.log" append="true">
<PatternLayout pattern="${PATTERN}"/>
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
</RollingFile>
<!--异步appender-->
<Async name="AsyncAppender" includeLocation="true">
<AppenderRef ref="ErrorAppender"/>
<AppenderRef ref="DebugAppender"/>
</Async>
</Appenders>
<Loggers>
<!--过滤掉spring和mybatis的一些无用的debug信息-->
<logger name="org.springframework" level="INFO">
</logger>
<logger name="org.mybatis" level="INFO">
</logger>
<logger name="cn.itcast.wanxinp2p.consumer.mapper" level="DEBUG">
</logger>
<logger name="springfox" level="INFO">
</logger>
<logger name="org.apache.http" level="INFO">
</logger>
<logger name="com.netflix.discovery" level="INFO">
</logger>
<logger name="RocketmqCommon" level="INFO" >
</logger>
<logger name="RocketmqRemoting" level="INFO" >
</logger>
<logger name="RocketmqClient" level="WARN">
</logger>
<logger name="org.dromara.hmily" level="WARN">
</logger>
<logger name="org.dromara.hmily.lottery" level="WARN">
</logger>
<logger name="org.dromara.hmily.bonuspoint" level="WARN">
</logger>
<!--OFF 0-->
<!--FATAL 100-->
<!--ERROR 200-->
<!--WARN 300-->
<!--INFO 400-->
<!--DEBUG 500-->
<!--TRACE 600-->
<!--ALL Integer.MAX_VALUE-->
<Root level="DEBUG" includeLocation="true">
<AppenderRef ref="AsyncAppender"/>
<AppenderRef ref="Console"/>
<AppenderRef ref="DebugAppender"/>
</Root>
</Loggers>
</Configuration>
文件:xuecheng-plus-orders/api_pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>xuecheng-plus-orders</artifactId>
<groupId>com.xuecheng</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>xuecheng-plus-orders-api</artifactId>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.xuecheng</groupId>
<artifactId>xuecheng-plus-orders-model</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.xuecheng</groupId>
<artifactId>xuecheng-plus-orders-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--cloud的基础环境包-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-context</artifactId>
</dependency>
<!-- Spring Boot 的 Spring Web MVC 集成 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot 集成 Junit -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- 排除 Spring Boot 依赖的日志包冲突 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Spring Boot 集成 log4j2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<!-- Spring Boot 集成 swagger -->
<dependency>
<groupId>com.spring4all</groupId>
<artifactId>swagger-spring-boot-starter</artifactId>
</dependency>
<!--认证相关-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-oauth2</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.3.3</version>
</dependency>
</dependencies>
</project>
文件:xuecheng-plus-orders/model/com/xuecheng/orders/model/dto/AddOrderDto.java
package com.xuecheng.orders.model.dto; // 声明类所在的包路径
import lombok.Data; // 导入 Data 类
import lombok.ToString; // 导入 ToString 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 创建商品订单 // 保留原作者写的块注释
* @date 2022/10/4 10:21 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@ToString // 使用注解 @ToString
public class AddOrderDto { // 定义 class AddOrderDto
/** // 保留原作者写的块注释
* 总价 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Float totalPrice; // 执行语句
/** // 保留原作者写的块注释
* 订单类型 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String orderType; // 执行语句
/** // 保留原作者写的块注释
* 订单名称 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String orderName; // 执行语句
/** // 保留原作者写的块注释
* 订单描述 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String orderDescrip; // 执行语句
/** // 保留原作者写的块注释
* 订单明细json,不可为空 // 保留原作者写的块注释
* [{"goodsId":"","goodsType":"","goodsName":"","goodsPrice":"","goodsDetail":""},{...}] // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String orderDetail; // 执行语句
/** // 保留原作者写的块注释
* 外部系统业务id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String outBusinessId; // 执行语句
} // 代码块结束
文件:xuecheng-plus-orders/model/com/xuecheng/orders/model/dto/PayRecordDto.java
package com.xuecheng.orders.model.dto; // 声明类所在的包路径
import com.xuecheng.orders.model.po.XcPayRecord; // 导入 XcPayRecord 类
import lombok.Data; // 导入 Data 类
import lombok.ToString; // 导入 ToString 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 支付记录dto // 保留原作者写的块注释
* @date 2022/10/4 11:30 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@ToString // 使用注解 @ToString
public class PayRecordDto extends XcPayRecord { // 定义 class PayRecordDto
//二维码 // 保留原作者写的行内注释
private String qrcode; // 执行语句
} // 代码块结束
文件:xuecheng-plus-orders/model/com/xuecheng/orders/model/dto/PayStatusDto.java
package com.xuecheng.orders.model.dto; // 声明类所在的包路径
import lombok.Data; // 导入 Data 类
import lombok.ToString; // 导入 ToString 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 支付结果数据, 用于接收支付结果通知处理逻辑 // 保留原作者写的块注释
* @date 2022/10/4 16:49 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@ToString // 使用注解 @ToString
public class PayStatusDto { // 定义 class PayStatusDto
//商户订单号 // 保留原作者写的行内注释
String out_trade_no; // 执行语句
//支付宝交易号 // 保留原作者写的行内注释
String trade_no; // 执行语句
//交易状态 // 保留原作者写的行内注释
String trade_status; // 执行语句
//appid // 保留原作者写的行内注释
String app_id; // 执行语句
//total_amount // 保留原作者写的行内注释
String total_amount; // 执行语句
} // 代码块结束
文件:xuecheng-plus-orders/model/com/xuecheng/orders/model/po/XcOrders.java
package com.xuecheng.orders.model.po; // 声明类所在的包路径
import com.baomidou.mybatisplus.annotation.FieldFill; // 导入 FieldFill 类
import com.baomidou.mybatisplus.annotation.TableField; // 导入 TableField 类
import com.baomidou.mybatisplus.annotation.TableName; // 导入 TableName 类
import lombok.Data; // 导入 Data 类
import lombok.ToString; // 导入 ToString 类
import java.io.Serializable; // 导入 Serializable 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
/** // 保留原作者写的块注释
* <p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* @author itcast // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@ToString // 使用注解 @ToString
@TableName("xc_orders") // 使用注解 @TableName("xc_orders")
public class XcOrders implements Serializable { // 定义 class XcOrders
private static final long serialVersionUID = 1L; // 把 1L 赋值给 serialVersionUID
/** // 保留原作者写的块注释
* 订单号 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long id; // 执行语句
/** // 保留原作者写的块注释
* 总价 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Float totalPrice; // 执行语句
/** // 保留原作者写的块注释
* 创建时间 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@TableField(fill = FieldFill.INSERT) // 使用注解 @TableField(fill = FieldFill.INSERT)
private LocalDateTime createDate; // 执行语句
/** // 保留原作者写的块注释
* 交易状态 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String status; // 执行语句
/** // 保留原作者写的块注释
* 用户id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String userId; // 执行语句
/** // 保留原作者写的块注释
* 订单类型 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String orderType; // 执行语句
/** // 保留原作者写的块注释
* 订单名称 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String orderName; // 执行语句
/** // 保留原作者写的块注释
* 订单描述 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String orderDescrip; // 执行语句
/** // 保留原作者写的块注释
* 订单明细json // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String orderDetail; // 执行语句
/** // 保留原作者写的块注释
* 外部系统业务id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String outBusinessId; // 执行语句
} // 代码块结束
文件:xuecheng-plus-orders/model/com/xuecheng/orders/model/po/XcOrdersGoods.java
package com.xuecheng.orders.model.po; // 声明类所在的包路径
import com.baomidou.mybatisplus.annotation.IdType; // 导入 IdType 类
import com.baomidou.mybatisplus.annotation.TableId; // 导入 TableId 类
import com.baomidou.mybatisplus.annotation.TableName; // 导入 TableName 类
import lombok.Data; // 导入 Data 类
import lombok.ToString; // 导入 ToString 类
import java.io.Serializable; // 导入 Serializable 类
/** // 保留原作者写的块注释
* <p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* @author itcast // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@ToString // 使用注解 @ToString
@TableName("xc_orders_goods") // 使用注解 @TableName("xc_orders_goods")
public class XcOrdersGoods implements Serializable { // 定义 class XcOrdersGoods
private static final long serialVersionUID = 1L; // 把 1L 赋值给 serialVersionUID
@TableId(value = "id", type = IdType.AUTO) // 使用注解 @TableId(value = "id", type = IdType.AUTO)
private Long id; // 执行语句
/** // 保留原作者写的块注释
* 订单号 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long orderId; // 执行语句
/** // 保留原作者写的块注释
* 商品id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String goodsId; // 执行语句
/** // 保留原作者写的块注释
* 商品类型 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String goodsType; // 执行语句
/** // 保留原作者写的块注释
* 商品名称 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String goodsName; // 执行语句
/** // 保留原作者写的块注释
* 商品交易价,单位分 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Float goodsPrice; // 执行语句
/** // 保留原作者写的块注释
* 商品详情json,可为空 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String goodsDetail; // 执行语句
} // 代码块结束
文件:xuecheng-plus-orders/model/com/xuecheng/orders/model/po/XcPayRecord.java
package com.xuecheng.orders.model.po; // 声明类所在的包路径
import com.baomidou.mybatisplus.annotation.FieldFill; // 导入 FieldFill 类
import com.baomidou.mybatisplus.annotation.TableField; // 导入 TableField 类
import com.baomidou.mybatisplus.annotation.TableName; // 导入 TableName 类
import lombok.Data; // 导入 Data 类
import lombok.ToString; // 导入 ToString 类
import java.io.Serializable; // 导入 Serializable 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
/** // 保留原作者写的块注释
* <p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* @author itcast // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@ToString // 使用注解 @ToString
@TableName("xc_pay_record") // 使用注解 @TableName("xc_pay_record")
public class XcPayRecord implements Serializable { // 定义 class XcPayRecord
private static final long serialVersionUID = 1L; // 把 1L 赋值给 serialVersionUID
/** // 保留原作者写的块注释
* 支付记录号 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long id; // 执行语句
/** // 保留原作者写的块注释
* 本系统支付交易号 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long payNo; // 执行语句
/** // 保留原作者写的块注释
* 第三方支付交易流水号 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String outPayNo; // 执行语句
/** // 保留原作者写的块注释
* 第三方支付渠道编号 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String outPayChannel; // 执行语句
/** // 保留原作者写的块注释
* 商品订单号 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long orderId; // 执行语句
/** // 保留原作者写的块注释
* 订单名称 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String orderName; // 执行语句
/** // 保留原作者写的块注释
* 订单总价单位元 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Float totalPrice; // 执行语句
/** // 保留原作者写的块注释
* 币种CNY // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String currency; // 执行语句
/** // 保留原作者写的块注释
* 创建时间 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@TableField(fill = FieldFill.INSERT) // 使用注解 @TableField(fill = FieldFill.INSERT)
private LocalDateTime createDate; // 执行语句
/** // 保留原作者写的块注释
* 支付状态 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String status; // 执行语句
/** // 保留原作者写的块注释
* 支付成功时间 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private LocalDateTime paySuccessTime; // 执行语句
/** // 保留原作者写的块注释
* 用户id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String userId; // 执行语句
} // 代码块结束
文件:xuecheng-plus-orders/model_pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>xuecheng-plus-orders</artifactId>
<groupId>com.xuecheng</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>xuecheng-plus-orders-model</artifactId>
<dependencies>
<dependency>
<groupId>com.xuecheng</groupId>
<artifactId>xuecheng-plus-base</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--存在mybatisplus注解添加相关注解保证不报错-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-annotation</artifactId>
<version>${mybatis-plus-boot-starter.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-core</artifactId>
<version>${mybatis-plus-boot-starter.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
文件:xuecheng-plus-orders/pom.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <!-- SQL 语句片段 -->
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <!-- SQL 语句片段 -->
<modelVersion>4.0.0</modelVersion> <!-- SQL 语句片段 -->
<parent> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-parent</artifactId> <!-- SQL 语句片段 -->
<groupId>com.xuecheng</groupId> <!-- SQL 语句片段 -->
<version>0.0.1-SNAPSHOT</version> <!-- SQL 语句片段 -->
<relativePath>../xuecheng-plus-parent</relativePath> <!-- SQL 语句片段 -->
</parent> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-orders</artifactId> <!-- SQL 语句片段 -->
<packaging>pom</packaging> <!-- SQL 语句片段 -->
<modules> <!-- SQL 语句片段 -->
<module>xuecheng-plus-orders-api</module> <!-- SQL 语句片段 -->
<module>xuecheng-plus-orders-service</module> <!-- SQL 语句片段 -->
<module>xuecheng-plus-orders-model</module> <!-- SQL 语句片段 -->
</modules> <!-- SQL 语句片段 -->
</project> <!-- SQL 语句片段 -->
文件:xuecheng-plus-orders/root_pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>xuecheng-plus-parent</artifactId>
<groupId>com.xuecheng</groupId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../xuecheng-plus-parent</relativePath>
</parent>
<artifactId>xuecheng-plus-orders</artifactId>
<packaging>pom</packaging>
<modules>
<module>xuecheng-plus-orders-api</module>
<module>xuecheng-plus-orders-service</module>
<module>xuecheng-plus-orders-model</module>
</modules>
</project>
文件:xuecheng-plus-orders/service/main/com/xuecheng/orders/config/AlipayConfig.java
package com.xuecheng.orders.config; // 声明类所在的包路径
/** // 保留原作者写的块注释
* @description 支付宝配置参数 // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/20 22:45 // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public class AlipayConfig { // 定义 class AlipayConfig
// 商户appid // 保留原作者写的行内注释
// public static String APPID = ""; // 保留原作者写的行内注释
// 私钥 pkcs8格式的 // 保留原作者写的行内注释
// public static String RSA_PRIVATE_KEY = ""; // 保留原作者写的行内注释
// 服务器异步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 // 保留原作者写的行内注释
public static String notify_url = "http://商户网关地址/alipay.trade.wap.pay-JAVA-UTF-8/notify_url.jsp"; // 代码逻辑
// 页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 商户可以自定义同步跳转地址 // 保留原作者写的行内注释
public static String return_url = "http://商户网关地址/alipay.trade.wap.pay-JAVA-UTF-8/return_url.jsp"; // 代码逻辑
// 请求网关地址 // 保留原作者写的行内注释
public static String URL = "https://openapi.alipaydev.com/gateway.do"; // 代码逻辑
// 编码 // 保留原作者写的行内注释
public static String CHARSET = "UTF-8"; // 把 "UTF-8" 赋值给 CHARSET
// 返回格式 // 保留原作者写的行内注释
public static String FORMAT = "json"; // 把 "json" 赋值给 FORMAT
// 支付宝公钥 // 保留原作者写的行内注释
// public static String ALIPAY_PUBLIC_KEY = ""; // 保留原作者写的行内注释
// 日志记录目录 // 保留原作者写的行内注释
public static String log_path = "/log"; // 把 "/log" 赋值给 log_path
// RSA2 // 保留原作者写的行内注释
public static String SIGNTYPE = "RSA2"; // 把 "RSA2" 赋值给 SIGNTYPE
} // 代码块结束
文件:xuecheng-plus-orders/service/main/com/xuecheng/orders/config/MybatisPlusConfig.java
package com.xuecheng.orders.config; // 声明类所在的包路径
import com.baomidou.mybatisplus.annotation.DbType; // 导入 DbType 类
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; // 导入 MybatisPlusInterceptor 类
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; // 导入 PaginationInnerInterceptor 类
import org.mybatis.spring.annotation.MapperScan; // 导入 MapperScan 类
import org.springframework.context.annotation.Bean; // 导入 Bean 类
import org.springframework.context.annotation.Configuration; // 导入 Configuration 类
/** // 保留原作者写的块注释
* <P> // 保留原作者写的块注释
* Mybatis-Plus 配置 // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Configuration // 使用注解 @Configuration
@MapperScan("com.xuecheng.orders.mapper") // 使用注解 @MapperScan("com.xuecheng.orders.mapper")
public class MybatisPlusConfig { // 定义 class MybatisPlusConfig
/** // 保留原作者写的块注释
* 新的分页插件 // 保留原作者写的块注释
* 需要设置 MybatisConfiguration#useDeprecatedExecutor = false // 保留原作者写的块注释
* 避免缓存出现问题(该属性会在旧插件移除后一同移除) // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Bean // 使用注解 @Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() { // 定义方法 mybatisPlusInterceptor(...)
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // 创建 MybatisPlusInterceptor 对象并赋值给 interceptor
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 执行语句
return interceptor; // 返回 interceptor
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-orders/service/main/com/xuecheng/orders/config/PayNotifyConfig.java
package com.xuecheng.orders.config; // 声明类所在的包路径
import com.alibaba.fastjson.JSON; // 导入 JSON 类
import com.xuecheng.messagesdk.model.po.MqMessage; // 导入 MqMessage 类
import com.xuecheng.messagesdk.service.MqMessageService; // 导入 MqMessageService 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.amqp.core.*; // 导入 * 类
import org.springframework.amqp.rabbit.core.RabbitTemplate; // 导入 RabbitTemplate 类
import org.springframework.beans.BeansException; // 导入 BeansException 类
import org.springframework.beans.factory.annotation.Qualifier; // 导入 Qualifier 类
import org.springframework.context.ApplicationContext; // 导入 ApplicationContext 类
import org.springframework.context.ApplicationContextAware; // 导入 ApplicationContextAware 类
import org.springframework.context.annotation.Bean; // 导入 Bean 类
import org.springframework.context.annotation.Configuration; // 导入 Configuration 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description TODO // 保留原作者写的块注释
* @date 2023/2/23 16:59 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Slf4j // 使用注解 @Slf4j
@Configuration // 使用注解 @Configuration
public class PayNotifyConfig implements ApplicationContextAware { // 定义 class PayNotifyConfig
//交换机 // 保留原作者写的行内注释
public static final String PAYNOTIFY_EXCHANGE_FANOUT = "paynotify_exchange_fanout"; // 把 "paynotify_exchange_fanout" 赋值给 PAYNOTIFY_EXCHANGE_FANOUT
//支付结果通知消息类型 // 保留原作者写的行内注释
public static final String MESSAGE_TYPE = "payresult_notify"; // 把 "payresult_notify" 赋值给 MESSAGE_TYPE
//支付通知队列 // 保留原作者写的行内注释
public static final String PAYNOTIFY_QUEUE = "paynotify_queue"; // 把 "paynotify_queue" 赋值给 PAYNOTIFY_QUEUE
//声明交换机,且持久化 // 保留原作者写的行内注释
@Bean(PAYNOTIFY_EXCHANGE_FANOUT) // 使用注解 @Bean(PAYNOTIFY_EXCHANGE_FANOUT)
public FanoutExchange paynotify_exchange_fanout() { // 定义方法 paynotify_exchange_fanout(...)
// 三个参数:交换机名称、是否持久化、当没有queue与其绑定时是否自动删除 // 保留原作者写的行内注释
return new FanoutExchange(PAYNOTIFY_EXCHANGE_FANOUT, true, false); // 返回 new FanoutExchange(PAYNOTIFY_EXCHANGE_FANOUT, true, false)
} // 代码块结束
//支付通知队列,且持久化 // 保留原作者写的行内注释
@Bean(PAYNOTIFY_QUEUE) // 使用注解 @Bean(PAYNOTIFY_QUEUE)
public Queue course_publish_queue() { // 定义方法 course_publish_queue(...)
return QueueBuilder.durable(PAYNOTIFY_QUEUE).build(); // 返回 QueueBuilder.durable(PAYNOTIFY_QUEUE).build()
} // 代码块结束
//交换机和支付通知队列绑定 // 保留原作者写的行内注释
@Bean // 使用注解 @Bean
public Binding binding_course_publish_queue(@Qualifier(PAYNOTIFY_QUEUE) Queue queue, @Qualifier(PAYNOTIFY_EXCHANGE_FANOUT) FanoutExchange exchange) { // 定义方法 binding_course_publish_queue(...)
return BindingBuilder.bind(queue).to(exchange); // 返回 BindingBuilder.bind(queue).to(exchange)
} // 代码块结束
@Override // 使用注解 @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { // 定义方法 setApplicationContext(...)
// 获取RabbitTemplate // 保留原作者写的行内注释
RabbitTemplate rabbitTemplate = applicationContext.getBean(RabbitTemplate.class); // 把 applicationContext.getBean(RabbitTemplate.class) 赋值给 rabbitTemplate
//消息处理service // 保留原作者写的行内注释
MqMessageService mqMessageService = applicationContext.getBean(MqMessageService.class); // 把 applicationContext.getBean(MqMessageService.class) 赋值给 mqMessageService
// 设置ReturnCallback // 保留原作者写的行内注释
rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> { // 定义方法 方法(...)
// 投递失败,记录日志 // 保留原作者写的行内注释
log.info("消息发送失败,应答码{},原因{},交换机{},路由键{},消息{}", // 代码逻辑
replyCode, replyText, exchange, routingKey, message.toString()); // 执行语句
MqMessage mqMessage = JSON.parseObject(message.toString(), MqMessage.class); // 把 JSON.parseObject(message.toString(), MqMessage.class) 赋值给 mqMessage
//将消息再添加到消息表 // 保留原作者写的行内注释
mqMessageService.addMessage(mqMessage.getMessageType(),mqMessage.getBusinessKey1(),mqMessage.getBusinessKey2(),mqMessage.getBusinessKey3()); // 执行语句
}); // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-orders/service/main/com/xuecheng/orders/mapper/XcOrdersGoodsMapper.java
package com.xuecheng.orders.mapper; // 声明类所在的包路径
import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.orders.model.po.XcOrdersGoods; // 导入 XcOrdersGoods 类
/** // 保留原作者写的块注释
* <p> // 保留原作者写的块注释
* Mapper 接口 // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* @author itcast // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public interface XcOrdersGoodsMapper extends BaseMapper<XcOrdersGoods> { // 定义 interface XcOrdersGoodsMapper
} // 代码块结束
文件:xuecheng-plus-orders/service/main/com/xuecheng/orders/mapper/XcOrdersGoodsMapper.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.orders.mapper.XcOrdersGoodsMapper"> <!-- MyBatis 映射文件的根标签 -->
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.xuecheng.orders.model.po.XcOrdersGoods"> <!-- 定义结果映射 -->
<id column="id" property="id" /> <!-- 主键列的映射规则 -->
<result column="order_id" property="orderId" /> <!-- 字段与属性的映射规则 -->
<result column="goods_id" property="goodsId" /> <!-- 字段与属性的映射规则 -->
<result column="goods_type" property="goodsType" /> <!-- 字段与属性的映射规则 -->
<result column="goods_name" property="goodsName" /> <!-- 字段与属性的映射规则 -->
<result column="goods_price" property="goodsPrice" /> <!-- 字段与属性的映射规则 -->
<result column="goods_detail" property="goodsDetail" /> <!-- 字段与属性的映射规则 -->
</resultMap> <!-- 结束 resultMap 区块 -->
<!-- 通用查询结果列 -->
<sql id="Base_Column_List"> <!-- 声明可复用的 SQL 片段 -->
id, order_id, goods_id, goods_type, goods_name, goods_price, goods_detail <!-- SQL 语句片段 -->
</sql> <!-- 结束 SQL 片段 -->
</mapper> <!-- 结束 mapper 标签 -->
文件:xuecheng-plus-orders/service/main/com/xuecheng/orders/mapper/XcOrdersMapper.java
package com.xuecheng.orders.mapper; // 声明类所在的包路径
import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.orders.model.po.XcOrders; // 导入 XcOrders 类
/** // 保留原作者写的块注释
* <p> // 保留原作者写的块注释
* Mapper 接口 // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* @author itcast // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public interface XcOrdersMapper extends BaseMapper<XcOrders> { // 定义 interface XcOrdersMapper
} // 代码块结束
文件:xuecheng-plus-orders/service/main/com/xuecheng/orders/mapper/XcOrdersMapper.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.orders.mapper.XcOrdersMapper"> <!-- MyBatis 映射文件的根标签 -->
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.xuecheng.orders.model.po.XcOrders"> <!-- 定义结果映射 -->
<id column="id" property="id" /> <!-- 主键列的映射规则 -->
<result column="total_price" property="totalPrice" /> <!-- 字段与属性的映射规则 -->
<result column="create_date" property="createDate" /> <!-- 字段与属性的映射规则 -->
<result column="status" property="status" /> <!-- 字段与属性的映射规则 -->
<result column="user_id" property="userId" /> <!-- 字段与属性的映射规则 -->
<result column="company_id" property="companyId" /> <!-- 字段与属性的映射规则 -->
<result column="order_type" property="orderType" /> <!-- 字段与属性的映射规则 -->
<result column="order_descrip" property="orderDescrip" /> <!-- 字段与属性的映射规则 -->
<result column="order_detail" property="orderDetail" /> <!-- 字段与属性的映射规则 -->
<result column="out_order_id" property="outOrderId" /> <!-- 字段与属性的映射规则 -->
</resultMap> <!-- 结束 resultMap 区块 -->
<!-- 通用查询结果列 -->
<sql id="Base_Column_List"> <!-- 声明可复用的 SQL 片段 -->
id, total_price, create_date, status, user_id, company_id, order_type, order_descrip, order_detail, out_order_id <!-- SQL 语句片段 -->
</sql> <!-- 结束 SQL 片段 -->
</mapper> <!-- 结束 mapper 标签 -->
文件:xuecheng-plus-orders/service/main/com/xuecheng/orders/mapper/XcPayRecordMapper.java
package com.xuecheng.orders.mapper; // 声明类所在的包路径
import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.orders.model.po.XcPayRecord; // 导入 XcPayRecord 类
/** // 保留原作者写的块注释
* <p> // 保留原作者写的块注释
* Mapper 接口 // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* @author itcast // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public interface XcPayRecordMapper extends BaseMapper<XcPayRecord> { // 定义 interface XcPayRecordMapper
} // 代码块结束
文件:xuecheng-plus-orders/service/main/com/xuecheng/orders/mapper/XcPayRecordMapper.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.orders.mapper.XcPayRecordMapper"> <!-- MyBatis 映射文件的根标签 -->
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.xuecheng.orders.model.po.XcPayRecord"> <!-- 定义结果映射 -->
<id column="id" property="id" /> <!-- 主键列的映射规则 -->
<result column="pay_no" property="payNo" /> <!-- 字段与属性的映射规则 -->
<result column="out_pay_no" property="outPayNo" /> <!-- 字段与属性的映射规则 -->
<result column="out_pay_channel" property="outPayChannel" /> <!-- 字段与属性的映射规则 -->
<result column="order_id" property="orderId" /> <!-- 字段与属性的映射规则 -->
<result column="order_name" property="orderName" /> <!-- 字段与属性的映射规则 -->
<result column="total_price" property="totalPrice" /> <!-- 字段与属性的映射规则 -->
<result column="currency" property="currency" /> <!-- 字段与属性的映射规则 -->
<result column="create_date" property="createDate" /> <!-- 字段与属性的映射规则 -->
<result column="status" property="status" /> <!-- 字段与属性的映射规则 -->
<result column="pay_success_time" property="paySuccessTime" /> <!-- 字段与属性的映射规则 -->
<result column="user_id" property="userId" /> <!-- 字段与属性的映射规则 -->
</resultMap> <!-- 结束 resultMap 区块 -->
<!-- 通用查询结果列 -->
<sql id="Base_Column_List"> <!-- 声明可复用的 SQL 片段 -->
id, pay_no, out_pay_no, out_pay_channel, order_id,order_name, total_price, currency, create_date, status, pay_success_time, user_id <!-- SQL 语句片段 -->
</sql> <!-- 结束 SQL 片段 -->
</mapper> <!-- 结束 mapper 标签 -->
文件:xuecheng-plus-orders/service/main/com/xuecheng/orders/service/impl/OrderServiceImpl.java
package com.xuecheng.orders.service.impl; // 声明类所在的包路径
import com.alibaba.fastjson.JSON; // 导入 JSON 类
import com.alibaba.fastjson.JSONObject; // 导入 JSONObject 类
import com.alipay.api.AlipayApiException; // 导入 AlipayApiException 类
import com.alipay.api.AlipayClient; // 导入 AlipayClient 类
import com.alipay.api.DefaultAlipayClient; // 导入 DefaultAlipayClient 类
import com.alipay.api.request.AlipayTradeQueryRequest; // 导入 AlipayTradeQueryRequest 类
import com.alipay.api.response.AlipayTradeQueryResponse; // 导入 AlipayTradeQueryResponse 类
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; // 导入 LambdaQueryWrapper 类
import com.xuecheng.base.exception.XueChengPlusException; // 导入 XueChengPlusException 类
import com.xuecheng.base.utils.IdWorkerUtils; // 导入 IdWorkerUtils 类
import com.xuecheng.base.utils.QRCodeUtil; // 导入 QRCodeUtil 类
import com.xuecheng.messagesdk.model.po.MqMessage; // 导入 MqMessage 类
import com.xuecheng.messagesdk.service.MqMessageService; // 导入 MqMessageService 类
import com.xuecheng.orders.config.AlipayConfig; // 导入 AlipayConfig 类
import com.xuecheng.orders.config.PayNotifyConfig; // 导入 PayNotifyConfig 类
import com.xuecheng.orders.mapper.XcOrdersGoodsMapper; // 导入 XcOrdersGoodsMapper 类
import com.xuecheng.orders.mapper.XcOrdersMapper; // 导入 XcOrdersMapper 类
import com.xuecheng.orders.mapper.XcPayRecordMapper; // 导入 XcPayRecordMapper 类
import com.xuecheng.orders.model.dto.AddOrderDto; // 导入 AddOrderDto 类
import com.xuecheng.orders.model.dto.PayRecordDto; // 导入 PayRecordDto 类
import com.xuecheng.orders.model.dto.PayStatusDto; // 导入 PayStatusDto 类
import com.xuecheng.orders.model.po.XcOrders; // 导入 XcOrders 类
import com.xuecheng.orders.model.po.XcOrdersGoods; // 导入 XcOrdersGoods 类
import com.xuecheng.orders.model.po.XcPayRecord; // 导入 XcPayRecord 类
import com.xuecheng.orders.service.OrderService; // 导入 OrderService 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.amqp.core.Message; // 导入 Message 类
import org.springframework.amqp.core.MessageBuilder; // 导入 MessageBuilder 类
import org.springframework.amqp.core.MessageDeliveryMode; // 导入 MessageDeliveryMode 类
import org.springframework.amqp.rabbit.connection.CorrelationData; // 导入 CorrelationData 类
import org.springframework.amqp.rabbit.core.RabbitTemplate; // 导入 RabbitTemplate 类
import org.springframework.beans.BeanUtils; // 导入 BeanUtils 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.beans.factory.annotation.Value; // 导入 Value 类
import org.springframework.stereotype.Service; // 导入 Service 类
import org.springframework.transaction.annotation.Transactional; // 导入 Transactional 类
import java.io.IOException; // 导入 IOException 类
import java.nio.charset.StandardCharsets; // 导入 StandardCharsets 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
import java.util.List; // 导入 List 类
import java.util.Map; // 导入 Map 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 订单相关的接口 // 保留原作者写的块注释
* @date 2023/2/26 10:12 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Slf4j // 使用注解 @Slf4j
@Service // 使用注解 @Service
public class OrderServiceImpl implements OrderService { // 定义 class OrderServiceImpl
@Autowired // 使用注解 @Autowired
XcOrdersMapper ordersMapper; // 执行语句
@Autowired // 使用注解 @Autowired
XcOrdersGoodsMapper ordersGoodsMapper; // 执行语句
@Autowired // 使用注解 @Autowired
MqMessageService mqMessageService; // 执行语句
@Autowired // 使用注解 @Autowired
XcPayRecordMapper payRecordMapper; // 执行语句
@Autowired // 使用注解 @Autowired
RabbitTemplate rabbitTemplate; // 执行语句
@Autowired // 使用注解 @Autowired
OrderServiceImpl currentProxy; // 执行语句
@Value("${pay.qrcodeurl}") // 使用注解 @Value("${pay.qrcodeurl}")
String qrcodeurl; // 执行语句
@Value("${pay.alipay.APP_ID}") // 使用注解 @Value("${pay.alipay.APP_ID}")
String APP_ID; // 执行语句
@Value("${pay.alipay.APP_PRIVATE_KEY}") // 使用注解 @Value("${pay.alipay.APP_PRIVATE_KEY}")
String APP_PRIVATE_KEY; // 执行语句
@Value("${pay.alipay.ALIPAY_PUBLIC_KEY}") // 使用注解 @Value("${pay.alipay.ALIPAY_PUBLIC_KEY}")
String ALIPAY_PUBLIC_KEY; // 执行语句
@Transactional // 使用注解 @Transactional
@Override // 使用注解 @Override
public PayRecordDto createOrder(String userId, AddOrderDto addOrderDto) { // 定义方法 createOrder(...)
//插入订单表,订单主表,订单明细表 // 保留原作者写的行内注释
XcOrders xcOrders = saveXcOrders(userId, addOrderDto); // 把 saveXcOrders(userId, addOrderDto) 赋值给 xcOrders
//插入支付记录 // 保留原作者写的行内注释
XcPayRecord payRecord = createPayRecord(xcOrders); // 把 createPayRecord(xcOrders) 赋值给 payRecord
Long payNo = payRecord.getPayNo(); // 把 payRecord.getPayNo() 的返回值赋给 payNo
//生成二维码 // 保留原作者写的行内注释
QRCodeUtil qrCodeUtil = new QRCodeUtil(); // 创建 QRCodeUtil 对象并赋值给 qrCodeUtil
//支付二维码的url // 保留原作者写的行内注释
String url = String.format(qrcodeurl, payNo); // 把 String.format(qrcodeurl, payNo) 赋值给 url
//二维码图片 // 保留原作者写的行内注释
String qrCode = null; // 把变量 qrCode 初始化为 null
try { // 尝试执行可能抛出异常的代码
qrCode = qrCodeUtil.createQRCode(url, 200, 200); // 把 qrCodeUtil.createQRCode(url, 200, 200) 赋值给 qrCode
} catch (IOException e) { // 定义方法 catch(...)
XueChengPlusException.cast("生成二维码出错"); // 执行语句
} // 代码块结束
PayRecordDto payRecordDto = new PayRecordDto(); // 创建 PayRecordDto 对象并赋值给 payRecordDto
BeanUtils.copyProperties(payRecord,payRecordDto); // 执行语句
payRecordDto.setQrcode(qrCode); // 执行语句
return payRecordDto; // 返回 payRecordDto
} // 代码块结束
@Override // 使用注解 @Override
public XcPayRecord getPayRecordByPayno(String payNo) { // 定义方法 getPayRecordByPayno(...)
XcPayRecord xcPayRecord = payRecordMapper.selectOne(new LambdaQueryWrapper<XcPayRecord>().eq(XcPayRecord::getPayNo, payNo)); // 把 payRecordMapper.selectOne(new LambdaQueryWrapper<XcPayRecord>().eq(XcPayRecord::getPayNo, payNo)) 赋值给 xcPayRecord
return xcPayRecord; // 返回 xcPayRecord
} // 代码块结束
@Override // 使用注解 @Override
public PayRecordDto queryPayResult(String payNo) { // 定义方法 queryPayResult(...)
//调用支付宝的接口查询支付结果 // 保留原作者写的行内注释
PayStatusDto payStatusDto = queryPayResultFromAlipay(payNo); // 把 queryPayResultFromAlipay(payNo) 赋值给 payStatusDto
System.out.println(payStatusDto); // 执行语句
//拿到支付结果更新支付记录表和订单表的支付状态 // 保留原作者写的行内注释
currentProxy.saveAliPayStatus(payStatusDto); // 执行语句
//要返回最新的支付记录信息 // 保留原作者写的行内注释
XcPayRecord payRecordByPayno = getPayRecordByPayno(payNo); // 把 getPayRecordByPayno(payNo) 赋值给 payRecordByPayno
PayRecordDto payRecordDto = new PayRecordDto(); // 创建 PayRecordDto 对象并赋值给 payRecordDto
BeanUtils.copyProperties(payRecordByPayno,payRecordDto); // 执行语句
return payRecordDto; // 返回 payRecordDto
} // 代码块结束
/** // 保留原作者写的块注释
* 请求支付宝查询支付结果 // 保留原作者写的块注释
* @param payNo 支付交易号 // 保留原作者写的块注释
* @return 支付结果 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public PayStatusDto queryPayResultFromAlipay(String payNo){ // 定义方法 queryPayResultFromAlipay(...)
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, APP_ID, APP_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE); // 创建 DefaultAlipayClient 对象并赋值给 alipayClient
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest(); // 创建 AlipayTradeQueryRequest 对象并赋值给 request
JSONObject bizContent = new JSONObject(); // 创建 JSONObject 对象并赋值给 bizContent
bizContent.put("out_trade_no", payNo); // 执行语句
//bizContent.put("trade_no", "2014112611001004680073956707"); // 保留原作者写的行内注释
request.setBizContent(bizContent.toString()); // 执行语句
//支付宝返回的信息 // 保留原作者写的行内注释
String body = null; // 把变量 body 初始化为 null
try { // 尝试执行可能抛出异常的代码
AlipayTradeQueryResponse response = alipayClient.execute ( request ); //通过alipayClient调用API,获得对应的response类 // 把 alipayClient.execute ( request ) 赋值给 response
if(!response.isSuccess()){//交易不成功 // 定义方法 方法(...)
XueChengPlusException.cast("请求支付宝查询支付结果失败"); // 执行语句
} // 代码块结束
body = response.getBody(); // 把 response.getBody() 的返回值赋给 body
} catch (AlipayApiException e) { // 定义方法 catch(...)
e.printStackTrace(); // 执行语句
XueChengPlusException.cast("请求支付查询支付结果异常"); // 执行语句
} // 代码块结束
Map bodyMap = JSON.parseObject(body, Map.class); // 把 JSON.parseObject(body, Map.class) 赋值给 bodyMap
Map alipay_trade_query_response = (Map) bodyMap.get("alipay_trade_query_response"); // 把 (Map) bodyMap.get("alipay_trade_query_response") 赋值给 alipay_trade_query_response
//解析支付结果 // 保留原作者写的行内注释
String trade_no = (String) alipay_trade_query_response.get("trade_no"); // 把 (String) alipay_trade_query_response.get("trade_no") 赋值给 trade_no
String trade_status = (String) alipay_trade_query_response.get("trade_status"); // 把 (String) alipay_trade_query_response.get("trade_status") 赋值给 trade_status
String total_amount = (String) alipay_trade_query_response.get("total_amount"); // 把 (String) alipay_trade_query_response.get("total_amount") 赋值给 total_amount
PayStatusDto payStatusDto = new PayStatusDto(); // 创建 PayStatusDto 对象并赋值给 payStatusDto
payStatusDto.setOut_trade_no(payNo); // 执行语句
payStatusDto.setTrade_no(trade_no);//支付宝的交易号 // 执行语句
payStatusDto.setTrade_status(trade_status);//交易状态 // 执行语句
payStatusDto.setApp_id(APP_ID); // 执行语句
payStatusDto.setTotal_amount(total_amount);//总金额 // 执行语句
return payStatusDto; // 返回 payStatusDto
} // 代码块结束
/** // 保留原作者写的块注释
* @description 保存支付宝支付结果 // 保留原作者写的块注释
* @param payStatusDto 支付结果信息 从支付宝查询到的信息 // 保留原作者写的块注释
* @return void // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/4 16:52 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Transactional // 使用注解 @Transactional
public void saveAliPayStatus(PayStatusDto payStatusDto){ // 定义方法 saveAliPayStatus(...)
//支付记录号 // 保留原作者写的行内注释
String payNO = payStatusDto.getOut_trade_no(); // 把 payStatusDto.getOut_trade_no() 的返回值赋给 payNO
XcPayRecord payRecordByPayno = getPayRecordByPayno(payNO); // 把 getPayRecordByPayno(payNO) 赋值给 payRecordByPayno
if(payRecordByPayno == null){ // 定义方法 方法(...)
XueChengPlusException.cast("找不到相关的支付记录"); // 执行语句
} // 代码块结束
//拿到相关联的订单id // 保留原作者写的行内注释
Long orderId = payRecordByPayno.getOrderId(); // 把 payRecordByPayno.getOrderId() 的返回值赋给 orderId
XcOrders xcOrders = ordersMapper.selectById(orderId); // 把 ordersMapper.selectById(orderId) 赋值给 xcOrders
if(xcOrders == null){ // 定义方法 方法(...)
XueChengPlusException.cast("找不到相关联的订单"); // 执行语句
} // 代码块结束
//支付状态 // 保留原作者写的行内注释
String statusFromDb = payRecordByPayno.getStatus(); // 把 payRecordByPayno.getStatus() 的返回值赋给 statusFromDb
//如果数据库支付的状态已经是成功了,不再处理了 // 保留原作者写的行内注释
if("601002".equals(statusFromDb)){ // 定义方法 方法(...)
return ; // 返回
} // 代码块结束
//如果支付成功 // 保留原作者写的行内注释
String trade_status = payStatusDto.getTrade_status();//从支付宝查询到的支付结果 // 把 payStatusDto.getTrade_status() 的返回值赋给 trade_status
if(trade_status.equals("TRADE_SUCCESS")){//支付宝返回的信息为支付成功 // 定义方法 方法(...)
//更新支付记录表的状态为支付成功 // 保留原作者写的行内注释
payRecordByPayno.setStatus("601002"); // 执行语句
//支付宝的订单号 // 保留原作者写的行内注释
payRecordByPayno.setOutPayNo(payStatusDto.getTrade_no()); // 执行语句
//第三方支付渠道编号 // 保留原作者写的行内注释
payRecordByPayno.setOutPayChannel("Alipay"); // 执行语句
//支付成功时间 // 保留原作者写的行内注释
payRecordByPayno.setPaySuccessTime(LocalDateTime.now()); // 执行语句
payRecordMapper.updateById(payRecordByPayno); // 执行语句
//更新订单表的状态为支付成功 // 保留原作者写的行内注释
xcOrders.setStatus("600002");//订单状态为交易成功 // 执行语句
ordersMapper.updateById(xcOrders); // 执行语句
//将消息写到数据库 // 保留原作者写的行内注释
MqMessage mqMessage = mqMessageService.addMessage("payresult_notify", xcOrders.getOutBusinessId(), xcOrders.getOrderType(), null); // 把 mqMessageService.addMessage("payresult_notify", xcOrders.getOutBusinessId(), xcOrders.getOrderType(), null) 赋值给 mqMessage
//发送消息 // 保留原作者写的行内注释
notifyPayResult(mqMessage); // 执行语句
} // 代码块结束
} // 代码块结束
@Override // 使用注解 @Override
public void notifyPayResult(MqMessage message) { // 定义方法 notifyPayResult(...)
//消息内容 // 保留原作者写的行内注释
String jsonString = JSON.toJSONString(message); // 把 JSON.toJSONString(message) 赋值给 jsonString
//创建一个持久化消息 // 保留原作者写的行内注释
Message messageObj = MessageBuilder.withBody(jsonString.getBytes(StandardCharsets.UTF_8)).setDeliveryMode(MessageDeliveryMode.PERSISTENT).build(); // 把 MessageBuilder.withBody(jsonString.getBytes(StandardCharsets.UTF_8)).setDeliveryMode(MessageDeliveryMode.PERSISTENT).build() 的返回值赋给 messageObj
//消息id // 保留原作者写的行内注释
Long id = message.getId(); // 把 message.getId() 的返回值赋给 id
//全局消息id // 保留原作者写的行内注释
CorrelationData correlationData = new CorrelationData(id.toString()); // 创建 CorrelationData 对象并赋值给 correlationData
//使用correlationData指定回调方法 // 保留原作者写的行内注释
correlationData.getFuture().addCallback(result->{ // 定义方法 方法(...)
if(result.isAck()){ // 定义方法 方法(...)
//消息成功发送到了交换机 // 保留原作者写的行内注释
log.debug("发送消息成功:{}",jsonString); // 执行语句
//将消息从数据库表mq_message删除 // 保留原作者写的行内注释
mqMessageService.completed(id); // 执行语句
}else{ // 代码逻辑
//消息发送失败 // 保留原作者写的行内注释
log.debug("发送消息失败:{}",jsonString); // 执行语句
} // 代码块结束
},ex->{ // 代码逻辑
//发生异常了 // 保留原作者写的行内注释
log.debug("发送消息异常:{}",jsonString); // 执行语句
}); // 执行语句
//发送消息 // 保留原作者写的行内注释
rabbitTemplate.convertAndSend(PayNotifyConfig.PAYNOTIFY_EXCHANGE_FANOUT,"",messageObj,correlationData); // 执行语句
} // 代码块结束
/** // 保留原作者写的块注释
* 保存支付记录 // 保留原作者写的块注释
* @param orders // 保留原作者写的块注释
* @return // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public XcPayRecord createPayRecord(XcOrders orders){ // 定义方法 createPayRecord(...)
//订单id // 保留原作者写的行内注释
Long orderId = orders.getId(); // 把 orders.getId() 的返回值赋给 orderId
XcOrders xcOrders = ordersMapper.selectById(orderId); // 把 ordersMapper.selectById(orderId) 赋值给 xcOrders
//如果此订单不存在不能添加支付记录 // 保留原作者写的行内注释
if(xcOrders == null){ // 定义方法 方法(...)
XueChengPlusException.cast("订单不存在"); // 执行语句
} // 代码块结束
//订单状态 // 保留原作者写的行内注释
String status = xcOrders.getStatus(); // 把 xcOrders.getStatus() 的返回值赋给 status
//如果此订单支付结果为成功,不再添加支付记录,避免重复支付 // 保留原作者写的行内注释
if("601002".equals(status)){//支付成功 // 定义方法 方法(...)
XueChengPlusException.cast("此订单已支付"); // 执行语句
} // 代码块结束
//添加支付记录 // 保留原作者写的行内注释
XcPayRecord xcPayRecord = new XcPayRecord(); // 创建 XcPayRecord 对象并赋值给 xcPayRecord
xcPayRecord.setPayNo(IdWorkerUtils.getInstance().nextId());//支付记录号,将来要传给支付宝 // 执行语句
xcPayRecord.setOrderId(orderId); // 执行语句
xcPayRecord.setOrderName(xcOrders.getOrderName()); // 执行语句
xcPayRecord.setTotalPrice(xcOrders.getTotalPrice()); // 执行语句
xcPayRecord.setCurrency("CNY"); // 执行语句
xcPayRecord.setCreateDate(LocalDateTime.now()); // 执行语句
xcPayRecord.setStatus("601001");//未支付 // 执行语句
xcPayRecord.setUserId(xcOrders.getUserId()); // 执行语句
int insert = payRecordMapper.insert(xcPayRecord); // 把 payRecordMapper.insert(xcPayRecord) 赋值给 insert
if(insert<=0){ // 定义方法 方法(...)
XueChengPlusException.cast("插入支付记录失败"); // 执行语句
} // 代码块结束
return xcPayRecord; // 返回 xcPayRecord
} // 代码块结束
/** // 保留原作者写的块注释
* 保存订单信息 // 保留原作者写的块注释
* @param userId // 保留原作者写的块注释
* @param addOrderDto // 保留原作者写的块注释
* @return // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public XcOrders saveXcOrders(String userId, AddOrderDto addOrderDto){ // 定义方法 saveXcOrders(...)
//插入订单表,订单主表,订单明细表 // 保留原作者写的行内注释
//进行幂等性判断,同一个选课记录只能有一个订单 // 保留原作者写的行内注释
XcOrders xcOrders = getOrderByBusinessId(addOrderDto.getOutBusinessId()); // 把 getOrderByBusinessId(addOrderDto.getOutBusinessId()) 赋值给 xcOrders
if(xcOrders!=null){ // 定义方法 方法(...)
return xcOrders; // 返回 xcOrders
} // 代码块结束
//插入订单主表 // 保留原作者写的行内注释
xcOrders = new XcOrders(); // 创建 XcOrders 对象并赋值给 xcOrders
//使用雪花算法生成订单号 // 保留原作者写的行内注释
xcOrders.setId(IdWorkerUtils.getInstance().nextId()); // 执行语句
xcOrders.setTotalPrice(addOrderDto.getTotalPrice()); // 执行语句
xcOrders.setCreateDate(LocalDateTime.now()); // 执行语句
xcOrders.setStatus("600001");//未支付 // 执行语句
xcOrders.setUserId(userId); // 执行语句
xcOrders.setOrderType("60201");//订单类型 // 执行语句
xcOrders.setOrderName(addOrderDto.getOrderName()); // 执行语句
xcOrders.setOrderDescrip(addOrderDto.getOrderDescrip()); // 执行语句
xcOrders.setOrderDetail(addOrderDto.getOrderDetail()); // 执行语句
xcOrders.setOutBusinessId(addOrderDto.getOutBusinessId());//如果是选课这里记录选课表的id // 执行语句
int insert = ordersMapper.insert(xcOrders); // 把 ordersMapper.insert(xcOrders) 赋值给 insert
if(insert<=0){ // 定义方法 方法(...)
XueChengPlusException.cast("添加订单失败"); // 执行语句
} // 代码块结束
//订单id // 保留原作者写的行内注释
Long orderId = xcOrders.getId(); // 把 xcOrders.getId() 的返回值赋给 orderId
//插入订单明细表 // 保留原作者写的行内注释
//将前端传入的明细json串转成List // 保留原作者写的行内注释
String orderDetailJson = addOrderDto.getOrderDetail(); // 把 addOrderDto.getOrderDetail() 的返回值赋给 orderDetailJson
List<XcOrdersGoods> xcOrdersGoods = JSON.parseArray(orderDetailJson, XcOrdersGoods.class); // 把 JSON.parseArray(orderDetailJson, XcOrdersGoods.class) 赋值给 xcOrdersGoods
//遍历xcOrdersGoods插入订单明细表 // 保留原作者写的行内注释
xcOrdersGoods.forEach(goods->{ // 定义方法 方法(...)
goods.setOrderId(orderId); // 执行语句
//插入订单明细表 // 保留原作者写的行内注释
int insert1 = ordersGoodsMapper.insert(goods); // 把 ordersGoodsMapper.insert(goods) 赋值给 insert1
}); // 执行语句
return xcOrders; // 返回 xcOrders
} // 代码块结束
/** // 保留原作者写的块注释
* 根据业务id查询订单 ,业务id是选课记录表中的主键 // 保留原作者写的块注释
* @param businessId // 保留原作者写的块注释
* @return // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public XcOrders getOrderByBusinessId(String businessId) { // 定义方法 getOrderByBusinessId(...)
XcOrders orders = ordersMapper.selectOne(new LambdaQueryWrapper<XcOrders>().eq(XcOrders::getOutBusinessId, businessId)); // 把 ordersMapper.selectOne(new LambdaQueryWrapper<XcOrders>().eq(XcOrders::getOutBusinessId, businessId)) 赋值给 orders
return orders; // 返回 orders
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-orders/service/main/com/xuecheng/orders/service/OrderService.java
package com.xuecheng.orders.service; // 声明类所在的包路径
import com.xuecheng.messagesdk.model.po.MqMessage; // 导入 MqMessage 类
import com.xuecheng.orders.model.dto.AddOrderDto; // 导入 AddOrderDto 类
import com.xuecheng.orders.model.dto.PayRecordDto; // 导入 PayRecordDto 类
import com.xuecheng.orders.model.dto.PayStatusDto; // 导入 PayStatusDto 类
import com.xuecheng.orders.model.po.XcPayRecord; // 导入 XcPayRecord 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 订单相关的service接口 // 保留原作者写的块注释
* @date 2023/2/26 10:11 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public interface OrderService { // 定义 interface OrderService
/** // 保留原作者写的块注释
* @description 创建商品订单 // 保留原作者写的块注释
* @param addOrderDto 订单信息 // 保留原作者写的块注释
* @return PayRecordDto 支付记录(包括二维码) // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/4 11:02 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public PayRecordDto createOrder(String userId, AddOrderDto addOrderDto); // 执行语句
/** // 保留原作者写的块注释
* @description 查询支付记录 // 保留原作者写的块注释
* @param payNo 交易记录号 // 保留原作者写的块注释
* @return com.xuecheng.orders.model.po.XcPayRecord // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/20 23:38 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public XcPayRecord getPayRecordByPayno(String payNo); // 执行语句
/** // 保留原作者写的块注释
* 请求支付宝查询支付结果 // 保留原作者写的块注释
* @param payNo 支付记录id // 保留原作者写的块注释
* @return 支付记录信息 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public PayRecordDto queryPayResult(String payNo); // 执行语句
/** // 保留原作者写的块注释
* 保存支付状态 // 保留原作者写的块注释
* @param payStatusDto // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public void saveAliPayStatus(PayStatusDto payStatusDto); // 执行语句
/** // 保留原作者写的块注释
* 发送通知结果 // 保留原作者写的块注释
* @param message // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public void notifyPayResult(MqMessage message); // 执行语句
} // 代码块结束
文件:xuecheng-plus-orders/service_pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>xuecheng-plus-orders</artifactId>
<groupId>com.xuecheng</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>xuecheng-plus-orders-service</artifactId>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.xuecheng</groupId>
<artifactId>xuecheng-plus-message-sdk</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.xuecheng</groupId>
<artifactId>xuecheng-plus-orders-model</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!-- MySQL 驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- mybatis plus的依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
</dependency>
<!-- Spring Boot 集成 Junit -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- 排除 Spring Boot 依赖的日志包冲突 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- Spring Boot 集成 log4j2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-- Spring Cloud 微服务远程调用 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 支付宝SDK -->
<dependency>
<groupId>com.alipay.sdk</groupId>
<artifactId>alipay-sdk-java</artifactId>
<version>3.7.73.ALL</version>
</dependency>
<!-- 支付宝SDK依赖的日志 -->
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
</dependencies>
</project>
文件:xuecheng-plus-orders/test_service/com/xuecheng/orders/AliPayTest.java
package com.xuecheng.orders; // 声明类所在的包路径
import com.alibaba.fastjson.JSONObject; // 导入 JSONObject 类
import com.alipay.api.AlipayApiException; // 导入 AlipayApiException 类
import com.alipay.api.AlipayClient; // 导入 AlipayClient 类
import com.alipay.api.DefaultAlipayClient; // 导入 DefaultAlipayClient 类
import com.alipay.api.request.AlipayTradeQueryRequest; // 导入 AlipayTradeQueryRequest 类
import com.alipay.api.response.AlipayTradeQueryResponse; // 导入 AlipayTradeQueryResponse 类
import com.xuecheng.orders.config.AlipayConfig; // 导入 AlipayConfig 类
import org.junit.jupiter.api.Test; // 导入 Test 类
import org.springframework.beans.factory.annotation.Value; // 导入 Value 类
import org.springframework.boot.test.context.SpringBootTest; // 导入 SpringBootTest 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 请求支付宝查询订单状态 // 保留原作者写的块注释
* @date 2023/2/25 16:49 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@SpringBootTest // 使用注解 @SpringBootTest
public class AliPayTest { // 定义 class AliPayTest
@Value("${pay.alipay.APP_ID}") // 使用注解 @Value("${pay.alipay.APP_ID}")
String APP_ID; // 执行语句
@Value("${pay.alipay.APP_PRIVATE_KEY}") // 使用注解 @Value("${pay.alipay.APP_PRIVATE_KEY}")
String APP_PRIVATE_KEY; // 执行语句
@Value("${pay.alipay.ALIPAY_PUBLIC_KEY}") // 使用注解 @Value("${pay.alipay.ALIPAY_PUBLIC_KEY}")
String ALIPAY_PUBLIC_KEY; // 执行语句
@Test // 使用注解 @Test
public void queryPayResult() throws AlipayApiException { // 定义方法 queryPayResult(...)
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, APP_ID, APP_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE); // 创建 DefaultAlipayClient 对象并赋值给 alipayClient
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest(); // 创建 AlipayTradeQueryRequest 对象并赋值给 request
JSONObject bizContent = new JSONObject(); // 创建 JSONObject 对象并赋值给 bizContent
bizContent.put("out_trade_no", "1629685380690747392"); // 执行语句
//bizContent.put("trade_no", "2014112611001004680073956707"); // 保留原作者写的行内注释
request.setBizContent(bizContent.toString()); // 执行语句
AlipayTradeQueryResponse response = alipayClient.execute ( request ); //通过alipayClient调用API,获得对应的response类 // 把 alipayClient.execute ( request ) 赋值给 response
String body = response.getBody(); // 把 response.getBody() 的返回值赋给 body
System.out.print( body); // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-orders/test_service/com/xuecheng/orders/OrdersApplication.java
package com.xuecheng.orders; // 声明类所在的包路径
import org.springframework.boot.SpringApplication; // 导入 SpringApplication 类
import org.springframework.boot.autoconfigure.SpringBootApplication; // 导入 SpringBootApplication 类
import org.springframework.cloud.openfeign.EnableFeignClients; // 导入 EnableFeignClients 类
@SpringBootApplication // 使用注解 @SpringBootApplication
public class OrdersApplication { // 定义 class OrdersApplication
public static void main(String[] args) { // 定义方法 main(...)
SpringApplication.run(OrdersApplication.class, args); // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-orders/test_service/com/xuecheng/orders/Test1.java
package com.xuecheng.orders; // 声明类所在的包路径
import org.junit.jupiter.api.Test; // 导入 Test 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.boot.test.context.SpringBootTest; // 导入 SpringBootTest 类
/** // 保留原作者写的块注释
* @description TODO // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/2 10:32 // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@SpringBootTest // 使用注解 @SpringBootTest
public class Test1 { // 定义 class Test1
@Test // 使用注解 @Test
public void test(){ // 定义方法 test(...)
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-orders/test_service/resources/bootstrap.yml
spring:
application:
name: orders-service
cloud:
nacos:
server-addr: 192.168.101.65:8848
discovery:
namespace: dev402
group: xuecheng-plus-project
config:
namespace: dev402
group: xuecheng-plus-project
file-extension: yaml
refresh-enabled: true
shared-configs:
- data-id: logging-${spring.profiles.active}.yaml
group: xuecheng-plus-common
refresh: true
#profiles默认为dev
profiles:
active: dev
文件:xuecheng-plus-orders/test_service/resources/log4j2-dev.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorInterval="180" packages="">
<properties>
<property name="logdir">logs</property>
<property name="PATTERN">%date{YYYY-MM-dd HH:mm:ss,SSS} %level [%thread][%file:%line] - %msg%n%throwable</property>
</properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="${PATTERN}"/>
</Console>
<RollingFile name="ErrorAppender" fileName="${logdir}/error.log"
filePattern="${logdir}/$${date:yyyy-MM-dd}/error.%d{yyyy-MM-dd-HH}.log" append="true">
<PatternLayout pattern="${PATTERN}"/>
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
</RollingFile>
<RollingFile name="DebugAppender" fileName="${logdir}/info.log"
filePattern="${logdir}/$${date:yyyy-MM-dd}/info.%d{yyyy-MM-dd-HH}.log" append="true">
<PatternLayout pattern="${PATTERN}"/>
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
</RollingFile>
<!--异步appender-->
<Async name="AsyncAppender" includeLocation="true">
<AppenderRef ref="ErrorAppender"/>
<AppenderRef ref="DebugAppender"/>
</Async>
</Appenders>
<Loggers>
<!--过滤掉spring和mybatis的一些无用的debug信息-->
<logger name="org.springframework" level="INFO">
</logger>
<logger name="org.mybatis" level="INFO">
</logger>
<logger name="cn.itcast.wanxinp2p.consumer.mapper" level="DEBUG">
</logger>
<logger name="springfox" level="INFO">
</logger>
<logger name="org.apache.http" level="INFO">
</logger>
<logger name="com.netflix.discovery" level="INFO">
</logger>
<logger name="RocketmqCommon" level="INFO" >
</logger>
<logger name="RocketmqRemoting" level="INFO" >
</logger>
<logger name="RocketmqClient" level="WARN">
</logger>
<logger name="org.dromara.hmily" level="WARN">
</logger>
<logger name="org.dromara.hmily.lottery" level="WARN">
</logger>
<logger name="org.dromara.hmily.bonuspoint" level="WARN">
</logger>
<!--OFF 0-->
<!--FATAL 100-->
<!--ERROR 200-->
<!--WARN 300-->
<!--INFO 400-->
<!--DEBUG 500-->
<!--TRACE 600-->
<!--ALL Integer.MAX_VALUE-->
<Root level="DEBUG" includeLocation="true">
<AppenderRef ref="AsyncAppender"/>
<AppenderRef ref="Console"/>
<AppenderRef ref="DebugAppender"/>
</Root>
</Loggers>
</Configuration>
文件:xuecheng-plus-orders/xuecheng-plus-orders-api/pom.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <!-- SQL 语句片段 -->
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <!-- SQL 语句片段 -->
<modelVersion>4.0.0</modelVersion> <!-- SQL 语句片段 -->
<parent> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-orders</artifactId> <!-- SQL 语句片段 -->
<groupId>com.xuecheng</groupId> <!-- SQL 语句片段 -->
<version>0.0.1-SNAPSHOT</version> <!-- SQL 语句片段 -->
</parent> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-orders-api</artifactId> <!-- SQL 语句片段 -->
<dependencies> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.alibaba.cloud</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.alibaba.cloud</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.xuecheng</groupId> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-orders-model</artifactId> <!-- SQL 语句片段 -->
<version>0.0.1-SNAPSHOT</version> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.xuecheng</groupId> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-orders-service</artifactId> <!-- SQL 语句片段 -->
<version>0.0.1-SNAPSHOT</version> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!--cloud的基础环境包-->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.cloud</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-cloud-context</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!-- Spring Boot 的 Spring Web MVC 集成 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-boot-starter-web</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!-- Spring Boot 集成 Junit -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-boot-starter-test</artifactId> <!-- SQL 语句片段 -->
<scope>test</scope> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-boot-starter-validation</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!-- 排除 Spring Boot 依赖的日志包冲突 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-boot-starter</artifactId> <!-- SQL 语句片段 -->
<exclusions> <!-- SQL 语句片段 -->
<exclusion> <!-- SQL 语句片段 -->
<groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-boot-starter-logging</artifactId> <!-- SQL 语句片段 -->
</exclusion> <!-- SQL 语句片段 -->
</exclusions> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!-- Spring Boot 集成 log4j2 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-boot-starter-log4j2</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!-- Spring Boot 集成 swagger -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.spring4all</groupId> <!-- SQL 语句片段 -->
<artifactId>swagger-spring-boot-starter</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!--认证相关-->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.cloud</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-cloud-starter-security</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.cloud</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-cloud-starter-oauth2</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.apache.commons</groupId> <!-- SQL 语句片段 -->
<artifactId>commons-lang3</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.google.zxing</groupId> <!-- SQL 语句片段 -->
<artifactId>core</artifactId> <!-- SQL 语句片段 -->
<version>3.3.3</version> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.google.zxing</groupId> <!-- SQL 语句片段 -->
<artifactId>javase</artifactId> <!-- SQL 语句片段 -->
<version>3.3.3</version> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
</dependencies> <!-- SQL 语句片段 -->
</project> <!-- SQL 语句片段 -->
文件:xuecheng-plus-orders/xuecheng-plus-orders-api/src/main/java/com/xuecheng/orders/api/OrderController.java
package com.xuecheng.orders.api; // 声明类所在的包路径
import com.alipay.api.AlipayApiException; // 导入 AlipayApiException 类
import com.alipay.api.AlipayClient; // 导入 AlipayClient 类
import com.alipay.api.DefaultAlipayClient; // 导入 DefaultAlipayClient 类
import com.alipay.api.internal.util.AlipaySignature; // 导入 AlipaySignature 类
import com.alipay.api.request.AlipayTradeWapPayRequest; // 导入 AlipayTradeWapPayRequest 类
import com.xuecheng.base.exception.XueChengPlusException; // 导入 XueChengPlusException 类
import com.xuecheng.orders.config.AlipayConfig; // 导入 AlipayConfig 类
import com.xuecheng.orders.model.dto.AddOrderDto; // 导入 AddOrderDto 类
import com.xuecheng.orders.model.dto.PayRecordDto; // 导入 PayRecordDto 类
import com.xuecheng.orders.model.dto.PayStatusDto; // 导入 PayStatusDto 类
import com.xuecheng.orders.model.po.XcPayRecord; // 导入 XcPayRecord 类
import com.xuecheng.orders.service.OrderService; // 导入 OrderService 类
import com.xuecheng.orders.util.SecurityUtil; // 导入 SecurityUtil 类
import io.swagger.annotations.Api; // 导入 Api 类
import io.swagger.annotations.ApiOperation; // 导入 ApiOperation 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.beans.factory.annotation.Value; // 导入 Value 类
import org.springframework.stereotype.Controller; // 导入 Controller 类
import org.springframework.web.bind.annotation.GetMapping; // 导入 GetMapping 类
import org.springframework.web.bind.annotation.PostMapping; // 导入 PostMapping 类
import org.springframework.web.bind.annotation.RequestBody; // 导入 RequestBody 类
import org.springframework.web.bind.annotation.ResponseBody; // 导入 ResponseBody 类
import javax.servlet.http.HttpServletRequest; // 导入 HttpServletRequest 类
import javax.servlet.http.HttpServletResponse; // 导入 HttpServletResponse 类
import java.io.IOException; // 导入 IOException 类
import java.io.UnsupportedEncodingException; // 导入 UnsupportedEncodingException 类
import java.util.HashMap; // 导入 HashMap 类
import java.util.Iterator; // 导入 Iterator 类
import java.util.Map; // 导入 Map 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 订单相关的接口 // 保留原作者写的块注释
* @date 2023/2/26 10:09 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Api(value = "订单支付接口", tags = "订单支付接口") // 使用注解 @Api(value = "订单支付接口", tags = "订单支付接口")
@Slf4j // 使用注解 @Slf4j
@Controller // 使用注解 @Controller
public class OrderController { // 定义 class OrderController
@Autowired // 使用注解 @Autowired
OrderService orderService; // 执行语句
@Value("${pay.alipay.APP_ID}") // 使用注解 @Value("${pay.alipay.APP_ID}")
String APP_ID; // 执行语句
@Value("${pay.alipay.APP_PRIVATE_KEY}") // 使用注解 @Value("${pay.alipay.APP_PRIVATE_KEY}")
String APP_PRIVATE_KEY; // 执行语句
@Value("${pay.alipay.ALIPAY_PUBLIC_KEY}") // 使用注解 @Value("${pay.alipay.ALIPAY_PUBLIC_KEY}")
String ALIPAY_PUBLIC_KEY; // 执行语句
@ApiOperation("生成支付二维码") // 使用注解 @ApiOperation("生成支付二维码")
@PostMapping("/generatepaycode") // 使用注解 @PostMapping("/generatepaycode")
@ResponseBody // 使用注解 @ResponseBody
public PayRecordDto generatePayCode(@RequestBody AddOrderDto addOrderDto) { // 定义方法 generatePayCode(...)
SecurityUtil.XcUser user = SecurityUtil.getUser(); // 把 SecurityUtil.getUser() 的返回值赋给 user
String userId = user.getId(); // 把 user.getId() 的返回值赋给 userId
//调用service,完成插入订单信息、插入支付记录、生成支付二维码 // 保留原作者写的行内注释
PayRecordDto payRecordDto = orderService.createOrder(userId, addOrderDto); // 把 orderService.createOrder(userId, addOrderDto) 赋值给 payRecordDto
return payRecordDto; // 返回 payRecordDto
} // 代码块结束
@ApiOperation("扫码下单接口") // 使用注解 @ApiOperation("扫码下单接口")
@GetMapping("/requestpay") // 使用注解 @GetMapping("/requestpay")
public void requestpay(String payNo, HttpServletResponse httpResponse) throws IOException, AlipayApiException { // 定义方法 requestpay(...)
//传入了支付记录号,判断支付记录号是否存在 // 保留原作者写的行内注释
XcPayRecord payRecordByPayno = orderService.getPayRecordByPayno(payNo); // 把 orderService.getPayRecordByPayno(payNo) 赋值给 payRecordByPayno
if(payRecordByPayno == null){ // 定义方法 方法(...)
XueChengPlusException.cast("支付记录不存在"); // 执行语句
} // 代码块结束
//支付结果 // 保留原作者写的行内注释
String status = payRecordByPayno.getStatus(); // 把 payRecordByPayno.getStatus() 的返回值赋给 status
if ("601002".equals(status)) { // 定义方法 方法(...)
XueChengPlusException.cast("已支付,无需重复支付"); // 执行语句
} // 代码块结束
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, APP_ID, APP_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE); // 创建 DefaultAlipayClient 对象并赋值给 alipayClient
AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();//创建API对应的request // 创建 AlipayTradeWapPayRequest 对象并赋值给 alipayRequest
// alipayRequest.setReturnUrl("http://domain.com/CallBack/return_url.jsp"); // 保留原作者写的行内注释
alipayRequest.setNotifyUrl("http://tjxt-user-t.itheima.net/xuecheng/orders/paynotify");//在公共参数中设置回跳和通知地址 // 代码逻辑
alipayRequest.setBizContent("{" + // 代码逻辑
" \"out_trade_no\":\""+payNo+"\"," + // 代码逻辑
" \"total_amount\":"+payRecordByPayno.getTotalPrice()+"," + // 代码逻辑
" \"subject\":\""+payRecordByPayno.getOrderName()+"\"," + // 代码逻辑
" \"product_code\":\"QUICK_WAP_WAY\"" + // 代码逻辑
" }");//填充业务参数 // 执行语句
String form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK请求支付宝下单 // 把 alipayClient.pageExecute(alipayRequest).getBody() 的返回值赋给 form
httpResponse.setContentType("text/html;charset=" + AlipayConfig.CHARSET); // 把 " + AlipayConfig.CHARSET) 赋值给 httpResponse.setContentType("text/html;charset
httpResponse.getWriter().write(form);//直接将完整的表单html输出到页面 // 执行语句
httpResponse.getWriter().flush(); // 执行语句
} // 代码块结束
@ApiOperation("查询支付结果") // 使用注解 @ApiOperation("查询支付结果")
@GetMapping("/payresult") // 使用注解 @GetMapping("/payresult")
@ResponseBody // 使用注解 @ResponseBody
public PayRecordDto payresult(String payNo) throws IOException { // 定义方法 payresult(...)
//查询支付结果 // 保留原作者写的行内注释
PayRecordDto payRecordDto = orderService.queryPayResult(payNo); // 把 orderService.queryPayResult(payNo) 赋值给 payRecordDto
return payRecordDto; // 返回 payRecordDto
} // 代码块结束
//接收支付宝通知 // 保留原作者写的行内注释
@PostMapping("/paynotify") // 使用注解 @PostMapping("/paynotify")
public void paynotify(HttpServletRequest request, HttpServletResponse response) throws IOException, AlipayApiException { // 定义方法 paynotify(...)
//获取支付宝POST过来反馈信息 // 保留原作者写的行内注释
Map<String,String> params = new HashMap<String,String>(); // 创建 HashMap<String,String> 对象并赋值给 params
Map requestParams = request.getParameterMap(); // 把 request.getParameterMap() 的返回值赋给 requestParams
for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) { // 定义方法 方法(...)
String name = (String) iter.next(); // 把 (String) iter.next() 的返回值赋给 name
String[] values = (String[]) requestParams.get(name); // 把 (String[]) requestParams.get(name) 赋值给 values
String valueStr = ""; // 把 "" 赋值给 valueStr
for (int i = 0; i < values.length; i++) { // 定义方法 方法(...)
valueStr = (i == values.length - 1) ? valueStr + values[i] // 代码逻辑
: valueStr + values[i] + ","; // 执行语句
} // 代码块结束
params.put(name, valueStr); // 执行语句
} // 代码块结束
boolean verify_result = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2"); // 把 AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2") 赋值给 verify_result
if(verify_result){//验证成功 // 定义方法 方法(...)
//商户订单号 // 保留原作者写的行内注释
String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8"); // 创建 String 对象并赋值给 out_trade_no
//支付宝交易号 // 保留原作者写的行内注释
String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8"); // 创建 String 对象并赋值给 trade_no
//交易金额 // 保留原作者写的行内注释
String total_amount = new String(request.getParameter("total_amount").getBytes("ISO-8859-1"),"UTF-8"); // 创建 String 对象并赋值给 total_amount
//交易状态 // 保留原作者写的行内注释
String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8"); // 创建 String 对象并赋值给 trade_status
if (trade_status.equals("TRADE_SUCCESS")){ // 定义方法 方法(...)
//更新支付记录表的支付状态为成功,订单表的状态为成功 // 保留原作者写的行内注释
PayStatusDto payStatusDto = new PayStatusDto(); // 创建 PayStatusDto 对象并赋值给 payStatusDto
payStatusDto.setTrade_status(trade_status); // 执行语句
payStatusDto.setTrade_no(trade_no); // 执行语句
payStatusDto.setOut_trade_no(out_trade_no); // 执行语句
payStatusDto.setTotal_amount(total_amount); // 执行语句
payStatusDto.setApp_id(APP_ID); // 执行语句
orderService.saveAliPayStatus(payStatusDto); // 执行语句
} // 代码块结束
response.getWriter().write("success"); // 执行语句
}else{//验证失败 // 代码逻辑
response.getWriter().write("fail"); // 执行语句
} // 代码块结束
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-orders/xuecheng-plus-orders-api/src/main/java/com/xuecheng/orders/api/PayTestController.java
package com.xuecheng.orders.api; // 声明类所在的包路径
import com.alipay.api.AlipayApiException; // 导入 AlipayApiException 类
import com.alipay.api.AlipayClient; // 导入 AlipayClient 类
import com.alipay.api.DefaultAlipayClient; // 导入 DefaultAlipayClient 类
import com.alipay.api.internal.util.AlipaySignature; // 导入 AlipaySignature 类
import com.alipay.api.request.AlipayTradeWapPayRequest; // 导入 AlipayTradeWapPayRequest 类
import com.xuecheng.orders.config.AlipayConfig; // 导入 AlipayConfig 类
import org.springframework.beans.factory.annotation.Value; // 导入 Value 类
import org.springframework.stereotype.Controller; // 导入 Controller 类
import org.springframework.web.bind.annotation.PostMapping; // 导入 PostMapping 类
import org.springframework.web.bind.annotation.RequestMapping; // 导入 RequestMapping 类
import javax.servlet.ServletException; // 导入 ServletException 类
import javax.servlet.http.HttpServletRequest; // 导入 HttpServletRequest 类
import javax.servlet.http.HttpServletResponse; // 导入 HttpServletResponse 类
import java.io.IOException; // 导入 IOException 类
import java.io.UnsupportedEncodingException; // 导入 UnsupportedEncodingException 类
import java.util.HashMap; // 导入 HashMap 类
import java.util.Iterator; // 导入 Iterator 类
import java.util.Map; // 导入 Map 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 扫码支付的测试 // 保留原作者写的块注释
* @date 2023/2/25 16:17 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Controller // 使用注解 @Controller
public class PayTestController { // 定义 class PayTestController
@Value("${pay.alipay.APP_ID}") // 使用注解 @Value("${pay.alipay.APP_ID}")
String APP_ID; // 执行语句
@Value("${pay.alipay.APP_PRIVATE_KEY}") // 使用注解 @Value("${pay.alipay.APP_PRIVATE_KEY}")
String APP_PRIVATE_KEY; // 执行语句
@Value("${pay.alipay.ALIPAY_PUBLIC_KEY}") // 使用注解 @Value("${pay.alipay.ALIPAY_PUBLIC_KEY}")
String ALIPAY_PUBLIC_KEY; // 执行语句
//下单接口测试 // 保留原作者写的行内注释
@RequestMapping("/alipaytest") // 使用注解 @RequestMapping("/alipaytest")
public void doPost(HttpServletRequest httpRequest, // 代码逻辑
HttpServletResponse httpResponse) throws ServletException, IOException, AlipayApiException { // 代码逻辑
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, APP_ID, APP_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE); // 创建 DefaultAlipayClient 对象并赋值给 alipayClient
AlipayTradeWapPayRequest alipayRequest = new AlipayTradeWapPayRequest();//创建API对应的request // 创建 AlipayTradeWapPayRequest 对象并赋值给 alipayRequest
// alipayRequest.setReturnUrl("http://domain.com/CallBack/return_url.jsp"); // 保留原作者写的行内注释
alipayRequest.setNotifyUrl("http://tjxt-user-t.itheima.net/xuecheng/orders/paynotify");//在公共参数中设置回跳和通知地址 // 代码逻辑
alipayRequest.setBizContent("{" + // 代码逻辑
" \"out_trade_no\":\"202303200101020011\"," + // 代码逻辑
" \"total_amount\":0.1," + // 代码逻辑
" \"subject\":\"Iphone14 16G\"," + // 代码逻辑
" \"product_code\":\"QUICK_WAP_WAY\"" + // 代码逻辑
" }");//填充业务参数 // 执行语句
String form = alipayClient.pageExecute(alipayRequest).getBody(); //调用SDK生成表单 // 把 alipayClient.pageExecute(alipayRequest).getBody() 的返回值赋给 form
httpResponse.setContentType("text/html;charset=" + AlipayConfig.CHARSET); // 把 " + AlipayConfig.CHARSET) 赋值给 httpResponse.setContentType("text/html;charset
httpResponse.getWriter().write(form);//直接将完整的表单html输出到页面 // 执行语句
httpResponse.getWriter().flush(); // 执行语句
} // 代码块结束
//支付结果通知 // 保留原作者写的行内注释
@PostMapping("/paynotifytest") // 使用注解 @PostMapping("/paynotifytest")
public void paynotify(HttpServletRequest request,HttpServletResponse response) throws IOException, AlipayApiException { // 定义方法 paynotify(...)
//获取支付宝POST过来反馈信息 // 保留原作者写的行内注释
Map<String,String> params = new HashMap<String,String>(); // 创建 HashMap<String,String> 对象并赋值给 params
Map requestParams = request.getParameterMap(); // 把 request.getParameterMap() 的返回值赋给 requestParams
for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) { // 定义方法 方法(...)
String name = (String) iter.next(); // 把 (String) iter.next() 的返回值赋给 name
String[] values = (String[]) requestParams.get(name); // 把 (String[]) requestParams.get(name) 赋值给 values
String valueStr = ""; // 把 "" 赋值给 valueStr
for (int i = 0; i < values.length; i++) { // 定义方法 方法(...)
valueStr = (i == values.length - 1) ? valueStr + values[i] // 代码逻辑
: valueStr + values[i] + ","; // 执行语句
} // 代码块结束
//乱码解决,这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化 // 保留原作者写的行内注释
//valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk"); // 保留原作者写的行内注释
params.put(name, valueStr); // 执行语句
} // 代码块结束
//获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)// // 保留原作者写的行内注释
//获取支付宝的通知返回参数,可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)// // 保留原作者写的行内注释
//计算得出通知验证结果 // 保留原作者写的行内注释
//boolean AlipaySignature.rsaCheckV1(Map<String, String> params, String publicKey, String charset, String sign_type) // 保留原作者写的行内注释
boolean verify_result = AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2"); // 把 AlipaySignature.rsaCheckV1(params, ALIPAY_PUBLIC_KEY, AlipayConfig.CHARSET, "RSA2") 赋值给 verify_result
if(verify_result){//验证成功 // 定义方法 方法(...)
////////////////////////////////////////////////////////////////////////////////////////// // 保留原作者写的行内注释
//请在这里加上商户的业务逻辑程序代码 // 保留原作者写的行内注释
//商户订单号 // 保留原作者写的行内注释
String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8"); // 创建 String 对象并赋值给 out_trade_no
//支付宝交易号 // 保留原作者写的行内注释
String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8"); // 创建 String 对象并赋值给 trade_no
//交易状态 // 保留原作者写的行内注释
String trade_status = new String(request.getParameter("trade_status").getBytes("ISO-8859-1"),"UTF-8"); // 创建 String 对象并赋值给 trade_status
//——请根据您的业务逻辑来编写程序(以下代码仅作参考)—— // 保留原作者写的行内注释
if(trade_status.equals("TRADE_FINISHED")){ // 定义方法 方法(...)
//判断该笔订单是否在商户网站中已经做过处理 // 保留原作者写的行内注释
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序 // 保留原作者写的行内注释
//请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的 // 保留原作者写的行内注释
//如果有做过处理,不执行商户的业务程序 // 保留原作者写的行内注释
//注意: // 保留原作者写的行内注释
//如果签约的是可退款协议,退款日期超过可退款期限后(如三个月可退款),支付宝系统发送该交易状态通知 // 保留原作者写的行内注释
//如果没有签约可退款协议,那么付款完成后,支付宝系统发送该交易状态通知。 // 保留原作者写的行内注释
} else if (trade_status.equals("TRADE_SUCCESS")){ // 定义方法 if(...)
//判断该笔订单是否在商户网站中已经做过处理 // 保留原作者写的行内注释
//如果没有做过处理,根据订单号(out_trade_no)在商户网站的订单系统中查到该笔订单的详细,并执行商户的业务程序 // 保留原作者写的行内注释
//请务必判断请求时的total_fee、seller_id与通知时获取的total_fee、seller_id为一致的 // 保留原作者写的行内注释
//如果有做过处理,不执行商户的业务程序 // 保留原作者写的行内注释
System.out.println(trade_status); // 执行语句
//注意: // 保留原作者写的行内注释
//如果签约的是可退款协议,那么付款完成后,支付宝系统发送该交易状态通知。 // 保留原作者写的行内注释
} // 代码块结束
//——请根据您的业务逻辑来编写程序(以上代码仅作参考)—— // 保留原作者写的行内注释
response.getWriter().write("success"); // 执行语句
////////////////////////////////////////////////////////////////////////////////////////// // 保留原作者写的行内注释
}else{//验证失败 // 代码逻辑
response.getWriter().write("fail"); // 执行语句
} // 代码块结束
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-orders/xuecheng-plus-orders-api/src/main/java/com/xuecheng/orders/config/ResouceServerConfig.java
package com.xuecheng.orders.config; // 声明类所在的包路径
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.context.annotation.Configuration; // 导入 Configuration 类
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; // 导入 EnableGlobalMethodSecurity 类
import org.springframework.security.config.annotation.web.builders.HttpSecurity; // 导入 HttpSecurity 类
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer; // 导入 EnableResourceServer 类
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter; // 导入 ResourceServerConfigurerAdapter 类
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer; // 导入 ResourceServerSecurityConfigurer 类
import org.springframework.security.oauth2.provider.token.TokenStore; // 导入 TokenStore 类
/** // 保留原作者写的块注释
* @author Administrator // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
**/ // 保留原作者写的块注释
@Configuration // 使用注解 @Configuration
@EnableResourceServer // 使用注解 @EnableResourceServer
@EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true) // 使用注解 @EnableGlobalMethodSecurity(securedEnabled = true,prePostEnabled = true)
public class ResouceServerConfig extends ResourceServerConfigurerAdapter { // 定义 class ResouceServerConfig
//资源服务标识 // 保留原作者写的行内注释
public static final String RESOURCE_ID = "xuecheng-plus"; // 把 "xuecheng-plus" 赋值给 RESOURCE_ID
@Autowired // 使用注解 @Autowired
TokenStore tokenStore; // 执行语句
@Override // 使用注解 @Override
public void configure(ResourceServerSecurityConfigurer resources) { // 定义方法 configure(...)
resources.resourceId(RESOURCE_ID)//资源 id // 代码逻辑
.tokenStore(tokenStore) // 代码逻辑
.stateless(true); // 执行语句
} // 代码块结束
@Override // 使用注解 @Override
public void configure(HttpSecurity http) throws Exception { // 定义方法 configure(...)
http.csrf().disable() // 代码逻辑
.authorizeRequests() // 代码逻辑
// .antMatchers("/r/**","/course/**").authenticated()//所有/r/**的请求必须认证通过 // 保留原作者写的行内注释
.anyRequest().permitAll() // 代码逻辑
; // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-orders/xuecheng-plus-orders-api/src/main/java/com/xuecheng/orders/config/TokenConfig.java
package com.xuecheng.orders.config; // 声明类所在的包路径
import org.springframework.context.annotation.Bean; // 导入 Bean 类
import org.springframework.context.annotation.Configuration; // 导入 Configuration 类
import org.springframework.security.oauth2.provider.token.TokenStore; // 导入 TokenStore 类
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter; // 导入 JwtAccessTokenConverter 类
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore; // 导入 JwtTokenStore 类
/** // 保留原作者写的块注释
* @author Administrator // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
**/ // 保留原作者写的块注释
@Configuration // 使用注解 @Configuration
public class TokenConfig { // 定义 class TokenConfig
//jwt签名密钥,与认证服务保持一致 // 保留原作者写的行内注释
private String SIGNING_KEY = "mq123"; // 把 "mq123" 赋值给 SIGNING_KEY
@Bean // 使用注解 @Bean
public TokenStore tokenStore() { // 定义方法 tokenStore(...)
//JWT令牌存储方案 // 保留原作者写的行内注释
return new JwtTokenStore(accessTokenConverter()); // 返回 new JwtTokenStore(accessTokenConverter())
} // 代码块结束
@Bean // 使用注解 @Bean
public JwtAccessTokenConverter accessTokenConverter() { // 定义方法 accessTokenConverter(...)
JwtAccessTokenConverter converter = new JwtAccessTokenConverter(); // 创建 JwtAccessTokenConverter 对象并赋值给 converter
converter.setSigningKey(SIGNING_KEY); // 执行语句
return converter; // 返回 converter
} // 代码块结束
/* @Bean // 保留原作者写的块注释
public TokenStore tokenStore() { // 定义方法 tokenStore(...)
//使用内存存储令牌(普通令牌) // 保留原作者写的行内注释
return new InMemoryTokenStore(); // 返回 new InMemoryTokenStore()
}*/ // 代码逻辑
} // 代码块结束
文件:xuecheng-plus-orders/xuecheng-plus-orders-api/src/main/java/com/xuecheng/orders/util/SecurityUtil.java
package com.xuecheng.orders.util; // 声明类所在的包路径
import com.alibaba.fastjson.JSON; // 导入 JSON 类
import lombok.Data; // 导入 Data 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.security.core.context.SecurityContextHolder; // 导入 SecurityContextHolder 类
import java.io.Serializable; // 导入 Serializable 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
/*** // 保留原作者写的块注释
* 获取当前登录用户信息,使用解析jwt中的用户信息 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Slf4j // 使用注解 @Slf4j
public class SecurityUtil { // 定义 class SecurityUtil
public static XcUser getUser() { // 定义方法 getUser(...)
try { // 尝试执行可能抛出异常的代码
Object principalObj = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); // 把 SecurityContextHolder.getContext().getAuthentication().getPrincipal() 的返回值赋给 principalObj
if (principalObj instanceof String) { // 定义方法 方法(...)
//取出用户身份信息 // 保留原作者写的行内注释
String principal = principalObj.toString(); // 把 principalObj.toString() 的返回值赋给 principal
//将json转成对象 // 保留原作者写的行内注释
XcUser user = JSON.parseObject(principal, XcUser.class); // 把 JSON.parseObject(principal, XcUser.class) 赋值给 user
return user; // 返回 user
} // 代码块结束
} catch (Exception e) { // 定义方法 catch(...)
log.error("获取当前登录用户身份出错:{}", e.getMessage()); // 执行语句
e.printStackTrace(); // 执行语句
} // 代码块结束
return null; // 返回 null
} // 代码块结束
@Data // 使用注解 @Data
public static class XcUser implements Serializable { // 代码逻辑
private static final long serialVersionUID = 1L; // 把 1L 赋值给 serialVersionUID
private String id; // 执行语句
private String username; // 执行语句
private String password; // 执行语句
private String salt; // 执行语句
private String name; // 执行语句
private String nickname; // 执行语句
private String wxUnionid; // 执行语句
private String companyId; // 执行语句
/** // 保留原作者写的块注释
* 头像 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String userpic; // 执行语句
private String utype; // 执行语句
private LocalDateTime birthday; // 执行语句
private String sex; // 执行语句
private String email; // 执行语句
private String cellphone; // 执行语句
private String qq; // 执行语句
/** // 保留原作者写的块注释
* 用户状态 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String status; // 执行语句
private LocalDateTime createTime; // 执行语句
private LocalDateTime updateTime; // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-orders/xuecheng-plus-orders-api/src/main/java/com/xuecheng/OrdersApiApplication.java
package com.xuecheng; // 声明类所在的包路径
import org.springframework.boot.SpringApplication; // 导入 SpringApplication 类
import org.springframework.boot.autoconfigure.SpringBootApplication; // 导入 SpringBootApplication 类
@SpringBootApplication // 使用注解 @SpringBootApplication
public class OrdersApiApplication { // 定义 class OrdersApiApplication
public static void main(String[] args) { // 定义方法 main(...)
SpringApplication.run(OrdersApiApplication.class, args); // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-orders/xuecheng-plus-orders-api/src/main/resources/bootstrap.yml
#微服务配置
spring:
application:
name: orders-api
cloud:
nacos:
server-addr: 192.168.101.65:8848
discovery:
namespace: dev402
group: xuecheng-plus-project
config:
namespace: dev402
group: xuecheng-plus-project
file-extension: yaml
refresh-enabled: true
extension-configs:
- data-id: orders-service-${spring.profiles.active}.yaml
group: xuecheng-plus-project
refresh: true
shared-configs:
- data-id: swagger-${spring.profiles.active}.yaml
group: xuecheng-plus-common
refresh: true
- data-id: logging-${spring.profiles.active}.yaml
group: xuecheng-plus-common
refresh: true
- data-id: rabbitmq-${spring.profiles.active}.yaml
group: xuecheng-plus-common
refresh: true
profiles:
active: dev
文件:xuecheng-plus-orders/xuecheng-plus-orders-api/src/main/resources/log4j2-dev.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<Configuration monitorInterval="180" packages=""> <!-- SQL 语句片段 -->
<properties> <!-- SQL 语句片段 -->
<property name="logdir">logs</property> <!-- SQL 语句片段 -->
<property name="PATTERN">%date{YYYY-MM-dd HH:mm:ss,SSS} %level [%thread][%file:%line] - %msg%n%throwable</property> <!-- SQL 语句片段 -->
</properties> <!-- SQL 语句片段 -->
<Appenders> <!-- SQL 语句片段 -->
<Console name="Console" target="SYSTEM_OUT"> <!-- SQL 语句片段 -->
<PatternLayout pattern="${PATTERN}"/> <!-- SQL 语句片段 -->
</Console> <!-- SQL 语句片段 -->
<RollingFile name="ErrorAppender" fileName="${logdir}/error.log" <!-- SQL 语句片段 -->
filePattern="${logdir}/$${date:yyyy-MM-dd}/error.%d{yyyy-MM-dd-HH}.log" append="true"> <!-- SQL 语句片段 -->
<PatternLayout pattern="${PATTERN}"/> <!-- SQL 语句片段 -->
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/> <!-- SQL 语句片段 -->
<Policies> <!-- SQL 语句片段 -->
<TimeBasedTriggeringPolicy interval="1" modulate="true" /> <!-- SQL 语句片段 -->
</Policies> <!-- SQL 语句片段 -->
</RollingFile> <!-- SQL 语句片段 -->
<RollingFile name="DebugAppender" fileName="${logdir}/info.log" <!-- SQL 语句片段 -->
filePattern="${logdir}/$${date:yyyy-MM-dd}/info.%d{yyyy-MM-dd-HH}.log" append="true"> <!-- SQL 语句片段 -->
<PatternLayout pattern="${PATTERN}"/> <!-- SQL 语句片段 -->
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/> <!-- SQL 语句片段 -->
<Policies> <!-- SQL 语句片段 -->
<TimeBasedTriggeringPolicy interval="1" modulate="true" /> <!-- SQL 语句片段 -->
</Policies> <!-- SQL 语句片段 -->
</RollingFile> <!-- SQL 语句片段 -->
<!--异步appender-->
<Async name="AsyncAppender" includeLocation="true"> <!-- SQL 语句片段 -->
<AppenderRef ref="ErrorAppender"/> <!-- SQL 语句片段 -->
<AppenderRef ref="DebugAppender"/> <!-- SQL 语句片段 -->
</Async> <!-- SQL 语句片段 -->
</Appenders> <!-- SQL 语句片段 -->
<Loggers> <!-- SQL 语句片段 -->
<!--过滤掉spring和mybatis的一些无用的debug信息-->
<logger name="org.springframework" level="INFO"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="org.mybatis" level="INFO"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="cn.itcast.wanxinp2p.consumer.mapper" level="DEBUG"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="springfox" level="INFO"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="org.apache.http" level="INFO"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="com.netflix.discovery" level="INFO"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="RocketmqCommon" level="INFO" > <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="RocketmqRemoting" level="INFO" > <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="RocketmqClient" level="WARN"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="org.dromara.hmily" level="WARN"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="org.dromara.hmily.lottery" level="WARN"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="org.dromara.hmily.bonuspoint" level="WARN"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<!--OFF 0-->
<!--FATAL 100-->
<!--ERROR 200-->
<!--WARN 300-->
<!--INFO 400-->
<!--DEBUG 500-->
<!--TRACE 600-->
<!--ALL Integer.MAX_VALUE-->
<Root level="DEBUG" includeLocation="true"> <!-- SQL 语句片段 -->
<AppenderRef ref="AsyncAppender"/> <!-- SQL 语句片段 -->
<AppenderRef ref="Console"/> <!-- SQL 语句片段 -->
<AppenderRef ref="DebugAppender"/> <!-- SQL 语句片段 -->
</Root> <!-- SQL 语句片段 -->
</Loggers> <!-- SQL 语句片段 -->
</Configuration> <!-- SQL 语句片段 -->
文件:xuecheng-plus-orders/xuecheng-plus-orders-model/pom.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <!-- SQL 语句片段 -->
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <!-- SQL 语句片段 -->
<modelVersion>4.0.0</modelVersion> <!-- SQL 语句片段 -->
<parent> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-orders</artifactId> <!-- SQL 语句片段 -->
<groupId>com.xuecheng</groupId> <!-- SQL 语句片段 -->
<version>0.0.1-SNAPSHOT</version> <!-- SQL 语句片段 -->
</parent> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-orders-model</artifactId> <!-- SQL 语句片段 -->
<dependencies> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.xuecheng</groupId> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-base</artifactId> <!-- SQL 语句片段 -->
<version>0.0.1-SNAPSHOT</version> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!--存在mybatisplus注解添加相关注解保证不报错-->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.baomidou</groupId> <!-- SQL 语句片段 -->
<artifactId>mybatis-plus-annotation</artifactId> <!-- SQL 语句片段 -->
<version>${mybatis-plus-boot-starter.version}</version> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.baomidou</groupId> <!-- SQL 语句片段 -->
<artifactId>mybatis-plus-core</artifactId> <!-- SQL 语句片段 -->
<version>${mybatis-plus-boot-starter.version}</version> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.projectlombok</groupId> <!-- SQL 语句片段 -->
<artifactId>lombok</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
</dependencies> <!-- SQL 语句片段 -->
</project> <!-- SQL 语句片段 -->
文件:xuecheng-plus-orders/xuecheng-plus-orders-model/src/main/java/com/xuecheng/orders/model/dto/AddOrderDto.java
package com.xuecheng.orders.model.dto; // 声明类所在的包路径
import lombok.Data; // 导入 Data 类
import lombok.ToString; // 导入 ToString 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 创建商品订单 // 保留原作者写的块注释
* @date 2022/10/4 10:21 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@ToString // 使用注解 @ToString
public class AddOrderDto { // 定义 class AddOrderDto
/** // 保留原作者写的块注释
* 总价 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Float totalPrice; // 执行语句
/** // 保留原作者写的块注释
* 订单类型 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String orderType; // 执行语句
/** // 保留原作者写的块注释
* 订单名称 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String orderName; // 执行语句
/** // 保留原作者写的块注释
* 订单描述 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String orderDescrip; // 执行语句
/** // 保留原作者写的块注释
* 订单明细json,不可为空 // 保留原作者写的块注释
* [{"goodsId":"","goodsType":"","goodsName":"","goodsPrice":"","goodsDetail":""},{...}] // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String orderDetail; // 执行语句
/** // 保留原作者写的块注释
* 外部系统业务id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String outBusinessId; // 执行语句
} // 代码块结束
文件:xuecheng-plus-orders/xuecheng-plus-orders-model/src/main/java/com/xuecheng/orders/model/dto/PayRecordDto.java
package com.xuecheng.orders.model.dto; // 声明类所在的包路径
import com.xuecheng.orders.model.po.XcPayRecord; // 导入 XcPayRecord 类
import lombok.Data; // 导入 Data 类
import lombok.ToString; // 导入 ToString 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 支付记录dto // 保留原作者写的块注释
* @date 2022/10/4 11:30 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@ToString // 使用注解 @ToString
public class PayRecordDto extends XcPayRecord { // 定义 class PayRecordDto
//二维码 // 保留原作者写的行内注释
private String qrcode; // 执行语句
} // 代码块结束
文件:xuecheng-plus-orders/xuecheng-plus-orders-model/src/main/java/com/xuecheng/orders/model/dto/PayStatusDto.java
package com.xuecheng.orders.model.dto; // 声明类所在的包路径
import lombok.Data; // 导入 Data 类
import lombok.ToString; // 导入 ToString 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 支付结果数据, 用于接收支付结果通知处理逻辑 // 保留原作者写的块注释
* @date 2022/10/4 16:49 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@ToString // 使用注解 @ToString
public class PayStatusDto { // 定义 class PayStatusDto
//商户订单号 // 保留原作者写的行内注释
String out_trade_no; // 执行语句
//支付宝交易号 // 保留原作者写的行内注释
String trade_no; // 执行语句
//交易状态 // 保留原作者写的行内注释
String trade_status; // 执行语句
//appid // 保留原作者写的行内注释
String app_id; // 执行语句
//total_amount // 保留原作者写的行内注释
String total_amount; // 执行语句
} // 代码块结束
文件:xuecheng-plus-orders/xuecheng-plus-orders-model/src/main/java/com/xuecheng/orders/model/po/XcOrders.java
package com.xuecheng.orders.model.po; // 声明类所在的包路径
import com.baomidou.mybatisplus.annotation.FieldFill; // 导入 FieldFill 类
import com.baomidou.mybatisplus.annotation.TableField; // 导入 TableField 类
import com.baomidou.mybatisplus.annotation.TableName; // 导入 TableName 类
import lombok.Data; // 导入 Data 类
import lombok.ToString; // 导入 ToString 类
import java.io.Serializable; // 导入 Serializable 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
/** // 保留原作者写的块注释
* <p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* @author itcast // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@ToString // 使用注解 @ToString
@TableName("xc_orders") // 使用注解 @TableName("xc_orders")
public class XcOrders implements Serializable { // 定义 class XcOrders
private static final long serialVersionUID = 1L; // 把 1L 赋值给 serialVersionUID
/** // 保留原作者写的块注释
* 订单号 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long id; // 执行语句
/** // 保留原作者写的块注释
* 总价 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Float totalPrice; // 执行语句
/** // 保留原作者写的块注释
* 创建时间 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@TableField(fill = FieldFill.INSERT) // 使用注解 @TableField(fill = FieldFill.INSERT)
private LocalDateTime createDate; // 执行语句
/** // 保留原作者写的块注释
* 交易状态 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String status; // 执行语句
/** // 保留原作者写的块注释
* 用户id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String userId; // 执行语句
/** // 保留原作者写的块注释
* 订单类型 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String orderType; // 执行语句
/** // 保留原作者写的块注释
* 订单名称 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String orderName; // 执行语句
/** // 保留原作者写的块注释
* 订单描述 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String orderDescrip; // 执行语句
/** // 保留原作者写的块注释
* 订单明细json // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String orderDetail; // 执行语句
/** // 保留原作者写的块注释
* 外部系统业务id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String outBusinessId; // 执行语句
} // 代码块结束
文件:xuecheng-plus-orders/xuecheng-plus-orders-model/src/main/java/com/xuecheng/orders/model/po/XcOrdersGoods.java
package com.xuecheng.orders.model.po; // 声明类所在的包路径
import com.baomidou.mybatisplus.annotation.IdType; // 导入 IdType 类
import com.baomidou.mybatisplus.annotation.TableId; // 导入 TableId 类
import com.baomidou.mybatisplus.annotation.TableName; // 导入 TableName 类
import lombok.Data; // 导入 Data 类
import lombok.ToString; // 导入 ToString 类
import java.io.Serializable; // 导入 Serializable 类
/** // 保留原作者写的块注释
* <p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* @author itcast // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@ToString // 使用注解 @ToString
@TableName("xc_orders_goods") // 使用注解 @TableName("xc_orders_goods")
public class XcOrdersGoods implements Serializable { // 定义 class XcOrdersGoods
private static final long serialVersionUID = 1L; // 把 1L 赋值给 serialVersionUID
@TableId(value = "id", type = IdType.AUTO) // 使用注解 @TableId(value = "id", type = IdType.AUTO)
private Long id; // 执行语句
/** // 保留原作者写的块注释
* 订单号 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long orderId; // 执行语句
/** // 保留原作者写的块注释
* 商品id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String goodsId; // 执行语句
/** // 保留原作者写的块注释
* 商品类型 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String goodsType; // 执行语句
/** // 保留原作者写的块注释
* 商品名称 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String goodsName; // 执行语句
/** // 保留原作者写的块注释
* 商品交易价,单位分 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Float goodsPrice; // 执行语句
/** // 保留原作者写的块注释
* 商品详情json,可为空 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String goodsDetail; // 执行语句
} // 代码块结束
文件:xuecheng-plus-orders/xuecheng-plus-orders-model/src/main/java/com/xuecheng/orders/model/po/XcPayRecord.java
package com.xuecheng.orders.model.po; // 声明类所在的包路径
import com.baomidou.mybatisplus.annotation.FieldFill; // 导入 FieldFill 类
import com.baomidou.mybatisplus.annotation.TableField; // 导入 TableField 类
import com.baomidou.mybatisplus.annotation.TableName; // 导入 TableName 类
import lombok.Data; // 导入 Data 类
import lombok.ToString; // 导入 ToString 类
import java.io.Serializable; // 导入 Serializable 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
/** // 保留原作者写的块注释
* <p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* @author itcast // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Data // 使用注解 @Data
@ToString // 使用注解 @ToString
@TableName("xc_pay_record") // 使用注解 @TableName("xc_pay_record")
public class XcPayRecord implements Serializable { // 定义 class XcPayRecord
private static final long serialVersionUID = 1L; // 把 1L 赋值给 serialVersionUID
/** // 保留原作者写的块注释
* 支付记录号 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long id; // 执行语句
/** // 保留原作者写的块注释
* 本系统支付交易号 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long payNo; // 执行语句
/** // 保留原作者写的块注释
* 第三方支付交易流水号 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String outPayNo; // 执行语句
/** // 保留原作者写的块注释
* 第三方支付渠道编号 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String outPayChannel; // 执行语句
/** // 保留原作者写的块注释
* 商品订单号 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Long orderId; // 执行语句
/** // 保留原作者写的块注释
* 订单名称 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String orderName; // 执行语句
/** // 保留原作者写的块注释
* 订单总价单位元 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private Float totalPrice; // 执行语句
/** // 保留原作者写的块注释
* 币种CNY // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String currency; // 执行语句
/** // 保留原作者写的块注释
* 创建时间 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@TableField(fill = FieldFill.INSERT) // 使用注解 @TableField(fill = FieldFill.INSERT)
private LocalDateTime createDate; // 执行语句
/** // 保留原作者写的块注释
* 支付状态 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String status; // 执行语句
/** // 保留原作者写的块注释
* 支付成功时间 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private LocalDateTime paySuccessTime; // 执行语句
/** // 保留原作者写的块注释
* 用户id // 保留原作者写的块注释
*/ // 保留原作者写的块注释
private String userId; // 执行语句
} // 代码块结束
文件:xuecheng-plus-orders/xuecheng-plus-orders-service/pom.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <!-- SQL 语句片段 -->
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <!-- SQL 语句片段 -->
<modelVersion>4.0.0</modelVersion> <!-- SQL 语句片段 -->
<parent> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-orders</artifactId> <!-- SQL 语句片段 -->
<groupId>com.xuecheng</groupId> <!-- SQL 语句片段 -->
<version>0.0.1-SNAPSHOT</version> <!-- SQL 语句片段 -->
</parent> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-orders-service</artifactId> <!-- SQL 语句片段 -->
<dependencies> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.alibaba.cloud</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.alibaba.cloud</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.xuecheng</groupId> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-message-sdk</artifactId> <!-- SQL 语句片段 -->
<version>0.0.1-SNAPSHOT</version> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.xuecheng</groupId> <!-- SQL 语句片段 -->
<artifactId>xuecheng-plus-orders-model</artifactId> <!-- SQL 语句片段 -->
<version>0.0.1-SNAPSHOT</version> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!-- MySQL 驱动 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>mysql</groupId> <!-- SQL 语句片段 -->
<artifactId>mysql-connector-java</artifactId> <!-- SQL 语句片段 -->
<scope>runtime</scope> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!-- mybatis plus的依赖 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.baomidou</groupId> <!-- SQL 语句片段 -->
<artifactId>mybatis-plus-boot-starter</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!-- Spring Boot 集成 Junit -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-boot-starter-test</artifactId> <!-- SQL 语句片段 -->
<scope>test</scope> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!-- 排除 Spring Boot 依赖的日志包冲突 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-boot-starter</artifactId> <!-- SQL 语句片段 -->
<exclusions> <!-- SQL 语句片段 -->
<exclusion> <!-- SQL 语句片段 -->
<groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-boot-starter-logging</artifactId> <!-- SQL 语句片段 -->
</exclusion> <!-- SQL 语句片段 -->
</exclusions> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!-- Spring Boot 集成 log4j2 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-boot-starter-log4j2</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-boot-starter-amqp</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-boot-starter-freemarker</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!-- Spring Cloud 微服务远程调用 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.cloud</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-cloud-starter-openfeign</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!-- 支付宝SDK -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.alipay.sdk</groupId> <!-- SQL 语句片段 -->
<artifactId>alipay-sdk-java</artifactId> <!-- SQL 语句片段 -->
<version>3.7.73.ALL</version> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<!-- 支付宝SDK依赖的日志 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>commons-logging</groupId> <!-- SQL 语句片段 -->
<artifactId>commons-logging</artifactId> <!-- SQL 语句片段 -->
<version>1.2</version> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>com.xuxueli</groupId> <!-- SQL 语句片段 -->
<artifactId>xxl-job-core</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
<dependency> <!-- SQL 语句片段 -->
<groupId>org.springframework.boot</groupId> <!-- SQL 语句片段 -->
<artifactId>spring-boot-starter-amqp</artifactId> <!-- SQL 语句片段 -->
</dependency> <!-- SQL 语句片段 -->
</dependencies> <!-- SQL 语句片段 -->
</project> <!-- SQL 语句片段 -->
文件:xuecheng-plus-orders/xuecheng-plus-orders-service/src/main/java/com/xuecheng/orders/config/AlipayConfig.java
package com.xuecheng.orders.config; // 声明类所在的包路径
/** // 保留原作者写的块注释
* @description 支付宝配置参数 // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/20 22:45 // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public class AlipayConfig { // 定义 class AlipayConfig
// 商户appid // 保留原作者写的行内注释
// public static String APPID = ""; // 保留原作者写的行内注释
// 私钥 pkcs8格式的 // 保留原作者写的行内注释
// public static String RSA_PRIVATE_KEY = ""; // 保留原作者写的行内注释
// 服务器异步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 // 保留原作者写的行内注释
public static String notify_url = "http://商户网关地址/alipay.trade.wap.pay-JAVA-UTF-8/notify_url.jsp"; // 代码逻辑
// 页面跳转同步通知页面路径 需http://或者https://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 商户可以自定义同步跳转地址 // 保留原作者写的行内注释
public static String return_url = "http://商户网关地址/alipay.trade.wap.pay-JAVA-UTF-8/return_url.jsp"; // 代码逻辑
// 请求网关地址 // 保留原作者写的行内注释
public static String URL = "https://openapi.alipaydev.com/gateway.do"; // 代码逻辑
// 编码 // 保留原作者写的行内注释
public static String CHARSET = "UTF-8"; // 把 "UTF-8" 赋值给 CHARSET
// 返回格式 // 保留原作者写的行内注释
public static String FORMAT = "json"; // 把 "json" 赋值给 FORMAT
// 支付宝公钥 // 保留原作者写的行内注释
// public static String ALIPAY_PUBLIC_KEY = ""; // 保留原作者写的行内注释
// 日志记录目录 // 保留原作者写的行内注释
public static String log_path = "/log"; // 把 "/log" 赋值给 log_path
// RSA2 // 保留原作者写的行内注释
public static String SIGNTYPE = "RSA2"; // 把 "RSA2" 赋值给 SIGNTYPE
} // 代码块结束
文件:xuecheng-plus-orders/xuecheng-plus-orders-service/src/main/java/com/xuecheng/orders/config/MybatisPlusConfig.java
package com.xuecheng.orders.config; // 声明类所在的包路径
import com.baomidou.mybatisplus.annotation.DbType; // 导入 DbType 类
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; // 导入 MybatisPlusInterceptor 类
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; // 导入 PaginationInnerInterceptor 类
import org.mybatis.spring.annotation.MapperScan; // 导入 MapperScan 类
import org.springframework.context.annotation.Bean; // 导入 Bean 类
import org.springframework.context.annotation.Configuration; // 导入 Configuration 类
/** // 保留原作者写的块注释
* <P> // 保留原作者写的块注释
* Mybatis-Plus 配置 // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Configuration // 使用注解 @Configuration
@MapperScan("com.xuecheng.orders.mapper") // 使用注解 @MapperScan("com.xuecheng.orders.mapper")
public class MybatisPlusConfig { // 定义 class MybatisPlusConfig
/** // 保留原作者写的块注释
* 新的分页插件 // 保留原作者写的块注释
* 需要设置 MybatisConfiguration#useDeprecatedExecutor = false // 保留原作者写的块注释
* 避免缓存出现问题(该属性会在旧插件移除后一同移除) // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Bean // 使用注解 @Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() { // 定义方法 mybatisPlusInterceptor(...)
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // 创建 MybatisPlusInterceptor 对象并赋值给 interceptor
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 执行语句
return interceptor; // 返回 interceptor
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-orders/xuecheng-plus-orders-service/src/main/java/com/xuecheng/orders/config/PayNotifyConfig.java
package com.xuecheng.orders.config; // 声明类所在的包路径
import com.alibaba.fastjson.JSON; // 导入 JSON 类
import com.xuecheng.messagesdk.model.po.MqMessage; // 导入 MqMessage 类
import com.xuecheng.messagesdk.service.MqMessageService; // 导入 MqMessageService 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.amqp.core.*; // 导入 * 类
import org.springframework.amqp.rabbit.core.RabbitTemplate; // 导入 RabbitTemplate 类
import org.springframework.beans.BeansException; // 导入 BeansException 类
import org.springframework.beans.factory.annotation.Qualifier; // 导入 Qualifier 类
import org.springframework.context.ApplicationContext; // 导入 ApplicationContext 类
import org.springframework.context.ApplicationContextAware; // 导入 ApplicationContextAware 类
import org.springframework.context.annotation.Bean; // 导入 Bean 类
import org.springframework.context.annotation.Configuration; // 导入 Configuration 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description TODO // 保留原作者写的块注释
* @date 2023/2/23 16:59 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Slf4j // 使用注解 @Slf4j
@Configuration // 使用注解 @Configuration
public class PayNotifyConfig implements ApplicationContextAware { // 定义 class PayNotifyConfig
//交换机 // 保留原作者写的行内注释
public static final String PAYNOTIFY_EXCHANGE_FANOUT = "paynotify_exchange_fanout"; // 把 "paynotify_exchange_fanout" 赋值给 PAYNOTIFY_EXCHANGE_FANOUT
//支付结果通知消息类型 // 保留原作者写的行内注释
public static final String MESSAGE_TYPE = "payresult_notify"; // 把 "payresult_notify" 赋值给 MESSAGE_TYPE
//支付通知队列 // 保留原作者写的行内注释
public static final String PAYNOTIFY_QUEUE = "paynotify_queue"; // 把 "paynotify_queue" 赋值给 PAYNOTIFY_QUEUE
//声明交换机,且持久化 // 保留原作者写的行内注释
@Bean(PAYNOTIFY_EXCHANGE_FANOUT) // 使用注解 @Bean(PAYNOTIFY_EXCHANGE_FANOUT)
public FanoutExchange paynotify_exchange_fanout() { // 定义方法 paynotify_exchange_fanout(...)
// 三个参数:交换机名称、是否持久化、当没有queue与其绑定时是否自动删除 // 保留原作者写的行内注释
return new FanoutExchange(PAYNOTIFY_EXCHANGE_FANOUT, true, false); // 返回 new FanoutExchange(PAYNOTIFY_EXCHANGE_FANOUT, true, false)
} // 代码块结束
//支付通知队列,且持久化 // 保留原作者写的行内注释
@Bean(PAYNOTIFY_QUEUE) // 使用注解 @Bean(PAYNOTIFY_QUEUE)
public Queue course_publish_queue() { // 定义方法 course_publish_queue(...)
return QueueBuilder.durable(PAYNOTIFY_QUEUE).build(); // 返回 QueueBuilder.durable(PAYNOTIFY_QUEUE).build()
} // 代码块结束
//交换机和支付通知队列绑定 // 保留原作者写的行内注释
@Bean // 使用注解 @Bean
public Binding binding_course_publish_queue(@Qualifier(PAYNOTIFY_QUEUE) Queue queue, @Qualifier(PAYNOTIFY_EXCHANGE_FANOUT) FanoutExchange exchange) { // 定义方法 binding_course_publish_queue(...)
return BindingBuilder.bind(queue).to(exchange); // 返回 BindingBuilder.bind(queue).to(exchange)
} // 代码块结束
@Override // 使用注解 @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { // 定义方法 setApplicationContext(...)
// 获取RabbitTemplate // 保留原作者写的行内注释
RabbitTemplate rabbitTemplate = applicationContext.getBean(RabbitTemplate.class); // 把 applicationContext.getBean(RabbitTemplate.class) 赋值给 rabbitTemplate
//消息处理service // 保留原作者写的行内注释
MqMessageService mqMessageService = applicationContext.getBean(MqMessageService.class); // 把 applicationContext.getBean(MqMessageService.class) 赋值给 mqMessageService
// 设置ReturnCallback // 保留原作者写的行内注释
rabbitTemplate.setReturnCallback((message, replyCode, replyText, exchange, routingKey) -> { // 定义方法 方法(...)
// 投递失败,记录日志 // 保留原作者写的行内注释
log.info("消息发送失败,应答码{},原因{},交换机{},路由键{},消息{}", // 代码逻辑
replyCode, replyText, exchange, routingKey, message.toString()); // 执行语句
MqMessage mqMessage = JSON.parseObject(message.toString(), MqMessage.class); // 把 JSON.parseObject(message.toString(), MqMessage.class) 赋值给 mqMessage
//将消息再添加到消息表 // 保留原作者写的行内注释
mqMessageService.addMessage(mqMessage.getMessageType(),mqMessage.getBusinessKey1(),mqMessage.getBusinessKey2(),mqMessage.getBusinessKey3()); // 执行语句
}); // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-orders/xuecheng-plus-orders-service/src/main/java/com/xuecheng/orders/mapper/XcOrdersGoodsMapper.java
package com.xuecheng.orders.mapper; // 声明类所在的包路径
import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.orders.model.po.XcOrdersGoods; // 导入 XcOrdersGoods 类
/** // 保留原作者写的块注释
* <p> // 保留原作者写的块注释
* Mapper 接口 // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* @author itcast // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public interface XcOrdersGoodsMapper extends BaseMapper<XcOrdersGoods> { // 定义 interface XcOrdersGoodsMapper
} // 代码块结束
文件:xuecheng-plus-orders/xuecheng-plus-orders-service/src/main/java/com/xuecheng/orders/mapper/XcOrdersGoodsMapper.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.orders.mapper.XcOrdersGoodsMapper"> <!-- MyBatis 映射文件的根标签 -->
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.xuecheng.orders.model.po.XcOrdersGoods"> <!-- 定义结果映射 -->
<id column="id" property="id" /> <!-- 主键列的映射规则 -->
<result column="order_id" property="orderId" /> <!-- 字段与属性的映射规则 -->
<result column="goods_id" property="goodsId" /> <!-- 字段与属性的映射规则 -->
<result column="goods_type" property="goodsType" /> <!-- 字段与属性的映射规则 -->
<result column="goods_name" property="goodsName" /> <!-- 字段与属性的映射规则 -->
<result column="goods_price" property="goodsPrice" /> <!-- 字段与属性的映射规则 -->
<result column="goods_detail" property="goodsDetail" /> <!-- 字段与属性的映射规则 -->
</resultMap> <!-- 结束 resultMap 区块 -->
<!-- 通用查询结果列 -->
<sql id="Base_Column_List"> <!-- 声明可复用的 SQL 片段 -->
id, order_id, goods_id, goods_type, goods_name, goods_price, goods_detail <!-- SQL 语句片段 -->
</sql> <!-- 结束 SQL 片段 -->
</mapper> <!-- 结束 mapper 标签 -->
文件:xuecheng-plus-orders/xuecheng-plus-orders-service/src/main/java/com/xuecheng/orders/mapper/XcOrdersMapper.java
package com.xuecheng.orders.mapper; // 声明类所在的包路径
import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.orders.model.po.XcOrders; // 导入 XcOrders 类
/** // 保留原作者写的块注释
* <p> // 保留原作者写的块注释
* Mapper 接口 // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* @author itcast // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public interface XcOrdersMapper extends BaseMapper<XcOrders> { // 定义 interface XcOrdersMapper
} // 代码块结束
文件:xuecheng-plus-orders/xuecheng-plus-orders-service/src/main/java/com/xuecheng/orders/mapper/XcOrdersMapper.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.orders.mapper.XcOrdersMapper"> <!-- MyBatis 映射文件的根标签 -->
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.xuecheng.orders.model.po.XcOrders"> <!-- 定义结果映射 -->
<id column="id" property="id" /> <!-- 主键列的映射规则 -->
<result column="total_price" property="totalPrice" /> <!-- 字段与属性的映射规则 -->
<result column="create_date" property="createDate" /> <!-- 字段与属性的映射规则 -->
<result column="status" property="status" /> <!-- 字段与属性的映射规则 -->
<result column="user_id" property="userId" /> <!-- 字段与属性的映射规则 -->
<result column="company_id" property="companyId" /> <!-- 字段与属性的映射规则 -->
<result column="order_type" property="orderType" /> <!-- 字段与属性的映射规则 -->
<result column="order_descrip" property="orderDescrip" /> <!-- 字段与属性的映射规则 -->
<result column="order_detail" property="orderDetail" /> <!-- 字段与属性的映射规则 -->
<result column="out_order_id" property="outOrderId" /> <!-- 字段与属性的映射规则 -->
</resultMap> <!-- 结束 resultMap 区块 -->
<!-- 通用查询结果列 -->
<sql id="Base_Column_List"> <!-- 声明可复用的 SQL 片段 -->
id, total_price, create_date, status, user_id, company_id, order_type, order_descrip, order_detail, out_order_id <!-- SQL 语句片段 -->
</sql> <!-- 结束 SQL 片段 -->
</mapper> <!-- 结束 mapper 标签 -->
文件:xuecheng-plus-orders/xuecheng-plus-orders-service/src/main/java/com/xuecheng/orders/mapper/XcPayRecordMapper.java
package com.xuecheng.orders.mapper; // 声明类所在的包路径
import com.baomidou.mybatisplus.core.mapper.BaseMapper; // 导入 BaseMapper 类
import com.xuecheng.orders.model.po.XcPayRecord; // 导入 XcPayRecord 类
/** // 保留原作者写的块注释
* <p> // 保留原作者写的块注释
* Mapper 接口 // 保留原作者写的块注释
* </p> // 保留原作者写的块注释
* // 保留原作者写的块注释
* @author itcast // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public interface XcPayRecordMapper extends BaseMapper<XcPayRecord> { // 定义 interface XcPayRecordMapper
} // 代码块结束
文件:xuecheng-plus-orders/xuecheng-plus-orders-service/src/main/java/com/xuecheng/orders/mapper/XcPayRecordMapper.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- SQL 语句片段 -->
<mapper namespace="com.xuecheng.orders.mapper.XcPayRecordMapper"> <!-- MyBatis 映射文件的根标签 -->
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.xuecheng.orders.model.po.XcPayRecord"> <!-- 定义结果映射 -->
<id column="id" property="id" /> <!-- 主键列的映射规则 -->
<result column="pay_no" property="payNo" /> <!-- 字段与属性的映射规则 -->
<result column="out_pay_no" property="outPayNo" /> <!-- 字段与属性的映射规则 -->
<result column="out_pay_channel" property="outPayChannel" /> <!-- 字段与属性的映射规则 -->
<result column="order_id" property="orderId" /> <!-- 字段与属性的映射规则 -->
<result column="order_name" property="orderName" /> <!-- 字段与属性的映射规则 -->
<result column="total_price" property="totalPrice" /> <!-- 字段与属性的映射规则 -->
<result column="currency" property="currency" /> <!-- 字段与属性的映射规则 -->
<result column="create_date" property="createDate" /> <!-- 字段与属性的映射规则 -->
<result column="status" property="status" /> <!-- 字段与属性的映射规则 -->
<result column="pay_success_time" property="paySuccessTime" /> <!-- 字段与属性的映射规则 -->
<result column="user_id" property="userId" /> <!-- 字段与属性的映射规则 -->
</resultMap> <!-- 结束 resultMap 区块 -->
<!-- 通用查询结果列 -->
<sql id="Base_Column_List"> <!-- 声明可复用的 SQL 片段 -->
id, pay_no, out_pay_no, out_pay_channel, order_id,order_name, total_price, currency, create_date, status, pay_success_time, user_id <!-- SQL 语句片段 -->
</sql> <!-- 结束 SQL 片段 -->
</mapper> <!-- 结束 mapper 标签 -->
文件:xuecheng-plus-orders/xuecheng-plus-orders-service/src/main/java/com/xuecheng/orders/service/impl/OrderServiceImpl.java
package com.xuecheng.orders.service.impl; // 声明类所在的包路径
import com.alibaba.fastjson.JSON; // 导入 JSON 类
import com.alibaba.fastjson.JSONObject; // 导入 JSONObject 类
import com.alipay.api.AlipayApiException; // 导入 AlipayApiException 类
import com.alipay.api.AlipayClient; // 导入 AlipayClient 类
import com.alipay.api.DefaultAlipayClient; // 导入 DefaultAlipayClient 类
import com.alipay.api.request.AlipayTradeQueryRequest; // 导入 AlipayTradeQueryRequest 类
import com.alipay.api.response.AlipayTradeQueryResponse; // 导入 AlipayTradeQueryResponse 类
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; // 导入 LambdaQueryWrapper 类
import com.xuecheng.base.exception.XueChengPlusException; // 导入 XueChengPlusException 类
import com.xuecheng.base.utils.IdWorkerUtils; // 导入 IdWorkerUtils 类
import com.xuecheng.base.utils.QRCodeUtil; // 导入 QRCodeUtil 类
import com.xuecheng.messagesdk.model.po.MqMessage; // 导入 MqMessage 类
import com.xuecheng.messagesdk.service.MqMessageService; // 导入 MqMessageService 类
import com.xuecheng.orders.config.AlipayConfig; // 导入 AlipayConfig 类
import com.xuecheng.orders.config.PayNotifyConfig; // 导入 PayNotifyConfig 类
import com.xuecheng.orders.mapper.XcOrdersGoodsMapper; // 导入 XcOrdersGoodsMapper 类
import com.xuecheng.orders.mapper.XcOrdersMapper; // 导入 XcOrdersMapper 类
import com.xuecheng.orders.mapper.XcPayRecordMapper; // 导入 XcPayRecordMapper 类
import com.xuecheng.orders.model.dto.AddOrderDto; // 导入 AddOrderDto 类
import com.xuecheng.orders.model.dto.PayRecordDto; // 导入 PayRecordDto 类
import com.xuecheng.orders.model.dto.PayStatusDto; // 导入 PayStatusDto 类
import com.xuecheng.orders.model.po.XcOrders; // 导入 XcOrders 类
import com.xuecheng.orders.model.po.XcOrdersGoods; // 导入 XcOrdersGoods 类
import com.xuecheng.orders.model.po.XcPayRecord; // 导入 XcPayRecord 类
import com.xuecheng.orders.service.OrderService; // 导入 OrderService 类
import lombok.extern.slf4j.Slf4j; // 导入 Slf4j 类
import org.springframework.amqp.core.Message; // 导入 Message 类
import org.springframework.amqp.core.MessageBuilder; // 导入 MessageBuilder 类
import org.springframework.amqp.core.MessageDeliveryMode; // 导入 MessageDeliveryMode 类
import org.springframework.amqp.rabbit.connection.CorrelationData; // 导入 CorrelationData 类
import org.springframework.amqp.rabbit.core.RabbitTemplate; // 导入 RabbitTemplate 类
import org.springframework.beans.BeanUtils; // 导入 BeanUtils 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.beans.factory.annotation.Value; // 导入 Value 类
import org.springframework.stereotype.Service; // 导入 Service 类
import org.springframework.transaction.annotation.Transactional; // 导入 Transactional 类
import java.io.IOException; // 导入 IOException 类
import java.nio.charset.StandardCharsets; // 导入 StandardCharsets 类
import java.time.LocalDateTime; // 导入 LocalDateTime 类
import java.util.List; // 导入 List 类
import java.util.Map; // 导入 Map 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 订单相关的接口 // 保留原作者写的块注释
* @date 2023/2/26 10:12 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Slf4j // 使用注解 @Slf4j
@Service // 使用注解 @Service
public class OrderServiceImpl implements OrderService { // 定义 class OrderServiceImpl
@Autowired // 使用注解 @Autowired
XcOrdersMapper ordersMapper; // 执行语句
@Autowired // 使用注解 @Autowired
XcOrdersGoodsMapper ordersGoodsMapper; // 执行语句
@Autowired // 使用注解 @Autowired
MqMessageService mqMessageService; // 执行语句
@Autowired // 使用注解 @Autowired
XcPayRecordMapper payRecordMapper; // 执行语句
@Autowired // 使用注解 @Autowired
RabbitTemplate rabbitTemplate; // 执行语句
@Autowired // 使用注解 @Autowired
OrderServiceImpl currentProxy; // 执行语句
@Value("${pay.qrcodeurl}") // 使用注解 @Value("${pay.qrcodeurl}")
String qrcodeurl; // 执行语句
@Value("${pay.alipay.APP_ID}") // 使用注解 @Value("${pay.alipay.APP_ID}")
String APP_ID; // 执行语句
@Value("${pay.alipay.APP_PRIVATE_KEY}") // 使用注解 @Value("${pay.alipay.APP_PRIVATE_KEY}")
String APP_PRIVATE_KEY; // 执行语句
@Value("${pay.alipay.ALIPAY_PUBLIC_KEY}") // 使用注解 @Value("${pay.alipay.ALIPAY_PUBLIC_KEY}")
String ALIPAY_PUBLIC_KEY; // 执行语句
@Transactional // 使用注解 @Transactional
@Override // 使用注解 @Override
public PayRecordDto createOrder(String userId, AddOrderDto addOrderDto) { // 定义方法 createOrder(...)
//插入订单表,订单主表,订单明细表 // 保留原作者写的行内注释
XcOrders xcOrders = saveXcOrders(userId, addOrderDto); // 把 saveXcOrders(userId, addOrderDto) 赋值给 xcOrders
//插入支付记录 // 保留原作者写的行内注释
XcPayRecord payRecord = createPayRecord(xcOrders); // 把 createPayRecord(xcOrders) 赋值给 payRecord
Long payNo = payRecord.getPayNo(); // 把 payRecord.getPayNo() 的返回值赋给 payNo
//生成二维码 // 保留原作者写的行内注释
QRCodeUtil qrCodeUtil = new QRCodeUtil(); // 创建 QRCodeUtil 对象并赋值给 qrCodeUtil
//支付二维码的url // 保留原作者写的行内注释
String url = String.format(qrcodeurl, payNo); // 把 String.format(qrcodeurl, payNo) 赋值给 url
//二维码图片 // 保留原作者写的行内注释
String qrCode = null; // 把变量 qrCode 初始化为 null
try { // 尝试执行可能抛出异常的代码
qrCode = qrCodeUtil.createQRCode(url, 200, 200); // 把 qrCodeUtil.createQRCode(url, 200, 200) 赋值给 qrCode
} catch (IOException e) { // 定义方法 catch(...)
XueChengPlusException.cast("生成二维码出错"); // 执行语句
} // 代码块结束
PayRecordDto payRecordDto = new PayRecordDto(); // 创建 PayRecordDto 对象并赋值给 payRecordDto
BeanUtils.copyProperties(payRecord,payRecordDto); // 执行语句
payRecordDto.setQrcode(qrCode); // 执行语句
return payRecordDto; // 返回 payRecordDto
} // 代码块结束
@Override // 使用注解 @Override
public XcPayRecord getPayRecordByPayno(String payNo) { // 定义方法 getPayRecordByPayno(...)
XcPayRecord xcPayRecord = payRecordMapper.selectOne(new LambdaQueryWrapper<XcPayRecord>().eq(XcPayRecord::getPayNo, payNo)); // 把 payRecordMapper.selectOne(new LambdaQueryWrapper<XcPayRecord>().eq(XcPayRecord::getPayNo, payNo)) 赋值给 xcPayRecord
return xcPayRecord; // 返回 xcPayRecord
} // 代码块结束
@Override // 使用注解 @Override
public PayRecordDto queryPayResult(String payNo) { // 定义方法 queryPayResult(...)
//调用支付宝的接口查询支付结果 // 保留原作者写的行内注释
PayStatusDto payStatusDto = queryPayResultFromAlipay(payNo); // 把 queryPayResultFromAlipay(payNo) 赋值给 payStatusDto
System.out.println(payStatusDto); // 执行语句
//拿到支付结果更新支付记录表和订单表的支付状态 // 保留原作者写的行内注释
currentProxy.saveAliPayStatus(payStatusDto); // 执行语句
//要返回最新的支付记录信息 // 保留原作者写的行内注释
XcPayRecord payRecordByPayno = getPayRecordByPayno(payNo); // 把 getPayRecordByPayno(payNo) 赋值给 payRecordByPayno
PayRecordDto payRecordDto = new PayRecordDto(); // 创建 PayRecordDto 对象并赋值给 payRecordDto
BeanUtils.copyProperties(payRecordByPayno,payRecordDto); // 执行语句
return payRecordDto; // 返回 payRecordDto
} // 代码块结束
/** // 保留原作者写的块注释
* 请求支付宝查询支付结果 // 保留原作者写的块注释
* @param payNo 支付交易号 // 保留原作者写的块注释
* @return 支付结果 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public PayStatusDto queryPayResultFromAlipay(String payNo){ // 定义方法 queryPayResultFromAlipay(...)
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, APP_ID, APP_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE); // 创建 DefaultAlipayClient 对象并赋值给 alipayClient
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest(); // 创建 AlipayTradeQueryRequest 对象并赋值给 request
JSONObject bizContent = new JSONObject(); // 创建 JSONObject 对象并赋值给 bizContent
bizContent.put("out_trade_no", payNo); // 执行语句
//bizContent.put("trade_no", "2014112611001004680073956707"); // 保留原作者写的行内注释
request.setBizContent(bizContent.toString()); // 执行语句
//支付宝返回的信息 // 保留原作者写的行内注释
String body = null; // 把变量 body 初始化为 null
try { // 尝试执行可能抛出异常的代码
AlipayTradeQueryResponse response = alipayClient.execute ( request ); //通过alipayClient调用API,获得对应的response类 // 把 alipayClient.execute ( request ) 赋值给 response
if(!response.isSuccess()){//交易不成功 // 定义方法 方法(...)
XueChengPlusException.cast("请求支付宝查询支付结果失败"); // 执行语句
} // 代码块结束
body = response.getBody(); // 把 response.getBody() 的返回值赋给 body
} catch (AlipayApiException e) { // 定义方法 catch(...)
e.printStackTrace(); // 执行语句
XueChengPlusException.cast("请求支付查询支付结果异常"); // 执行语句
} // 代码块结束
Map bodyMap = JSON.parseObject(body, Map.class); // 把 JSON.parseObject(body, Map.class) 赋值给 bodyMap
Map alipay_trade_query_response = (Map) bodyMap.get("alipay_trade_query_response"); // 把 (Map) bodyMap.get("alipay_trade_query_response") 赋值给 alipay_trade_query_response
//解析支付结果 // 保留原作者写的行内注释
String trade_no = (String) alipay_trade_query_response.get("trade_no"); // 把 (String) alipay_trade_query_response.get("trade_no") 赋值给 trade_no
String trade_status = (String) alipay_trade_query_response.get("trade_status"); // 把 (String) alipay_trade_query_response.get("trade_status") 赋值给 trade_status
String total_amount = (String) alipay_trade_query_response.get("total_amount"); // 把 (String) alipay_trade_query_response.get("total_amount") 赋值给 total_amount
PayStatusDto payStatusDto = new PayStatusDto(); // 创建 PayStatusDto 对象并赋值给 payStatusDto
payStatusDto.setOut_trade_no(payNo); // 执行语句
payStatusDto.setTrade_no(trade_no);//支付宝的交易号 // 执行语句
payStatusDto.setTrade_status(trade_status);//交易状态 // 执行语句
payStatusDto.setApp_id(APP_ID); // 执行语句
payStatusDto.setTotal_amount(total_amount);//总金额 // 执行语句
return payStatusDto; // 返回 payStatusDto
} // 代码块结束
/** // 保留原作者写的块注释
* @description 保存支付宝支付结果 // 保留原作者写的块注释
* @param payStatusDto 支付结果信息 从支付宝查询到的信息 // 保留原作者写的块注释
* @return void // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/4 16:52 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@Transactional // 使用注解 @Transactional
public void saveAliPayStatus(PayStatusDto payStatusDto){ // 定义方法 saveAliPayStatus(...)
//支付记录号 // 保留原作者写的行内注释
String payNO = payStatusDto.getOut_trade_no(); // 把 payStatusDto.getOut_trade_no() 的返回值赋给 payNO
XcPayRecord payRecordByPayno = getPayRecordByPayno(payNO); // 把 getPayRecordByPayno(payNO) 赋值给 payRecordByPayno
if(payRecordByPayno == null){ // 定义方法 方法(...)
XueChengPlusException.cast("找不到相关的支付记录"); // 执行语句
} // 代码块结束
//拿到相关联的订单id // 保留原作者写的行内注释
Long orderId = payRecordByPayno.getOrderId(); // 把 payRecordByPayno.getOrderId() 的返回值赋给 orderId
XcOrders xcOrders = ordersMapper.selectById(orderId); // 把 ordersMapper.selectById(orderId) 赋值给 xcOrders
if(xcOrders == null){ // 定义方法 方法(...)
XueChengPlusException.cast("找不到相关联的订单"); // 执行语句
} // 代码块结束
//支付状态 // 保留原作者写的行内注释
String statusFromDb = payRecordByPayno.getStatus(); // 把 payRecordByPayno.getStatus() 的返回值赋给 statusFromDb
//如果数据库支付的状态已经是成功了,不再处理了 // 保留原作者写的行内注释
if("601002".equals(statusFromDb)){ // 定义方法 方法(...)
return ; // 返回
} // 代码块结束
//如果支付成功 // 保留原作者写的行内注释
String trade_status = payStatusDto.getTrade_status();//从支付宝查询到的支付结果 // 把 payStatusDto.getTrade_status() 的返回值赋给 trade_status
if(trade_status.equals("TRADE_SUCCESS")){//支付宝返回的信息为支付成功 // 定义方法 方法(...)
//更新支付记录表的状态为支付成功 // 保留原作者写的行内注释
payRecordByPayno.setStatus("601002"); // 执行语句
//支付宝的订单号 // 保留原作者写的行内注释
payRecordByPayno.setOutPayNo(payStatusDto.getTrade_no()); // 执行语句
//第三方支付渠道编号 // 保留原作者写的行内注释
payRecordByPayno.setOutPayChannel("Alipay"); // 执行语句
//支付成功时间 // 保留原作者写的行内注释
payRecordByPayno.setPaySuccessTime(LocalDateTime.now()); // 执行语句
payRecordMapper.updateById(payRecordByPayno); // 执行语句
//更新订单表的状态为支付成功 // 保留原作者写的行内注释
xcOrders.setStatus("600002");//订单状态为交易成功 // 执行语句
ordersMapper.updateById(xcOrders); // 执行语句
//将消息写到数据库 // 保留原作者写的行内注释
MqMessage mqMessage = mqMessageService.addMessage("payresult_notify", xcOrders.getOutBusinessId(), xcOrders.getOrderType(), null); // 把 mqMessageService.addMessage("payresult_notify", xcOrders.getOutBusinessId(), xcOrders.getOrderType(), null) 赋值给 mqMessage
//发送消息 // 保留原作者写的行内注释
notifyPayResult(mqMessage); // 执行语句
} // 代码块结束
} // 代码块结束
@Override // 使用注解 @Override
public void notifyPayResult(MqMessage message) { // 定义方法 notifyPayResult(...)
//消息内容 // 保留原作者写的行内注释
String jsonString = JSON.toJSONString(message); // 把 JSON.toJSONString(message) 赋值给 jsonString
//创建一个持久化消息 // 保留原作者写的行内注释
Message messageObj = MessageBuilder.withBody(jsonString.getBytes(StandardCharsets.UTF_8)).setDeliveryMode(MessageDeliveryMode.PERSISTENT).build(); // 把 MessageBuilder.withBody(jsonString.getBytes(StandardCharsets.UTF_8)).setDeliveryMode(MessageDeliveryMode.PERSISTENT).build() 的返回值赋给 messageObj
//消息id // 保留原作者写的行内注释
Long id = message.getId(); // 把 message.getId() 的返回值赋给 id
//全局消息id // 保留原作者写的行内注释
CorrelationData correlationData = new CorrelationData(id.toString()); // 创建 CorrelationData 对象并赋值给 correlationData
//使用correlationData指定回调方法 // 保留原作者写的行内注释
correlationData.getFuture().addCallback(result->{ // 定义方法 方法(...)
if(result.isAck()){ // 定义方法 方法(...)
//消息成功发送到了交换机 // 保留原作者写的行内注释
log.debug("发送消息成功:{}",jsonString); // 执行语句
//将消息从数据库表mq_message删除 // 保留原作者写的行内注释
mqMessageService.completed(id); // 执行语句
}else{ // 代码逻辑
//消息发送失败 // 保留原作者写的行内注释
log.debug("发送消息失败:{}",jsonString); // 执行语句
} // 代码块结束
},ex->{ // 代码逻辑
//发生异常了 // 保留原作者写的行内注释
log.debug("发送消息异常:{}",jsonString); // 执行语句
}); // 执行语句
//发送消息 // 保留原作者写的行内注释
rabbitTemplate.convertAndSend(PayNotifyConfig.PAYNOTIFY_EXCHANGE_FANOUT,"",messageObj,correlationData); // 执行语句
} // 代码块结束
/** // 保留原作者写的块注释
* 保存支付记录 // 保留原作者写的块注释
* @param orders // 保留原作者写的块注释
* @return // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public XcPayRecord createPayRecord(XcOrders orders){ // 定义方法 createPayRecord(...)
//订单id // 保留原作者写的行内注释
Long orderId = orders.getId(); // 把 orders.getId() 的返回值赋给 orderId
XcOrders xcOrders = ordersMapper.selectById(orderId); // 把 ordersMapper.selectById(orderId) 赋值给 xcOrders
//如果此订单不存在不能添加支付记录 // 保留原作者写的行内注释
if(xcOrders == null){ // 定义方法 方法(...)
XueChengPlusException.cast("订单不存在"); // 执行语句
} // 代码块结束
//订单状态 // 保留原作者写的行内注释
String status = xcOrders.getStatus(); // 把 xcOrders.getStatus() 的返回值赋给 status
//如果此订单支付结果为成功,不再添加支付记录,避免重复支付 // 保留原作者写的行内注释
if("601002".equals(status)){//支付成功 // 定义方法 方法(...)
XueChengPlusException.cast("此订单已支付"); // 执行语句
} // 代码块结束
//添加支付记录 // 保留原作者写的行内注释
XcPayRecord xcPayRecord = new XcPayRecord(); // 创建 XcPayRecord 对象并赋值给 xcPayRecord
xcPayRecord.setPayNo(IdWorkerUtils.getInstance().nextId());//支付记录号,将来要传给支付宝 // 执行语句
xcPayRecord.setOrderId(orderId); // 执行语句
xcPayRecord.setOrderName(xcOrders.getOrderName()); // 执行语句
xcPayRecord.setTotalPrice(xcOrders.getTotalPrice()); // 执行语句
xcPayRecord.setCurrency("CNY"); // 执行语句
xcPayRecord.setCreateDate(LocalDateTime.now()); // 执行语句
xcPayRecord.setStatus("601001");//未支付 // 执行语句
xcPayRecord.setUserId(xcOrders.getUserId()); // 执行语句
int insert = payRecordMapper.insert(xcPayRecord); // 把 payRecordMapper.insert(xcPayRecord) 赋值给 insert
if(insert<=0){ // 定义方法 方法(...)
XueChengPlusException.cast("插入支付记录失败"); // 执行语句
} // 代码块结束
return xcPayRecord; // 返回 xcPayRecord
} // 代码块结束
/** // 保留原作者写的块注释
* 保存订单信息 // 保留原作者写的块注释
* @param userId // 保留原作者写的块注释
* @param addOrderDto // 保留原作者写的块注释
* @return // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public XcOrders saveXcOrders(String userId, AddOrderDto addOrderDto){ // 定义方法 saveXcOrders(...)
//插入订单表,订单主表,订单明细表 // 保留原作者写的行内注释
//进行幂等性判断,同一个选课记录只能有一个订单 // 保留原作者写的行内注释
XcOrders xcOrders = getOrderByBusinessId(addOrderDto.getOutBusinessId()); // 把 getOrderByBusinessId(addOrderDto.getOutBusinessId()) 赋值给 xcOrders
if(xcOrders!=null){ // 定义方法 方法(...)
return xcOrders; // 返回 xcOrders
} // 代码块结束
//插入订单主表 // 保留原作者写的行内注释
xcOrders = new XcOrders(); // 创建 XcOrders 对象并赋值给 xcOrders
//使用雪花算法生成订单号 // 保留原作者写的行内注释
xcOrders.setId(IdWorkerUtils.getInstance().nextId()); // 执行语句
xcOrders.setTotalPrice(addOrderDto.getTotalPrice()); // 执行语句
xcOrders.setCreateDate(LocalDateTime.now()); // 执行语句
xcOrders.setStatus("600001");//未支付 // 执行语句
xcOrders.setUserId(userId); // 执行语句
xcOrders.setOrderType("60201");//订单类型 // 执行语句
xcOrders.setOrderName(addOrderDto.getOrderName()); // 执行语句
xcOrders.setOrderDescrip(addOrderDto.getOrderDescrip()); // 执行语句
xcOrders.setOrderDetail(addOrderDto.getOrderDetail()); // 执行语句
xcOrders.setOutBusinessId(addOrderDto.getOutBusinessId());//如果是选课这里记录选课表的id // 执行语句
int insert = ordersMapper.insert(xcOrders); // 把 ordersMapper.insert(xcOrders) 赋值给 insert
if(insert<=0){ // 定义方法 方法(...)
XueChengPlusException.cast("添加订单失败"); // 执行语句
} // 代码块结束
//订单id // 保留原作者写的行内注释
Long orderId = xcOrders.getId(); // 把 xcOrders.getId() 的返回值赋给 orderId
//插入订单明细表 // 保留原作者写的行内注释
//将前端传入的明细json串转成List // 保留原作者写的行内注释
String orderDetailJson = addOrderDto.getOrderDetail(); // 把 addOrderDto.getOrderDetail() 的返回值赋给 orderDetailJson
List<XcOrdersGoods> xcOrdersGoods = JSON.parseArray(orderDetailJson, XcOrdersGoods.class); // 把 JSON.parseArray(orderDetailJson, XcOrdersGoods.class) 赋值给 xcOrdersGoods
//遍历xcOrdersGoods插入订单明细表 // 保留原作者写的行内注释
xcOrdersGoods.forEach(goods->{ // 定义方法 方法(...)
goods.setOrderId(orderId); // 执行语句
//插入订单明细表 // 保留原作者写的行内注释
int insert1 = ordersGoodsMapper.insert(goods); // 把 ordersGoodsMapper.insert(goods) 赋值给 insert1
}); // 执行语句
return xcOrders; // 返回 xcOrders
} // 代码块结束
/** // 保留原作者写的块注释
* 根据业务id查询订单 ,业务id是选课记录表中的主键 // 保留原作者写的块注释
* @param businessId // 保留原作者写的块注释
* @return // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public XcOrders getOrderByBusinessId(String businessId) { // 定义方法 getOrderByBusinessId(...)
XcOrders orders = ordersMapper.selectOne(new LambdaQueryWrapper<XcOrders>().eq(XcOrders::getOutBusinessId, businessId)); // 把 ordersMapper.selectOne(new LambdaQueryWrapper<XcOrders>().eq(XcOrders::getOutBusinessId, businessId)) 赋值给 orders
return orders; // 返回 orders
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-orders/xuecheng-plus-orders-service/src/main/java/com/xuecheng/orders/service/OrderService.java
package com.xuecheng.orders.service; // 声明类所在的包路径
import com.xuecheng.messagesdk.model.po.MqMessage; // 导入 MqMessage 类
import com.xuecheng.orders.model.dto.AddOrderDto; // 导入 AddOrderDto 类
import com.xuecheng.orders.model.dto.PayRecordDto; // 导入 PayRecordDto 类
import com.xuecheng.orders.model.dto.PayStatusDto; // 导入 PayStatusDto 类
import com.xuecheng.orders.model.po.XcPayRecord; // 导入 XcPayRecord 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 订单相关的service接口 // 保留原作者写的块注释
* @date 2023/2/26 10:11 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public interface OrderService { // 定义 interface OrderService
/** // 保留原作者写的块注释
* @description 创建商品订单 // 保留原作者写的块注释
* @param addOrderDto 订单信息 // 保留原作者写的块注释
* @return PayRecordDto 支付记录(包括二维码) // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/4 11:02 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public PayRecordDto createOrder(String userId, AddOrderDto addOrderDto); // 执行语句
/** // 保留原作者写的块注释
* @description 查询支付记录 // 保留原作者写的块注释
* @param payNo 交易记录号 // 保留原作者写的块注释
* @return com.xuecheng.orders.model.po.XcPayRecord // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/20 23:38 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public XcPayRecord getPayRecordByPayno(String payNo); // 执行语句
/** // 保留原作者写的块注释
* 请求支付宝查询支付结果 // 保留原作者写的块注释
* @param payNo 支付记录id // 保留原作者写的块注释
* @return 支付记录信息 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public PayRecordDto queryPayResult(String payNo); // 执行语句
/** // 保留原作者写的块注释
* 保存支付状态 // 保留原作者写的块注释
* @param payStatusDto // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public void saveAliPayStatus(PayStatusDto payStatusDto); // 执行语句
/** // 保留原作者写的块注释
* 发送通知结果 // 保留原作者写的块注释
* @param message // 保留原作者写的块注释
*/ // 保留原作者写的块注释
public void notifyPayResult(MqMessage message); // 执行语句
} // 代码块结束
文件:xuecheng-plus-orders/xuecheng-plus-orders-service/src/test/java/com/xuecheng/orders/AliPayTest.java
package com.xuecheng.orders; // 声明类所在的包路径
import com.alibaba.fastjson.JSONObject; // 导入 JSONObject 类
import com.alipay.api.AlipayApiException; // 导入 AlipayApiException 类
import com.alipay.api.AlipayClient; // 导入 AlipayClient 类
import com.alipay.api.DefaultAlipayClient; // 导入 DefaultAlipayClient 类
import com.alipay.api.request.AlipayTradeQueryRequest; // 导入 AlipayTradeQueryRequest 类
import com.alipay.api.response.AlipayTradeQueryResponse; // 导入 AlipayTradeQueryResponse 类
import com.xuecheng.orders.config.AlipayConfig; // 导入 AlipayConfig 类
import org.junit.jupiter.api.Test; // 导入 Test 类
import org.springframework.beans.factory.annotation.Value; // 导入 Value 类
import org.springframework.boot.test.context.SpringBootTest; // 导入 SpringBootTest 类
/** // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
* @description 请求支付宝查询订单状态 // 保留原作者写的块注释
* @date 2023/2/25 16:49 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@SpringBootTest // 使用注解 @SpringBootTest
public class AliPayTest { // 定义 class AliPayTest
@Value("${pay.alipay.APP_ID}") // 使用注解 @Value("${pay.alipay.APP_ID}")
String APP_ID; // 执行语句
@Value("${pay.alipay.APP_PRIVATE_KEY}") // 使用注解 @Value("${pay.alipay.APP_PRIVATE_KEY}")
String APP_PRIVATE_KEY; // 执行语句
@Value("${pay.alipay.ALIPAY_PUBLIC_KEY}") // 使用注解 @Value("${pay.alipay.ALIPAY_PUBLIC_KEY}")
String ALIPAY_PUBLIC_KEY; // 执行语句
@Test // 使用注解 @Test
public void queryPayResult() throws AlipayApiException { // 定义方法 queryPayResult(...)
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.URL, APP_ID, APP_PRIVATE_KEY, AlipayConfig.FORMAT, AlipayConfig.CHARSET, ALIPAY_PUBLIC_KEY,AlipayConfig.SIGNTYPE); // 创建 DefaultAlipayClient 对象并赋值给 alipayClient
AlipayTradeQueryRequest request = new AlipayTradeQueryRequest(); // 创建 AlipayTradeQueryRequest 对象并赋值给 request
JSONObject bizContent = new JSONObject(); // 创建 JSONObject 对象并赋值给 bizContent
bizContent.put("out_trade_no", "1629685380690747392"); // 执行语句
//bizContent.put("trade_no", "2014112611001004680073956707"); // 保留原作者写的行内注释
request.setBizContent(bizContent.toString()); // 执行语句
AlipayTradeQueryResponse response = alipayClient.execute ( request ); //通过alipayClient调用API,获得对应的response类 // 把 alipayClient.execute ( request ) 赋值给 response
String body = response.getBody(); // 把 response.getBody() 的返回值赋给 body
System.out.print( body); // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-orders/xuecheng-plus-orders-service/src/test/java/com/xuecheng/orders/OrdersApplication.java
package com.xuecheng.orders; // 声明类所在的包路径
import org.springframework.boot.SpringApplication; // 导入 SpringApplication 类
import org.springframework.boot.autoconfigure.SpringBootApplication; // 导入 SpringBootApplication 类
import org.springframework.cloud.openfeign.EnableFeignClients; // 导入 EnableFeignClients 类
@SpringBootApplication // 使用注解 @SpringBootApplication
public class OrdersApplication { // 定义 class OrdersApplication
public static void main(String[] args) { // 定义方法 main(...)
SpringApplication.run(OrdersApplication.class, args); // 执行语句
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-orders/xuecheng-plus-orders-service/src/test/java/com/xuecheng/orders/Test1.java
package com.xuecheng.orders; // 声明类所在的包路径
import org.junit.jupiter.api.Test; // 导入 Test 类
import org.springframework.beans.factory.annotation.Autowired; // 导入 Autowired 类
import org.springframework.boot.test.context.SpringBootTest; // 导入 SpringBootTest 类
/** // 保留原作者写的块注释
* @description TODO // 保留原作者写的块注释
* @author Mr.M // 保留原作者写的块注释
* @date 2022/10/2 10:32 // 保留原作者写的块注释
* @version 1.0 // 保留原作者写的块注释
*/ // 保留原作者写的块注释
@SpringBootTest // 使用注解 @SpringBootTest
public class Test1 { // 定义 class Test1
@Test // 使用注解 @Test
public void test(){ // 定义方法 test(...)
} // 代码块结束
} // 代码块结束
文件:xuecheng-plus-orders/xuecheng-plus-orders-service/src/test/resources/bootstrap.yml
spring:
application:
name: orders-service
cloud:
nacos:
server-addr: 192.168.101.65:8848
discovery:
namespace: dev402
group: xuecheng-plus-project
config:
namespace: dev402
group: xuecheng-plus-project
file-extension: yaml
refresh-enabled: true
shared-configs:
- data-id: logging-${spring.profiles.active}.yaml
group: xuecheng-plus-common
refresh: true
#profiles默认为dev
profiles:
active: dev
文件:xuecheng-plus-orders/xuecheng-plus-orders-service/src/test/resources/log4j2-dev.xml
<?xml version="1.0" encoding="UTF-8"?> <!-- XML 声明 -->
<Configuration monitorInterval="180" packages=""> <!-- SQL 语句片段 -->
<properties> <!-- SQL 语句片段 -->
<property name="logdir">logs</property> <!-- SQL 语句片段 -->
<property name="PATTERN">%date{YYYY-MM-dd HH:mm:ss,SSS} %level [%thread][%file:%line] - %msg%n%throwable</property> <!-- SQL 语句片段 -->
</properties> <!-- SQL 语句片段 -->
<Appenders> <!-- SQL 语句片段 -->
<Console name="Console" target="SYSTEM_OUT"> <!-- SQL 语句片段 -->
<PatternLayout pattern="${PATTERN}"/> <!-- SQL 语句片段 -->
</Console> <!-- SQL 语句片段 -->
<RollingFile name="ErrorAppender" fileName="${logdir}/error.log" <!-- SQL 语句片段 -->
filePattern="${logdir}/$${date:yyyy-MM-dd}/error.%d{yyyy-MM-dd-HH}.log" append="true"> <!-- SQL 语句片段 -->
<PatternLayout pattern="${PATTERN}"/> <!-- SQL 语句片段 -->
<ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/> <!-- SQL 语句片段 -->
<Policies> <!-- SQL 语句片段 -->
<TimeBasedTriggeringPolicy interval="1" modulate="true" /> <!-- SQL 语句片段 -->
</Policies> <!-- SQL 语句片段 -->
</RollingFile> <!-- SQL 语句片段 -->
<RollingFile name="DebugAppender" fileName="${logdir}/info.log" <!-- SQL 语句片段 -->
filePattern="${logdir}/$${date:yyyy-MM-dd}/info.%d{yyyy-MM-dd-HH}.log" append="true"> <!-- SQL 语句片段 -->
<PatternLayout pattern="${PATTERN}"/> <!-- SQL 语句片段 -->
<ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY"/> <!-- SQL 语句片段 -->
<Policies> <!-- SQL 语句片段 -->
<TimeBasedTriggeringPolicy interval="1" modulate="true" /> <!-- SQL 语句片段 -->
</Policies> <!-- SQL 语句片段 -->
</RollingFile> <!-- SQL 语句片段 -->
<!--异步appender-->
<Async name="AsyncAppender" includeLocation="true"> <!-- SQL 语句片段 -->
<AppenderRef ref="ErrorAppender"/> <!-- SQL 语句片段 -->
<AppenderRef ref="DebugAppender"/> <!-- SQL 语句片段 -->
</Async> <!-- SQL 语句片段 -->
</Appenders> <!-- SQL 语句片段 -->
<Loggers> <!-- SQL 语句片段 -->
<!--过滤掉spring和mybatis的一些无用的debug信息-->
<logger name="org.springframework" level="INFO"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="org.mybatis" level="INFO"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="cn.itcast.wanxinp2p.consumer.mapper" level="DEBUG"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="springfox" level="INFO"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="org.apache.http" level="INFO"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="com.netflix.discovery" level="INFO"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="RocketmqCommon" level="INFO" > <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="RocketmqRemoting" level="INFO" > <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="RocketmqClient" level="WARN"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="org.dromara.hmily" level="WARN"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="org.dromara.hmily.lottery" level="WARN"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<logger name="org.dromara.hmily.bonuspoint" level="WARN"> <!-- SQL 语句片段 -->
</logger> <!-- SQL 语句片段 -->
<!--OFF 0-->
<!--FATAL 100-->
<!--ERROR 200-->
<!--WARN 300-->
<!--INFO 400-->
<!--DEBUG 500-->
<!--TRACE 600-->
<!--ALL Integer.MAX_VALUE-->
<Root level="DEBUG" includeLocation="true"> <!-- SQL 语句片段 -->
<AppenderRef ref="AsyncAppender"/> <!-- SQL 语句片段 -->
<AppenderRef ref="Console"/> <!-- SQL 语句片段 -->
<AppenderRef ref="DebugAppender"/> <!-- SQL 语句片段 -->
</Root> <!-- SQL 语句片段 -->
</Loggers> <!-- SQL 语句片段 -->
</Configuration> <!-- SQL 语句片段 -->
评论
0 条
还没有评论,先写一条吧。