diff --git a/docker-compose.yml b/docker-compose.yml index a37c5319..e69de29b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,10 +0,0 @@ -version: "3" -services: - aida_back: - container_name: stable-version-aida-back - build: . -# volumes: -# # 数据挂载 -# - /workspace/home/aida/file/:/workspace/home/aida/file/ - ports: - - "10086:5567" \ No newline at end of file diff --git a/pom.xml b/pom.xml index af34168f..87a9fc66 100644 --- a/pom.xml +++ b/pom.xml @@ -177,6 +177,13 @@ commons-pool2 + + + com.alipay.sdk + alipay-sdk-java + 4.22.57.ALL + + diff --git a/src/main/java/com/ai/da/common/RabbitMQ/MQConfig.java b/src/main/java/com/ai/da/common/RabbitMQ/MQConfig.java index d4e24508..bb4aa412 100644 --- a/src/main/java/com/ai/da/common/RabbitMQ/MQConfig.java +++ b/src/main/java/com/ai/da/common/RabbitMQ/MQConfig.java @@ -16,7 +16,9 @@ import org.springframework.beans.factory.annotation.Value; public class MQConfig { public static final String GENERATE_EXCHANGE_FANOUT = "generate-exchange"; - public static final String GENERATE_QUEUE = "generate-queue-prod"; +// public static final String GENERATE_QUEUE = "generate-queue-prod"; +// public static final String GENERATE_QUEUE = "generate-queue-test"; + public static final String GENERATE_QUEUE = "generate-queue-dev"; public MQConfig() { } diff --git a/src/main/java/com/ai/da/common/config/AlipayClientConfig.java b/src/main/java/com/ai/da/common/config/AlipayClientConfig.java new file mode 100644 index 00000000..5b1ec344 --- /dev/null +++ b/src/main/java/com/ai/da/common/config/AlipayClientConfig.java @@ -0,0 +1,43 @@ +package com.ai.da.common.config; + +import com.alipay.api.*; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; +import org.springframework.core.env.Environment; + +import javax.annotation.Resource; + +@Configuration +//加载配置文件 +@PropertySource("classpath:alipay-sandbox.properties") +public class AlipayClientConfig { + + @Resource + private Environment config; + + @Bean + public AlipayClient alipayClient() throws AlipayApiException { + + AlipayConfig alipayConfig = new AlipayConfig(); + + //设置网关地址 + alipayConfig.setServerUrl(config.getProperty("alipay.gateway-url")); + //设置应用Id + alipayConfig.setAppId(config.getProperty("alipay.app-id")); + //设置应用私钥 + alipayConfig.setPrivateKey(config.getProperty("alipay.merchant-private-key")); + //设置请求格式,固定值json + alipayConfig.setFormat(AlipayConstants.FORMAT_JSON); + //设置字符集 + alipayConfig.setCharset(AlipayConstants.CHARSET_UTF8); + //设置支付宝公钥 + alipayConfig.setAlipayPublicKey(config.getProperty("alipay.alipay-public-key")); + //设置签名类型 + alipayConfig.setSignType(AlipayConstants.SIGN_TYPE_RSA2); + //构造client + AlipayClient alipayClient = new DefaultAlipayClient(alipayConfig); + + return alipayClient; + } +} diff --git a/src/main/java/com/ai/da/common/enums/AliPayTradeStateEnum.java b/src/main/java/com/ai/da/common/enums/AliPayTradeStateEnum.java new file mode 100644 index 00000000..573ec7dd --- /dev/null +++ b/src/main/java/com/ai/da/common/enums/AliPayTradeStateEnum.java @@ -0,0 +1,39 @@ +package com.ai.da.common.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public enum AliPayTradeStateEnum { + + /** + * 支付成功 + */ + SUCCESS("TRADE_SUCCESS"), + + /** + * 未支付 + */ + NOTPAY("WAIT_BUYER_PAY"), + + /** + * 已关闭 + */ + CLOSED("TRADE_CLOSED"), + + /** + * 退款成功 + */ + REFUND_SUCCESS("REFUND_SUCCESS"), + + /** + * 退款失败 + */ + REFUND_ERROR("REFUND_ERROR"); + + /** + * 类型 + */ + private final String type; +} diff --git a/src/main/java/com/ai/da/common/enums/OrderStatusEnum.java b/src/main/java/com/ai/da/common/enums/OrderStatusEnum.java new file mode 100644 index 00000000..ede1e162 --- /dev/null +++ b/src/main/java/com/ai/da/common/enums/OrderStatusEnum.java @@ -0,0 +1,49 @@ +package com.ai.da.common.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public enum OrderStatusEnum { + /** + * 未支付 + */ + NOT_PAY("未支付"), + + + /** + * 支付成功 + */ + SUCCESS("支付成功"), + + /** + * 已关闭 + */ + CLOSED("超时已关闭"), + + /** + * 已取消 + */ + CANCEL("用户已取消"), + + /** + * 退款中 + */ + REFUND_PROCESSING("退款中"), + + /** + * 已退款 + */ + REFUND_SUCCESS("已退款"), + + /** + * 退款异常 + */ + REFUND_ABNORMAL("退款异常"); + + /** + * 类型 + */ + private final String type; +} diff --git a/src/main/java/com/ai/da/common/enums/PayTypeEnum.java b/src/main/java/com/ai/da/common/enums/PayTypeEnum.java new file mode 100644 index 00000000..cb2e89f8 --- /dev/null +++ b/src/main/java/com/ai/da/common/enums/PayTypeEnum.java @@ -0,0 +1,24 @@ +package com.ai.da.common.enums; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@AllArgsConstructor +@Getter +public enum PayTypeEnum { + /** + * 微信 + */ + WXPAY("微信"), + + + /** + * 支付宝 + */ + ALIPAY("支付宝"); + + /** + * 类型 + */ + private final String type; +} diff --git a/src/main/java/com/ai/da/common/security/filter/AuthenticationFilter.java b/src/main/java/com/ai/da/common/security/filter/AuthenticationFilter.java index c2625612..6efefd84 100644 --- a/src/main/java/com/ai/da/common/security/filter/AuthenticationFilter.java +++ b/src/main/java/com/ai/da/common/security/filter/AuthenticationFilter.java @@ -47,7 +47,7 @@ public class AuthenticationFilter extends OncePerRequestFilter { "/api/third/party/addUser","/api/third/party/addTrialUser", "/api/third/party/editUser", "/api/element/initDefaultSysFile", "/api/third/party/addNoLoginRequiredNew","/api/third/party/deleteNoLoginRequiredNew", "/api/third/party/existNoLoginRequired","/api/third/party/getRedirectUrl", - "/api/python/chatStream", +// "/api/python/chatStream", "/api/python/flush", "/api/account/healthy" ); diff --git a/src/main/java/com/ai/da/common/task/AliPayTask.java b/src/main/java/com/ai/da/common/task/AliPayTask.java new file mode 100644 index 00000000..0d9c8390 --- /dev/null +++ b/src/main/java/com/ai/da/common/task/AliPayTask.java @@ -0,0 +1,42 @@ +package com.ai.da.common.task; + +import com.ai.da.mapper.entity.OrderInfo; +import com.ai.da.common.enums.PayTypeEnum; +import com.ai.da.service.AliPayService; +import com.ai.da.service.OrderInfoService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Component; + +import javax.annotation.Resource; +import java.util.List; + +@Slf4j +@Component +public class AliPayTask { + + @Resource + private OrderInfoService orderInfoService; + + @Resource + private AliPayService aliPayService; + + /** + * 从第0秒开始每隔30秒执行1次,查询创建超过5分钟,并且未支付的订单 + */ + @Scheduled(cron = "0/30 * * * * ?") + public void orderConfirm(){ + + log.info("orderConfirm 被执行......"); + + List orderInfoList = orderInfoService.getNoPayOrderByDuration(1, PayTypeEnum.ALIPAY.getType()); + + for (OrderInfo orderInfo : orderInfoList) { + String orderNo = orderInfo.getOrderNo(); + log.warn("超时订单 ===> {}", orderNo); + + //核实订单状态:调用支付宝查单接口 + aliPayService.checkOrderStatus(orderNo); + } + } +} diff --git a/src/main/java/com/ai/da/common/utils/OrderNoUtils.java b/src/main/java/com/ai/da/common/utils/OrderNoUtils.java new file mode 100644 index 00000000..2b0108de --- /dev/null +++ b/src/main/java/com/ai/da/common/utils/OrderNoUtils.java @@ -0,0 +1,46 @@ +package com.ai.da.common.utils; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.Random; + +/** + * 订单号工具类 + * + * @author qy + * @since 1.0 + */ +public class OrderNoUtils { + + /** + * 获取订单编号 + * @return + */ + public static String getOrderNo() { + return "ORDER_" + getNo(); + } + + /** + * 获取退款单编号 + * @return + */ + public static String getRefundNo() { + return "REFUND_" + getNo(); + } + + /** + * 获取编号 + * @return + */ + public static String getNo() { + SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss"); + String newDate = sdf.format(new Date()); + String result = ""; + Random random = new Random(); + for (int i = 0; i < 3; i++) { + result += random.nextInt(10); + } + return newDate + result; + } + +} diff --git a/src/main/java/com/ai/da/controller/AliPayController.java b/src/main/java/com/ai/da/controller/AliPayController.java new file mode 100644 index 00000000..a6f3c20f --- /dev/null +++ b/src/main/java/com/ai/da/controller/AliPayController.java @@ -0,0 +1,208 @@ +package com.ai.da.controller; + +import com.ai.da.common.response.Response; +import com.ai.da.mapper.entity.OrderInfo; +import com.ai.da.service.AliPayService; +import com.ai.da.service.OrderInfoService; +import com.alipay.api.AlipayApiException; +import com.alipay.api.AlipayConstants; +import com.alipay.api.internal.util.AlipaySignature; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.env.Environment; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.Map; + +@CrossOrigin +@RestController +@RequestMapping("/api/ali-pay") +@Api(tags = "网站支付宝支付") +@Slf4j +public class AliPayController { + + @Resource + private AliPayService aliPayService; + + @Resource + private Environment config; + + @Resource + private OrderInfoService orderInfoService; + + @ApiOperation("统一收单下单并支付页面接口的调用") + @PostMapping("/trade/page/pay/{productId}") + public Response tradePagePay(@PathVariable Long productId,@RequestParam String returnUrl){ + + System.out.println(productId + " " + returnUrl); + + log.info("统一收单下单并支付页面接口的调用"); + //支付宝开放平台接受 request 请求对象后 + // 会为开发者生成一个html 形式的 form表单,包含自动提交的脚本 + String formStr = aliPayService.tradeCreate(productId, returnUrl); + //我们将form表单字符串返回给前端程序,之后前端将会调用自动提交脚本,进行表单的提交 + //此时,表单会自动提交到action属性所指向的支付宝开放平台中,从而为用户展示一个支付页面 + return Response.success(formStr); + } + + @ApiOperation("支付通知") + @PostMapping("/trade/notify") + public String tradeNotify(@RequestParam Map params){ + + log.info("支付通知正在执行"); + log.info("通知参数 ===> {}", params); + + String result = "failure"; + + try { + //异步通知验签 + boolean signVerified = AlipaySignature.rsaCheckV1( + params, + config.getProperty("alipay.alipay-public-key"), + AlipayConstants.CHARSET_UTF8, + AlipayConstants.SIGN_TYPE_RSA2); //调用SDK验证签名 + + if(!signVerified){ + //验签失败则记录异常日志,并在response中返回failure. + log.error("支付成功异步通知验签失败!"); + return result; + } + + // 验签成功后 + log.info("支付成功异步通知验签成功!"); + + //按照支付结果异步通知中的描述,对支付结果中的业务内容进行二次校验, + //1 商户需要验证该通知数据中的 out_trade_no 是否为商户系统中创建的订单号 + String outTradeNo = params.get("out_trade_no"); + OrderInfo order = orderInfoService.getOrderByOrderNo(outTradeNo); + if(order == null){ + log.error("订单不存在"); + return result; + } + + //2 判断 total_amount 是否确实为该订单的实际金额(即商户订单创建时的金额) + String totalAmount = params.get("total_amount"); + int totalAmountInt = new BigDecimal(totalAmount).multiply(new BigDecimal("100")).intValue(); + int totalFeeInt = order.getTotalFee().intValue(); + if(totalAmountInt != totalFeeInt){ + log.error("金额校验失败"); + return result; + } + + //3 校验通知中的 seller_id(或者 seller_email) 是否为 out_trade_no 这笔单据的对应的操作方 + String sellerId = params.get("seller_id"); + String sellerIdProperty = config.getProperty("alipay.seller-id"); + if(!sellerId.equals(sellerIdProperty)){ + log.error("商家pid校验失败"); + return result; + } + + //4 验证 app_id 是否为该商户本身 + String appId = params.get("app_id"); + String appIdProperty = config.getProperty("alipay.app-id"); + if(!appId.equals(appIdProperty)){ + log.error("appid校验失败"); + return result; + } + + //在支付宝的业务通知中,只有交易通知状态为 TRADE_SUCCESS时, + // 支付宝才会认定为买家付款成功。 + String tradeStatus = params.get("trade_status"); + if(!"TRADE_SUCCESS".equals(tradeStatus)){ + log.error("支付未成功"); + return result; + } + + //处理业务 修改订单状态 记录支付日志 + aliPayService.processOrder(params); + + //校验成功后在response中返回success并继续商户自身业务处理,校验失败返回failure + result = "success"; + } catch (AlipayApiException e) { + e.printStackTrace(); + } + return result; + } + + /** + * 用户取消订单 + * @param orderNo + * @return + */ + @ApiOperation("用户取消订单") + @PostMapping("/trade/close/{orderNo}") + public Response cancel(@PathVariable String orderNo){ + + log.info("取消订单"); + aliPayService.cancelOrder(orderNo); + return Response.success("订单已取消"); + } + + /** + * 查询订单 + * @param orderNo + * @return + */ + @ApiOperation("查询订单:测试订单状态用") + @GetMapping("/trade/query/{orderNo}") + public Response queryOrder(@PathVariable String orderNo) { + + log.info("查询订单"); + + String result = aliPayService.queryOrder(orderNo); + return Response.success(result); + + } + + /** + * 申请退款 + * @param orderNo + * @param reason + * @return + */ + @ApiOperation("申请退款") + @PostMapping("/trade/refund/{orderNo}/{reason}") + public Response refunds(@PathVariable String orderNo, @PathVariable String reason){ + + log.info("申请退款"); + aliPayService.refund(orderNo, reason); + return Response.success(); + } + + /** + * 查询退款 + * @param orderNo + * @return + * @throws Exception + */ + @ApiOperation("查询退款:测试用") + @GetMapping("/trade/fastpay/refund/{orderNo}") + public Response queryRefund(@PathVariable String orderNo) throws Exception { + + log.info("查询退款"); + + String result = aliPayService.queryRefund(orderNo); + return Response.success(result); + } + + /** + * 根据账单类型和日期获取账单url地址 + * + * @param billDate + * @param type + * @return + */ + @ApiOperation("获取账单url") + @GetMapping("/bill/downloadurl/query/{billDate}/{type}") + public Response queryTradeBill( + @PathVariable String billDate, + @PathVariable String type) { + log.info("获取账单url"); + String downloadUrl = aliPayService.queryBill(billDate, type); + return Response.success(downloadUrl); + } + +} diff --git a/src/main/java/com/ai/da/controller/GenerateController.java b/src/main/java/com/ai/da/controller/GenerateController.java index b3f6fb5b..c752fbc0 100644 --- a/src/main/java/com/ai/da/controller/GenerateController.java +++ b/src/main/java/com/ai/da/controller/GenerateController.java @@ -6,6 +6,7 @@ import com.ai.da.model.dto.GenerateThroughImageTextDTO; import com.ai.da.model.vo.GenerateCaptionVO; import com.ai.da.model.vo.GenerateCollectionVO; import com.ai.da.model.vo.GenerateLikeVO; +import com.ai.da.model.vo.PrepareForGenerateVO; import com.ai.da.service.GenerateService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; @@ -55,7 +56,7 @@ public class GenerateController { @ApiOperation(value = "发起生成请求,异步获取结果") @PostMapping("/prepare") - public Response prepareForGenerate(@Valid @RequestBody GenerateThroughImageTextDTO generateThroughImageTextDTO) { + public Response prepareForGenerate(@Valid @RequestBody GenerateThroughImageTextDTO generateThroughImageTextDTO) { return Response.success(generateService.prepareForGenerate(generateThroughImageTextDTO)); } diff --git a/src/main/java/com/ai/da/controller/OrderInfoController.java b/src/main/java/com/ai/da/controller/OrderInfoController.java new file mode 100644 index 00000000..b71d0e04 --- /dev/null +++ b/src/main/java/com/ai/da/controller/OrderInfoController.java @@ -0,0 +1,50 @@ +package com.ai.da.controller; + +import com.ai.da.common.enums.OrderStatusEnum; +import com.ai.da.common.response.Response; +import com.ai.da.mapper.entity.OrderInfo; +import com.ai.da.service.OrderInfoService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.*; + +import javax.annotation.Resource; +import java.util.List; + +@CrossOrigin //开放前端的跨域访问 +@Api(tags = "商品订单管理") +@RestController +@RequestMapping("/api/order-info") +public class OrderInfoController { + + @Resource + private OrderInfoService orderInfoService; + + @ApiOperation("订单列表") + @GetMapping("/list") + public Response> list(){ + + List list = orderInfoService.listOrderByCreateTimeDesc(); + return Response.success(list); + } + + /** + * 查询本地订单状态 + * @param orderNo + * @return + */ + @ApiOperation("查询本地订单状态") + @GetMapping("/query-order-status/{orderNo}") + public Response queryOrderStatus(@PathVariable String orderNo){ + + String orderStatus = orderInfoService.getOrderStatus(orderNo); + if(OrderStatusEnum.SUCCESS.getType().equals(orderStatus)){ + return Response.success("支付成功"); //支付成功 + } + + return Response.success(101,"支付中......"); + } + + + +} diff --git a/src/main/java/com/ai/da/controller/ProductController.java b/src/main/java/com/ai/da/controller/ProductController.java new file mode 100644 index 00000000..b22b1537 --- /dev/null +++ b/src/main/java/com/ai/da/controller/ProductController.java @@ -0,0 +1,42 @@ +package com.ai.da.controller; + + +import com.ai.da.common.response.Response; +import com.ai.da.mapper.entity.Product; +import com.ai.da.service.ProductService; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import org.springframework.web.bind.annotation.CrossOrigin; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import javax.annotation.Resource; +import java.util.Date; +import java.util.List; + +@CrossOrigin //开放前端的跨域访问 +@Api(tags = "商品管理") +@RestController +@RequestMapping("/api/product") +public class ProductController { + + @Resource + private ProductService productService; + + @ApiOperation("测试接口") + @GetMapping("/test") + public Response test(){ + + return Response.success("now" + new Date()); + } + + @ApiOperation("商品列表") + @GetMapping("/list") + public Response> list(){ + + List list = productService.list(); + return Response.success(list); + } + +} diff --git a/src/main/java/com/ai/da/mapper/OrderInfoMapper.java b/src/main/java/com/ai/da/mapper/OrderInfoMapper.java new file mode 100644 index 00000000..4b8b6d68 --- /dev/null +++ b/src/main/java/com/ai/da/mapper/OrderInfoMapper.java @@ -0,0 +1,8 @@ +package com.ai.da.mapper; + +import com.ai.da.mapper.entity.OrderInfo; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +public interface OrderInfoMapper extends BaseMapper { + +} diff --git a/src/main/java/com/ai/da/mapper/PaymentInfoMapper.java b/src/main/java/com/ai/da/mapper/PaymentInfoMapper.java new file mode 100644 index 00000000..1406b6bc --- /dev/null +++ b/src/main/java/com/ai/da/mapper/PaymentInfoMapper.java @@ -0,0 +1,7 @@ +package com.ai.da.mapper; + +import com.ai.da.mapper.entity.PaymentInfo; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +public interface PaymentInfoMapper extends BaseMapper { +} diff --git a/src/main/java/com/ai/da/mapper/ProductMapper.java b/src/main/java/com/ai/da/mapper/ProductMapper.java new file mode 100644 index 00000000..1ffdf2eb --- /dev/null +++ b/src/main/java/com/ai/da/mapper/ProductMapper.java @@ -0,0 +1,8 @@ +package com.ai.da.mapper; + +import com.ai.da.mapper.entity.Product; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +public interface ProductMapper extends BaseMapper { + +} diff --git a/src/main/java/com/ai/da/mapper/RefundInfoMapper.java b/src/main/java/com/ai/da/mapper/RefundInfoMapper.java new file mode 100644 index 00000000..8f9c746e --- /dev/null +++ b/src/main/java/com/ai/da/mapper/RefundInfoMapper.java @@ -0,0 +1,9 @@ +package com.ai.da.mapper; + + +import com.ai.da.mapper.entity.RefundInfo; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +public interface RefundInfoMapper extends BaseMapper { + +} diff --git a/src/main/java/com/ai/da/mapper/primary/entity/OrderInfo.java b/src/main/java/com/ai/da/mapper/primary/entity/OrderInfo.java new file mode 100644 index 00000000..12255f12 --- /dev/null +++ b/src/main/java/com/ai/da/mapper/primary/entity/OrderInfo.java @@ -0,0 +1,25 @@ +package com.ai.da.mapper.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +@Data +@TableName("t_order_info") +public class OrderInfo extends BaseEntity{ + + private String title;//订单标题 + + private String orderNo;//商户订单编号 + + private Long userId;//用户id + + private Long productId;//支付产品id + + private Integer totalFee;//订单金额(分) + + private String codeUrl;//订单二维码连接 + + private String orderStatus;//订单状态 + + private String paymentType;//支付方式 +} diff --git a/src/main/java/com/ai/da/mapper/primary/entity/PaymentInfo.java b/src/main/java/com/ai/da/mapper/primary/entity/PaymentInfo.java new file mode 100644 index 00000000..ceacf94a --- /dev/null +++ b/src/main/java/com/ai/da/mapper/primary/entity/PaymentInfo.java @@ -0,0 +1,23 @@ +package com.ai.da.mapper.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +@Data +@TableName("t_payment_info") +public class PaymentInfo extends BaseEntity{ + + private String orderNo;//商品订单编号 + + private String transactionId;//支付系统交易编号 + + private String paymentType;//支付类型 + + private String tradeType;//交易类型 + + private String tradeState;//交易状态 + + private Integer payerTotal;//支付金额(分) + + private String content;//通知参数 +} diff --git a/src/main/java/com/ai/da/mapper/primary/entity/Product.java b/src/main/java/com/ai/da/mapper/primary/entity/Product.java new file mode 100644 index 00000000..9aa55531 --- /dev/null +++ b/src/main/java/com/ai/da/mapper/primary/entity/Product.java @@ -0,0 +1,13 @@ +package com.ai.da.mapper.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +@Data +@TableName("t_product") +public class Product extends BaseEntity{ + + private String title; //商品名称 + + private Integer price; //价格(分) +} diff --git a/src/main/java/com/ai/da/mapper/primary/entity/RefundInfo.java b/src/main/java/com/ai/da/mapper/primary/entity/RefundInfo.java new file mode 100644 index 00000000..594be318 --- /dev/null +++ b/src/main/java/com/ai/da/mapper/primary/entity/RefundInfo.java @@ -0,0 +1,27 @@ +package com.ai.da.mapper.entity; + +import com.baomidou.mybatisplus.annotation.TableName; +import lombok.Data; + +@Data +@TableName("t_refund_info") +public class RefundInfo extends BaseEntity{ + + private String orderNo;//商品订单编号 + + private String refundNo;//退款单编号 + + private String refundId;//支付系统退款单号 + + private Integer totalFee;//原订单金额(分) + + private Integer refund;//退款金额(分) + + private String reason;//退款原因 + + private String refundStatus;//退款单状态 + + private String contentReturn;//申请退款返回参数 + + private String contentNotify;//退款结果通知参数 +} diff --git a/src/main/java/com/ai/da/model/dto/GenerateThroughImageTextDTO.java b/src/main/java/com/ai/da/model/dto/GenerateThroughImageTextDTO.java index fd45533c..1adfdbef 100644 --- a/src/main/java/com/ai/da/model/dto/GenerateThroughImageTextDTO.java +++ b/src/main/java/com/ai/da/model/dto/GenerateThroughImageTextDTO.java @@ -47,4 +47,7 @@ public class GenerateThroughImageTextDTO { @ApiModelProperty("唯一id,用于保持消息唯一性") String uniqueId; + + @ApiModelProperty("是否是测试用户") + Boolean isTestUser; } diff --git a/src/main/java/com/ai/da/model/vo/PrepareForGenerateVO.java b/src/main/java/com/ai/da/model/vo/PrepareForGenerateVO.java new file mode 100644 index 00000000..438d94db --- /dev/null +++ b/src/main/java/com/ai/da/model/vo/PrepareForGenerateVO.java @@ -0,0 +1,25 @@ +package com.ai.da.model.vo; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +@Data +@ApiModel("prepare for generate响应vo") +public class PrepareForGenerateVO { + + @ApiModelProperty("uniqueId") + private String uniqueId; + + @ApiModelProperty("剩余使用次数") + private Integer leftUsageCount; + + public PrepareForGenerateVO(String uniqueId, Integer leftUsageCount) { + this.uniqueId = uniqueId; + this.leftUsageCount = leftUsageCount; + } + + public PrepareForGenerateVO(Integer leftUsageCount) { + this.leftUsageCount = leftUsageCount; + } +} diff --git a/src/main/java/com/ai/da/service/AliPayService.java b/src/main/java/com/ai/da/service/AliPayService.java new file mode 100644 index 00000000..796126a2 --- /dev/null +++ b/src/main/java/com/ai/da/service/AliPayService.java @@ -0,0 +1,22 @@ +package com.ai.da.service; + +import java.util.Map; + +public interface AliPayService { + String tradeCreate(Long productId,String returnUrl); + + void processOrder(Map params); + + void cancelOrder(String orderNo); + + String queryOrder(String orderNo); + + void checkOrderStatus(String orderNo); + + void refund(String orderNo, String reason); + + String queryRefund(String orderNo); + + String queryBill(String billDate, String type); + +} diff --git a/src/main/java/com/ai/da/service/GenerateService.java b/src/main/java/com/ai/da/service/GenerateService.java index 09b10687..8e3a841c 100644 --- a/src/main/java/com/ai/da/service/GenerateService.java +++ b/src/main/java/com/ai/da/service/GenerateService.java @@ -7,6 +7,7 @@ import com.ai.da.model.dto.GenerateThroughImageTextDTO; import com.ai.da.model.vo.GenerateCaptionVO; import com.ai.da.model.vo.GenerateCollectionVO; import com.ai.da.model.vo.GenerateLikeVO; +import com.ai.da.model.vo.PrepareForGenerateVO; import com.baomidou.mybatisplus.extension.service.IService; import java.util.List; @@ -27,7 +28,7 @@ public interface GenerateService extends IService { GenerateCollectionVO getGenerateResult(String uniqueId); - String prepareForGenerate(GenerateThroughImageTextDTO generateThroughImageTextDTO); + PrepareForGenerateVO prepareForGenerate(GenerateThroughImageTextDTO generateThroughImageTextDTO); Long getRankPosition(String uniqueId); diff --git a/src/main/java/com/ai/da/service/OrderInfoService.java b/src/main/java/com/ai/da/service/OrderInfoService.java new file mode 100644 index 00000000..1507d931 --- /dev/null +++ b/src/main/java/com/ai/da/service/OrderInfoService.java @@ -0,0 +1,25 @@ +package com.ai.da.service; + + +import com.ai.da.common.enums.OrderStatusEnum; +import com.ai.da.mapper.entity.OrderInfo; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +public interface OrderInfoService extends IService { + + OrderInfo createOrderByProductId(Long productId, String paymentType); + + void saveCodeUrl(String orderNo, String codeUrl); + + List listOrderByCreateTimeDesc(); + + void updateStatusByOrderNo(String orderNo, OrderStatusEnum orderStatus); + + String getOrderStatus(String orderNo); + + List getNoPayOrderByDuration(int minutes, String paymentType); + + OrderInfo getOrderByOrderNo(String orderNo); +} diff --git a/src/main/java/com/ai/da/service/PaymentInfoService.java b/src/main/java/com/ai/da/service/PaymentInfoService.java new file mode 100644 index 00000000..aa1470e4 --- /dev/null +++ b/src/main/java/com/ai/da/service/PaymentInfoService.java @@ -0,0 +1,10 @@ +package com.ai.da.service; + +import java.util.Map; + +public interface PaymentInfoService { + + void createPaymentInfo(String plainText); + + void createPaymentInfoForAliPay(Map params); +} diff --git a/src/main/java/com/ai/da/service/ProductService.java b/src/main/java/com/ai/da/service/ProductService.java new file mode 100644 index 00000000..9ac2597d --- /dev/null +++ b/src/main/java/com/ai/da/service/ProductService.java @@ -0,0 +1,8 @@ +package com.ai.da.service; + +import com.ai.da.mapper.entity.Product; +import com.baomidou.mybatisplus.extension.service.IService; + +public interface ProductService extends IService { + +} diff --git a/src/main/java/com/ai/da/service/RefundInfoService.java b/src/main/java/com/ai/da/service/RefundInfoService.java new file mode 100644 index 00000000..014004cd --- /dev/null +++ b/src/main/java/com/ai/da/service/RefundInfoService.java @@ -0,0 +1,20 @@ +package com.ai.da.service; + + +import com.ai.da.mapper.entity.RefundInfo; +import com.baomidou.mybatisplus.extension.service.IService; + +import java.util.List; + +public interface RefundInfoService extends IService { + + RefundInfo createRefundByOrderNo(String orderNo, String reason); + + void updateRefund(String content); + + List getNoRefundOrderByDuration(int minutes); + + RefundInfo createRefundByOrderNoForAliPay(String orderNo, String reason); + + void updateRefundForAliPay(String refundNo, String content, String refundStatus); +} diff --git a/src/main/java/com/ai/da/service/impl/AliPayServiceImpl.java b/src/main/java/com/ai/da/service/impl/AliPayServiceImpl.java new file mode 100644 index 00000000..a018ff9d --- /dev/null +++ b/src/main/java/com/ai/da/service/impl/AliPayServiceImpl.java @@ -0,0 +1,395 @@ +package com.ai.da.service.impl; + +import com.ai.da.common.enums.AliPayTradeStateEnum; +import com.ai.da.common.enums.OrderStatusEnum; +import com.ai.da.common.enums.PayTypeEnum; +import com.ai.da.mapper.entity.OrderInfo; +import com.ai.da.mapper.entity.RefundInfo; +import com.ai.da.service.AliPayService; +import com.ai.da.service.OrderInfoService; +import com.ai.da.service.PaymentInfoService; +import com.ai.da.service.RefundInfoService; +import com.alibaba.fastjson.JSONObject; +import com.alipay.api.AlipayApiException; +import com.alipay.api.AlipayClient; +import com.alipay.api.request.*; +import com.alipay.api.response.*; +import com.google.gson.Gson; +import com.google.gson.internal.LinkedTreeMap; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.env.Environment; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import javax.annotation.Resource; +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.locks.ReentrantLock; + +@Service +@Slf4j +public class AliPayServiceImpl implements AliPayService { + + @Resource + private OrderInfoService orderInfoService; + + @Resource + private AlipayClient alipayClient; + + @Resource + private Environment config; + + @Resource + private PaymentInfoService paymentInfoService; + + @Resource + private RefundInfoService refundsInfoService; + + private final ReentrantLock lock = new ReentrantLock(); + + @Transactional(rollbackFor = Exception.class) + @Override + public String tradeCreate(Long productId, String returnUrl) { + + try { + //生成订单 + log.info("生成订单"); + OrderInfo orderInfo = orderInfoService.createOrderByProductId(productId, PayTypeEnum.ALIPAY.getType()); + + //调用支付宝接口 + AlipayTradePagePayRequest request = new AlipayTradePagePayRequest(); + //配置需要的公共请求参数 + //支付完成后,支付宝发起异步通知的地址 + request.setNotifyUrl(config.getProperty("alipay.notify-url")); + //支付完成后,我们想让页面跳转回aida的页面,配置returnUrl +// request.setReturnUrl(config.getProperty("alipay.return-url")); + request.setReturnUrl(returnUrl); + + //组装当前业务方法的请求参数 + JSONObject bizContent = new JSONObject(); + bizContent.put("out_trade_no", orderInfo.getOrderNo()); + BigDecimal total = new BigDecimal(orderInfo.getTotalFee().toString()).divide(new BigDecimal("100")); + bizContent.put("total_amount", total); + bizContent.put("subject", orderInfo.getTitle()); + bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY"); + + request.setBizContent(bizContent.toString()); + + //执行请求,调用支付宝接口 + AlipayTradePagePayResponse response = alipayClient.pageExecute(request); + + if(response.isSuccess()){ + log.info("调用成功,返回结果 ===> " + response.getBody()); + return response.getBody(); + } else { + log.info("调用失败,返回码 ===> " + response.getCode() + ", 返回描述 ===> " + response.getMsg()); + throw new RuntimeException("创建支付交易失败"); + } + } catch (AlipayApiException e) { + e.printStackTrace(); + throw new RuntimeException("创建支付交易失败"); + } + } + + /** + * 处理订单 + * @param params + */ + @Transactional(rollbackFor = Exception.class) + @Override + public void processOrder(Map params) { + + log.info("处理订单"); + + //获取订单号 + String orderNo = params.get("out_trade_no"); + + /*在对业务数据进行状态检查和处理之前, + 要采用数据锁进行并发控制, + 以避免函数重入造成的数据混乱*/ + //尝试获取锁: + // 成功获取则立即返回true,获取失败则立即返回false。不必一直等待锁的释放 + if(lock.tryLock()) { + try { + + //处理重复通知 + //接口调用的幂等性:无论接口被调用多少次,以下业务执行一次 + String orderStatus = orderInfoService.getOrderStatus(orderNo); + if (!OrderStatusEnum.NOT_PAY.getType().equals(orderStatus)) { + return; + } + + //更新订单状态 + orderInfoService.updateStatusByOrderNo(orderNo, OrderStatusEnum.SUCCESS); + + //记录支付日志 + paymentInfoService.createPaymentInfoForAliPay(params); + + } finally { + //要主动释放锁 + lock.unlock(); + } + } + + } + + /** + * 用户取消订单 + * @param orderNo + */ + @Override + public void cancelOrder(String orderNo) { + + //调用支付宝提供的统一收单交易关闭接口 + this.closeOrder(orderNo); + + //更新用户订单状态 + orderInfoService.updateStatusByOrderNo(orderNo, OrderStatusEnum.CANCEL); + } + + /** + * 查询订单 + * @param orderNo + * @return 返回订单查询结果,如果返回null则表示支付宝端尚未创建订单 + */ + @Override + public String queryOrder(String orderNo) { + + try { + log.info("查单接口调用 ===> {}", orderNo); + + AlipayTradeQueryRequest request = new AlipayTradeQueryRequest(); + JSONObject bizContent = new JSONObject(); + bizContent.put("out_trade_no", orderNo); + request.setBizContent(bizContent.toString()); + + AlipayTradeQueryResponse response = alipayClient.execute(request); + if(response.isSuccess()){ + log.info("调用成功,返回结果 ===> " + response.getBody()); + return response.getBody(); + } else { + log.info("调用失败,返回码 ===> " + response.getCode() + ", 返回描述 ===> " + response.getMsg()); + //throw new RuntimeException("查单接口的调用失败"); + return null;//订单不存在 + } + + } catch (AlipayApiException e) { + e.printStackTrace(); + throw new RuntimeException("查单接口的调用失败"); + } + } + + /** + * 根据订单号调用支付宝查单接口,核实订单状态 + * 如果订单未创建,则更新商户端订单状态 + * 如果订单未支付,则调用关单接口关闭订单,并更新商户端订单状态 + * 如果订单已支付,则更新商户端订单状态,并记录支付日志 + * @param orderNo + */ + @Override + public void checkOrderStatus(String orderNo) { + + log.warn("根据订单号核实订单状态 ===> {}", orderNo); + + String result = this.queryOrder(orderNo); + + //订单未创建 + if(result == null){ + log.warn("核实订单未创建 ===> {}", orderNo); + //更新本地订单状态 + orderInfoService.updateStatusByOrderNo(orderNo, OrderStatusEnum.CLOSED); + } + + //解析查单响应结果 + Gson gson = new Gson(); + HashMap resultMap = gson.fromJson(result, HashMap.class); + LinkedTreeMap alipayTradeQueryResponse = resultMap.get("alipay_trade_query_response"); + + String tradeStatus = (String)alipayTradeQueryResponse.get("trade_status"); + if(AliPayTradeStateEnum.NOTPAY.getType().equals(tradeStatus)){ + log.warn("核实订单未支付 ===> {}", orderNo); + + //如果订单未支付,则调用关单接口关闭订单 + this.closeOrder(orderNo); + + // 并更新商户端订单状态 + orderInfoService.updateStatusByOrderNo(orderNo, OrderStatusEnum.CLOSED); + } + + if(AliPayTradeStateEnum.SUCCESS.getType().equals(tradeStatus)){ + log.warn("核实订单已支付 ===> {}", orderNo); + + //如果订单已支付,则更新商户端订单状态 + orderInfoService.updateStatusByOrderNo(orderNo, OrderStatusEnum.SUCCESS); + + //并记录支付日志 + paymentInfoService.createPaymentInfoForAliPay(alipayTradeQueryResponse); + } + + } + + /** + * 关单接口的调用 + * @param orderNo 订单号 + */ + private void closeOrder(String orderNo) { + + try { + log.info("关单接口的调用,订单号 ===> {}", orderNo); + + AlipayTradeCloseRequest request = new AlipayTradeCloseRequest(); + JSONObject bizContent = new JSONObject(); + bizContent.put("out_trade_no", orderNo); + request.setBizContent(bizContent.toString()); + AlipayTradeCloseResponse response = alipayClient.execute(request); + + if(response.isSuccess()){ + log.info("调用成功,返回结果 ===> " + response.getBody()); + } else { + log.info("调用失败,返回码 ===> " + response.getCode() + ", 返回描述 ===> " + response.getMsg()); + //throw new RuntimeException("关单接口的调用失败"); + } + + } catch (AlipayApiException e) { + e.printStackTrace(); + throw new RuntimeException("关单接口的调用失败"); + } + } + + /** + * 退款 + * @param orderNo + * @param reason + */ + @Transactional(rollbackFor = Exception.class) + @Override + public void refund(String orderNo, String reason) { + + try { + log.info("调用退款API"); + + //创建退款单 + RefundInfo refundInfo = refundsInfoService.createRefundByOrderNoForAliPay(orderNo, reason); + + //调用统一收单交易退款接口 + AlipayTradeRefundRequest request = new AlipayTradeRefundRequest (); + + //组装当前业务方法的请求参数 + JSONObject bizContent = new JSONObject(); + bizContent.put("out_trade_no", orderNo);//订单编号 + BigDecimal refund = new BigDecimal(refundInfo.getRefund().toString()).divide(new BigDecimal("100")); + //BigDecimal refund = new BigDecimal("2").divide(new BigDecimal("100")); + bizContent.put("refund_amount", refund);//退款金额:不能大于支付金额 + bizContent.put("refund_reason", reason);//退款原因(可选) + + request.setBizContent(bizContent.toString()); + + //执行请求,调用支付宝接口 + AlipayTradeRefundResponse response = alipayClient.execute(request); + + if(response.isSuccess()){ + log.info("调用成功,返回结果 ===> " + response.getBody()); + + //更新订单状态 + orderInfoService.updateStatusByOrderNo(orderNo, OrderStatusEnum.REFUND_SUCCESS); + + //更新退款单 + refundsInfoService.updateRefundForAliPay( + refundInfo.getRefundNo(), + response.getBody(), + AliPayTradeStateEnum.REFUND_SUCCESS.getType()); //退款成功 + + } else { + log.info("调用失败,返回码 ===> " + response.getCode() + ", 返回描述 ===> " + response.getMsg()); + + //更新订单状态 + orderInfoService.updateStatusByOrderNo(orderNo, OrderStatusEnum.REFUND_ABNORMAL); + + //更新退款单 + refundsInfoService.updateRefundForAliPay( + refundInfo.getRefundNo(), + response.getBody(), + AliPayTradeStateEnum.REFUND_ERROR.getType()); //退款失败 + } + + + } catch (AlipayApiException e) { + e.printStackTrace(); + throw new RuntimeException("创建退款申请失败"); + } + } + + /** + * 查询退款 + * @param orderNo + * @return + */ + @Override + public String queryRefund(String orderNo) { + + try { + log.info("查询退款接口调用 ===> {}", orderNo); + + AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest(); + JSONObject bizContent = new JSONObject(); + bizContent.put("out_trade_no", orderNo); + bizContent.put("out_request_no", orderNo); + request.setBizContent(bizContent.toString()); + + AlipayTradeFastpayRefundQueryResponse response = alipayClient.execute(request); + if(response.isSuccess()){ + log.info("调用成功,返回结果 ===> " + response.getBody()); + return response.getBody(); + } else { + log.info("调用失败,返回码 ===> " + response.getCode() + ", 返回描述 ===> " + response.getMsg()); + //throw new RuntimeException("查单接口的调用失败"); + return null;//订单不存在 + } + + } catch (AlipayApiException e) { + e.printStackTrace(); + throw new RuntimeException("查单接口的调用失败"); + } + } + + /** + * 申请账单 + * @param billDate + * @param type + * @return + */ + @Override + public String queryBill(String billDate, String type) { + + try { + + AlipayDataDataserviceBillDownloadurlQueryRequest request = new AlipayDataDataserviceBillDownloadurlQueryRequest(); + JSONObject bizContent = new JSONObject(); + bizContent.put("bill_type", type); + bizContent.put("bill_date", billDate); + request.setBizContent(bizContent.toString()); + AlipayDataDataserviceBillDownloadurlQueryResponse response = alipayClient.execute(request); + + if(response.isSuccess()){ + log.info("调用成功,返回结果 ===> " + response.getBody()); + + //获取账单下载地址 + Gson gson = new Gson(); + HashMap resultMap = gson.fromJson(response.getBody(), HashMap.class); + LinkedTreeMap billDownloadurlResponse = resultMap.get("alipay_data_dataservice_bill_downloadurl_query_response"); + String billDownloadUrl = (String)billDownloadurlResponse.get("bill_download_url"); + + return billDownloadUrl; + } else { + log.info("调用失败,返回码 ===> " + response.getCode() + ", 返回描述 ===> " + response.getMsg()); + throw new RuntimeException("申请账单失败"); + } + + } catch (AlipayApiException e) { + e.printStackTrace(); + throw new RuntimeException("申请账单失败"); + } + } + +} diff --git a/src/main/java/com/ai/da/service/impl/ChatRobotServiceImpl.java b/src/main/java/com/ai/da/service/impl/ChatRobotServiceImpl.java index fb56d871..7e3ba77d 100644 --- a/src/main/java/com/ai/da/service/impl/ChatRobotServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/ChatRobotServiceImpl.java @@ -74,6 +74,8 @@ public class ChatRobotServiceImpl implements ChatRobotService { @Value("${minio.bucketName.sysImage}") private String sysImage; + @Resource + private AccountMapper accountMapper; Gson gson = new GsonBuilder().create(); private final ExecutorService executorService = Executors.newSingleThreadExecutor(); @@ -178,7 +180,8 @@ public class ChatRobotServiceImpl implements ChatRobotService { chatRobot.setSessionId(data.getString("session_id")); BigDecimal totalCost = data.getBigDecimal("total_cost"); // 校验本次余额够不够 - checkBalance(totalCost, chatSendDTO.getUser_id()); + ChatRobotVO balance = checkBalance(totalCost, chatSendDTO.getUser_id()); + if (!Objects.isNull(balance)) return balance; chatRobot.setTotalCost(totalCost); chatRobot.setTotalTokens(data.getLong("total_tokens")); chatRobot.setUserId(chatSendDTO.getUser_id()); @@ -248,7 +251,7 @@ public class ChatRobotServiceImpl implements ChatRobotService { throw new BusinessException("chat-bot.interface.exception"); } - private void checkBalance(BigDecimal totalCost, Long userId) { + private ChatRobotVO checkBalance(BigDecimal totalCost, Long userId) { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("user_id", userId); queryWrapper.ge("create_time", LocalDateTime.now().withDayOfMonth(1).withHour(0).withMinute(0).withSecond(0)); @@ -257,10 +260,25 @@ public class ChatRobotServiceImpl implements ChatRobotService { List chatRobots = chatRobotMapper.selectList(queryWrapper); if (!CollectionUtils.isEmpty(chatRobots)) { BigDecimal totalCostUsed = chatRobots.get(0).getTotalCost(); - if (totalCostUsed.add(totalCost).compareTo(BigDecimal.valueOf(5)) > 0) { - throw new BusinessException("Your balance is insufficient"); + Account account = accountMapper.selectById(userId); + ChatRobot chatRobot = new ChatRobot(); + if (account.getIsTrial() == 1) { + if (totalCostUsed.add(totalCost).compareTo(BigDecimal.valueOf(0.1)) > 0) { + String messageFromResource = BusinessException.getMessageFromResource("balance.insufficient.for.trial"); + chatRobot.setOutput(messageFromResource); +// throw new BusinessException("Your balance is insufficient"); + return CopyUtil.copyObject(chatRobot, ChatRobotVO.class); + } + }else { + if (totalCostUsed.add(totalCost).compareTo(BigDecimal.valueOf(5)) > 0) { + String messageFromResource = BusinessException.getMessageFromResource("balance.insufficient.for.paying"); + chatRobot.setOutput(messageFromResource); +// throw new BusinessException("Your balance is insufficient"); + return CopyUtil.copyObject(chatRobot, ChatRobotVO.class); + } } } + return null; } @Override @@ -323,9 +341,14 @@ public class ChatRobotServiceImpl implements ChatRobotService { if (CollectionUtils.isEmpty(chatRobots)) { return BigDecimal.ONE; } else { + Account account = accountMapper.selectById(userId); BigDecimal totalCost = BigDecimal.valueOf(5).subtract(chatRobots.get(0).getTotalCost()); - BigDecimal result = totalCost.divide(BigDecimal.valueOf(5), 4, RoundingMode.HALF_UP); - return result; + if (account.getIsTrial() == 1) { + totalCost = BigDecimal.valueOf(0.1).subtract(chatRobots.get(0).getTotalCost()); + return totalCost.divide(BigDecimal.valueOf(0.1), 4, RoundingMode.HALF_UP); + }else { + return totalCost.divide(BigDecimal.valueOf(5), 4, RoundingMode.HALF_UP); + } } } diff --git a/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java b/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java index 14a16046..cae9902e 100644 --- a/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/GenerateServiceImpl.java @@ -314,7 +314,7 @@ public class GenerateServiceImpl extends ServiceImpl i } @Override - public String prepareForGenerate(GenerateThroughImageTextDTO generateThroughImageTextDTO) { + public PrepareForGenerateVO prepareForGenerate(GenerateThroughImageTextDTO generateThroughImageTextDTO) { // 1、参数检查,判断必须参数是否为空 if (Objects.isNull(generateThroughImageTextDTO.getUserId())) { throw new BusinessException("userId cannot be empty"); @@ -323,6 +323,16 @@ public class GenerateServiceImpl extends ServiceImpl i if (!GenerateModeEnum.getGenerateModeList().contains(generateType)) { throw new BusinessException("unknown.generate.type"); } + + // 判断试用用户是否还有剩余试用机会 + int trialsCount = 0; + if (generateThroughImageTextDTO.getIsTestUser()){ + trialsCount = getTrialsCount(generateThroughImageTextDTO.getUserId(), generateThroughImageTextDTO.getLevel1Type()); + if (trialsCount >= 2){ + return new PrepareForGenerateVO(0); + } + } + String text = generateThroughImageTextDTO.getText(); Long elementId = generateThroughImageTextDTO.getCollectionElementId(); validateGeneraType(new Generate(), text, elementId, generateType); @@ -361,7 +371,7 @@ public class GenerateServiceImpl extends ServiceImpl i rabbitMQService.publishMessage(jsonString); // 5、返回唯一id - return uuid; + return new PrepareForGenerateVO(uuid, 2 - trialsCount); } @Override @@ -458,4 +468,28 @@ public class GenerateServiceImpl extends ServiceImpl i GenerateCancel generateCancel = new GenerateCancel(userId, uniqueId, DateUtil.getByTimeZone(timeZone)); generateCancelMapper.insert(generateCancel); } + + // 判断试用用户试用generate机会是否使用完毕 + private int getTrialsCount(Long userId, String level1Type){ + List getGenerateList = getGenerateByAccountId(userId, level1Type); + int trialsCount ; + if (getGenerateList.isEmpty()){ + trialsCount = 0; + } else if (getGenerateList.size() == 1) { + trialsCount = 1; + } else if (getGenerateList.size() == 2) { + trialsCount = 2; + }else { + trialsCount = 2; + } + return trialsCount; + } + + public List getGenerateByAccountId(Long accountId, String level1Type){ + QueryWrapper qw = new QueryWrapper<>(); + qw.eq("account_id",accountId); + qw.eq("level1_type", level1Type); + + return baseMapper.selectList(qw); + } } diff --git a/src/main/java/com/ai/da/service/impl/OrderInfoServiceImpl.java b/src/main/java/com/ai/da/service/impl/OrderInfoServiceImpl.java new file mode 100644 index 00000000..aa1f5255 --- /dev/null +++ b/src/main/java/com/ai/da/service/impl/OrderInfoServiceImpl.java @@ -0,0 +1,172 @@ +package com.ai.da.service.impl; + + +import com.ai.da.common.enums.OrderStatusEnum; +import com.ai.da.common.utils.OrderNoUtils; +import com.ai.da.mapper.OrderInfoMapper; +import com.ai.da.mapper.ProductMapper; +import com.ai.da.mapper.entity.OrderInfo; +import com.ai.da.mapper.entity.Product; +import com.ai.da.service.OrderInfoService; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.time.Duration; +import java.time.Instant; +import java.util.List; + +@Service +@Slf4j +public class OrderInfoServiceImpl extends ServiceImpl implements OrderInfoService { + + @Resource + private ProductMapper productMapper; + + /*@Resource + private OrderInfoMapper orderInfoMapper;*/ + + @Override + public OrderInfo createOrderByProductId(Long productId, String paymentType) { + + //查找已存在但未支付的订单 + OrderInfo orderInfo = this.getNoPayOrderByProductId(productId, paymentType); + if( orderInfo != null){ + return orderInfo; + } + + //获取商品信息 + Product product = productMapper.selectById(productId); + + //生成订单 + orderInfo = new OrderInfo(); + orderInfo.setTitle(product.getTitle()); + orderInfo.setOrderNo(OrderNoUtils.getOrderNo()); //订单号 + orderInfo.setProductId(productId); + orderInfo.setTotalFee(product.getPrice()); //分 + orderInfo.setOrderStatus(OrderStatusEnum.NOT_PAY.getType()); //未支付 + orderInfo.setPaymentType(paymentType); + baseMapper.insert(orderInfo); + + return orderInfo; + } + + /** + * 存储订单二维码 + * @param orderNo + * @param codeUrl + */ + @Override + public void saveCodeUrl(String orderNo, String codeUrl) { + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("order_no", orderNo); + + OrderInfo orderInfo = new OrderInfo(); + orderInfo.setCodeUrl(codeUrl); + + baseMapper.update(orderInfo, queryWrapper); + } + + /** + * 查询订单列表,并倒序查询 + * @return + */ + @Override + public List listOrderByCreateTimeDesc() { + + QueryWrapper queryWrapper = new QueryWrapper().orderByDesc("create_time"); + return baseMapper.selectList(queryWrapper); + } + + /** + * 根据订单号更新订单状态 + * @param orderNo + * @param orderStatus + */ + @Override + public void updateStatusByOrderNo(String orderNo, OrderStatusEnum orderStatus) { + + log.info("更新订单状态 ===> {}", orderStatus.getType()); + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("order_no", orderNo); + + OrderInfo orderInfo = new OrderInfo(); + orderInfo.setOrderStatus(orderStatus.getType()); + + baseMapper.update(orderInfo, queryWrapper); + } + + /** + * 根据订单号获取订单状态 + * @param orderNo + * @return + */ + @Override + public String getOrderStatus(String orderNo) { + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("order_no", orderNo); + OrderInfo orderInfo = baseMapper.selectOne(queryWrapper); + if(orderInfo == null){ + return null; + } + return orderInfo.getOrderStatus(); + } + + /** + * 查询创建超过minutes分钟并且未支付的订单 + * @param minutes + * @return + */ + @Override + public List getNoPayOrderByDuration(int minutes, String paymentType) { + + Instant instant = Instant.now().minus(Duration.ofMinutes(minutes)); + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("order_status", OrderStatusEnum.NOT_PAY.getType()); + queryWrapper.le("create_time", instant); + queryWrapper.eq("payment_type", paymentType); + + List orderInfoList = baseMapper.selectList(queryWrapper); + + return orderInfoList; + } + + /** + * 根据订单号获取订单 + * @param orderNo + * @return + */ + @Override + public OrderInfo getOrderByOrderNo(String orderNo) { + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("order_no", orderNo); + OrderInfo orderInfo = baseMapper.selectOne(queryWrapper); + + return orderInfo; + } + + + /** + * 根据商品id查询未支付订单 + * 防止重复创建订单对象 + * @param productId + * @return + */ + private OrderInfo getNoPayOrderByProductId(Long productId, String paymentType) { + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("product_id", productId); + queryWrapper.eq("order_status", OrderStatusEnum.NOT_PAY.getType()); + queryWrapper.eq("payment_type", paymentType); +// queryWrapper.eq("user_id", userId); + OrderInfo orderInfo = baseMapper.selectOne(queryWrapper); + return orderInfo; + } +} diff --git a/src/main/java/com/ai/da/service/impl/PaymentInfoServiceImpl.java b/src/main/java/com/ai/da/service/impl/PaymentInfoServiceImpl.java new file mode 100644 index 00000000..4bafa595 --- /dev/null +++ b/src/main/java/com/ai/da/service/impl/PaymentInfoServiceImpl.java @@ -0,0 +1,90 @@ +package com.ai.da.service.impl; + +import com.ai.da.common.enums.PayTypeEnum; +import com.ai.da.mapper.PaymentInfoMapper; +import com.ai.da.mapper.entity.PaymentInfo; +import com.ai.da.service.PaymentInfoService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.google.gson.Gson; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.math.BigDecimal; +import java.util.HashMap; +import java.util.Map; + +@Service +@Slf4j +public class PaymentInfoServiceImpl extends ServiceImpl implements PaymentInfoService { + + /** + * 记录支付日志:微信支付 + * @param plainText + */ + @Override + public void createPaymentInfo(String plainText) { + + log.info("记录支付日志"); + + Gson gson = new Gson(); + HashMap plainTextMap = gson.fromJson(plainText, HashMap.class); + + //订单号 + String orderNo = (String)plainTextMap.get("out_trade_no"); + //业务编号 + String transactionId = (String)plainTextMap.get("transaction_id"); + //支付类型 + String tradeType = (String)plainTextMap.get("trade_type"); + //交易状态 + String tradeState = (String)plainTextMap.get("trade_state"); + //用户实际支付金额 + Map amount = (Map)plainTextMap.get("amount"); + Integer payerTotal = ((Double) amount.get("payer_total")).intValue(); + + PaymentInfo paymentInfo = new PaymentInfo(); + paymentInfo.setOrderNo(orderNo); + paymentInfo.setPaymentType(PayTypeEnum.WXPAY.getType()); + paymentInfo.setTransactionId(transactionId); + paymentInfo.setTradeType(tradeType); + paymentInfo.setTradeState(tradeState); + paymentInfo.setPayerTotal(payerTotal); + paymentInfo.setContent(plainText); + + baseMapper.insert(paymentInfo); + } + + /** + * 记录支付日志:支付宝 + * @param params + */ + @Override + public void createPaymentInfoForAliPay(Map params) { + + log.info("记录支付日志"); + + //获取订单号 + String orderNo = params.get("out_trade_no"); + //业务编号 + String transactionId = params.get("trade_no"); + //交易状态 + String tradeStatus = params.get("trade_status"); + //交易金额 + String totalAmount = params.get("total_amount"); + int totalAmountInt = new BigDecimal(totalAmount).multiply(new BigDecimal("100")).intValue(); + + + PaymentInfo paymentInfo = new PaymentInfo(); + paymentInfo.setOrderNo(orderNo); + paymentInfo.setPaymentType(PayTypeEnum.ALIPAY.getType()); + paymentInfo.setTransactionId(transactionId); + paymentInfo.setTradeType("电脑网站支付"); + paymentInfo.setTradeState(tradeStatus); + paymentInfo.setPayerTotal(totalAmountInt); + + Gson gson = new Gson(); + String json = gson.toJson(params, HashMap.class); + paymentInfo.setContent(json); + + baseMapper.insert(paymentInfo); + } +} diff --git a/src/main/java/com/ai/da/service/impl/ProductServiceImpl.java b/src/main/java/com/ai/da/service/impl/ProductServiceImpl.java new file mode 100644 index 00000000..0aa9d4b3 --- /dev/null +++ b/src/main/java/com/ai/da/service/impl/ProductServiceImpl.java @@ -0,0 +1,12 @@ +package com.ai.da.service.impl; + +import com.ai.da.mapper.ProductMapper; +import com.ai.da.mapper.entity.Product; +import com.ai.da.service.ProductService; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import org.springframework.stereotype.Service; + +@Service +public class ProductServiceImpl extends ServiceImpl implements ProductService { + +} diff --git a/src/main/java/com/ai/da/service/impl/RefundInfoServiceImpl.java b/src/main/java/com/ai/da/service/impl/RefundInfoServiceImpl.java new file mode 100644 index 00000000..f05dd74f --- /dev/null +++ b/src/main/java/com/ai/da/service/impl/RefundInfoServiceImpl.java @@ -0,0 +1,156 @@ +package com.ai.da.service.impl; + +import com.ai.da.common.utils.OrderNoUtils; +import com.ai.da.mapper.RefundInfoMapper; +import com.ai.da.mapper.entity.OrderInfo; +import com.ai.da.mapper.entity.RefundInfo; +import com.ai.da.service.OrderInfoService; +import com.ai.da.service.RefundInfoService; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; + +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.google.gson.Gson; +import org.springframework.stereotype.Service; + +import javax.annotation.Resource; +import java.time.Duration; +import java.time.Instant; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@Service +public class RefundInfoServiceImpl extends ServiceImpl implements RefundInfoService { + + @Resource + private OrderInfoService orderInfoService; + + /** + * 根据订单号创建退款订单 + * @param orderNo + * @return + */ + @Override + public RefundInfo createRefundByOrderNo(String orderNo, String reason) { + + //根据订单号获取订单信息 + OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(orderNo); + + //根据订单号生成退款订单 + RefundInfo refundInfo = new RefundInfo(); + refundInfo.setOrderNo(orderNo);//订单编号 + refundInfo.setRefundNo(OrderNoUtils.getRefundNo());//退款单编号 + refundInfo.setTotalFee(orderInfo.getTotalFee());//原订单金额(分) + refundInfo.setRefund(orderInfo.getTotalFee());//退款金额(分) + refundInfo.setReason(reason);//退款原因 + + //保存退款订单 + baseMapper.insert(refundInfo); + + return refundInfo; + } + + + /** + * 记录退款记录 + * @param content + */ + @Override + public void updateRefund(String content) { + + //将json字符串转换成Map + Gson gson = new Gson(); + Map resultMap = gson.fromJson(content, HashMap.class); + + //根据退款单编号修改退款单 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("refund_no", resultMap.get("out_refund_no")); + + //设置要修改的字段 + RefundInfo refundInfo = new RefundInfo(); + + refundInfo.setRefundId(resultMap.get("refund_id"));//微信支付退款单号 + + //查询退款和申请退款中的返回参数 + if(resultMap.get("status") != null){ + refundInfo.setRefundStatus(resultMap.get("status"));//退款状态 + refundInfo.setContentReturn(content);//将全部响应结果存入数据库的content字段 + } + //退款回调中的回调参数 + if(resultMap.get("refund_status") != null){ + refundInfo.setRefundStatus(resultMap.get("refund_status"));//退款状态 + refundInfo.setContentNotify(content);//将全部响应结果存入数据库的content字段 + } + + //更新退款单 + baseMapper.update(refundInfo, queryWrapper); + } + + /** + * 找出申请退款超过minutes分钟并且未成功的退款单 + * @param minutes + * @return + */ + @Override + public List getNoRefundOrderByDuration(int minutes) { + + //minutes分钟之前的时间 + Instant instant = Instant.now().minus(Duration.ofMinutes(minutes)); + + QueryWrapper queryWrapper = new QueryWrapper<>(); +// queryWrapper.eq("refund_status", WxRefundStatus.PROCESSING.getType()); + queryWrapper.le("create_time", instant); + List refundInfoList = baseMapper.selectList(queryWrapper); + return refundInfoList; + } + + /** + * 根据订单号创建退款订单 + * @param orderNo + * @return + */ + @Override + public RefundInfo createRefundByOrderNoForAliPay(String orderNo, String reason) { + + //根据订单号获取订单信息 + OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(orderNo); + + //根据订单号生成退款订单 + RefundInfo refundInfo = new RefundInfo(); + refundInfo.setOrderNo(orderNo);//订单编号 + refundInfo.setRefundNo(OrderNoUtils.getRefundNo());//退款单编号 + + refundInfo.setTotalFee(orderInfo.getTotalFee());//原订单金额(分) + refundInfo.setRefund(orderInfo.getTotalFee());//退款金额(分) + refundInfo.setReason(reason);//退款原因 + + //保存退款订单 + baseMapper.insert(refundInfo); + + return refundInfo; + } + + /** + * 更新退款记录 + * @param refundNo + * @param content + * @param refundStatus + */ + @Override + public void updateRefundForAliPay(String refundNo, String content, String refundStatus) { + + //根据退款单编号修改退款单 + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("refund_no", refundNo); + + //设置要修改的字段 + RefundInfo refundInfo = new RefundInfo(); + refundInfo.setRefundStatus(refundStatus);//退款状态 + refundInfo.setContentReturn(content);//将全部响应结果存入数据库的content字段 + + //更新退款单 + baseMapper.update(refundInfo, queryWrapper); + + } + +} diff --git a/src/main/resources/alipay-sandbox.properties b/src/main/resources/alipay-sandbox.properties new file mode 100644 index 00000000..45a528e0 --- /dev/null +++ b/src/main/resources/alipay-sandbox.properties @@ -0,0 +1,39 @@ +# 支付宝支付相关参数 + +# 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号 +#alipay.app-id=2021000119635499 +alipay.app-id=9021000134653815 + +# 商户PID,卖家支付宝账号ID +#alipay.seller-id=2088621957993562 +alipay.seller-id=2088721029614572 + +# 支付宝网关 +#alipay.gateway-url=https://openapi.alipaydev.com/gateway.do +alipay.gateway-url=https://openapi-sandbox.dl.alipaydev.com/gateway.do + +# 商户私钥,您的PKCS8格式RSA2私钥 +#alipay.merchant-private-key=MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCJPnt6TMZ1A06SMeNxQT0WhGbRd74JBCcdqQt4POzBMJ1NE6U/OiG2xZEnUqYWC2ukkOgZZEvTuWDI9q2aEFN7E2Fcj39JCwRmE0an153JIOkb9L2nngTsAAN7cwLZZ6/dAPnrZjtN0f/HRVBXPSNLBdpoS/pbKRurM2NccZkbTZtluCdt4IvBBjjcV3DJOCYP9yrLTP3HYDxep3HrZCvXuR2Iseb+c6qc4IF/2UKQTz+iavxCy3zJTYbDzD0cL7yC4HmSD7vbNGZvkzZB1RNWt0NILj2LdFG10T7zZahN461FiYozRfD7LDPXqq+uuZMM5i0jpXVrs2MDk6HeS0lJAgMBAAECggEAF87wCrpQ3zGwqqne4+HGYCad046rN9MxmfKeW8Bt7eGqGBnlW7+Q460ITkMHLuHSTZ0ZtnXwtYz+Hj60xPo6ESq+hBkcoqY3oCGN60X7SE3eQoxFblN6VRp3gC3me6KCHpuxv0Vf2lMoxP/gPRINElG0ns03ZCMQerWSchH+1n5xUX/SrsgYDLaHfCxSpGsI/iyjTHXl+KqZeiFoRY+0tlJCTsc6P8JBYEeI5l8Iza/CjxDgFT41B4RksMw9ZEUCwxMiQhqIOThdTxtpA+MpUjoizhngq1xAXMcEz3QlnV7V2icyWjDAAz7bMCISUBa2MLkNWb392/yROKCBcXKYZQKBgQDY5T8QbC3GiUw0IQrVwm1A46zBzMDuQV+a4/2q63f8BBRZcbOluzxuCSfsTIVFKF1eJqpD75+76rB2z39P5xSS2/9SuO9FofV5iUDZuC93mOvR5nwh0rkgizhes81p+i7S9VcQcLTM/gK8ta3VXC3Pv/9bIGlTyFPLS0iMLUJlywKBgQCh/PIjoBFqKWpB6wSTn8hotvvE0WU1XMhm09WnlrMN2O+TuL71PoVS5vhCBgCJW5e3OOOS1K8uYLWaAQY9g/PvzYWLKF7CkCZNTvdds67QMreU9Cfm3jOwUkOibXarJEwY0l52k4xihQ6o8QGvG6XmNw3oq3RX/t/Y0DC84lMKuwKBgQCBQnYIAoBxToe0lXCQnfNgdY8SXEUqeJlShMc7YmM6NPAvsfxfK6vC4///6kaORZUHNEHKhPcMFbyeweBcrRlswGF0WjR2qiPSD4MvfX4EZ4U6rYKS4bNkerPYdI1ZuDjJjl8ZtCF7/XGCJz/25J2Eryauly1OOhf+Etqkd6CXawKBgDlmf4seMm2TBWMcW3/QM9zfUnHY3Ws+WIkPcXs0THiQsbx/z7Lpl6bbz4bdx5zkxusXDpU+JmFhxZgv2r07n9oO0s6P3JxHJjtoywD6Je0Cu8jdh7IodNp7HBpXfaCBeTGmgfC0sh9LFPnKhRU+z9e3FIepEc4Is9uJUmvsKw73AoGAM44/Oz7axzcVEIaD/7jyy1GiaYCmI55qqjocXfbK9QlWDiLnGfbx2UB6BC1y7WD6a9bMpatLXppTDEL+qHX0jUp0u06LQnJi9SAUBcff4LioSJxBrYx6ovYjAEmpoyiW/AAQBJ1oyp1UvpX0avfMa0Hdo1e+YnFEZluCr184uns= +alipay.merchant-private-key=MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCS8D3aAKvh+juT+5GEXkbKsHtoSK8odQ3htEH3XE+TP5PiXiOiv7pCnVDaIJ5gxfVBeQNC/D7E0zD7J+F1pRFtXA2MQ/ZMXd21hCjkXjIdBBo7iprPKD51AQIHJ8ocjKH0AnCcWAKPN03HvwCbPyYVXHcGO7XrIE2XFgTszsJYOw/dvruVxVF/OEXtVmgOJYIbHQnd+EfJ68BbMWbebzNBgy2YN/EBJldMMoaFcwtei7wCvUcNxWWqaus+n5u9+xFzPX/5495F3clu9yDydIdmvoRYEMdlzb0PbEzGg1KAaIHb8weNVd0bypOTkVK4Y/2tkPfAAv1hF4e6Uf2MAFw5AgMBAAECggEAc1/mAP4T+F0mWLzodrob9dz7GVgxCKBYpQeH4HWAGguKz+zBKHJJCzNBH/UKxsvJFn6xe/BaTOvTAvI+isRw2aC1FpTqmO3/Px6liSMZUEU/X88mXVCpMe/3qqyoeyBFrjYYO/qzD8cJ8LReAohkG9O9tYw+/H8hzWdBuLtkSCft1iHMUFT9M78lHgHIidUZHio+ga55yLEzx8iLibKXeRTFBAtrzknP0SWO25yHtPuPQhmAF8MGDzACm7fFOsccqBH11EmJGUlMAygT89bWXkWSGtPtbmprNe1lVsg0BlyZdgts5qHIrQYAEr/8o/MZI1d3dXv0UC4YTbA1ibaDsQKBgQDWui+5fJ/Xxc30XsSqGU9mgmM2Qf6PrriixTWfbe0Xdw090D+n4zjyfHOjZCEchFbv1FaDNpTt04IZ0bt2Fx6TwhHFxZnIWAMuLLt0ei4A/iCgTfkCrSwvhJ5uuAA5wFDTJIfyQ+JOpk79BVXm5uk2WuvXWTZXIcz2gA4E8PPnJQKBgQCvLnSQkmWCRv9TU8Mk9lXpWruQf8c3oVxvJ0CFDJK3+33PswiZTX+jcymAvK6kd1H0Mg8jJvH+uyeNPyF7aQW8NHasejqRNhyGyj1ZhRTuDIDGs2qIkZv1RAoDB12T0zATMeoJRbycQpOvi6FGI6KkOmjbgVzrrOPLdYh7wKxOhQKBgBg9MEH6BXkwBQ2+3Ohurv3dXiGz1W6WxJTrOiBjIk5xy/bcWTM0fSsyTUN2fB5h+gZcq99n++vU4mzTthughH0dfTAcHD33YXSG7Co72JGYHkq6Qo/AyKociF3rO2tJgFY1W3tHmnZSY7xAK/BCxLS0EsdedLnlQOPalLqOEJpZAoGAOFCq0D7/ut2v/s2SkjNOcvHkEhPBqzSIToNDzoG4OMT0MOzQ+tdbDORclzIQwnZJNkNRcm92o/juQg3laZLdcR88dz3jzgKjMQGar0iE7fG/BCFxQe3tQO9aeJbJklf1wHXvUoPEmkccyvYMJkwWYM0WIFp50JmHsURbV80clzECgYEAjJdoYgyJSKyuOSJQ8DSyAGGmUZdUILNDZl3KTYWAlPySmDqtqRb0nHpr/iOSlCuazEfOm3CnKaNqa7lx+Fyp3JYdYKa218crif4mjAnEoINcxTrCFVCe+bQqj2oYNi+rSptO6ingTUMv9HPjz0U2DhBRFI/pLPyQnOZx70hOCyQ= + +# 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥 +#alipay.alipay-public-key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvKoCpGtG31iY2Llj3t8MKRpaVCntnalWmXbKcHCiaYcUUjzcMPH3/tOr5ORK5W1NjuLu9uRrsXqROBmQYN+0y4nea+fU989i2IxtOGR/h2Kvhyyk/lPjNkmgz7K8VqbGGeVzTadPSK49FcrDVEshJ6C92vEKq6TmUfhKgCLiLZ288fHBDRvzUnoj8O/LBXiDroq1zX+DXYCHcQeFljkF5ivyxDZBkWl23hYTtnFClvN5lVLK4d294wyprF7IMv3XhQOfJS+Pr527CsfwT0JE44lyidCvslvn9DSdHdIfTIzHDsIEiDzB/OvRCbwpEA7UGnWQxQf7AusX2TTRQHWW7wIDAQAB +alipay.alipay-public-key=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhDXg0niJ+GSB4VRvPJqzgDhNCP68TRZRLSKLCr/cw6qy911UxRNS96f/ALE7TOLYEsqsolV1inrJ1PU3+BZY9LiKthzEJhdVNzEwXtQrZVknRt3rDtWM2PkKanlQt9LN1Kr28eZ1jJipbkyTLBZOR5RxQ6M6BW0hewrMq/aJLzugP6I7pFHy2iF9zmIm0upy3bUiO5kJwCCXAXfKTG4bLPzhMZCWmDipuscnvR/TN2Nka3WGAJVpiUuRo/poxWKlQpKl6K9rz5RypiAJSaW8zacNyBZ45xIoep3d48v/izOSq2NxLDs6oMUb/BwpJRgfex6dOrnqyIXy0+i9DwEDEwIDAQAB + +# 接口内容加密秘钥,对称秘钥 +#alipay.content-key=D8entyfafkkFwtMbUqj3Mw== +alipay.content-key=hKZgxtPGmOivCphtHM5gNg== + +# 页面跳转同步通知页面路径 +alipay.return-url=http://localhost:8080/#/success + +# 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问 +# 注意:每次重新启动ngrok,都需要根据实际情况修改这个配置 +#alipay.notify-url=https://77ea-221-239-177-21.ngrok.io/api/ali-pay/trade/notify +#alipay.notify-url=https://03a3-117-143-125-44.ngrok-free.app/api/ali-pay/trade/notify +alipay.notify-url=https://3b38-18-167-251-121.ngrok-free.app/api/ali-pay/trade/notify + + + + + diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index 4e41f8a4..7bd28386 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -20,7 +20,8 @@ spring.security.jwtTokenPrefix=Bearer- spring.security.jwtExpiration=8640000000 #spring security权限设置 认证了token还要认证权限 不然报错Full authentication is required to access this resource spring.security.ignorePaths=/,/favicon.ico,/doc.html,/webjars/**,/swagger-resources,/v2/api-docs,\ - /api/account/**,/api/element/**,/api/python/**,/api/design/**,/api/history/**,/api/library/**,/api/third/party/**,/api/generate/**,/api/workspace/**,/api/classification/** + /api/account/**,/api/element/**,/api/python/**,/api/design/**,/api/history/**,/api/library/**,/api/third/party/**,/api/generate/**,/api/workspace/**,/api/classification/**,\ + /api/product/**,/api/ali-pay/**,/api/order-info/** spring.security.authApi=/auth/login diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties index e4df2d00..6a2b9d4d 100644 --- a/src/main/resources/application-prod.properties +++ b/src/main/resources/application-prod.properties @@ -1,10 +1,11 @@ -server.port=5566 +server.port=5567 #datasource spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://18.167.251.121:3306/aida?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true spring.datasource.username=root spring.datasource.password=QWa998345 +#spring.datasource.password=QWa998345 #security spring.security.jwtSecret=JWTSECRET diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index f00b793a..974fee23 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -2,7 +2,7 @@ #spring.profiles.active=test #����application-prod�ļ�(��������) -spring.profiles.active=dev +#spring.profiles.active=prod #����application-dev�ļ�(��������) -#spring.profiles.active=dev +spring.profiles.active=dev diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties index 3fa4295a..ca17378d 100644 --- a/src/main/resources/messages_en.properties +++ b/src/main/resources/messages_en.properties @@ -152,6 +152,8 @@ classificationName.already.exists=The label name you've entered already exists. # 用来提醒用户可能会导致不良后果的操作,但不一定是错误。用户需要认真考虑是否继续当前操作。 the.classification.you.deleted.has.associated.library=The label you are attempting to delete is associated with existing data. Are you sure you wish to proceed with deletion? the.model.has.been.referenced.by.the.workspace=This model is currently in use by a workspace. Deleting it might affect the workspace. Confirm deletion only if you are sure. +balance.insufficient.for.trial=Want to continue using it immediately? Please consider upgrading to our subscription plan to get more quota. +balance.insufficient.for.paying=You have reached your usage limit for this month. # Errors: # 这类错误是由系统内部错误引起的,用户通常无法自行解决,需要联系支持或等待系统管理员介入。 diff --git a/src/main/resources/messages_zh.properties b/src/main/resources/messages_zh.properties index 6f330d93..8fecb5f9 100644 --- a/src/main/resources/messages_zh.properties +++ b/src/main/resources/messages_zh.properties @@ -150,6 +150,8 @@ classificationName.already.exists=您输入的标签名已存在。请输入不 # 用来提醒用户可能会导致不良后果的操作,但不一定是错误。用户需要认真考虑是否继续当前操作。 the.classification.you.deleted.has.associated.library=您正在尝试删除的标签与现有数据相关联。您确定要继续删除吗? the.model.has.been.referenced.by.the.workspace=此模型当前正在工作区中使用。删除它可能会影响工作区。仅在确信后再确认删除。 +balance.insufficient.for.trial=想要立即继续使用?请考虑升级到我们的订阅计划,以获得更多额度。 +balance.insufficient.for.paying=您已达到本月的使用额度限制。 # Errors: # 这类错误是由系统内部错误引起的,用户通常无法自行解决,需要联系支持或等待系统管理员介入。