package com.ruoyi.web.controller.api; import com.alibaba.fastjson2.JSONObject; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.ruoyi.common.core.domain.R; import com.ruoyi.common.utils.CodeGenerateUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.framework.web.service.TokenService; import com.ruoyi.system.model.TSysAppUser; import com.ruoyi.system.model.TSysInspection; import com.ruoyi.system.model.TSysOtherConfig; import com.ruoyi.system.model.TSysPayRecord; import com.ruoyi.system.service.TSysAppUserService; import com.ruoyi.system.service.TSysInspectionService; import com.ruoyi.system.service.TSysOtherConfigService; import com.ruoyi.system.service.TSysPayRecordService; import com.ruoyi.system.wxPay.enums.TradeStateEnum; import com.ruoyi.system.wxPay.model.WeixinPayProperties; import com.ruoyi.system.wxPay.utils.WxTimeUtils; import com.ruoyi.system.wxPay.utils.WxV3Pay; import com.wechat.pay.contrib.apache.httpclient.util.AesUtil; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.PrintWriter; import java.math.BigDecimal; import java.nio.charset.StandardCharsets; import java.time.LocalDateTime; import java.util.List; import java.util.Map; import java.util.Objects; /** * 微信相关接口 */ @Slf4j @RestController @CrossOrigin @RequestMapping("/wx/") @Api(tags = {"微信支付相关接口"}) public class WxPayController { @Autowired private WxV3Pay wxV3Pay; @Autowired private TokenService tokenService; @Autowired private TSysAppUserService sysAppUserService; @Autowired private TSysOtherConfigService sysOtherConfigService; @Autowired private TSysPayRecordService sysPayRecordService; @Autowired private WeixinPayProperties weixinPayProperties; @Autowired private TSysInspectionService sysInspectionService; /** * 按实际修改 */ @ApiOperation("订单支付") @PostMapping("orderPay") public R> orderPay(@RequestParam(value = "inspectionId",required = false) String inspectionId,@RequestParam(value = "orderType") Integer orderType) { TSysOtherConfig sysOtherConfig = sysOtherConfigService.getById(1); String userId = tokenService.getLoginUserApplet().getUserId(); TSysAppUser sysAppUser = sysAppUserService.getById(userId); Long totalPrice = 0L; if (orderType==1){ if (Objects.isNull(sysOtherConfig.getAiPrice())) { return R.fail("系统未配置AI单次支付价格"); } totalPrice= sysOtherConfig.getAiPrice().multiply(new BigDecimal(100)).longValue(); } if (orderType==2){ if (Objects.isNull(sysOtherConfig.getAiMonthPrice())) { return R.fail("系统未配置AI包月支付价格"); } totalPrice= sysOtherConfig.getAiMonthPrice().multiply(new BigDecimal(100)).longValue(); } if(totalPrice == 0L && StringUtils.isNotBlank(inspectionId)){ TSysInspection sysInspection = sysInspectionService.getById(inspectionId); sysInspection.setIsPay(1); sysInspectionService.updateById(sysInspection); return R.ok(); } // 价格 // 生成订单号 String orderNo = CodeGenerateUtils.generateOrderSn(); // 查询用户信息 用户openid String openId = sysAppUser.getOpenId(); // 存储支付记录 sysPayRecordService.saveData(orderNo, userId, orderType==1?sysOtherConfig.getAiPrice():sysOtherConfig.getAiMonthPrice(), 1, orderType, inspectionId); // 调用支付方法 Map result = wxV3Pay.jsApi(orderNo, totalPrice, openId,"AI检测报告支付",""); log.info("支付参数:{}", result); return R.ok(result); } /** * 支付回调 */ @PostMapping("pay/notify") @ApiOperation("订单回调") public void payNotify(HttpServletRequest request, HttpServletResponse response) throws Exception { try { System.err.println("微信回调"); BufferedReader reader = request.getReader(); StringBuilder requestBody = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { requestBody.append(line); } System.err.println("全部请求体" + requestBody); JSONObject jsonObject = JSONObject.parseObject(requestBody.toString()); JSONObject resource = jsonObject.getJSONObject("resource"); AesUtil aesUtil = new AesUtil(weixinPayProperties.getV3().getApiKey().getBytes(StandardCharsets.UTF_8)); String decryptedData = aesUtil.decryptToString(resource.getString("associated_data").getBytes(StandardCharsets.UTF_8), resource.getString("nonce").getBytes(StandardCharsets.UTF_8), resource.getString("ciphertext")); System.err.println("微信解密的字符串信息" + decryptedData); JSONObject jsonInfo = JSONObject.parse(decryptedData); String out_trade_no = jsonInfo.getString("out_trade_no"); String transaction_id = jsonInfo.getString("transaction_id"); String trade_state = jsonInfo.getString("trade_state"); String success_time = jsonInfo.getString("success_time"); // 查询订单 TSysPayRecord sysPayRecord = sysPayRecordService.getOne(Wrappers.lambdaQuery(TSysPayRecord.class) .eq(TSysPayRecord::getOrderNo, out_trade_no).last("LIMIT 1")); if (trade_state.equals(TradeStateEnum.SUCCESS.name())) { log.info("回调成功"); // 订单号查询订单 sysPayRecord.setPayState(2); sysPayRecord.setPayTime(WxTimeUtils.dateToLocalDateTime(WxTimeUtils.toRfc3339Date(success_time))); sysPayRecord.setTransactionId(transaction_id); String appUserId = sysPayRecord.getAppUserId(); TSysAppUser appUser = sysAppUserService.getById(appUserId); if (sysPayRecord.getOrderType()==2){ LocalDateTime localDateTime = LocalDateTime.now().plusMonths(1L); localDateTime = localDateTime.withHour(23).withMinute(59).withSecond(57); appUser.setVipEndTime(localDateTime); sysAppUserService.updateById(appUser); List list = sysInspectionService.lambdaQuery().eq(TSysInspection::getAppUserId, appUserId) .list(); if (!list.isEmpty()){ for (TSysInspection tSysInspection : list) { tSysInspection.setIsPay(1); } sysInspectionService.updateBatchById(list); } }else { // 处理检测报告为可见 TSysInspection sysInspection = sysInspectionService.getById(sysPayRecord.getInspectionId()); sysInspection.setIsPay(1); sysInspectionService.updateById(sysInspection); } sysPayRecordService.updateById(sysPayRecord); PrintWriter out = response.getWriter(); out.print("SUCCESS"); out.flush(); out.close(); } } catch (Exception e) { log.error("支付回调异常:{}", e, e); wxV3Pay.ack(false, e.getMessage()); } } }