exam-system/pom.xml
@@ -31,6 +31,12 @@ <artifactId>qiniu-java-sdk</artifactId> <version>[7.2.0, 7.2.99]</version> </dependency> <dependency> <groupId>org.redisson</groupId> <artifactId>redisson</artifactId> <version>3.18.0</version> <scope>compile</scope> </dependency> </dependencies> exam-system/src/main/java/com/gkhy/exam/pay/controller/NonCoalPayController.java
@@ -147,7 +147,7 @@ */ @PostMapping("/editNonCoalStu") @ApiOperation(value = "修改非煤缴费学员") public AjaxResult editNonCoalStu(@RequestBody NonCoalPayStudent nonCoalPayStudent) { public AjaxResult editNonCoalStu(@Validated @RequestBody NonCoalPayStudent nonCoalPayStudent) { return toAjax(nonCoalPayStudentService.updateNonCoalPayStudent(nonCoalPayStudent)); } @@ -194,4 +194,16 @@ } @PostMapping("/sendOrder") @ApiOperation(value = "生成财政订单") @Anonymous @RepeatSubmit @ApiImplicitParams({ @ApiImplicitParam(name = "id", dataTypeClass = Long.class, value = "个人缴费学员数据id,团队缴费数据id", required = true), @ApiImplicitParam(name = "payType", dataTypeClass = String.class, value = "1个人2是团队", required = true), }) public AjaxResult sendOrder(@RequestParam("id") Long id, @RequestParam("payType") String payType) { return success(nonCoalPayStudentService.sendOrder(id, payType)); } } exam-system/src/main/java/com/gkhy/exam/pay/dto/rep/NonCoalCateRep.java
对比新文件 @@ -0,0 +1,68 @@ package com.gkhy.exam.pay.dto.rep; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import java.math.BigDecimal; @Data public class NonCoalCateRep { /** * $column.columnComment */ private Long id; /** * $column.columnComment */ @ApiModelProperty("非煤管理id") private Long nonCoalPayId; /** * 类别id */ @ApiModelProperty("类别id") private Long categoryId; @ApiModelProperty("类别名称") private String subjectName; /** * 类别1理论2实操 */ @ApiModelProperty("类别类型id") private Long categoryType; @ApiModelProperty("缴费金额") private BigDecimal categoryAmount; @ApiModelProperty("业务编码") private String businessCode; /** * 单位编码 */ @ApiModelProperty("单位编码") private String companyCode; /** * 开票人 */ @ApiModelProperty("开票人") private String drawer; /** * 复核人 */ @ApiModelProperty("复核人") private String reviewer; /** * 开票单位社会信用代码 */ @ApiModelProperty("开票单位社会信用代码") private String invoicingCompanyCode; } exam-system/src/main/java/com/gkhy/exam/pay/dto/rep/NonCoalPayOrder.java
对比新文件 @@ -0,0 +1,20 @@ package com.gkhy.exam.pay.dto.rep; import lombok.Data; import java.math.BigDecimal; import java.util.List; @Data public class NonCoalPayOrder { private Long id; private String batchName; private BigDecimal amount; private Long payPersonType; private String payCompanyName; private String payCompanyCard; private List<NonCoalStuRep> nonCoalStuList; private List<NonCoalCateRep> nonCoalPayCategoryList; } exam-system/src/main/java/com/gkhy/exam/pay/dto/rep/NonCoalStuRep.java
对比新文件 @@ -0,0 +1,46 @@ package com.gkhy.exam.pay.dto.rep; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @Data public class NonCoalStuRep { private Long id; /** * 姓名 */ @ApiModelProperty("姓名") private String studentName; /** * 身份证号 */ @ApiModelProperty("身份证号") private String idCard; /** * 电话 */ @ApiModelProperty("电话") private String phone; /** * 0男 1女 2未知 */ @ApiModelProperty("性别 0男1女2未知") private Long sex; /** * 是否缴款0否1是 */ @ApiModelProperty("是否缴款0否1是") private Long payStatus; @ApiModelProperty("财政订单编号") private String orderId; } exam-system/src/main/java/com/gkhy/exam/pay/mapper/NonCoalPayMapper.java
@@ -3,6 +3,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.gkhy.exam.pay.dto.rep.NonCoalPayDetailH5RepDto; import com.gkhy.exam.pay.dto.rep.NonCoalPayDetailRepDto; import com.gkhy.exam.pay.dto.rep.NonCoalPayOrder; import com.gkhy.exam.pay.dto.rep.NonCoalPayPageRepDto; import com.gkhy.exam.pay.entity.NonCoalPay; import org.apache.ibatis.annotations.Param; @@ -59,6 +60,8 @@ */ public int insertNonCoalPay(NonCoalPay nonCoalPay); List<NonCoalPayOrder> selectNonCoalPayOrderByParam(@Param("dataId") Long dataId, @Param("payType") Long payType); /** * 修改【请填写功能名称】 * exam-system/src/main/java/com/gkhy/exam/pay/service/NonCoalPayStudentService.java
@@ -31,6 +31,8 @@ */ public List<NonCoalPayStudent> selectNonCoalPayStudentList(NonCoalPayStudent nonCoalPayStudent); public String sendOrder(Long dataId, String payType); /** * 新增【请填写功能名称】 * exam-system/src/main/java/com/gkhy/exam/pay/service/impl/CoalPayServiceImpl.java
@@ -23,7 +23,6 @@ import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import com.ruoyi.system.mapper.SysDeptMapper; import org.aspectj.lang.reflect.UnlockSignature; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.beans.BeanUtils; @@ -37,7 +36,6 @@ import java.util.Date; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Lock; import java.util.stream.Collectors; @Service @@ -58,11 +56,13 @@ @Autowired private RedissonClient redissonClient; @Autowired private PayUtils payUtils; /** * 缴费管理列表 * * @param coalPay * @return */ @@ -137,6 +137,7 @@ /** * 修改缴费信息 * * @param coalPayDto * @return */ @@ -224,7 +225,7 @@ CoalTicket coalTicket = coalCategoryMapper.selectCoalTicket(); PayReqData payReqData = new PayReqData(); payReqData.setOrderNo(RandomUtil.generateOrderNumber()); payReqData.setOrderNo(RandomUtil.generateOrderNumber(coalPayId, "CO")); payReqData.setMoney(coalPay.getAmount()); payReqData.setAmount(1); payReqData.setPayerName(coalPayStudent.getName()); @@ -248,7 +249,7 @@ CoalPayStudent payStudent = new CoalPayStudent(); RLock lock = redissonClient.getLock("SWSPKMAS_PAY_PERSON"); RLock lock = redissonClient.getLock("SWSPKMAS_PAY_PERSON_" + coalPayId); try { lock.lock(10, TimeUnit.SECONDS); if (coalPayStudent.getGovPayStatus()!=0){ @@ -259,7 +260,7 @@ } ResultVo resultVo = PayUtils.sendApiPost(payReqData); ResultVo resultVo = payUtils.sendApiPost(payReqData); if (resultVo.getRespcode().equals("BUS0000")){ payStudent.setId(studentId); payStudent.setOrderId(resultVo.getRespdata().getOrderNo()); exam-system/src/main/java/com/gkhy/exam/pay/service/impl/NonCoalPayStudentServiceImpl.java
@@ -4,23 +4,34 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.gkhy.exam.institutionalaccess.enums.StudentSex; import com.gkhy.exam.pay.dto.rep.NonCoalCateRep; import com.gkhy.exam.pay.dto.rep.NonCoalPayOrder; import com.gkhy.exam.pay.dto.rep.NonCoalStuRep; import com.gkhy.exam.pay.dto.req.NonCoalPayStuImport; import com.gkhy.exam.pay.dto.req.NonCoalPayStudentReqDto; import com.gkhy.exam.pay.entity.NonCoalPay; import com.gkhy.exam.pay.entity.NonCoalPayStudent; import com.gkhy.exam.pay.entity.PayReqData; import com.gkhy.exam.pay.mapper.NonCoalPayMapper; import com.gkhy.exam.pay.mapper.NonCoalPayStudentMapper; import com.gkhy.exam.pay.service.NonCoalPayStudentService; import com.gkhy.exam.pay.utils.PayUtils; import com.gkhy.exam.pay.utils.ResultVo; import com.ruoyi.common.constant.ResultConstants; import com.ruoyi.common.exception.BusinessException; import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.utils.RandomUtil; import com.ruoyi.common.utils.RedisLock; import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.StringUtils; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import java.math.BigDecimal; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; @@ -31,11 +42,138 @@ * @date 2025-01-16 */ @Service @Slf4j public class NonCoalPayStudentServiceImpl extends ServiceImpl<NonCoalPayStudentMapper, NonCoalPayStudent> implements NonCoalPayStudentService { @Resource private NonCoalPayStudentMapper nonCoalPayStudentMapper; @Resource private NonCoalPayMapper nonCoalPayMapper; @Resource private PayUtils payUtils; @Autowired private RedisLock redisLock; private static final String NON_COAL_PAY_STUDENT_LOCK = "NON_COAL_PAY_STUDENT_LOCK_"; @Override public String sendOrder(Long dataId, String payType) { String lockKey = NON_COAL_PAY_STUDENT_LOCK + dataId + "_PAY_TYPE_" + payType; Boolean b = redisLock.tryLock(lockKey, 10, 20, TimeUnit.SECONDS); if (b) { String orderNo = RandomUtil.generateOrderNumber(dataId, "NC"); List<NonCoalPayOrder> nonCoalPayOrders = nonCoalPayMapper.selectNonCoalPayOrderByParam(dataId, Long.valueOf(payType)); if (StringUtils.isEmpty(nonCoalPayOrders)) { throw new BusinessException(this.getClass(), ResultConstants.BUSINESS_ERROR, "未找到相关缴费信息"); } NonCoalPayOrder nonCoalPayOrder = nonCoalPayOrders.get(0); List<NonCoalStuRep> nonCoalStuList = nonCoalPayOrder.getNonCoalStuList(); if (StringUtils.isEmpty(nonCoalStuList)) { throw new BusinessException(this.getClass(), ResultConstants.BUSINESS_ERROR, "未找到需要缴费的学员"); } NonCoalStuRep nonCoalStuRep = nonCoalStuList.get(0); if (nonCoalStuRep.getPayStatus() == 1) { throw new BusinessException(this.getClass(), ResultConstants.BUSINESS_ERROR, "已缴费请勿重复缴费"); } List<NonCoalCateRep> nonCoalPayCategoryList = nonCoalPayOrder.getNonCoalPayCategoryList(); if (StringUtils.isEmpty(nonCoalPayCategoryList)) { throw new BusinessException(this.getClass(), ResultConstants.BUSINESS_ERROR, "缴费信息缺失"); } // 业务处理 //查询主信息 查询是否是团队 PayReqData payReqData = dealData(nonCoalPayOrder, orderNo, payType); try { ResultVo resultVo = payUtils.sendApiPost(payReqData); log.info("调用接口返回结果:" + resultVo); if (resultVo.getRespcode().equals("BUS0000")) { String orderId = resultVo.getRespdata().getOrderId(); String billNo = resultVo.getRespdata().getBillNo(); if (StringUtils.isNotEmpty(orderId)) { // 更新订单 if ("1".equals(payType)) { baseMapper.update(null, Wrappers.<NonCoalPayStudent>lambdaUpdate() .set(NonCoalPayStudent::getOrderId, orderId) .set(NonCoalPayStudent::getOrderNo, orderNo) .set(NonCoalPayStudent::getPayCode, billNo) .eq(NonCoalPayStudent::getId, dataId).eq(NonCoalPayStudent::getDelFlag, 0) .eq(NonCoalPayStudent::getPayType, payType).eq(NonCoalPayStudent::getPayStatus, 0)); } else { //团体缴费 baseMapper.update(null, Wrappers.<NonCoalPayStudent>lambdaUpdate() .set(NonCoalPayStudent::getOrderId, orderId) .set(NonCoalPayStudent::getOrderNo, orderNo) .set(NonCoalPayStudent::getPayCode, billNo) .eq(NonCoalPayStudent::getNonCoalPayId, dataId).eq(NonCoalPayStudent::getDelFlag, 0) .eq(NonCoalPayStudent::getPayType, payType).eq(NonCoalPayStudent::getPayStatus, 0)); } } return orderId; } else { log.error("生成订单失败:" + resultVo.getRespmsg() + ",请稍后重试,错误编码:" + resultVo.getRespcode() + "参数如下:" + payReqData); throw new BusinessException(this.getClass(), ResultConstants.BUSINESS_ERROR, "发起支付失败,请稍后重试"); } } catch (Exception e) { log.error("发起支付调用接口失败:" + e); throw new BusinessException(this.getClass(), ResultConstants.BUSINESS_ERROR, e.getMessage()); } finally { redisLock.unlock(lockKey); } } return null; } private PayReqData dealData(NonCoalPayOrder nonCoalPayOrder, String orderNo, String payType) { List<NonCoalStuRep> nonCoalStuList = nonCoalPayOrder.getNonCoalStuList(); List<NonCoalCateRep> nonCoalPayCategoryList = nonCoalPayOrder.getNonCoalPayCategoryList(); PayReqData payReqData = new PayReqData(); payReqData.setOrderNo(orderNo); payReqData.setPayerType(Integer.valueOf(payType)); payReqData.setMoney(nonCoalPayOrder.getAmount().multiply(BigDecimal.valueOf(nonCoalStuList.size()))); payReqData.setAmount(nonCoalStuList.size()); payReqData.setDesc(nonCoalPayOrder.getBatchName()); NonCoalCateRep nonCoalCateRep1 = nonCoalPayCategoryList.get(0); payReqData.setHandlingPerson(nonCoalCateRep1.getDrawer()); payReqData.setChecker(nonCoalCateRep1.getReviewer()); payReqData.setEnterCode(nonCoalCateRep1.getCompanyCode()); payReqData.setInvoiceSocialCode(nonCoalCateRep1.getInvoicingCompanyCode()); List<PayReqData.Feedata> feedatas1 = new ArrayList<>(); for (NonCoalCateRep nonCoalCateRep : nonCoalPayCategoryList) { PayReqData.Feedata feedatas = new PayReqData.Feedata(); feedatas.setAmount(nonCoalStuList.size()); feedatas.setBusCode(nonCoalCateRep.getBusinessCode()); feedatas.setPrice(nonCoalCateRep.getCategoryAmount()); feedatas1.add(feedatas); } payReqData.setFeeDatas(feedatas1); if ("1".equals(payType)) { //个人缴费 NonCoalStuRep nonCoalStuRep = nonCoalStuList.get(0); payReqData.setPayerName(nonCoalStuRep.getStudentName()); payReqData.setCertNo(nonCoalStuRep.getIdCard()); } else { //团体缴费 payReqData.setPayerName(nonCoalPayOrder.getPayCompanyName()); payReqData.setCertNo(nonCoalPayOrder.getPayCompanyCard()); //todo 待确认 payReqData.setInvoiceSocialCode(nonCoalPayOrder.getPayCompanyCard()); payReqData.setEnterCode(nonCoalPayOrder.getPayCompanyCard()); } return payReqData; } /** * 查询【请填写功能名称】 exam-system/src/main/java/com/gkhy/exam/pay/utils/PayUtils.java
@@ -2,8 +2,12 @@ import com.alibaba.fastjson2.JSONObject; import com.gkhy.exam.pay.entity.PayReqData; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.digest.DigestUtils; import org.apache.http.*; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.StatusLine; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.HttpClient; import org.apache.http.client.HttpResponseException; @@ -25,8 +29,9 @@ import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; import org.apache.http.message.BasicNameValuePair; import org.apache.http.util.EntityUtils; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.annotation.Resource; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; @@ -40,12 +45,25 @@ /** * 缴费相关接口 */ @Component @Slf4j public class PayUtils { private final static String appid="ED76A5F1703540BE977D34780B371FEB"; // private final static String appid = "ED76A5F1703540BE977D34780B371FEB"; @Value("${finance.orderUrl}") private String orderUrl; public static ResultVo sendApiPost(PayReqData payReqData) throws IOException { @Value("${finance.payNotifyUrl}") private String payNotifyUrl; @Value("${finance.payQueryUrl}") private String payQueryUrl; @Value("${finance.apiId}") private String appId; public ResultVo sendApiPost(PayReqData payReqData) throws IOException { //正式 String proUrl="http://finpt.xjcz.gov.cn/fs-service/fs-pay/invoice.do"; @@ -54,18 +72,18 @@ Map<String, String> param = new HashMap<>(); HttpPost httpPost = new HttpPost(testUrl); HttpPost httpPost = new HttpPost(orderUrl); //请求参数转为json格式base64编码 String reqData = Base64.getEncoder().encodeToString(JSONObject.toJSONString(payReqData).getBytes()); String mac = appid+"||"+reqData; String mac = appId + "||" + reqData; mac = DigestUtils.md5Hex(mac.getBytes()); param.put("appid",appid); param.put("appid", appId); param.put("reqdata",reqData); param.put("mac",mac); httpPost.setEntity(assemblyFormEntity(param,"utf-8")); HttpClient httpClient = getHttpClient(testUrl); HttpClient httpClient = getHttpClient(orderUrl); HttpResultVo execute = httpClient.execute(httpPost, getResponseHandler()); String stringContent = execute.getStringContent(); ResultVo resultVo = JSONObject.parseObject(stringContent, ResultVo.class); @@ -117,10 +135,12 @@ } @Override public void checkClientTrusted(X509Certificate[] xcs, String str) {} public void checkClientTrusted(X509Certificate[] xcs, String str) { } @Override public void checkServerTrusted(X509Certificate[] xcs, String str) {} public void checkServerTrusted(X509Certificate[] xcs, String str) { } }; SSLContext ctx = SSLContext.getInstance(SSLConnectionSocketFactory.TLS); ctx.init(null, new TrustManager[] {trustManager}, null); @@ -210,7 +230,7 @@ //缴费结果通知 public static Map<String,String> receive(JSONObject jsonObject) throws IOException { public Map<String, String> receive(JSONObject jsonObject) throws IOException { Map<String, String> params = new HashMap<>(); JSONObject reqdata = new JSONObject(); @@ -224,9 +244,9 @@ reqdata.put("status",notarize); String req = Base64.getEncoder().encodeToString(reqdata.toJSONString().getBytes()); String mac = appid+"||"+req; String mac = appId + "||" + req; mac = DigestUtils.md5Hex(mac.getBytes()); params.put("appid",appid); params.put("appid", appId); params.put("reqdata",req); params.put("mac",mac); @@ -234,28 +254,26 @@ } //缴费结果确认查询 public static String affirmPost(String orderNo) throws IOException { String porUrl="http://finpt.xjcz.gov.cn/fs-service/fs-pay/notifyConfirm.do"; String testUrl="http://finpt.xjcz.gov.cn/fs-service-test/fs-pay/notifyConfirm.do"; public String affirmPost(String orderNo) throws IOException { HashMap<String, String> param = new HashMap<>(); JSONObject jsonObject = new JSONObject(); jsonObject.put("orderNo",orderNo); String reqdata = Base64.getEncoder().encodeToString(jsonObject.toJSONString().getBytes()); String mac = appid+"||"+reqdata; String mac = appId + "||" + reqdata; mac=DigestUtils.md5Hex(mac.getBytes()); param.put("appid",appid); param.put("appid", appId); param.put("reqdata",reqdata); param.put("mac",mac); HttpPost httppost = new HttpPost(testUrl); HttpPost httppost = new HttpPost(payNotifyUrl); httppost.setEntity(assemblyFormEntity(param,"utf-8")); HttpClient httpClient = getHttpClient(testUrl); HttpClient httpClient = getHttpClient(payNotifyUrl); HttpResultVo execute = httpClient.execute(httppost, getResponseHandler()); String stringContent = execute.getStringContent(); ResultVo resultVo = JSONObject.parseObject(stringContent, ResultVo.class); System.out.printf("请求结果为:"+resultVo); log.info("请求结果为:" + resultVo); if (resultVo.getRespcode().equals("BUS0000")){ return "success"; } @@ -263,7 +281,7 @@ } //缴费结果查询 public static JSONObject query(String orderNo) throws IOException { public JSONObject query(String orderNo) throws IOException { String proUrl="http://finpt.xjcz.gov.cn/fs-service/fs-pay/query.do"; String testUrl="http://finpt.xjcz.gov.cn/fs-service-test/fs-pay/query.do"; @@ -272,19 +290,19 @@ JSONObject jsonObject = new JSONObject(); jsonObject.put("orderNo",orderNo); String reqdata = Base64.getEncoder().encodeToString(jsonObject.toJSONString().getBytes()); String mac = appid+"||"+reqdata; String mac = appId + "||" + reqdata; mac = DigestUtils.md5Hex(mac.getBytes()); param.put("appid",appid); param.put("appid", appId); param.put("reqdata",reqdata); param.put("mac",mac); HttpPost httppost = new HttpPost(testUrl); HttpPost httppost = new HttpPost(payQueryUrl); httppost.setEntity(assemblyFormEntity(param,"utf-8")); HttpClient httpClient = getHttpClient(testUrl); HttpClient httpClient = getHttpClient(payQueryUrl); HttpResultVo execute = httpClient.execute(httppost, getResponseHandler()); String stringContent = execute.getStringContent(); JSONObject result = JSONObject.parseObject(stringContent); System.out.printf("请求结果json为:"+result); log.info("请求结果json为:" + result); return result; } } exam-system/src/main/resources/mapper/pay/NonCoalPayMapper.xml
@@ -202,6 +202,75 @@ </select> <resultMap type="com.gkhy.exam.pay.dto.rep.NonCoalPayOrder" id="getNonCoalPayResultOrder"> <result property="id" column="id"/> <result property="batchName" column="batch_name"/> <result property="amount" column="amount"/> <result property="payPersonType" column="pay_person_type"/> <result property="payCompanyName" column="pay_company_name"/> <result property="payCompanyCard" column="pay_company_card"/> <collection property="nonCoalPayCategoryList" javaType="java.util.List" resultMap="nonCoalPayCategoryListOrder"/> <collection property="nonCoalStuList" javaType="java.util.List" resultMap="nonCoalPayStuListOrder"/> </resultMap> <resultMap id="nonCoalPayCategoryListOrder" type="com.gkhy.exam.pay.dto.rep.NonCoalCateRep"> <result property="id" column="non_category_id"/> <result property="businessCode" column="business_code"/> <result property="companyCode" column="company_code"/> <result property="invoicingCompanyCode" column="invoicing_company_code"/> <result property="drawer" column="drawer"/> <result property="reviewer" column="reviewer"/> <result property="categoryId" column="category_id"/> <result property="subjectName" column="subject_name"/> <result property="categoryType" column="category_type"/> <result property="categoryAmount" column="category_amount"/> </resultMap> <resultMap id="nonCoalPayStuListOrder" type="com.gkhy.exam.pay.dto.rep.NonCoalStuRep"> <result property="id" column="non_coal_student_id"/> <result property="phone" column="phone"/> <result property="idCard" column="id_card"/> <result property="studentName" column="student_name"/> <result property="payStatus" column="pay_status"/> <result property="orderId" column="order_id"/> </resultMap> <select id="selectNonCoalPayOrderByParam" resultMap="getNonCoalPayResultOrder"> select a.id, a.batch_name, a.pay_type, a.amount, a.pay_person_type, a.pay_company_name, a.pay_company_card, b.id as non_category_id, b.category_id, c.subject_name, c.category_type, c.business_code, c.company_code, c.drawer, c.reviewer, c.invoicing_company_code, b.category_amount, t.id as non_coal_student_id, t.phone, t.id_card, t.name as student_name, t.pay_status, t.order_id from non_coal_pay a inner join non_coal_pay_student t on t.non_coal_pay_id = a.id and t.del_flag = 0 and t.pay_status = 0 inner join non_coal_pay_category b on a.id = b.non_coal_pay_id and b.del_flag = 0 left join non_coal_category c on b.category_id = c.id and c.del_flag = 0 where a.del_flag = 0 <if test="payType != null and payType == 2 ">and a.id = #{dataId} and t.pay_type = #{payType}</if> <if test="payType != null and payType == 1 ">and t.id = #{dataId} and t.pay_type = #{payType}</if> </select> <insert id="insertNonCoalPay" parameterType="NonCoalPay" useGeneratedKeys="true" keyProperty="id"> insert into non_coal_pay exam-system/src/test/java/TextPay.java
@@ -1,21 +1,16 @@ import com.alibaba.fastjson2.JSONObject; import com.gkhy.exam.pay.entity.PayReqData; import com.gkhy.exam.pay.utils.PayUtils; import com.gkhy.exam.pay.utils.ResultVo; import com.google.gson.JsonObject; import com.ruoyi.common.utils.RandomUtil; import com.ruoyi.common.utils.uuid.UUID; import lombok.extern.log4j.Log4j2; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.junit4.SpringRunner; import java.io.IOException; import java.math.BigDecimal; import java.util.ArrayList; import java.util.List; import java.util.Map; @SpringBootTest(classes = TextPay.class) @ActiveProfiles("dev") @@ -31,7 +26,7 @@ PayReqData.Feedata feedatas = new PayReqData.Feedata(); payReqData.setDesc("安全技术考试考务费_煤矿安全作业-001504"); payReqData.setOrderNo(RandomUtil.generateOrderNumber()); payReqData.setOrderNo(RandomUtil.generateOrderNumber(1L, "CO")); payReqData.setMoney(BigDecimal.valueOf(103)); payReqData.setAmount(1); payReqData.setPayerName("测试"); @@ -57,19 +52,15 @@ } @Test public void text001(){ try { // String s = PayUtils.affirmPost("10000001"); JSONObject query = PayUtils.query("1000001"); } catch (IOException e) { throw new RuntimeException(e); // try { //// String s = PayUtils.affirmPost("10000001"); // //JSONObject query = PayUtils.query("1000001"); // } catch (IOException e) { // throw new RuntimeException(e); // } } } } ruoyi-admin/src/main/resources/application-dev.yml
@@ -130,3 +130,10 @@ accesskey: 5YprpjY0BJiyjII2VqlHed7UhBEvvkPZicbwd8Kl secretkey: m3gGQNQ9cLmVBBZwPXZ5-Wzr0duzyAPPmJUx4_ay templateid: 1844221365930962944 #财政接口地址及api finance: apiId: ED76A5F1703540BE977D34780B371FEB orderUrl: http://finpt.xjcz.gov.cn/fs-service-test/fs-pay/invoice.do payNotifyUrl: http://finpt.xjcz.gov.cn/fs-service-test/fs-pay/notifyConfirm.do payQueryUrl: http://finpt.xjcz.gov.cn/fs-service/fs-pay/query.do ruoyi-admin/src/main/resources/application-pro.yml
@@ -129,3 +129,10 @@ accesskey: 5YprpjY0BJiyjII2VqlHed7UhBEvvkPZicbwd8Kl secretkey: m3gGQNQ9cLmVBBZwPXZ5-Wzr0duzyAPPmJUx4_ay templateid: 1844221365930962944 finance: apiId: ED76A5F1703540BE977D34780B371FEB orderUrl: http://finpt.xjcz.gov.cn/fs-service/fs-pay/invoice.do payNotifyUrl: http://finpt.xjcz.gov.cn/fs-service/fs-pay/notifyConfirm.do payQueryUrl: http://finpt.xjcz.gov.cn/fs-service-test/fs-pay/query.do ruoyi-common/src/main/java/com/ruoyi/common/config/RedissonConfig.java
对比新文件 @@ -0,0 +1,29 @@ package com.ruoyi.common.config; import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.Config; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class RedissonConfig { @Value("${spring.redis.host}") private String host; @Value("${spring.redis.port}") private String port; // @Value("${spring.redis.password}") // private String password; @Bean(destroyMethod = "shutdown") @ConditionalOnMissingBean(RedissonClient.class) public RedissonClient redissonClient() { Config config = new Config(); config.useSingleServer().setAddress("redis://" + host + ":" + port); // 更多.set return Redisson.create(config); } } ruoyi-common/src/main/java/com/ruoyi/common/utils/RandomUtil.java
@@ -35,20 +35,20 @@ public static void main(String[] args) { String s = generateRandomString(26); System.out.println(s); System.out.println(generateOrderNumber()); System.out.println(generateOrderNumber(10L, "NC")); } private static final Random RANDOM = new Random(); private static final AtomicInteger SEQUENCE = new AtomicInteger(0); private static final int MAX_SEQUENCE = 99999;// 5位数的序列号 private static final String ORDER_PER = "SN"; public static synchronized String generateOrderNumber() { public static String generateOrderNumber(Long dataId, String orderType) { String datePart = new SimpleDateFormat("yyyyMMddhhmm").format(new Date()); int sequencePart = SEQUENCE.getAndIncrement() % MAX_SEQUENCE; String sequenceStr = String.format("%05d", sequencePart); // 保证序列号是5位数,不足的前面补0 int randomPart = RANDOM.nextInt(90000) + 10000; // 生成5位随机数 return ORDER_PER + datePart + sequenceStr; return ORDER_PER + datePart + String.format("%05d", randomPart) + dataId; } } ruoyi-common/src/main/java/com/ruoyi/common/utils/RedisLock.java
对比新文件 @@ -0,0 +1,98 @@ package com.ruoyi.common.utils; import org.redisson.api.RLock; import org.redisson.api.RedissonClient; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.concurrent.TimeUnit; @Component public class RedisLock { @Autowired private RedissonClient redissonClient; /** * 获取锁 * * @param lockKey 锁实例key * @return 锁信息 */ public RLock getRLock(String lockKey) { return redissonClient.getLock(lockKey); } /** * 加锁 * * @param lockKey 锁实例key * @return 锁信息 */ public RLock lock(String lockKey) { RLock lock = getRLock(lockKey); lock.lock(); return lock; } /** * 加锁 * * @param lockKey 锁实例key * @param leaseTime 上锁后自动释放锁时间 * @return true=成功;false=失败 */ public Boolean tryLock(String lockKey, long leaseTime) { return tryLock(lockKey, 0, leaseTime, TimeUnit.SECONDS); } /** * 加锁 * * @param lockKey 锁实例key * @param leaseTime 上锁后自动释放锁时间 * @param unit 时间颗粒度 * @return true=加锁成功;false=加锁失败 */ public Boolean tryLock(String lockKey, long leaseTime, TimeUnit unit) { return tryLock(lockKey, 0, leaseTime, unit); } /** * 加锁 * * @param lockKey 锁实例key * @param waitTime 最多等待时间 * @param leaseTime 上锁后自动释放锁时间 * @param unit 时间颗粒度 * @return true=加锁成功;false=加锁失败 */ public Boolean tryLock(String lockKey, long waitTime, long leaseTime, TimeUnit unit) { RLock rLock = getRLock(lockKey); boolean tryLock = false; try { tryLock = rLock.tryLock(waitTime, leaseTime, unit); } catch (InterruptedException e) { return false; } return tryLock; } /** * 释放锁 * * @param lockKey 锁实例key */ public void unlock(String lockKey) { RLock lock = getRLock(lockKey); lock.unlock(); } /** * 释放锁 * * @param lock 锁信息 */ public void unlock(RLock lock) { lock.unlock(); } }