Merge branch 'dev/dev_xp' into dev/dev
# Conflicts: # src/main/java/com/ai/da/model/vo/AccountLoginVO.java # src/main/java/com/ai/da/service/impl/AccountServiceImpl.java
This commit is contained in:
@@ -75,5 +75,9 @@ public class CommonConstant {
|
|||||||
|
|
||||||
public static final String PORTFOLIO_DELETED_CN = "作品已删除";
|
public static final String PORTFOLIO_DELETED_CN = "作品已删除";
|
||||||
|
|
||||||
|
public static final String TIME_FORMAT_MMM_dd_yyyy_EEEE = "MMM. dd, yyyy, EEEE";
|
||||||
|
|
||||||
|
public static final String TIME_FORMAT_MMM_dd_yyyy = "MMM. dd, yyyy";
|
||||||
|
|
||||||
|
public static final String AFFILIATE_LINK = "https://www.aida.com.hk?ref=";
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,38 +10,34 @@ public enum OrderStatusEnum {
|
|||||||
* 未支付
|
* 未支付
|
||||||
*/
|
*/
|
||||||
NOT_PAY("未支付"),
|
NOT_PAY("未支付"),
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 支付成功
|
* 支付成功
|
||||||
*/
|
*/
|
||||||
SUCCESS("支付成功"),
|
SUCCESS("支付成功"),
|
||||||
|
/**
|
||||||
|
* 支付失败
|
||||||
|
*/
|
||||||
|
FAILURE("支付失败"),
|
||||||
/**
|
/**
|
||||||
* 已关闭
|
* 已关闭
|
||||||
*/
|
*/
|
||||||
TIMEOUT_CLOSED("超时已关闭"),
|
TIMEOUT_CLOSED("超时已关闭"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 已取消
|
* 已取消
|
||||||
*/
|
*/
|
||||||
CANCEL("用户已取消"),
|
CANCEL("用户已取消"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 退款中
|
* 退款中
|
||||||
*/
|
*/
|
||||||
REFUND_PROCESSING("退款中"),
|
REFUND_PROCESSING("退款中"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 已退款
|
* 已退款
|
||||||
*/
|
*/
|
||||||
REFUND_SUCCESS("已退款"),
|
REFUND_SUCCESS("已退款"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 退款异常
|
* 退款异常
|
||||||
*/
|
*/
|
||||||
REFUND_ABNORMAL("退款异常"),
|
REFUND_ABNORMAL("退款异常"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* paypal订单状态为 APPROVED
|
* paypal订单状态为 APPROVED
|
||||||
*/
|
*/
|
||||||
|
|||||||
25
src/main/java/com/ai/da/common/enums/ProductEnum.java
Normal file
25
src/main/java/com/ai/da/common/enums/ProductEnum.java
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package com.ai.da.common.enums;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@AllArgsConstructor
|
||||||
|
public enum ProductEnum {
|
||||||
|
// 积分购买
|
||||||
|
CreditsProduct("AiDA credits purchase", 6L),
|
||||||
|
// 年度订阅
|
||||||
|
AnnualSubscription("AiDA Annual Subscription", 5000L),
|
||||||
|
// 月度订阅
|
||||||
|
MonthlySubscription("AiDA Monthly Subscription", 500L),
|
||||||
|
// 测试
|
||||||
|
DailySubscription("AiDA Daily Subscription", 5L),
|
||||||
|
;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型
|
||||||
|
*/
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
private final Long price;
|
||||||
|
}
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
package com.ai.da.common.task;
|
|
||||||
|
|
||||||
import com.ai.da.mapper.primary.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("Alipay orderConfirm 被执行......");
|
|
||||||
|
|
||||||
List<OrderInfo> orderInfoList = orderInfoService.getNoPayOrderByDuration(5, PayTypeEnum.ALIPAY.getType());
|
|
||||||
|
|
||||||
for (OrderInfo orderInfo : orderInfoList) {
|
|
||||||
String orderNo = orderInfo.getOrderNo();
|
|
||||||
log.warn("超时订单 ===> {}", orderNo);
|
|
||||||
|
|
||||||
//核实订单状态:调用支付宝查单接口
|
|
||||||
aliPayService.checkOrderStatus(orderNo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
package com.ai.da.common.task;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
@Slf4j
|
|
||||||
public class GenerateTask {
|
|
||||||
|
|
||||||
// @Scheduled(cron = "0 0 */1 * * ?")
|
|
||||||
public void generateScheduled(){
|
|
||||||
log.info("测试定时器:generate");
|
|
||||||
|
|
||||||
try{
|
|
||||||
|
|
||||||
}catch(Exception e){
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
121
src/main/java/com/ai/da/common/task/PaymentTask.java
Normal file
121
src/main/java/com/ai/da/common/task/PaymentTask.java
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
package com.ai.da.common.task;
|
||||||
|
|
||||||
|
import com.ai.da.common.enums.PayTypeEnum;
|
||||||
|
import com.ai.da.mapper.primary.entity.OrderInfo;
|
||||||
|
import com.ai.da.service.*;
|
||||||
|
import com.paypal.http.exceptions.SerializeException;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@Component
|
||||||
|
public class PaymentTask {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private OrderInfoService orderInfoService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private StripeService stripeService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private AffiliateService affiliateService;
|
||||||
|
|
||||||
|
// 考虑删除该定时任务(原因:之后的订单列允许用户查看发票,发票未过期时仍可以支付,所以不需要手动使订单过期)
|
||||||
|
// @Scheduled(cron = "0/30 * * * * ?")
|
||||||
|
public void orderConfirmForStripe() throws SerializeException {
|
||||||
|
|
||||||
|
// 查看超过30分钟以上仍未支付的订单 置为超时订单
|
||||||
|
List<OrderInfo> orderInfoList = orderInfoService.getNoPayOrderByDuration(30, PayTypeEnum.STRIPE.getType());
|
||||||
|
|
||||||
|
for (OrderInfo orderInfo : orderInfoList) {
|
||||||
|
String orderNo = orderInfo.getOrderNo();
|
||||||
|
log.warn("超时订单 ===> {}", orderNo);
|
||||||
|
|
||||||
|
//核实订单状态:调用支付宝查单接口
|
||||||
|
stripeService.checkOrderStatus(orderNo);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private PayPalCheckoutService payPalCheckoutService;
|
||||||
|
|
||||||
|
// @Scheduled(cron = "0/30 * * * * ?")
|
||||||
|
public void orderConfirmForPaypal() throws SerializeException {
|
||||||
|
|
||||||
|
// log.info("PayPal orderConfirm 被执行......");
|
||||||
|
|
||||||
|
List<OrderInfo> orderInfoList = orderInfoService.getNoPayOrderByDuration(30, PayTypeEnum.PAYPAL.getType());
|
||||||
|
|
||||||
|
for (OrderInfo orderInfo : orderInfoList) {
|
||||||
|
String orderNo = orderInfo.getOrderNo();
|
||||||
|
log.warn("超时订单 ===> {}", orderNo);
|
||||||
|
|
||||||
|
//核实订单状态:调用支付宝查单接口
|
||||||
|
payPalCheckoutService.checkOrderStatus(orderNo);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private AliPayService aliPayService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 从第0秒开始每隔30秒执行1次,查询创建超过5分钟,并且未支付的订单
|
||||||
|
*/
|
||||||
|
// @Scheduled(cron = "0/30 * * * * ?")
|
||||||
|
public void orderConfirmForAlipay(){
|
||||||
|
/*
|
||||||
|
log.info("Alipay orderConfirm 被执行......");
|
||||||
|
|
||||||
|
List<OrderInfo> orderInfoList = orderInfoService.getNoPayOrderByDuration(5, PayTypeEnum.ALIPAY.getType());
|
||||||
|
|
||||||
|
for (OrderInfo orderInfo : orderInfoList) {
|
||||||
|
String orderNo = orderInfo.getOrderNo();
|
||||||
|
log.warn("超时订单 ===> {}", orderNo);
|
||||||
|
|
||||||
|
//核实订单状态:调用支付宝查单接口
|
||||||
|
aliPayService.checkOrderStatus(orderNo);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提前7天向用户发送提醒邮件,每天早上8点执行
|
||||||
|
@Scheduled(cron = "0 0 8 * * ?")
|
||||||
|
public void subscriptionReminder(){
|
||||||
|
stripeService.subscriptionReminder();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 每天凌晨检查subscription中有哪些已过期,更新状态
|
||||||
|
// @Scheduled(cron = "0 0 0 * * ?")
|
||||||
|
// public void checkSubscriptionExpiration(){
|
||||||
|
// stripeService.checkSubscriptionExpiration();
|
||||||
|
// }
|
||||||
|
|
||||||
|
// 如果有订阅已创建,但是没有发邮件通知的,需要主动获取回调信息并向用户发送邮件
|
||||||
|
public void checkSubscriptionPayment(){
|
||||||
|
//
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes
|
||||||
|
public void updateAffiliateInfoWithPayment(){
|
||||||
|
affiliateService.updateAffiliateInfoWithPayment();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Scheduled(cron = "0 0 8 28-31 * ?")
|
||||||
|
public void commissionSummaryReminder(){
|
||||||
|
// 每个月末的最后一天的早上八点执行
|
||||||
|
LocalDate today = LocalDate.now();
|
||||||
|
// 判断是否为月底
|
||||||
|
if (today.plusDays(1).getDayOfMonth() == 1) {
|
||||||
|
log.info("今天是月底,执行佣金结算提醒任务!");
|
||||||
|
affiliateService.commissionCalculation(null, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
package com.ai.da.common.task;
|
|
||||||
|
|
||||||
import com.ai.da.common.enums.PayTypeEnum;
|
|
||||||
import com.ai.da.mapper.primary.entity.OrderInfo;
|
|
||||||
import com.ai.da.service.OrderInfoService;
|
|
||||||
import com.ai.da.service.PayPalCheckoutService;
|
|
||||||
import com.paypal.http.exceptions.SerializeException;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.scheduling.annotation.Scheduled;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
import org.springframework.stereotype.Service;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Slf4j
|
|
||||||
@Component
|
|
||||||
public class PaypalTask {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private OrderInfoService orderInfoService;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private PayPalCheckoutService payPalCheckoutService;
|
|
||||||
|
|
||||||
// @Scheduled(cron = "0/30 * * * * ?")
|
|
||||||
public void orderConfirm() throws SerializeException {
|
|
||||||
|
|
||||||
// log.info("PayPal orderConfirm 被执行......");
|
|
||||||
|
|
||||||
List<OrderInfo> orderInfoList = orderInfoService.getNoPayOrderByDuration(30, PayTypeEnum.PAYPAL.getType());
|
|
||||||
|
|
||||||
for (OrderInfo orderInfo : orderInfoList) {
|
|
||||||
String orderNo = orderInfo.getOrderNo();
|
|
||||||
log.warn("超时订单 ===> {}", orderNo);
|
|
||||||
|
|
||||||
//核实订单状态:调用支付宝查单接口
|
|
||||||
payPalCheckoutService.checkOrderStatus(orderNo);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
package com.ai.da.common.task;
|
|
||||||
|
|
||||||
import com.ai.da.common.enums.PayTypeEnum;
|
|
||||||
import com.ai.da.mapper.primary.entity.OrderInfo;
|
|
||||||
import com.ai.da.service.OrderInfoService;
|
|
||||||
import com.ai.da.service.StripeService;
|
|
||||||
import com.paypal.http.exceptions.SerializeException;
|
|
||||||
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 StripeTask {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private OrderInfoService orderInfoService;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private StripeService stripeService;
|
|
||||||
|
|
||||||
// @Scheduled(cron = "0/30 * * * * ?")
|
|
||||||
public void orderConfirm() throws SerializeException {
|
|
||||||
|
|
||||||
// 查看超过30分钟以上仍未支付的订单 置为超时订单
|
|
||||||
List<OrderInfo> orderInfoList = orderInfoService.getNoPayOrderByDuration(30, PayTypeEnum.STRIPE.getType());
|
|
||||||
|
|
||||||
for (OrderInfo orderInfo : orderInfoList) {
|
|
||||||
String orderNo = orderInfo.getOrderNo();
|
|
||||||
log.warn("超时订单 ===> {}", orderNo);
|
|
||||||
|
|
||||||
//核实订单状态:调用支付宝查单接口
|
|
||||||
stripeService.checkOrderStatus(orderNo);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,8 +9,8 @@ import java.time.LocalDate;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.time.ZoneId;
|
import java.time.ZoneId;
|
||||||
import java.time.format.DateTimeFormatter;
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.TimeZone;
|
import java.util.TimeZone;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@@ -81,4 +81,21 @@ public class DateUtil {
|
|||||||
return String.valueOf(epochSecond).substring(0, 10);
|
return String.valueOf(epochSecond).substring(0, 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String changeTimeStampFormat(Long timeStamp, String type, String format){
|
||||||
|
// 将秒级时间戳转换为毫秒级
|
||||||
|
if (type.equals("seconds")){
|
||||||
|
timeStamp = timeStamp * 1000;
|
||||||
|
}
|
||||||
|
// 输出格式
|
||||||
|
SimpleDateFormat outputFormat = new SimpleDateFormat(format, Locale.ENGLISH);
|
||||||
|
// 创建Date对象
|
||||||
|
Date date = new Date(timeStamp);
|
||||||
|
// 格式化输出
|
||||||
|
return outputFormat.format(date);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String changeTimeStampFormat(LocalDateTime localDate){
|
||||||
|
return localDate.format(DateTimeFormatter.ofPattern("MMM. dd, yyyy, EEEE", Locale.US));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -278,4 +278,18 @@ public class RedisUtil {
|
|||||||
// 设置过期时间为 5 分钟(300 秒)
|
// 设置过期时间为 5 分钟(300 秒)
|
||||||
redisTemplate.expire(redisKey, 5, TimeUnit.MINUTES);
|
redisTemplate.expire(redisKey, 5, TimeUnit.MINUTES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final static String PAYMENT_INFO_LAST_SCAN_TIME = "PaymentInfoLastScanTime";
|
||||||
|
|
||||||
|
public final static String AFFILIATE_LINK_VIEW_KEY = "AffiliateLink:view:";
|
||||||
|
|
||||||
|
public void increaseAffiliateLinkViewCount(Long accountId) {
|
||||||
|
String key = AFFILIATE_LINK_VIEW_KEY + accountId;
|
||||||
|
redisTemplate.opsForValue().increment(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getAffiliateLinkViewCount(Long accountId) {
|
||||||
|
String key = AFFILIATE_LINK_VIEW_KEY + accountId;
|
||||||
|
return redisTemplate.opsForValue().increment(key, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,11 @@ package com.ai.da.common.utils;
|
|||||||
|
|
||||||
import com.ai.da.mapper.primary.entity.Account;
|
import com.ai.da.mapper.primary.entity.Account;
|
||||||
import com.ai.da.mapper.primary.entity.TrialOrder;
|
import com.ai.da.mapper.primary.entity.TrialOrder;
|
||||||
|
import com.ai.da.model.dto.AffiliateEmailParamsDTO;
|
||||||
|
import com.ai.da.model.dto.SubscriptionEmailParamsDTO;
|
||||||
import com.alibaba.fastjson.JSONObject;
|
import com.alibaba.fastjson.JSONObject;
|
||||||
import com.ai.da.common.config.exception.BusinessException;
|
import com.ai.da.common.config.exception.BusinessException;
|
||||||
|
import com.alibaba.fastjson2.JSON;
|
||||||
import com.tencentcloudapi.common.Credential;
|
import com.tencentcloudapi.common.Credential;
|
||||||
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
||||||
import com.tencentcloudapi.common.profile.ClientProfile;
|
import com.tencentcloudapi.common.profile.ClientProfile;
|
||||||
@@ -175,7 +178,7 @@ public class SendEmailUtil {
|
|||||||
subject = "Approval Confirmation for AiDA System Trial Access";
|
subject = "Approval Confirmation for AiDA System Trial Access";
|
||||||
if (country.equals("China")) {
|
if (country.equals("China")) {
|
||||||
template.setTemplateID(NOTIFICATION_CHINESE_TEMPLATE_ID);
|
template.setTemplateID(NOTIFICATION_CHINESE_TEMPLATE_ID);
|
||||||
}else {
|
} else {
|
||||||
template.setTemplateID(NOTIFICATION_TEMPLATE_ID);
|
template.setTemplateID(NOTIFICATION_TEMPLATE_ID);
|
||||||
}
|
}
|
||||||
template.setTemplateData(buildNotificationData(trialOrder, link));
|
template.setTemplateData(buildNotificationData(trialOrder, link));
|
||||||
@@ -225,7 +228,7 @@ public class SendEmailUtil {
|
|||||||
attachment.setFileName(fileName); // 设置附件文件名
|
attachment.setFileName(fileName); // 设置附件文件名
|
||||||
// 设置附件内容
|
// 设置附件内容
|
||||||
attachment.setContent(Base64.getEncoder().encodeToString(fileContent));
|
attachment.setContent(Base64.getEncoder().encodeToString(fileContent));
|
||||||
req.setAttachments(new Attachment[] {attachment});
|
req.setAttachments(new Attachment[]{attachment});
|
||||||
// 发送邮件
|
// 发送邮件
|
||||||
SendEmailResponse resp = client.SendEmail(req);
|
SendEmailResponse resp = client.SendEmail(req);
|
||||||
log.info("短信发送结果res###{}", SendEmailResponse.toJsonString(resp));
|
log.info("短信发送结果res###{}", SendEmailResponse.toJsonString(resp));
|
||||||
@@ -268,7 +271,9 @@ public class SendEmailUtil {
|
|||||||
throw new BusinessException("failed.to.send.mail");
|
throw new BusinessException("failed.to.send.mail");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private final static Long WILLBEEXPIRED_TEMPLATE_ID = 118178L;
|
private final static Long WILLBEEXPIRED_TEMPLATE_ID = 118178L;
|
||||||
|
|
||||||
public static void sendWillBeExpiredEmail(Account account, String senderAddress) {
|
public static void sendWillBeExpiredEmail(Account account, String senderAddress) {
|
||||||
try {
|
try {
|
||||||
// 实例化一个认证对象
|
// 实例化一个认证对象
|
||||||
@@ -360,7 +365,7 @@ public class SendEmailUtil {
|
|||||||
jsonObject.put("email", trialOrder.getEmail());
|
jsonObject.put("email", trialOrder.getEmail());
|
||||||
if (link) {
|
if (link) {
|
||||||
jsonObject.put("days", 14);
|
jsonObject.put("days", 14);
|
||||||
}else {
|
} else {
|
||||||
jsonObject.put("days", 5);
|
jsonObject.put("days", 5);
|
||||||
}
|
}
|
||||||
return jsonObject.toJSONString();
|
return jsonObject.toJSONString();
|
||||||
@@ -370,6 +375,7 @@ public class SendEmailUtil {
|
|||||||
private final static Long UPGRADE_SUCCESS_NOTIFICATION_ID = 118856L;
|
private final static Long UPGRADE_SUCCESS_NOTIFICATION_ID = 118856L;
|
||||||
private final static Long UPGRADE_NOTIFICATION_ID_CHINESE = 122898L;
|
private final static Long UPGRADE_NOTIFICATION_ID_CHINESE = 122898L;
|
||||||
private final static Long UPGRADE_SUCCESS_NOTIFICATION_ID_CHINESE = 122899L;
|
private final static Long UPGRADE_SUCCESS_NOTIFICATION_ID_CHINESE = 122899L;
|
||||||
|
|
||||||
public static void sendUpgradeNotification(Account account, String senderAddress, Integer type) {
|
public static void sendUpgradeNotification(Account account, String senderAddress, Integer type) {
|
||||||
try {
|
try {
|
||||||
// 实例化一个认证对象
|
// 实例化一个认证对象
|
||||||
@@ -418,7 +424,8 @@ public class SendEmailUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private final static Long GENERATE_EXCEPTION_WARNING_ID = 122589L;
|
private final static Long GENERATE_EXCEPTION_WARNING_ID = 122589L;
|
||||||
public static void sendGenerateExceptionWarning(String message){
|
|
||||||
|
public static void sendGenerateExceptionWarning(String message) {
|
||||||
try {
|
try {
|
||||||
// 实例化一个认证对象
|
// 实例化一个认证对象
|
||||||
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
|
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
|
||||||
@@ -457,7 +464,8 @@ public class SendEmailUtil {
|
|||||||
|
|
||||||
private final static Long QUESTIONNAIRE_FEEDBACK_EN_ID = 124151L;
|
private final static Long QUESTIONNAIRE_FEEDBACK_EN_ID = 124151L;
|
||||||
private final static Long QUESTIONNAIRE_FEEDBACK_CN_ID = 124156L;
|
private final static Long QUESTIONNAIRE_FEEDBACK_CN_ID = 124156L;
|
||||||
public static void questionnaireRelatedNotify(String userName, String email, String language){
|
|
||||||
|
public static void questionnaireRelatedNotify(String userName, String email, String language) {
|
||||||
try {
|
try {
|
||||||
// 实例化一个认证对象
|
// 实例化一个认证对象
|
||||||
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
|
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
|
||||||
@@ -502,7 +510,7 @@ public class SendEmailUtil {
|
|||||||
private final static Long RENEWAL_NOTIFICATION_FOR_OLD_USER_EN = 124892L;
|
private final static Long RENEWAL_NOTIFICATION_FOR_OLD_USER_EN = 124892L;
|
||||||
private final static Long RENEWAL_NOTIFICATION_FOR_OLD_USER_CN = 124891L;
|
private final static Long RENEWAL_NOTIFICATION_FOR_OLD_USER_CN = 124891L;
|
||||||
|
|
||||||
public static void notificationForPaidUser(String receiverAddress, int emailType, String country, String userName, String date){
|
public static void notificationForPaidUser(String receiverAddress, int emailType, String country, String userName, String date) {
|
||||||
try {
|
try {
|
||||||
// 实例化一个认证对象
|
// 实例化一个认证对象
|
||||||
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
|
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
|
||||||
@@ -525,7 +533,7 @@ public class SendEmailUtil {
|
|||||||
subject = "Welcome to AiDA!";
|
subject = "Welcome to AiDA!";
|
||||||
if (country.equals("China")) {
|
if (country.equals("China")) {
|
||||||
template.setTemplateID(NEW_USER_PAYMENT_NOTIFICATION_CN);
|
template.setTemplateID(NEW_USER_PAYMENT_NOTIFICATION_CN);
|
||||||
}else {
|
} else {
|
||||||
template.setTemplateID(NEW_USER_PAYMENT_NOTIFICATION_EN);
|
template.setTemplateID(NEW_USER_PAYMENT_NOTIFICATION_EN);
|
||||||
}
|
}
|
||||||
parameter.put("userName", userName);
|
parameter.put("userName", userName);
|
||||||
@@ -536,7 +544,7 @@ public class SendEmailUtil {
|
|||||||
subject = "Account renewal notification";
|
subject = "Account renewal notification";
|
||||||
if (country.equals("China")) {
|
if (country.equals("China")) {
|
||||||
template.setTemplateID(RENEWAL_NOTIFICATION_FOR_OLD_USER_CN);
|
template.setTemplateID(RENEWAL_NOTIFICATION_FOR_OLD_USER_CN);
|
||||||
}else {
|
} else {
|
||||||
template.setTemplateID(RENEWAL_NOTIFICATION_FOR_OLD_USER_EN);
|
template.setTemplateID(RENEWAL_NOTIFICATION_FOR_OLD_USER_EN);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -597,8 +605,8 @@ public class SendEmailUtil {
|
|||||||
|
|
||||||
private final static Long NEW_USER_REGISTER_NOTIFICATION_EN = 126919L;
|
private final static Long NEW_USER_REGISTER_NOTIFICATION_EN = 126919L;
|
||||||
|
|
||||||
public static void notificationForRegisterUser(String receiverAddress){
|
public static void notificationForRegisterUser(String receiverAddress) {
|
||||||
try{
|
try {
|
||||||
// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
|
// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
|
||||||
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
|
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
|
||||||
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
|
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
|
||||||
@@ -634,8 +642,8 @@ public class SendEmailUtil {
|
|||||||
private final static Long CHANGE_MAILBOX_CONFIRM_CN = 128278L;
|
private final static Long CHANGE_MAILBOX_CONFIRM_CN = 128278L;
|
||||||
private final static Long CHANGE_MAILBOX_CONFIRM_EN = 128277L;
|
private final static Long CHANGE_MAILBOX_CONFIRM_EN = 128277L;
|
||||||
|
|
||||||
public static void changeMailboxConfirm(String receiverAddress, String language, String name, String link){
|
public static void changeMailboxConfirm(String receiverAddress, String language, String name, String link) {
|
||||||
try{
|
try {
|
||||||
// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
|
// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
|
||||||
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
|
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
|
||||||
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
|
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
|
||||||
@@ -653,10 +661,10 @@ public class SendEmailUtil {
|
|||||||
req.setFromEmailAddress(SEND_ADDRESS);
|
req.setFromEmailAddress(SEND_ADDRESS);
|
||||||
req.setDestination(new String[]{receiverAddress});
|
req.setDestination(new String[]{receiverAddress});
|
||||||
Template template = new Template();
|
Template template = new Template();
|
||||||
if (language.equals("ENGLISH")){
|
if (language.equals("ENGLISH")) {
|
||||||
req.setSubject("Change the email address bound to the AiDA account");
|
req.setSubject("Change the email address bound to the AiDA account");
|
||||||
template.setTemplateID(CHANGE_MAILBOX_CONFIRM_EN);
|
template.setTemplateID(CHANGE_MAILBOX_CONFIRM_EN);
|
||||||
}else {
|
} else {
|
||||||
req.setSubject("更换AiDA账号绑定的邮箱地址");
|
req.setSubject("更换AiDA账号绑定的邮箱地址");
|
||||||
template.setTemplateID(CHANGE_MAILBOX_CONFIRM_CN);
|
template.setTemplateID(CHANGE_MAILBOX_CONFIRM_CN);
|
||||||
}
|
}
|
||||||
@@ -678,12 +686,12 @@ public class SendEmailUtil {
|
|||||||
|
|
||||||
private final static Long UPLOAD_TIMEOUT_REMINDER = 128324L;
|
private final static Long UPLOAD_TIMEOUT_REMINDER = 128324L;
|
||||||
|
|
||||||
public static void uploadTimeoutReminder(String userName, String time){
|
public static void uploadTimeoutReminder(String userName, String time) {
|
||||||
String xp = "xupei3360@163.com";
|
String xp = "xupei3360@163.com";
|
||||||
String shb = "shahaibodd99@gmail.com";
|
String shb = "shahaibodd99@gmail.com";
|
||||||
String wxd = "X1627315083@163.com";
|
String wxd = "X1627315083@163.com";
|
||||||
String pkc = "kaicpang.pang@connect.polyu.hk";
|
String pkc = "kaicpang.pang@connect.polyu.hk";
|
||||||
try{
|
try {
|
||||||
// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
|
// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
|
||||||
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
|
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
|
||||||
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
|
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
|
||||||
@@ -721,6 +729,7 @@ public class SendEmailUtil {
|
|||||||
|
|
||||||
private final static Long HALFPRICEPROMOTION_CN_ID = 128582L;
|
private final static Long HALFPRICEPROMOTION_CN_ID = 128582L;
|
||||||
private final static Long HALFPRICEPROMOTION_EN_ID = 128583L;
|
private final static Long HALFPRICEPROMOTION_EN_ID = 128583L;
|
||||||
|
|
||||||
public static void halfPricePromotion(Account account, String senderAddress, int type) {
|
public static void halfPricePromotion(Account account, String senderAddress, int type) {
|
||||||
try {
|
try {
|
||||||
// 实例化一个认证对象
|
// 实例化一个认证对象
|
||||||
@@ -750,7 +759,7 @@ public class SendEmailUtil {
|
|||||||
if (type == 1) {
|
if (type == 1) {
|
||||||
subject = "AiDA workshop - Win a trip to Hong Kong!";
|
subject = "AiDA workshop - Win a trip to Hong Kong!";
|
||||||
template.setTemplateID(HALFPRICEPROMOTION_EN_ID);
|
template.setTemplateID(HALFPRICEPROMOTION_EN_ID);
|
||||||
}else {
|
} else {
|
||||||
subject = "AiDA workshop - 赢取香港之旅";
|
subject = "AiDA workshop - 赢取香港之旅";
|
||||||
template.setTemplateID(HALFPRICEPROMOTION_CN_ID);
|
template.setTemplateID(HALFPRICEPROMOTION_CN_ID);
|
||||||
}
|
}
|
||||||
@@ -808,4 +817,171 @@ public class SendEmailUtil {
|
|||||||
throw new BusinessException("failed.to.send.mail");
|
throw new BusinessException("failed.to.send.mail");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private final static Long CANCEL_MERCHANT_EN = 130720L;
|
||||||
|
private final static Long NEW_MERCHANT_EN = 130721L;
|
||||||
|
private final static Long NEW_USER_EN = 130722L;
|
||||||
|
private final static Long NEW_USER_CN = 130723L;
|
||||||
|
private final static Long RENEWAL_MERCHANT_EN = 130724L;
|
||||||
|
private final static Long RENEWAL_USER_EN = 130725L;
|
||||||
|
private final static Long RENEWAL_USER_CN = 130726L;
|
||||||
|
private final static Long RENEWAL_REMINDER_USER_EN = 130727L;
|
||||||
|
private final static Long RENEWAL_REMINDER_USER_CN = 130728L;
|
||||||
|
private final static Long PAYMENT_FAILED_NEW_MERCHANT_EN = 131230L;
|
||||||
|
private final static Long PAYMENT_FAILED_RENEWAL_MERCHANT_EN = 131225L;
|
||||||
|
private final static Long PAYMENT_FAILED_RENEWAL_USER_EN = 131563L;
|
||||||
|
private final static Long PAYMENT_FAILED_RENEWAL_USER_CN = 131564L;
|
||||||
|
|
||||||
|
public static void subscriptionEmailReminder(String type, SubscriptionEmailParamsDTO subscriptionEmailParamsDTO, String language, String receiverAddress) {
|
||||||
|
try {
|
||||||
|
// String merchantEmail = "kimwong@code-create.com.hk";
|
||||||
|
String merchantEmail = "xupei3360@163.com";
|
||||||
|
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
|
||||||
|
// 实例化一个http选项,可选的,没有特殊需求可以跳过
|
||||||
|
HttpProfile httpProfile = new HttpProfile();
|
||||||
|
httpProfile.setEndpoint("ses.tencentcloudapi.com");
|
||||||
|
// 实例化一个client选项,可选的,没有特殊需求可以跳过
|
||||||
|
ClientProfile clientProfile = new ClientProfile();
|
||||||
|
clientProfile.setHttpProfile(httpProfile);
|
||||||
|
// 实例化要请求产品的client对象,clientProfile是可选的
|
||||||
|
SesClient client = new SesClient(cred, "ap-hongkong", clientProfile);
|
||||||
|
// 实例化一个请求对象,每个接口都会对应一个request对象
|
||||||
|
SendEmailRequest user = new SendEmailRequest();
|
||||||
|
user.setFromEmailAddress(SEND_ADDRESS);
|
||||||
|
user.setDestination(new String[]{receiverAddress});
|
||||||
|
SendEmailRequest merchant = new SendEmailRequest();
|
||||||
|
merchant.setFromEmailAddress(SEND_ADDRESS);
|
||||||
|
merchant.setDestination(new String[]{merchantEmail});
|
||||||
|
Template templateUser = new Template();
|
||||||
|
Template templateMerchant = new Template();
|
||||||
|
switch (type) {
|
||||||
|
case "cancel":
|
||||||
|
merchant.setSubject("[Code-Create] Subscription Cancelled");
|
||||||
|
templateMerchant.setTemplateID(CANCEL_MERCHANT_EN);
|
||||||
|
break;
|
||||||
|
case "fail_new":
|
||||||
|
merchant.setSubject("[Code-Create] Payment Failed : New Order (" + subscriptionEmailParamsDTO.getOrderId() + ")");
|
||||||
|
templateMerchant.setTemplateID(PAYMENT_FAILED_NEW_MERCHANT_EN);
|
||||||
|
break;
|
||||||
|
case "fail_renewal":
|
||||||
|
merchant.setSubject("[Code-Create] Payment Failed : Renewal Order (" + subscriptionEmailParamsDTO.getOrderId() + ")");
|
||||||
|
templateMerchant.setTemplateID(PAYMENT_FAILED_RENEWAL_MERCHANT_EN);
|
||||||
|
// todo to user
|
||||||
|
if (language.equals("ENGLISH")) {
|
||||||
|
user.setSubject("[Code-Create] Payment Failed : Renewal Order (" + subscriptionEmailParamsDTO.getOrderId() + ")");
|
||||||
|
templateUser.setTemplateID(PAYMENT_FAILED_RENEWAL_USER_EN);
|
||||||
|
} else {
|
||||||
|
user.setSubject("[Code-Create] 自动续费失败 (" + subscriptionEmailParamsDTO.getOrderId() + ")");
|
||||||
|
templateUser.setTemplateID(PAYMENT_FAILED_RENEWAL_USER_CN);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "new":
|
||||||
|
merchant.setSubject("[Code-Create] New Order(" + subscriptionEmailParamsDTO.getOrderId() + ")");
|
||||||
|
templateMerchant.setTemplateID(NEW_MERCHANT_EN);
|
||||||
|
if (language.equals("ENGLISH")) {
|
||||||
|
user.setSubject("[Code-Create] You have successfully subscribed to AiDA");
|
||||||
|
templateUser.setTemplateID(NEW_USER_EN);
|
||||||
|
} else {
|
||||||
|
user.setSubject("[Code-Create] 您已成功订阅AiDA");
|
||||||
|
templateUser.setTemplateID(NEW_USER_CN);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "renewal":
|
||||||
|
merchant.setSubject("[Code-Create] New subscription renewal order (" + subscriptionEmailParamsDTO.getOrderId() + ")");
|
||||||
|
templateMerchant.setTemplateID(RENEWAL_MERCHANT_EN);
|
||||||
|
if (language.equals("ENGLISH")) {
|
||||||
|
user.setSubject("[Code-Create] AiDA Renewal Successful");
|
||||||
|
templateUser.setTemplateID(RENEWAL_USER_EN);
|
||||||
|
} else {
|
||||||
|
user.setSubject("[Code-Create] AiDA续订成功");
|
||||||
|
templateUser.setTemplateID(RENEWAL_USER_CN);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case "reminder":
|
||||||
|
if (language.equals("ENGLISH")) {
|
||||||
|
user.setSubject("[Code-Create] AiDA Subscription Renewal Reminder");
|
||||||
|
templateUser.setTemplateID(RENEWAL_REMINDER_USER_EN);
|
||||||
|
} else {
|
||||||
|
user.setSubject("[Code-Create] AiDA续订提醒");
|
||||||
|
templateUser.setTemplateID(RENEWAL_REMINDER_USER_CN);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
log.error("unknown subscription email type");
|
||||||
|
// throw new BusinessException("unknown subscription email type");
|
||||||
|
}
|
||||||
|
|
||||||
|
templateUser.setTemplateData(JSON.toJSONString(subscriptionEmailParamsDTO));
|
||||||
|
user.setTemplate(templateUser);
|
||||||
|
|
||||||
|
templateMerchant.setTemplateData(JSON.toJSONString(subscriptionEmailParamsDTO));
|
||||||
|
merchant.setTemplate(templateMerchant);
|
||||||
|
|
||||||
|
if (!type.equals("cancel") && !type.equals("fail_new")) {
|
||||||
|
// 返回的resp是一个SendEmailResponse的实例,与请求对象对应
|
||||||
|
SendEmailResponse respUser = client.SendEmail(user);
|
||||||
|
log.info("邮件主题:{},发送结果toUser###{}", user.getSubject(), SendEmailResponse.toJsonString(respUser));
|
||||||
|
}
|
||||||
|
if (!type.equals("reminder")) {
|
||||||
|
SendEmailResponse respMerchant = client.SendEmail(merchant);
|
||||||
|
log.info("邮件主题:{},发送结果toMerchant###{}", merchant.getSubject(), SendEmailResponse.toJsonString(respMerchant));
|
||||||
|
}
|
||||||
|
} catch (TencentCloudSDKException e) {
|
||||||
|
log.info("邮件发送失败###{}", e.toString());
|
||||||
|
throw new BusinessException("failed.to.send.mail");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final static Long NEW_REGISTRATION = 132123L;
|
||||||
|
private final static Long AFFILIATE_ACCEPTED = 132124L;
|
||||||
|
private final static Long AFFILIATE_REFUSED = 132125L;
|
||||||
|
private final static Long AFFILIATE_MONTHLY_SUMMARY = 132126L;
|
||||||
|
|
||||||
|
public static void affiliateEmailReminder(String receiverAddress, AffiliateEmailParamsDTO paramsDTO, String type) {
|
||||||
|
try {
|
||||||
|
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
|
||||||
|
// 实例化一个http选项,可选的,没有特殊需求可以跳过
|
||||||
|
HttpProfile httpProfile = new HttpProfile();
|
||||||
|
httpProfile.setEndpoint("ses.tencentcloudapi.com");
|
||||||
|
// 实例化一个client选项,可选的,没有特殊需求可以跳过
|
||||||
|
ClientProfile clientProfile = new ClientProfile();
|
||||||
|
clientProfile.setHttpProfile(httpProfile);
|
||||||
|
// 实例化要请求产品的client对象,clientProfile是可选的
|
||||||
|
SesClient client = new SesClient(cred, "ap-hongkong", clientProfile);
|
||||||
|
// 实例化一个请求对象,每个接口都会对应一个request对象
|
||||||
|
SendEmailRequest req = new SendEmailRequest();
|
||||||
|
req.setFromEmailAddress(SEND_ADDRESS);
|
||||||
|
req.setDestination(new String[]{receiverAddress});
|
||||||
|
Template template = new Template();
|
||||||
|
switch (type) {
|
||||||
|
case "new":
|
||||||
|
req.setSubject("New Affiliate Registration");
|
||||||
|
template.setTemplateID(NEW_REGISTRATION);
|
||||||
|
break;
|
||||||
|
case "accepted":
|
||||||
|
req.setSubject("Affiliate Application Accepted");
|
||||||
|
template.setTemplateID(AFFILIATE_ACCEPTED);
|
||||||
|
break;
|
||||||
|
case "refused":
|
||||||
|
req.setSubject("Affiliate Application Refused");
|
||||||
|
template.setTemplateID(AFFILIATE_REFUSED);
|
||||||
|
break;
|
||||||
|
case "summary":
|
||||||
|
req.setSubject("Your Monthly AffiliateWP Summary for AiDA");
|
||||||
|
template.setTemplateID(AFFILIATE_MONTHLY_SUMMARY);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
template.setTemplateData(JSON.toJSONString(paramsDTO));
|
||||||
|
req.setTemplate(template);
|
||||||
|
|
||||||
|
// 返回的resp是一个SendEmailResponse的实例,与请求对象对应
|
||||||
|
SendEmailResponse resp = client.SendEmail(req);
|
||||||
|
log.info("短信发送结果res###{}", SendEmailResponse.toJsonString(resp));
|
||||||
|
} catch (TencentCloudSDKException e) {
|
||||||
|
log.info("邮件发送失败###{}", e.toString());
|
||||||
|
throw new BusinessException("failed.to.send.mail");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
86
src/main/java/com/ai/da/controller/AffiliateController.java
Normal file
86
src/main/java/com/ai/da/controller/AffiliateController.java
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
package com.ai.da.controller;
|
||||||
|
|
||||||
|
|
||||||
|
import com.ai.da.common.response.Response;
|
||||||
|
import com.ai.da.mapper.primary.entity.Affiliate;
|
||||||
|
import com.ai.da.model.dto.AffiliateQueryDTO;
|
||||||
|
import com.ai.da.model.vo.AffiliateInvitationDetailsVO;
|
||||||
|
import com.ai.da.model.vo.AffiliateVO;
|
||||||
|
import com.ai.da.service.AffiliateService;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import javax.validation.Valid;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/affiliate")
|
||||||
|
@Api(tags = "Affiliate模块")
|
||||||
|
public class AffiliateController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private AffiliateService affiliateService;
|
||||||
|
|
||||||
|
@ApiOperation(value = "注册成为affiliate")
|
||||||
|
@GetMapping("/registration")
|
||||||
|
public Response<Boolean> completeGuidance(@RequestParam(value = "promotionMethod", required = false) String promotionMethod) {
|
||||||
|
return Response.success(affiliateService.registerAsAnAffiliate(promotionMethod));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "获取affiliate列表")
|
||||||
|
@PostMapping("/list")
|
||||||
|
public Response<IPage<Affiliate>> getAffiliateList(@Valid @RequestBody AffiliateQueryDTO affiliateQueryDTO) {
|
||||||
|
return Response.success(affiliateService.getAffiliateList(affiliateQueryDTO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "获取affiliate个人中心")
|
||||||
|
@GetMapping("/personalCenter")
|
||||||
|
public Response<AffiliateVO> personalAffiliateCenter() {
|
||||||
|
return Response.success(affiliateService.personalAffiliateCenter());
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "获取个人佣金图表数据")
|
||||||
|
@GetMapping("/getPersonalMonthlyIncome")
|
||||||
|
public Response<double[]> getPersonalMonthlyIncome(@RequestParam("year")int year) {
|
||||||
|
return Response.success(affiliateService.getPersonalMonthlyIncome(year));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "审批affiliate申请")
|
||||||
|
@GetMapping("/approval")
|
||||||
|
public Response<Boolean> applicationApproval(@RequestParam("id") Long id, @RequestParam("isApproved")Boolean isApproved) {
|
||||||
|
return Response.success(affiliateService.applicationApproval(id, isApproved));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*@ApiOperation(value = "定时计算佣金")
|
||||||
|
@GetMapping("/testTask")
|
||||||
|
public Response<String> testTask() {
|
||||||
|
affiliateService.updateAffiliateInfoWithPayment();
|
||||||
|
return Response.success("success ");
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/*@ApiOperation(value = "每月发送结算邮件")
|
||||||
|
@GetMapping("/commissionCalculation")
|
||||||
|
public Response<String> commissionCalculation() {
|
||||||
|
affiliateService.commissionCalculation(null, null);
|
||||||
|
return Response.success("success ");
|
||||||
|
}*/
|
||||||
|
|
||||||
|
@ApiOperation(value = "affiliate链接浏览量增加")
|
||||||
|
@GetMapping("/viewsIncrease")
|
||||||
|
public Response<Boolean> viewsGet(@RequestParam("id") Long id) {
|
||||||
|
return Response.success(affiliateService.affiliateLinkViewsIncrease(id));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "获取每个affiliate产生的收入")
|
||||||
|
@PostMapping("/getEachAffiliateGeneratedRevenue")
|
||||||
|
public Response<IPage<AffiliateInvitationDetailsVO>> getEachAffiliateGeneratedRevenue(@RequestBody AffiliateQueryDTO affiliateQueryDTO) {
|
||||||
|
return Response.success(affiliateService.getEachAffiliateGeneratedRevenue(affiliateQueryDTO));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -66,6 +66,8 @@ public class ElementController {
|
|||||||
return Response.success();
|
return Response.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 该功能已删除 */
|
||||||
|
@Deprecated
|
||||||
@ApiOperation(value = "生成印花")
|
@ApiOperation(value = "生成印花")
|
||||||
@PostMapping("/generatePrint")
|
@PostMapping("/generatePrint")
|
||||||
public Response<GenerateCollectionItemVO> generatePrint(@Valid @RequestBody CollectionGeneratePrintDTO generatePrintDTO) {
|
public Response<GenerateCollectionItemVO> generatePrint(@Valid @RequestBody CollectionGeneratePrintDTO generatePrintDTO) {
|
||||||
|
|||||||
@@ -3,9 +3,10 @@ package com.ai.da.controller;
|
|||||||
import com.ai.da.common.enums.OrderStatusEnum;
|
import com.ai.da.common.enums.OrderStatusEnum;
|
||||||
import com.ai.da.common.response.PageBaseResponse;
|
import com.ai.da.common.response.PageBaseResponse;
|
||||||
import com.ai.da.common.response.Response;
|
import com.ai.da.common.response.Response;
|
||||||
import com.ai.da.mapper.primary.entity.OrderInfo;
|
|
||||||
import com.ai.da.model.dto.QueryPageByTimeDTO;
|
import com.ai.da.model.dto.QueryPageByTimeDTO;
|
||||||
|
import com.ai.da.model.vo.OrderListVO;
|
||||||
import com.ai.da.service.OrderInfoService;
|
import com.ai.da.service.OrderInfoService;
|
||||||
|
import com.ai.da.service.PaymentInfoService;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
@@ -22,10 +23,13 @@ public class OrderInfoController {
|
|||||||
@Resource
|
@Resource
|
||||||
private OrderInfoService orderInfoService;
|
private OrderInfoService orderInfoService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private PaymentInfoService paymentInfoService;
|
||||||
|
|
||||||
@ApiOperation("订单列表")
|
@ApiOperation("订单列表")
|
||||||
@PostMapping("/list")
|
@PostMapping("/list")
|
||||||
public Response<PageBaseResponse<OrderInfo>> list(@Valid @RequestBody QueryPageByTimeDTO queryPageByTimeDTO){
|
public Response<PageBaseResponse<OrderListVO>> list(@Valid @RequestBody QueryPageByTimeDTO queryPageByTimeDTO){
|
||||||
PageBaseResponse<OrderInfo> orderByAccountId = orderInfoService.getOrderByPage(queryPageByTimeDTO);
|
PageBaseResponse<OrderListVO> orderByAccountId = paymentInfoService.getPaymentInfo(queryPageByTimeDTO);
|
||||||
// List<OrderInfo> list = orderInfoService.listOrderByCreateTimeDesc();
|
// List<OrderInfo> list = orderInfoService.listOrderByCreateTimeDesc();
|
||||||
return Response.success(orderByAccountId);
|
return Response.success(orderByAccountId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,47 +1,55 @@
|
|||||||
package com.ai.da.controller;
|
package com.ai.da.controller;
|
||||||
|
|
||||||
import com.ai.da.common.response.Response;
|
import com.ai.da.common.response.Response;
|
||||||
|
import com.ai.da.model.dto.ProductPurchaseDTO;
|
||||||
import com.ai.da.service.StripeService;
|
import com.ai.da.service.StripeService;
|
||||||
import com.paypal.http.HttpResponse;
|
import com.paypal.http.HttpResponse;
|
||||||
import com.paypal.payments.Refund;
|
import com.paypal.payments.Refund;
|
||||||
|
import com.stripe.exception.StripeException;
|
||||||
import io.swagger.annotations.Api;
|
import io.swagger.annotations.Api;
|
||||||
import io.swagger.annotations.ApiOperation;
|
import io.swagger.annotations.ApiOperation;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import springfox.documentation.annotations.ApiIgnore;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import javax.validation.Valid;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Api(tags = "Stripe模块")
|
@Api(tags = "Stripe模块")
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/stripe")
|
@RequestMapping("/api/stripe")
|
||||||
|
@ApiIgnore
|
||||||
public class StripeController {
|
public class StripeController {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private StripeService stripeService;
|
private StripeService stripeService;
|
||||||
|
|
||||||
@ApiOperation("创建支付链接")
|
@ApiOperation("创建支付链接")
|
||||||
@PostMapping("/createOrder/{amount}")
|
@PostMapping("/createOrder")
|
||||||
public Response<String> pay(@PathVariable Integer amount, @RequestParam String returnUrl) {
|
public Response<String> pay(@Valid @RequestBody ProductPurchaseDTO productPurchaseDTO) {
|
||||||
return Response.success(stripeService.pay(amount, returnUrl));
|
return Response.success(stripeService.pay(productPurchaseDTO));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("支付通知")
|
@ApiOperation("支付通知")
|
||||||
@PostMapping("/trade/notify")
|
@PostMapping("/trade/notify")
|
||||||
public Response<String> callback(HttpServletRequest request) throws ServletException, IOException {
|
public void callback(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
|
||||||
Boolean result = stripeService.notify(request);
|
Boolean result = stripeService.notify(request);
|
||||||
if (result){
|
if (result){
|
||||||
return Response.success(200,"success");
|
response.setStatus(HttpServletResponse.SC_OK);
|
||||||
}else {
|
}else {
|
||||||
return Response.fail(400,"failure");
|
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ApiOperation("申请退款")
|
@ApiOperation("申请退款")
|
||||||
@PostMapping("/trade/refund/{orderNo}/{reason}")
|
@GetMapping("/trade/refund/{orderNo}/{reason}")
|
||||||
public Response<HttpResponse<Refund>> refund(@PathVariable String orderNo, @PathVariable String reason) throws IOException {
|
public Response<HttpResponse<Refund>> refund(@PathVariable String orderNo, @PathVariable String reason) throws IOException {
|
||||||
String response = stripeService.refund(null,orderNo,reason);
|
String response = stripeService.refund(null,orderNo,reason);
|
||||||
if (response.equals("退款成功")){
|
if (response.equals("退款成功")){
|
||||||
@@ -51,4 +59,57 @@ public class StripeController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ApiOperation("获取订阅")
|
||||||
|
@GetMapping("/getSubscription")
|
||||||
|
public Response<List<String>> getSubscription(@RequestParam String name, @RequestParam String email) {
|
||||||
|
try {
|
||||||
|
return Response.success(stripeService.getSubscriptionIds(name, email));
|
||||||
|
} catch (StripeException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation("取消订阅")
|
||||||
|
@GetMapping("/cancelSubscription")
|
||||||
|
public Response<String> cancelSubscription(@RequestParam String subscriptionId, @RequestParam(required = false) String reason) {
|
||||||
|
stripeService.cancelSubscription(subscriptionId, reason);
|
||||||
|
return Response.success("success");
|
||||||
|
}
|
||||||
|
@ApiOperation("临时 取消订阅")
|
||||||
|
@GetMapping("/cancelSubscriptionTemp")
|
||||||
|
public Response<String> cancelSubscriptionTemp(@RequestParam String subscriptionId) {
|
||||||
|
stripeService.cancelSubscriptionTemp(subscriptionId);
|
||||||
|
return Response.success("success");
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation("创建订阅 临时")
|
||||||
|
@GetMapping("/createSubscriptionTemp")
|
||||||
|
public Response<String> createSubscriptionTemp(@RequestParam String name, @RequestParam String email) {
|
||||||
|
return Response.success(stripeService.createSubscriptionTemp(name, email));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation("修改用户默认支付方式 临时")
|
||||||
|
@GetMapping("/changeCustomerPayment")
|
||||||
|
public Response<String> changeCustomerPayment(@RequestParam String name, @RequestParam String email) {
|
||||||
|
return Response.success(stripeService.changeCustomerPayment(name, email));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation("临时 发送续订失败邮件")
|
||||||
|
@GetMapping("/sendRenewalFailEmail")
|
||||||
|
public Response<Boolean> sendRenewalFailEmail(@RequestParam String invoiceId, @RequestParam String subscriptionId, @RequestParam String orderNo) {
|
||||||
|
return Response.success(stripeService.sendRenewalFailEmail(invoiceId, subscriptionId,orderNo));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation("临时 查询指定用户绑定的付款方式")
|
||||||
|
@GetMapping("/getCustomerPaymentMethod")
|
||||||
|
public Response<List<Map<String,String>>> getCustomerPaymentMethod(@RequestParam String name, @RequestParam String email) {
|
||||||
|
return Response.success(stripeService.getCustomerPaymentMethod(name, email));
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation("临时 解绑指定用户绑定的所有付款方式")
|
||||||
|
@GetMapping("/detachCustomerAllPaymentMethod")
|
||||||
|
public Response<String> detachCustomerAllPaymentMethod(@RequestParam String name, @RequestParam String email) {
|
||||||
|
return Response.success(stripeService.detachCustomerAllPaymentMethod(name, email));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.ai.da.mapper.primary;
|
||||||
|
|
||||||
|
import com.ai.da.mapper.primary.entity.AffiliateIncome;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public interface AffiliateIncomeMapper extends BaseMapper<AffiliateIncome> {
|
||||||
|
|
||||||
|
List<Map<String, Object>> getPersonalMonthlyIncome(Long affiliateAccountId, int year);
|
||||||
|
|
||||||
|
List<Map<String, Object>> getMonthlyAffiliateIncome(int year, int month);
|
||||||
|
}
|
||||||
11
src/main/java/com/ai/da/mapper/primary/AffiliateMapper.java
Normal file
11
src/main/java/com/ai/da/mapper/primary/AffiliateMapper.java
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
package com.ai.da.mapper.primary;
|
||||||
|
|
||||||
|
import com.ai.da.mapper.primary.entity.Affiliate;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public interface AffiliateMapper extends BaseMapper<Affiliate> {
|
||||||
|
|
||||||
|
Map<String, Long> getMonthlyApprovedAffiliate(int year, int month);
|
||||||
|
}
|
||||||
@@ -1,7 +1,14 @@
|
|||||||
package com.ai.da.mapper.primary;
|
package com.ai.da.mapper.primary;
|
||||||
|
|
||||||
import com.ai.da.mapper.primary.entity.PaymentInfo;
|
import com.ai.da.mapper.primary.entity.PaymentInfo;
|
||||||
|
import com.ai.da.model.vo.OrderListVO;
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public interface PaymentInfoMapper extends BaseMapper<PaymentInfo> {
|
public interface PaymentInfoMapper extends BaseMapper<PaymentInfo> {
|
||||||
|
|
||||||
|
List<OrderListVO> selectPageOrderList(Long accountId, String startTime, String endTime, int offset, int pageSize);
|
||||||
|
|
||||||
|
int queryOrderListTotalCount(Long accountId, String startTime, String endTime);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package com.ai.da.mapper.primary;
|
||||||
|
|
||||||
|
import com.ai.da.mapper.primary.entity.SubscriptionInfo;
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
|
||||||
|
public interface SubscriptionInfoMapper extends BaseMapper<SubscriptionInfo> {
|
||||||
|
|
||||||
|
}
|
||||||
30
src/main/java/com/ai/da/mapper/primary/entity/Affiliate.java
Normal file
30
src/main/java/com/ai/da/mapper/primary/entity/Affiliate.java
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package com.ai.da.mapper.primary.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
@TableName("t_affiliate")
|
||||||
|
public class Affiliate extends BaseEntity{
|
||||||
|
|
||||||
|
private Long accountId;
|
||||||
|
|
||||||
|
// Active(活跃) || Inactive(过期) || Pending(待审批) || Refused(拒绝)
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
private Float totalEarnings = 0.00F;
|
||||||
|
|
||||||
|
private Float monthlyEarnings = 0.00F;
|
||||||
|
|
||||||
|
private Float unpaidEarnings = 0.00F;
|
||||||
|
|
||||||
|
private Integer visits = 0;
|
||||||
|
|
||||||
|
private Boolean approved = false;
|
||||||
|
|
||||||
|
private String link;
|
||||||
|
|
||||||
|
private String promotionMethod;
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
package com.ai.da.mapper.primary.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
@TableName("t_affiliate_income")
|
||||||
|
public class AffiliateIncome extends BaseEntity {
|
||||||
|
|
||||||
|
private Long affiliateId;
|
||||||
|
|
||||||
|
private Long affiliateAccountId;
|
||||||
|
|
||||||
|
private Long inviteeAccountId;
|
||||||
|
|
||||||
|
private Float amount;
|
||||||
|
|
||||||
|
private LocalDateTime paymentTime;
|
||||||
|
|
||||||
|
private Float commission;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -21,5 +21,12 @@ public class OrderInfo extends BaseEntity{
|
|||||||
|
|
||||||
private String orderStatus;//订单状态
|
private String orderStatus;//订单状态
|
||||||
|
|
||||||
|
private String note;
|
||||||
|
|
||||||
private String paymentType;//支付方式
|
private String paymentType;//支付方式
|
||||||
|
|
||||||
|
// 可用于标记用户订单是否首次订阅
|
||||||
|
private byte isFirstSubscription = 0;
|
||||||
|
|
||||||
|
private byte isCommissionCalculated = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,9 @@ package com.ai.da.mapper.primary.entity;
|
|||||||
|
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@Data
|
@Data
|
||||||
@TableName("t_payment_info")
|
@TableName("t_payment_info")
|
||||||
public class PaymentInfo extends BaseEntity{
|
public class PaymentInfo extends BaseEntity{
|
||||||
@@ -13,11 +15,22 @@ public class PaymentInfo extends BaseEntity{
|
|||||||
|
|
||||||
private String paymentType;//支付类型
|
private String paymentType;//支付类型
|
||||||
|
|
||||||
private String tradeType;//交易类型
|
|
||||||
|
|
||||||
private String tradeState;//交易状态
|
private String tradeState;//交易状态
|
||||||
|
|
||||||
private Float payerTotal;//支付金额(元)
|
private Float payerTotal;//支付金额(元)
|
||||||
|
|
||||||
private String content;//通知参数
|
private String content;//通知参数
|
||||||
|
|
||||||
|
// 支付类型 new || renewal
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
// 当前支付是否已邮件通知 0 || 1
|
||||||
|
private Integer notified;
|
||||||
|
|
||||||
|
private String paymentMethod;
|
||||||
|
|
||||||
|
private String last4;
|
||||||
|
|
||||||
|
// 发票托管页面
|
||||||
|
private String hostedInvoiceUrl;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
package com.ai.da.mapper.primary.entity;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
@TableName("t_subscription_info")
|
||||||
|
public class SubscriptionInfo extends BaseEntity{
|
||||||
|
|
||||||
|
private Long accountId;
|
||||||
|
|
||||||
|
private String orderNo;
|
||||||
|
|
||||||
|
// stripe || paypal 平台生成的id
|
||||||
|
private String subscriptionId;
|
||||||
|
|
||||||
|
// month || year
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
// active || expired
|
||||||
|
private String status = "active";
|
||||||
|
|
||||||
|
private byte cancelNotified = (byte)0;
|
||||||
|
|
||||||
|
// 续订的下一个付款日
|
||||||
|
private String nextPayDate;
|
||||||
|
|
||||||
|
// 当前订阅订单有效期开始时间
|
||||||
|
private Long currentPeriodStart;
|
||||||
|
|
||||||
|
// 当前订阅订单有效期结束时间
|
||||||
|
private Long currentPeriodEnd;
|
||||||
|
|
||||||
|
// 取消订阅原因
|
||||||
|
private String cancelReason;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package com.ai.da.model.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class AffiliateEmailParamsDTO {
|
||||||
|
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
private String promotionMethod;
|
||||||
|
|
||||||
|
private String totalProgramRevenue;
|
||||||
|
|
||||||
|
private String newApprovedAffiliates;
|
||||||
|
|
||||||
|
private String unpaidEarnings;
|
||||||
|
|
||||||
|
private String paidEarnings;
|
||||||
|
|
||||||
|
public AffiliateEmailParamsDTO() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public AffiliateEmailParamsDTO(String username) {
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AffiliateEmailParamsDTO(String username, String promotionMethod) {
|
||||||
|
this.username = username;
|
||||||
|
this.promotionMethod = promotionMethod;
|
||||||
|
}
|
||||||
|
}
|
||||||
31
src/main/java/com/ai/da/model/dto/AffiliateQueryDTO.java
Normal file
31
src/main/java/com/ai/da/model/dto/AffiliateQueryDTO.java
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package com.ai.da.model.dto;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
@ApiModel("查询affiliate列表")
|
||||||
|
public class AffiliateQueryDTO extends TimeQueryBaseDTO{
|
||||||
|
@ApiModelProperty("Active(活跃) || Inactive(过期) || Pending(待审批) || Refused(拒绝)")
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
@ApiModelProperty("推广者id")
|
||||||
|
private Long affiliateId;
|
||||||
|
|
||||||
|
@ApiModelProperty("按时间 DESC 降序 || ASC 升序")
|
||||||
|
private String order = "ASC";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "AffiliateQueryDTO{" +
|
||||||
|
"status='" + status + '\'' + ' ' +
|
||||||
|
"startTime='" + super.getStartTime() + '\'' + ' ' +
|
||||||
|
"endTime='" + super.getEndTime() + '\'' + ' ' +
|
||||||
|
"page='" + super.getPage() + '\'' + ' ' +
|
||||||
|
"size='" + super.getSize() + '\'' + ' ' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,49 +12,50 @@ import javax.validation.constraints.NotNull;
|
|||||||
public class GenerateThroughImageTextDTO {
|
public class GenerateThroughImageTextDTO {
|
||||||
@NotNull(message = "userId cannot be empty")
|
@NotNull(message = "userId cannot be empty")
|
||||||
@ApiModelProperty("用户id")
|
@ApiModelProperty("用户id")
|
||||||
Long userId;
|
private Long userId;
|
||||||
|
|
||||||
@ApiModelProperty("caption | prompt")
|
@ApiModelProperty("caption | prompt")
|
||||||
String text;
|
private String text;
|
||||||
|
|
||||||
@ApiModelProperty("图片在t_collection_element表中的id")
|
@ApiModelProperty("图片在t_collection_element表中的id")
|
||||||
Long collectionElementId;
|
private Long collectionElementId;
|
||||||
|
|
||||||
// todo 后续取消这个字段的传输,由后端自行判断相关参数是否有值
|
// todo 后续取消这个字段的传输,由后端自行判断相关参数是否有值
|
||||||
// @NotBlank(message = "you have to choose the generate type")
|
// @NotBlank(message = "you have to choose the generate type")
|
||||||
@ApiModelProperty("text image text-image")
|
@ApiModelProperty("text image text-image")
|
||||||
String generateType;
|
private String generateType;
|
||||||
|
|
||||||
@ApiModelProperty("图片来源:update,从library中选择,从toProductImage结果中选择 collection || library || productImage")
|
@ApiModelProperty("图片来源:update,从library中选择,从toProductImage结果中选择 collection || library || productImage")
|
||||||
String designType;
|
private String designType;
|
||||||
|
|
||||||
@NotBlank(message = "level1Type cannot be empty!")
|
@NotBlank(message = "level1Type cannot be empty!")
|
||||||
@ApiModelProperty("Moodboard Printboard Sketchboard MarketingSketch")
|
@ApiModelProperty("Moodboard Printboard Sketchboard MarketingSketch")
|
||||||
String level1Type;
|
private String level1Type;
|
||||||
|
|
||||||
@ApiModelProperty("Outwear Dress Blouse Skirt Trousers || Logo Slogan Pattern")
|
@ApiModelProperty("Outwear Dress Blouse Skirt Trousers || Logo Slogan Pattern")
|
||||||
String level2Type;
|
private String level2Type;
|
||||||
|
|
||||||
@ApiModelProperty("性别")
|
@ApiModelProperty("性别")
|
||||||
String gender;
|
private String gender;
|
||||||
|
|
||||||
@ApiModelProperty("选择的模型名")
|
|
||||||
String version;
|
@ApiModelProperty("选择的模型名 high || fast")
|
||||||
|
private String version;
|
||||||
|
|
||||||
@NotBlank(message = "timeZone cannot be empty!")
|
@NotBlank(message = "timeZone cannot be empty!")
|
||||||
@ApiModelProperty("本地时区,比如 'Asia/Tokyo' 东京时间 , 'Asia/Shanghai' 北京时间 由js本地获取")
|
@ApiModelProperty("本地时区,比如 'Asia/Tokyo' 东京时间 , 'Asia/Shanghai' 北京时间 由js本地获取")
|
||||||
String timeZone;
|
private String timeZone;
|
||||||
|
|
||||||
@ApiModelProperty("唯一id,用于保持消息唯一性")
|
@ApiModelProperty("唯一id,用于保持消息唯一性")
|
||||||
String uniqueId;
|
private String uniqueId;
|
||||||
|
|
||||||
@NotNull(message = "Please check if the required fields are empty.(isTestUser)")
|
@NotNull(message = "Please check if the required fields are empty.(isTestUser)")
|
||||||
@ApiModelProperty("是否是测试用户")
|
@ApiModelProperty("是否是测试用户")
|
||||||
Boolean isTestUser;
|
private Boolean isTestUser;
|
||||||
|
|
||||||
@ApiModelProperty("页面上用户设计的slogan所截的图片")
|
@ApiModelProperty("页面上用户设计的slogan所截的图片")
|
||||||
String sloganBase64;
|
private String sloganBase64;
|
||||||
|
|
||||||
@ApiModelProperty("种子 取值范围 0~500")
|
@ApiModelProperty("种子 取值范围 0~500")
|
||||||
String seed;
|
private String seed;
|
||||||
}
|
}
|
||||||
|
|||||||
30
src/main/java/com/ai/da/model/dto/ProductPurchaseDTO.java
Normal file
30
src/main/java/com/ai/da/model/dto/ProductPurchaseDTO.java
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
package com.ai.da.model.dto;
|
||||||
|
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotBlank;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ApiModel("购买产品DTO")
|
||||||
|
public class ProductPurchaseDTO {
|
||||||
|
|
||||||
|
@ApiModelProperty("购买数量")
|
||||||
|
private int quantity;
|
||||||
|
|
||||||
|
// http://example.com
|
||||||
|
@NotBlank(message = "return url cannot be empty")
|
||||||
|
@ApiModelProperty("购买完成后返回页面地址")
|
||||||
|
private String returnUrl;
|
||||||
|
|
||||||
|
@NotBlank(message = "product name cannot be empty")
|
||||||
|
@ApiModelProperty("产品名 CreditsPurchase || Subscription")
|
||||||
|
private String productName;
|
||||||
|
|
||||||
|
@ApiModelProperty("Month || Year")
|
||||||
|
private String subscribeType;
|
||||||
|
|
||||||
|
@ApiModelProperty("是否自动续订 one_time || recurring")
|
||||||
|
private Boolean autoRenewal;
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package com.ai.da.model.dto;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class SubscriptionEmailParamsDTO {
|
||||||
|
// 用户名
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
// t_payment_info id(每次支付对于用户来说是一笔新订单)
|
||||||
|
private String orderId;
|
||||||
|
|
||||||
|
// 订单支付创建日期
|
||||||
|
private String createDate;
|
||||||
|
|
||||||
|
// 购买数量
|
||||||
|
private String quantity;
|
||||||
|
|
||||||
|
// 费用
|
||||||
|
private String totalFee;
|
||||||
|
|
||||||
|
// 当前订阅开始时间
|
||||||
|
private String lastOrderDate;
|
||||||
|
|
||||||
|
// 当前订阅结束时间
|
||||||
|
private String endOfPrepaidTerm;
|
||||||
|
|
||||||
|
// 付款方式
|
||||||
|
private String paymentMethod;
|
||||||
|
|
||||||
|
private String last4;
|
||||||
|
|
||||||
|
// 订阅Id
|
||||||
|
private String subscriptionId;
|
||||||
|
|
||||||
|
// 订阅方式
|
||||||
|
private String subscriptionType;
|
||||||
|
|
||||||
|
// 订阅开始时间
|
||||||
|
private String startDate;
|
||||||
|
|
||||||
|
// 下一个支付日期
|
||||||
|
private String nextPayDate;
|
||||||
|
|
||||||
|
// 下次付款时间(reminder)
|
||||||
|
private String renewalTime;
|
||||||
|
|
||||||
|
// 付款失败原因
|
||||||
|
private String failMessage;
|
||||||
|
|
||||||
|
private String accountPageRef;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
19
src/main/java/com/ai/da/model/dto/TimeQueryBaseDTO.java
Normal file
19
src/main/java/com/ai/da/model/dto/TimeQueryBaseDTO.java
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package com.ai.da.model.dto;
|
||||||
|
|
||||||
|
import com.ai.da.model.vo.PageQueryBaseVo;
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Data
|
||||||
|
@ApiModel("按时间查询")
|
||||||
|
public class TimeQueryBaseDTO extends PageQueryBaseVo {
|
||||||
|
|
||||||
|
@ApiModelProperty("按时间区间查询 区间起点")
|
||||||
|
private String startTime;
|
||||||
|
|
||||||
|
@ApiModelProperty("按时间区间查询 区间终点")
|
||||||
|
private String endTime;
|
||||||
|
}
|
||||||
@@ -46,4 +46,22 @@ public class AccountLoginVO {
|
|||||||
|
|
||||||
private String Language;
|
private String Language;
|
||||||
|
|
||||||
|
// 订阅id(stripe提供)
|
||||||
|
private String subscriptionId;
|
||||||
|
|
||||||
|
// 订阅状态
|
||||||
|
private String status;
|
||||||
|
|
||||||
|
// 订阅过期时间
|
||||||
|
private String expireTime;
|
||||||
|
|
||||||
|
// 订阅类型 month || year
|
||||||
|
private String subscriptionType;
|
||||||
|
|
||||||
|
// 是否自动续订
|
||||||
|
private boolean isAutoRenewal;
|
||||||
|
|
||||||
|
// 是否是affiliate
|
||||||
|
private boolean isAffiliate = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
package com.ai.da.model.vo;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class AffiliateInvitationDetailsVO {
|
||||||
|
|
||||||
|
private Long accountId;
|
||||||
|
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
private Float firstSubscriptionPaymentAmount;
|
||||||
|
|
||||||
|
private Float commission;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
|
||||||
|
private LocalDateTime time;
|
||||||
|
}
|
||||||
15
src/main/java/com/ai/da/model/vo/AffiliateVO.java
Normal file
15
src/main/java/com/ai/da/model/vo/AffiliateVO.java
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package com.ai.da.model.vo;
|
||||||
|
|
||||||
|
import com.ai.da.mapper.primary.entity.Affiliate;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class AffiliateVO extends Affiliate {
|
||||||
|
|
||||||
|
private Long linkViewCount;
|
||||||
|
|
||||||
|
}
|
||||||
29
src/main/java/com/ai/da/model/vo/OrderListVO.java
Normal file
29
src/main/java/com/ai/da/model/vo/OrderListVO.java
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package com.ai.da.model.vo;
|
||||||
|
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用于订单列表展示(展示的是所有支付信息)
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class OrderListVO {
|
||||||
|
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
private Float amount;
|
||||||
|
|
||||||
|
private String paymentMethod;
|
||||||
|
|
||||||
|
private String state;
|
||||||
|
|
||||||
|
private String orderType;
|
||||||
|
|
||||||
|
private String invoiceLink;
|
||||||
|
|
||||||
|
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone="GMT+8")
|
||||||
|
private LocalDateTime createTime;
|
||||||
|
}
|
||||||
31
src/main/java/com/ai/da/service/AffiliateService.java
Normal file
31
src/main/java/com/ai/da/service/AffiliateService.java
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package com.ai.da.service;
|
||||||
|
|
||||||
|
import com.ai.da.mapper.primary.entity.Affiliate;
|
||||||
|
import com.ai.da.model.dto.AffiliateQueryDTO;
|
||||||
|
import com.ai.da.model.vo.AffiliateInvitationDetailsVO;
|
||||||
|
import com.ai.da.model.vo.AffiliateVO;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
|
||||||
|
public interface AffiliateService extends IService<Affiliate> {
|
||||||
|
|
||||||
|
Boolean registerAsAnAffiliate(String promotionMethod);
|
||||||
|
|
||||||
|
IPage<Affiliate> getAffiliateList(AffiliateQueryDTO affiliateQueryDTO);
|
||||||
|
|
||||||
|
AffiliateVO personalAffiliateCenter();
|
||||||
|
|
||||||
|
double[] getPersonalMonthlyIncome(int year);
|
||||||
|
|
||||||
|
Boolean applicationApproval(Long id, Boolean isApproved);
|
||||||
|
|
||||||
|
void updateAffiliateInfoWithPayment();
|
||||||
|
|
||||||
|
Boolean affiliateLinkViewsIncrease(Long id);
|
||||||
|
|
||||||
|
IPage<AffiliateInvitationDetailsVO> getEachAffiliateGeneratedRevenue(AffiliateQueryDTO affiliateQueryDTO);
|
||||||
|
|
||||||
|
Affiliate getByAccountId(Long accountId);
|
||||||
|
|
||||||
|
void commissionCalculation(Integer year, Integer month);
|
||||||
|
}
|
||||||
@@ -17,9 +17,9 @@ public interface CreditsService extends IService<CreditsDetail> {
|
|||||||
|
|
||||||
String getCredits(Long accountId);
|
String getCredits(Long accountId);
|
||||||
|
|
||||||
void creditsRefund(Long accountId, Integer quantity);
|
void creditsRefund(Long accountId, Integer quantity, String orderNo);
|
||||||
|
|
||||||
void insertToCreditsDetail(Long accountId, String changeEvent, String credits, String changeType);
|
void insertToCreditsDetail(Long accountId, String changeEvent, String credits, String changeType, String orderNo);
|
||||||
|
|
||||||
PageBaseResponse<CreditsDetail> queryCreditsDetailsPage(QueryIncomeOrExpenditureDTO queryPageByTimeDTO);
|
PageBaseResponse<CreditsDetail> queryCreditsDetailsPage(QueryIncomeOrExpenditureDTO queryPageByTimeDTO);
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package com.ai.da.service;
|
|||||||
|
|
||||||
|
|
||||||
import com.ai.da.common.enums.OrderStatusEnum;
|
import com.ai.da.common.enums.OrderStatusEnum;
|
||||||
|
import com.ai.da.common.enums.ProductEnum;
|
||||||
import com.ai.da.common.response.PageBaseResponse;
|
import com.ai.da.common.response.PageBaseResponse;
|
||||||
import com.ai.da.mapper.primary.entity.OrderInfo;
|
import com.ai.da.mapper.primary.entity.OrderInfo;
|
||||||
import com.ai.da.model.dto.QueryPageByTimeDTO;
|
import com.ai.da.model.dto.QueryPageByTimeDTO;
|
||||||
@@ -13,6 +14,8 @@ public interface OrderInfoService extends IService<OrderInfo> {
|
|||||||
|
|
||||||
OrderInfo createOrderByProductId(Integer productId, String paymentType);
|
OrderInfo createOrderByProductId(Integer productId, String paymentType);
|
||||||
|
|
||||||
|
OrderInfo createOrderByProductId(Integer amount, String paymentType, ProductEnum product);
|
||||||
|
|
||||||
void saveCodeUrl(String orderNo, String codeUrl);
|
void saveCodeUrl(String orderNo, String codeUrl);
|
||||||
|
|
||||||
List<OrderInfo> listOrderByCreateTimeDesc();
|
List<OrderInfo> listOrderByCreateTimeDesc();
|
||||||
@@ -28,4 +31,7 @@ public interface OrderInfoService extends IService<OrderInfo> {
|
|||||||
PageBaseResponse<OrderInfo> getOrderByPage(QueryPageByTimeDTO queryPageByTimeDTO);
|
PageBaseResponse<OrderInfo> getOrderByPage(QueryPageByTimeDTO queryPageByTimeDTO);
|
||||||
|
|
||||||
void updateOrderNoById(Long id, String orderNo);
|
void updateOrderNoById(Long id, String orderNo);
|
||||||
|
|
||||||
|
void updateTotalFeeByOrderNo(String orderNo);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
package com.ai.da.service;
|
package com.ai.da.service;
|
||||||
|
|
||||||
|
import com.ai.da.common.response.PageBaseResponse;
|
||||||
import com.ai.da.mapper.primary.entity.PaymentInfo;
|
import com.ai.da.mapper.primary.entity.PaymentInfo;
|
||||||
import com.ai.da.model.dto.AlipayHKCallbackDTO;
|
import com.ai.da.model.dto.AlipayHKCallbackDTO;
|
||||||
|
import com.ai.da.model.dto.QueryPageByTimeDTO;
|
||||||
|
import com.ai.da.model.vo.OrderListVO;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import com.paypal.orders.Order;
|
import com.paypal.orders.Order;
|
||||||
import com.stripe.model.checkout.Session;
|
import com.stripe.model.Charge;
|
||||||
|
import com.stripe.model.Invoice;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public interface PaymentInfoService {
|
public interface PaymentInfoService extends IService<PaymentInfo> {
|
||||||
|
|
||||||
void createPaymentInfo(String plainText);
|
void createPaymentInfo(String plainText);
|
||||||
|
|
||||||
@@ -17,9 +23,13 @@ public interface PaymentInfoService {
|
|||||||
|
|
||||||
void createPaymentInfoForAliPayHK(AlipayHKCallbackDTO alipayHKCallbackDTO);
|
void createPaymentInfoForAliPayHK(AlipayHKCallbackDTO alipayHKCallbackDTO);
|
||||||
|
|
||||||
void createPaymentInfoForStripe(Session session);
|
PaymentInfo createOrUpdatePaymentInfoForStripe(Invoice invoice);
|
||||||
|
|
||||||
PaymentInfo getPaymentInfoByOrderId(String orderId);
|
PaymentInfo createOrUpdatePaymentInfoForStripe(Charge charge);
|
||||||
|
|
||||||
|
List<PaymentInfo> getPaymentInfoByOrderNo(String orderId, String order);
|
||||||
|
|
||||||
void updatePaymentStatusById(Long id, String status, String content);
|
void updatePaymentStatusById(Long id, String status, String content);
|
||||||
|
|
||||||
|
PageBaseResponse<OrderListVO> getPaymentInfo(QueryPageByTimeDTO queryPageByTimeDTO);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +1,50 @@
|
|||||||
package com.ai.da.service;
|
package com.ai.da.service;
|
||||||
|
|
||||||
|
import com.ai.da.mapper.primary.entity.SubscriptionInfo;
|
||||||
|
import com.ai.da.model.dto.ProductPurchaseDTO;
|
||||||
|
import com.stripe.exception.StripeException;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public interface StripeService {
|
public interface StripeService {
|
||||||
|
|
||||||
String pay(Integer quantity, String returnUrl);
|
String pay(ProductPurchaseDTO productPurchaseDTO);
|
||||||
|
|
||||||
Boolean notify(HttpServletRequest request);
|
Boolean notify(HttpServletRequest request);
|
||||||
|
|
||||||
|
SubscriptionInfo getLatestSubscriptionInfoByAccountId(Long accountId);
|
||||||
|
|
||||||
String refund(String amount, String orderId, String reason);
|
String refund(String amount, String orderId, String reason);
|
||||||
|
|
||||||
void checkOrderStatus(String orderNo);
|
void checkOrderStatus(String orderNo);
|
||||||
|
|
||||||
|
List<String> getSubscriptionIds(String name, String userEmail) throws StripeException;
|
||||||
|
|
||||||
|
Map<String, String> getPaymentMethodByInvoiceId(String invoiceId);
|
||||||
|
|
||||||
|
void cancelSubscription(String orderNo, String cancelReason);
|
||||||
|
|
||||||
|
void cancelSubscriptionTemp(String subscriptionId);
|
||||||
|
|
||||||
|
Map<String, String> getPaymentMethod(String paymentMethodId);
|
||||||
|
|
||||||
|
/*void updateSubscription(String subscriptionId);
|
||||||
|
|
||||||
|
void resume(String subscriptionId);*/
|
||||||
|
|
||||||
|
void subscriptionReminder();
|
||||||
|
|
||||||
|
void checkSubscriptionExpiration();
|
||||||
|
|
||||||
|
String createSubscriptionTemp(String name, String email);
|
||||||
|
|
||||||
|
String changeCustomerPayment(String name, String email);
|
||||||
|
|
||||||
|
boolean sendRenewalFailEmail(String invoiceId, String subscriptionId, String orderNo);
|
||||||
|
|
||||||
|
List<Map<String,String>> getCustomerPaymentMethod(String name, String email);
|
||||||
|
|
||||||
|
String detachCustomerAllPaymentMethod(String name, String email);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,6 +104,12 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
|
|||||||
@Resource
|
@Resource
|
||||||
private RedisUtil redisUtil;
|
private RedisUtil redisUtil;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private StripeService stripeService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private AffiliateService affiliateService;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public AccountPreLoginVO preLogin(AccountPreLoginDTO accountDTO) {
|
public AccountPreLoginVO preLogin(AccountPreLoginDTO accountDTO) {
|
||||||
@@ -2418,6 +2424,19 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
|
|||||||
response.setAccountExtendList(accountExtends);
|
response.setAccountExtendList(accountExtends);
|
||||||
}
|
}
|
||||||
response.setLanguage(Language.valueOf(account.getLanguage()).name());
|
response.setLanguage(Language.valueOf(account.getLanguage()).name());
|
||||||
|
SubscriptionInfo subscriptionInfo = stripeService.getLatestSubscriptionInfoByAccountId(accountId);
|
||||||
|
if (!Objects.isNull(subscriptionInfo)) {
|
||||||
|
response.setSubscriptionId(subscriptionInfo.getSubscriptionId());
|
||||||
|
response.setSubscriptionType(subscriptionInfo.getType());
|
||||||
|
response.setStatus(subscriptionInfo.getStatus());
|
||||||
|
response.setExpireTime(String.valueOf(subscriptionInfo.getCurrentPeriodEnd()));
|
||||||
|
response.setAutoRenewal(subscriptionInfo.getStatus().equals("active"));
|
||||||
|
}
|
||||||
|
|
||||||
|
Affiliate affiliate = affiliateService.getByAccountId(accountId);
|
||||||
|
if (!Objects.isNull(affiliate) && affiliate.getStatus().equals("Active")) {
|
||||||
|
response.setAffiliate(true);
|
||||||
|
}
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
295
src/main/java/com/ai/da/service/impl/AffiliateServiceImpl.java
Normal file
295
src/main/java/com/ai/da/service/impl/AffiliateServiceImpl.java
Normal file
@@ -0,0 +1,295 @@
|
|||||||
|
package com.ai.da.service.impl;
|
||||||
|
|
||||||
|
import com.ai.da.common.config.exception.BusinessException;
|
||||||
|
import com.ai.da.common.constant.CommonConstant;
|
||||||
|
import com.ai.da.common.context.UserContext;
|
||||||
|
import com.ai.da.common.response.ResultEnum;
|
||||||
|
import com.ai.da.common.utils.CopyUtil;
|
||||||
|
import com.ai.da.common.utils.RedisUtil;
|
||||||
|
import com.ai.da.common.utils.SendEmailUtil;
|
||||||
|
import com.ai.da.mapper.primary.AccountMapper;
|
||||||
|
import com.ai.da.mapper.primary.AffiliateIncomeMapper;
|
||||||
|
import com.ai.da.mapper.primary.AffiliateMapper;
|
||||||
|
import com.ai.da.mapper.primary.SubscriptionInfoMapper;
|
||||||
|
import com.ai.da.mapper.primary.entity.*;
|
||||||
|
import com.ai.da.model.dto.AffiliateEmailParamsDTO;
|
||||||
|
import com.ai.da.model.dto.AffiliateQueryDTO;
|
||||||
|
import com.ai.da.model.vo.AffiliateInvitationDetailsVO;
|
||||||
|
import com.ai.da.model.vo.AffiliateVO;
|
||||||
|
import com.ai.da.model.vo.AuthPrincipalVo;
|
||||||
|
import com.ai.da.service.AccountService;
|
||||||
|
import com.ai.da.service.AffiliateService;
|
||||||
|
import com.ai.da.service.OrderInfoService;
|
||||||
|
import com.ai.da.service.PaymentInfoService;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import com.mysql.cj.util.StringUtils;
|
||||||
|
import io.netty.util.internal.StringUtil;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
@Slf4j
|
||||||
|
public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate> implements AffiliateService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private OrderInfoService orderInfoService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private AccountService accountService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private PaymentInfoService paymentInfoService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SubscriptionInfoMapper subscriptionInfoMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private AffiliateIncomeMapper affiliateIncomeMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RedisUtil redisUtil;
|
||||||
|
|
||||||
|
// 推广者注册
|
||||||
|
public Boolean registerAsAnAffiliate(String promotionMethod){
|
||||||
|
AuthPrincipalVo userHolder = UserContext.getUserHolder();
|
||||||
|
// 判断该用户是否已注册
|
||||||
|
QueryWrapper<Affiliate> qw = new QueryWrapper<>();
|
||||||
|
qw.eq("account_id", userHolder.getId());
|
||||||
|
Affiliate affiliate = baseMapper.selectOne(qw);
|
||||||
|
if (Objects.isNull(affiliate)){
|
||||||
|
affiliate = new Affiliate();
|
||||||
|
affiliate.setAccountId(userHolder.getId());
|
||||||
|
affiliate.setStatus("Pending");
|
||||||
|
affiliate.setCreateTime(LocalDateTime.now());
|
||||||
|
affiliate.setPromotionMethod(promotionMethod);
|
||||||
|
baseMapper.insert(affiliate);
|
||||||
|
// 邮件通知审批者
|
||||||
|
// String email = "kimwong@code-create.com.hk";
|
||||||
|
String email = "xupei3360@163.com";
|
||||||
|
SendEmailUtil.affiliateEmailReminder(email, new AffiliateEmailParamsDTO(userHolder.getUsername(), promotionMethod), "new");
|
||||||
|
}else {
|
||||||
|
throw new BusinessException("You have registered an Affiliate", ResultEnum.PROMPT.getCode());
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IPage<Affiliate> getAffiliateList(AffiliateQueryDTO affiliateQueryDTO){
|
||||||
|
log.info("parameter => {}", affiliateQueryDTO.toString());
|
||||||
|
QueryWrapper<Affiliate> qw = new QueryWrapper<>();
|
||||||
|
qw.eq(!StringUtils.isNullOrEmpty(affiliateQueryDTO.getStatus()), "status", affiliateQueryDTO.getStatus())
|
||||||
|
.gt(!StringUtils.isNullOrEmpty(affiliateQueryDTO.getStartTime()), "create_time", affiliateQueryDTO.getStartTime())
|
||||||
|
.lt(!StringUtils.isNullOrEmpty(affiliateQueryDTO.getEndTime()), "create_time", affiliateQueryDTO.getEndTime())
|
||||||
|
.eq(!Objects.isNull(affiliateQueryDTO.getAffiliateId()), "id", affiliateQueryDTO.getAffiliateId())
|
||||||
|
.orderByDesc(affiliateQueryDTO.getOrder().equals("DESC"), "create_time");
|
||||||
|
return baseMapper.selectPage(new Page<>(affiliateQueryDTO.getPage(), affiliateQueryDTO.getSize()), qw);
|
||||||
|
}
|
||||||
|
|
||||||
|
public AffiliateVO personalAffiliateCenter(){
|
||||||
|
QueryWrapper<Affiliate> qw = new QueryWrapper<>();
|
||||||
|
Long accountId = UserContext.getUserHolder().getId();
|
||||||
|
qw.eq("account_id", accountId);
|
||||||
|
Affiliate affiliate = baseMapper.selectOne(qw);
|
||||||
|
AffiliateVO affiliateVO = CopyUtil.copyObject(affiliate, AffiliateVO.class);
|
||||||
|
affiliateVO.setLinkViewCount(getAffiliateLinkViewCount(affiliate.getId()));
|
||||||
|
return affiliateVO;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double[] getPersonalMonthlyIncome(int year){
|
||||||
|
Long accountId = UserContext.getUserHolder().getId();
|
||||||
|
List<Map<String, Object>> personalMonthlyIncome = affiliateIncomeMapper.getPersonalMonthlyIncome(accountId, year);
|
||||||
|
double[] commissions = new double[12];
|
||||||
|
personalMonthlyIncome.forEach(income -> {
|
||||||
|
int month = Integer.parseInt(income.get("yearMonth").toString());
|
||||||
|
commissions[month-1] = (double)income.get("totalCommission");
|
||||||
|
});
|
||||||
|
|
||||||
|
return commissions;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 审批申请
|
||||||
|
public Boolean applicationApproval(Long id, Boolean isApproved){
|
||||||
|
Affiliate affiliate = baseMapper.selectById(id);
|
||||||
|
|
||||||
|
// 1、更新db状态
|
||||||
|
if (isApproved){
|
||||||
|
// 更新状态
|
||||||
|
affiliate.setStatus("Active");
|
||||||
|
affiliate.setApproved(true);
|
||||||
|
affiliate.setLink(CommonConstant.AFFILIATE_LINK + affiliate.getId());
|
||||||
|
} else {
|
||||||
|
affiliate.setStatus("Refused");
|
||||||
|
affiliate.setApproved(false);
|
||||||
|
}
|
||||||
|
affiliate.setUpdateTime(LocalDateTime.now());
|
||||||
|
baseMapper.updateById(affiliate);
|
||||||
|
|
||||||
|
// 2、将批准结果邮件通知用户
|
||||||
|
Account account = accountService.getById(affiliate.getAccountId());
|
||||||
|
String userEmail = account.getUserEmail();
|
||||||
|
String userName = account.getUserName();
|
||||||
|
if (isApproved){
|
||||||
|
SendEmailUtil.affiliateEmailReminder(userEmail, new AffiliateEmailParamsDTO(userName), "accepted");
|
||||||
|
}else {
|
||||||
|
SendEmailUtil.affiliateEmailReminder(userEmail, new AffiliateEmailParamsDTO(userName), "refused");
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定时计算佣金
|
||||||
|
public void updateAffiliateInfoWithPayment(){
|
||||||
|
// id存redis
|
||||||
|
String lastTime = redisUtil.getFromString(RedisUtil.PAYMENT_INFO_LAST_SCAN_TIME);
|
||||||
|
String currentTime = LocalDateTime.now().toString();
|
||||||
|
// 1、查上次更新之后有无新订单
|
||||||
|
QueryWrapper<PaymentInfo> queryWrapper = new QueryWrapper<>();
|
||||||
|
if (!StringUtil.isNullOrEmpty(lastTime)){
|
||||||
|
queryWrapper.gt("create_time", lastTime);
|
||||||
|
}
|
||||||
|
queryWrapper.eq("type","new").eq("trade_state", "paid");
|
||||||
|
|
||||||
|
List<PaymentInfo> paymentInfos = paymentInfoService.getBaseMapper().selectList(queryWrapper);
|
||||||
|
if (!paymentInfos.isEmpty()){
|
||||||
|
paymentInfos.forEach(paymentInfo -> {
|
||||||
|
// 2、根据order_no查付款用户id
|
||||||
|
OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(paymentInfo.getOrderNo());
|
||||||
|
if (Objects.isNull(orderInfo)){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Long accountId = orderInfo.getAccountId();
|
||||||
|
// 3、查该用户之前是否有初次订阅的订单
|
||||||
|
QueryWrapper<OrderInfo> qwOrderInfo = new QueryWrapper<>();
|
||||||
|
qwOrderInfo.eq("account_id", accountId).eq("is_first_subscription", 1);
|
||||||
|
List<OrderInfo> orderInfos = orderInfoService.getBaseMapper().selectList(qwOrderInfo);
|
||||||
|
// 该用户首次订阅(非首次订阅,不分配佣金)
|
||||||
|
if (orderInfos.isEmpty()){
|
||||||
|
// 查询是否绑定affiliateId
|
||||||
|
Account account = accountService.getById(accountId);
|
||||||
|
if (!Objects.isNull(account.getInvitationCode())){
|
||||||
|
// 3、若有, 直接更新affiliate的所得
|
||||||
|
Affiliate affiliate = baseMapper.selectById(account.getInvitationCode());
|
||||||
|
Float payerTotal = paymentInfo.getPayerTotal();
|
||||||
|
|
||||||
|
if (payerTotal > 0){
|
||||||
|
// 分配新用户首次订阅所付费用的25%作为佣金
|
||||||
|
BigDecimal commission = BigDecimal.valueOf(payerTotal).multiply(new BigDecimal("0.25"));
|
||||||
|
BigDecimal monthlyEarning = BigDecimal.valueOf(affiliate.getMonthlyEarnings()).add(commission);
|
||||||
|
BigDecimal unpaidEarnings = BigDecimal.valueOf(affiliate.getUnpaidEarnings()).add(commission);
|
||||||
|
int visits = affiliate.getVisits() + 1;
|
||||||
|
affiliate.setMonthlyEarnings(monthlyEarning.floatValue());
|
||||||
|
affiliate.setUnpaidEarnings(unpaidEarnings.floatValue());
|
||||||
|
affiliate.setVisits(visits);
|
||||||
|
affiliate.setUpdateTime(LocalDateTime.now());
|
||||||
|
baseMapper.updateById(affiliate);
|
||||||
|
|
||||||
|
orderInfo.setIsCommissionCalculated((byte)1);
|
||||||
|
|
||||||
|
// 4、添加到t_affiliate_income
|
||||||
|
AffiliateIncome affiliateIncome = new AffiliateIncome();
|
||||||
|
affiliateIncome.setAffiliateId(affiliate.getId());
|
||||||
|
affiliateIncome.setAffiliateAccountId(affiliate.getAccountId());
|
||||||
|
affiliateIncome.setInviteeAccountId(accountId);
|
||||||
|
affiliateIncome.setAmount(payerTotal);
|
||||||
|
affiliateIncome.setPaymentTime(paymentInfo.getCreateTime());
|
||||||
|
affiliateIncome.setCommission(commission.floatValue());
|
||||||
|
affiliateIncome.setCreateTime(LocalDateTime.now());
|
||||||
|
affiliateIncomeMapper.insert(affiliateIncome);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
orderInfo.setIsFirstSubscription((byte)1);
|
||||||
|
orderInfo.setUpdateTime(LocalDateTime.now());
|
||||||
|
orderInfoService.updateById(orderInfo);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
redisUtil.addToString(RedisUtil.PAYMENT_INFO_LAST_SCAN_TIME, currentTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean affiliateLinkViewsIncrease(Long affiliateId) {
|
||||||
|
redisUtil.increaseAffiliateLinkViewCount(affiliateId);
|
||||||
|
return Boolean.TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Long getAffiliateLinkViewCount(Long affiliateId) {
|
||||||
|
return redisUtil.getAffiliateLinkViewCount(affiliateId);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查看每个affiliate带来收入的详情
|
||||||
|
@Override
|
||||||
|
public IPage<AffiliateInvitationDetailsVO> getEachAffiliateGeneratedRevenue(AffiliateQueryDTO affiliateQueryDTO) {
|
||||||
|
if (Objects.isNull(affiliateQueryDTO.getAffiliateId())){
|
||||||
|
throw new BusinessException("Please specify the affiliate ID.", ResultEnum.PROMPT.getCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
QueryWrapper<AffiliateIncome> affiliateIncomeQueryWrapper = new QueryWrapper<>();
|
||||||
|
affiliateIncomeQueryWrapper
|
||||||
|
.gt(!StringUtils.isNullOrEmpty(affiliateQueryDTO.getStartTime()), "create_time", affiliateQueryDTO.getStartTime())
|
||||||
|
.lt(!StringUtils.isNullOrEmpty(affiliateQueryDTO.getEndTime()), "create_time", affiliateQueryDTO.getEndTime())
|
||||||
|
.eq(!Objects.isNull(affiliateQueryDTO.getAffiliateId()), "affiliate_id", affiliateQueryDTO.getAffiliateId())
|
||||||
|
.orderByDesc(affiliateQueryDTO.getOrder().equals("DESC"), "create_time");
|
||||||
|
IPage<AffiliateIncome> affiliateIncomePage = affiliateIncomeMapper.selectPage(new Page<>(affiliateQueryDTO.getPage(), affiliateQueryDTO.getSize()), affiliateIncomeQueryWrapper);
|
||||||
|
return affiliateIncomePage.convert((Function<AffiliateIncome, AffiliateInvitationDetailsVO>) affiliateIncome -> {
|
||||||
|
AffiliateInvitationDetailsVO affiliateInvitationDetailsVO = CopyUtil.copyObject(affiliateIncome, AffiliateInvitationDetailsVO.class);
|
||||||
|
affiliateInvitationDetailsVO.setAccountId(affiliateIncome.getInviteeAccountId());
|
||||||
|
affiliateInvitationDetailsVO.setUsername(accountService.getBaseMapper().selectById(affiliateIncome.getInviteeAccountId()).getUserName());
|
||||||
|
affiliateInvitationDetailsVO.setFirstSubscriptionPaymentAmount(affiliateIncome.getAmount());
|
||||||
|
affiliateInvitationDetailsVO.setCommission(affiliateIncome.getCommission());
|
||||||
|
affiliateInvitationDetailsVO.setTime(affiliateIncome.getPaymentTime());
|
||||||
|
return affiliateInvitationDetailsVO;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void commissionCalculation(Integer year, Integer month) {
|
||||||
|
if (Objects.isNull(year)) {
|
||||||
|
year = LocalDateTime.now().getYear();
|
||||||
|
}
|
||||||
|
if (Objects.isNull(month)) {
|
||||||
|
month = LocalDateTime.now().getMonthValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Map<String, Object>> monthlyAffiliateIncome = affiliateIncomeMapper.getMonthlyAffiliateIncome(year, month);
|
||||||
|
// 1、总收入(近一个月通过affiliate产生的收入),未支付的金额 affiliate表中unpaid的总和
|
||||||
|
Double totalAmount = 0.0;
|
||||||
|
Double totalCommission = 0.0;
|
||||||
|
if (!monthlyAffiliateIncome.isEmpty()){
|
||||||
|
Map<String, Object> monthlyIncome = monthlyAffiliateIncome.get(0);
|
||||||
|
totalAmount = (Double) monthlyIncome.get("totalAmount");
|
||||||
|
totalCommission = (Double) monthlyIncome.get("totalCommission");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2、本月新注册的Affiliate
|
||||||
|
Map<String, Long> monthlyApprovedAffiliate = baseMapper.getMonthlyApprovedAffiliate(year, month);
|
||||||
|
Long count = monthlyApprovedAffiliate.get("count");
|
||||||
|
|
||||||
|
AffiliateEmailParamsDTO affiliateEmailParamsDTO = new AffiliateEmailParamsDTO();
|
||||||
|
affiliateEmailParamsDTO.setTotalProgramRevenue(totalAmount.toString());
|
||||||
|
affiliateEmailParamsDTO.setNewApprovedAffiliates(count.toString());
|
||||||
|
affiliateEmailParamsDTO.setUnpaidEarnings(totalCommission.toString());
|
||||||
|
affiliateEmailParamsDTO.setPaidEarnings("0");
|
||||||
|
|
||||||
|
String receiverEmail = "xupei3360@163.com";
|
||||||
|
// String receiverEmail = "kimwong@code-create.com.hk";
|
||||||
|
// 邮件通知
|
||||||
|
SendEmailUtil.affiliateEmailReminder(receiverEmail, affiliateEmailParamsDTO, "summary");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Affiliate getByAccountId(Long accountId) {
|
||||||
|
QueryWrapper<Affiliate> queryWrapper = new QueryWrapper<>();
|
||||||
|
queryWrapper.eq("account_id", accountId).orderByDesc("id").last("limit 1");
|
||||||
|
|
||||||
|
return baseMapper.selectOne(queryWrapper);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -217,7 +217,8 @@ public class AliPayServiceImpl implements AliPayService {
|
|||||||
creditsService.insertToCreditsDetail(orderByOrderNo.getAccountId(),
|
creditsService.insertToCreditsDetail(orderByOrderNo.getAccountId(),
|
||||||
CreditsEventsEnum.BUY_CREDITS.getName() + "--Alipay",
|
CreditsEventsEnum.BUY_CREDITS.getName() + "--Alipay",
|
||||||
String.valueOf((Long.parseLong(CreditsEventsEnum.BUY_CREDITS.getValue()) * quantity)),
|
String.valueOf((Long.parseLong(CreditsEventsEnum.BUY_CREDITS.getValue()) * quantity)),
|
||||||
"positive");
|
"positive",
|
||||||
|
orderByOrderNo.getOrderNo());
|
||||||
} finally {
|
} finally {
|
||||||
//要主动释放锁
|
//要主动释放锁
|
||||||
lock.unlock();
|
lock.unlock();
|
||||||
@@ -320,7 +321,8 @@ public class AliPayServiceImpl implements AliPayService {
|
|||||||
creditsService.insertToCreditsDetail(orderByOrderNo.getAccountId(),
|
creditsService.insertToCreditsDetail(orderByOrderNo.getAccountId(),
|
||||||
CreditsEventsEnum.BUY_CREDITS.getName() + "--Alipay",
|
CreditsEventsEnum.BUY_CREDITS.getName() + "--Alipay",
|
||||||
String.valueOf((Long.parseLong(CreditsEventsEnum.BUY_CREDITS.getValue()) * quantity)),
|
String.valueOf((Long.parseLong(CreditsEventsEnum.BUY_CREDITS.getValue()) * quantity)),
|
||||||
"positive");
|
"positive",
|
||||||
|
orderByOrderNo.getOrderNo());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -393,7 +395,7 @@ public class AliPayServiceImpl implements AliPayService {
|
|||||||
// 更新积分状态
|
// 更新积分状态
|
||||||
OrderInfo orderByOrderNo = orderInfoService.getOrderByOrderNo(orderNo);
|
OrderInfo orderByOrderNo = orderInfoService.getOrderByOrderNo(orderNo);
|
||||||
// creditsService.creditsRefund(orderByOrderNo.getAccountId(), orderByOrderNo.getTotalFee() / Integer.parseInt(CreditsEventsEnum.PRICE.getValue()));
|
// creditsService.creditsRefund(orderByOrderNo.getAccountId(), orderByOrderNo.getTotalFee() / Integer.parseInt(CreditsEventsEnum.PRICE.getValue()));
|
||||||
creditsService.creditsRefund(orderByOrderNo.getAccountId(), (int)(orderByOrderNo.getTotalFee() / Float.parseFloat(CreditsEventsEnum.PRICE.getValue())));
|
creditsService.creditsRefund(orderByOrderNo.getAccountId(), (int)(orderByOrderNo.getTotalFee() / Float.parseFloat(CreditsEventsEnum.PRICE.getValue())), orderNo);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
log.info("调用失败,返回码 ===> " + response.getCode() + ", 返回描述 ===> " + response.getMsg());
|
log.info("调用失败,返回码 ===> " + response.getCode() + ", 返回描述 ===> " + response.getMsg());
|
||||||
|
|||||||
@@ -248,7 +248,8 @@ public class AlipayHKServiceImpl implements AlipayHKService {
|
|||||||
creditsService.insertToCreditsDetail(orderByOrderNo.getAccountId(),
|
creditsService.insertToCreditsDetail(orderByOrderNo.getAccountId(),
|
||||||
CreditsEventsEnum.BUY_CREDITS.getName() + "--AlipayHK",
|
CreditsEventsEnum.BUY_CREDITS.getName() + "--AlipayHK",
|
||||||
String.valueOf((Long.parseLong(CreditsEventsEnum.BUY_CREDITS.getValue()) * quantity)),
|
String.valueOf((Long.parseLong(CreditsEventsEnum.BUY_CREDITS.getValue()) * quantity)),
|
||||||
"positive");
|
"positive",
|
||||||
|
orderByOrderNo.getOrderNo());
|
||||||
log.info("用户:{} 积分信息更新成功",orderByOrderNo.getAccountId());
|
log.info("用户:{} 积分信息更新成功",orderByOrderNo.getAccountId());
|
||||||
} finally {
|
} finally {
|
||||||
//要主动释放锁
|
//要主动释放锁
|
||||||
|
|||||||
@@ -216,6 +216,8 @@ public class CollectionElementServiceImpl extends ServiceImpl<CollectionElementM
|
|||||||
collectionElementMapper.deleteBatchIds(ids);
|
collectionElementMapper.deleteBatchIds(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 该方法已不再使用 */
|
||||||
|
@Deprecated
|
||||||
@Override
|
@Override
|
||||||
public GenerateCollectionItemVO generatePrint(CollectionGeneratePrintDTO generatePrintDTO) {
|
public GenerateCollectionItemVO generatePrint(CollectionGeneratePrintDTO generatePrintDTO) {
|
||||||
Long userId = UserContext.getUserHolder().getId();
|
Long userId = UserContext.getUserHolder().getId();
|
||||||
@@ -914,7 +916,7 @@ public class CollectionElementServiceImpl extends ServiceImpl<CollectionElementM
|
|||||||
generate.setAccountId(userId);
|
generate.setAccountId(userId);
|
||||||
generate.setLevel1Type(CollectionLevel1TypeEnum.PRINT_BOARD.getRealName());
|
generate.setLevel1Type(CollectionLevel1TypeEnum.PRINT_BOARD.getRealName());
|
||||||
generate.setGenerateType("synthesis");
|
generate.setGenerateType("synthesis");
|
||||||
generate.setModelName("Image Synthesis Model");
|
// generate.setModelName("Image Synthesis Model");
|
||||||
generate.setCreateDate(DateUtil.getByTimeZone(timeZone));
|
generate.setCreateDate(DateUtil.getByTimeZone(timeZone));
|
||||||
return generate;
|
return generate;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
|
|||||||
return account.getCredits().toString();
|
return account.getCredits().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void creditsRefund(Long accountId, Integer quantity) {
|
public void creditsRefund(Long accountId, Integer quantity, String orderNo) {
|
||||||
BigDecimal existingCredits = accountMapper.selectById(accountId).getCredits();
|
BigDecimal existingCredits = accountMapper.selectById(accountId).getCredits();
|
||||||
BigDecimal newCredits = new BigDecimal(CreditsEventsEnum.BUY_CREDITS.getValue()).multiply(new BigDecimal(quantity));
|
BigDecimal newCredits = new BigDecimal(CreditsEventsEnum.BUY_CREDITS.getValue()).multiply(new BigDecimal(quantity));
|
||||||
BigDecimal subtracted = existingCredits.subtract(newCredits);
|
BigDecimal subtracted = existingCredits.subtract(newCredits);
|
||||||
@@ -111,7 +111,7 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
|
|||||||
insertToCreditsDetail(accountId,
|
insertToCreditsDetail(accountId,
|
||||||
CreditsEventsEnum.REFUND.getName() + "--Stripe",
|
CreditsEventsEnum.REFUND.getName() + "--Stripe",
|
||||||
String.valueOf((Long.parseLong(CreditsEventsEnum.BUY_CREDITS.getValue()) * quantity)),
|
String.valueOf((Long.parseLong(CreditsEventsEnum.BUY_CREDITS.getValue()) * quantity)),
|
||||||
"negative");
|
"negative", orderNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -122,7 +122,7 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
|
|||||||
* @param changeType 变更类型 : positive->增 negative->减
|
* @param changeType 变更类型 : positive->增 negative->减
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void insertToCreditsDetail(Long accountId, String changeEvent, String credits, String changeType) {
|
public void insertToCreditsDetail(Long accountId, String changeEvent, String credits, String changeType, String orderNo) {
|
||||||
CreditsDetail creditsDetail = new CreditsDetail();
|
CreditsDetail creditsDetail = new CreditsDetail();
|
||||||
Account account = accountMapper.selectById(accountId);
|
Account account = accountMapper.selectById(accountId);
|
||||||
// BigDecimal finalCredits;
|
// BigDecimal finalCredits;
|
||||||
@@ -137,6 +137,7 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
|
|||||||
creditsDetail.setAccountId(accountId);
|
creditsDetail.setAccountId(accountId);
|
||||||
creditsDetail.setChangeEvent(changeEvent);
|
creditsDetail.setChangeEvent(changeEvent);
|
||||||
creditsDetail.setChangedCredits(changeCredits);
|
creditsDetail.setChangedCredits(changeCredits);
|
||||||
|
creditsDetail.setTaskId(orderNo);
|
||||||
// creditsDetail.setCredits(finalCredits);
|
// creditsDetail.setCredits(finalCredits);
|
||||||
creditsDetail.setCredits(account.getCredits());
|
creditsDetail.setCredits(account.getCredits());
|
||||||
creditsDetail.setCreateTime(LocalDateTime.now());
|
creditsDetail.setCreateTime(LocalDateTime.now());
|
||||||
|
|||||||
@@ -289,7 +289,7 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
if (b) creditsService.insertToCreditsDetail(accountId,
|
if (b) creditsService.insertToCreditsDetail(accountId,
|
||||||
CreditsEventsEnum.TO_PRODUCT_IMAGE.getName(),
|
CreditsEventsEnum.TO_PRODUCT_IMAGE.getName(),
|
||||||
CreditsEventsEnum.TO_PRODUCT_IMAGE.getValue(),
|
CreditsEventsEnum.TO_PRODUCT_IMAGE.getValue(),
|
||||||
"negative");
|
"negative", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -764,7 +764,7 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
|||||||
if (b) creditsService.insertToCreditsDetail(accountId,
|
if (b) creditsService.insertToCreditsDetail(accountId,
|
||||||
CreditsEventsEnum.RELIGHT.getName(),
|
CreditsEventsEnum.RELIGHT.getName(),
|
||||||
CreditsEventsEnum.RELIGHT.getValue(),
|
CreditsEventsEnum.RELIGHT.getValue(),
|
||||||
"negative");
|
"negative", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,15 +4,19 @@ package com.ai.da.service.impl;
|
|||||||
import com.ai.da.common.context.UserContext;
|
import com.ai.da.common.context.UserContext;
|
||||||
import com.ai.da.common.enums.CreditsEventsEnum;
|
import com.ai.da.common.enums.CreditsEventsEnum;
|
||||||
import com.ai.da.common.enums.OrderStatusEnum;
|
import com.ai.da.common.enums.OrderStatusEnum;
|
||||||
|
import com.ai.da.common.enums.ProductEnum;
|
||||||
import com.ai.da.common.response.PageBaseResponse;
|
import com.ai.da.common.response.PageBaseResponse;
|
||||||
import com.ai.da.common.utils.OrderNoUtils;
|
import com.ai.da.common.utils.OrderNoUtils;
|
||||||
import com.ai.da.mapper.primary.OrderInfoMapper;
|
import com.ai.da.mapper.primary.OrderInfoMapper;
|
||||||
|
import com.ai.da.mapper.primary.PaymentInfoMapper;
|
||||||
import com.ai.da.mapper.primary.ProductMapper;
|
import com.ai.da.mapper.primary.ProductMapper;
|
||||||
import com.ai.da.mapper.primary.entity.OrderInfo;
|
import com.ai.da.mapper.primary.entity.OrderInfo;
|
||||||
|
import com.ai.da.mapper.primary.entity.PaymentInfo;
|
||||||
import com.ai.da.model.dto.QueryPageByTimeDTO;
|
import com.ai.da.model.dto.QueryPageByTimeDTO;
|
||||||
import com.ai.da.model.vo.AuthPrincipalVo;
|
import com.ai.da.model.vo.AuthPrincipalVo;
|
||||||
import com.ai.da.service.OrderInfoService;
|
import com.ai.da.service.OrderInfoService;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import io.netty.util.internal.StringUtil;
|
import io.netty.util.internal.StringUtil;
|
||||||
@@ -34,9 +38,13 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
|||||||
@Resource
|
@Resource
|
||||||
private ProductMapper productMapper;
|
private ProductMapper productMapper;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private PaymentInfoMapper paymentInfoMapper;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OrderInfo createOrderByProductId(Integer amount, String paymentType) {
|
public OrderInfo createOrderByProductId(Integer amount, String paymentType) {
|
||||||
|
|
||||||
|
|
||||||
//查找已存在但未支付的订单
|
//查找已存在但未支付的订单
|
||||||
/*OrderInfo orderInfo = this.getNoPayOrderByProductId(amount, paymentType);
|
/*OrderInfo orderInfo = this.getNoPayOrderByProductId(amount, paymentType);
|
||||||
if( orderInfo != null){
|
if( orderInfo != null){
|
||||||
@@ -51,7 +59,7 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
|||||||
//生成订单
|
//生成订单
|
||||||
OrderInfo orderInfo = new OrderInfo();
|
OrderInfo orderInfo = new OrderInfo();
|
||||||
orderInfo.setAccountId(accountId);
|
orderInfo.setAccountId(accountId);
|
||||||
orderInfo.setTitle("积分购买 X" + amount );
|
orderInfo.setTitle("积分购买 X" + amount);
|
||||||
orderInfo.setOrderNo(OrderNoUtils.getOrderNo()); //订单号 ??
|
orderInfo.setOrderNo(OrderNoUtils.getOrderNo()); //订单号 ??
|
||||||
// orderInfo.setProductId(amount);
|
// orderInfo.setProductId(amount);
|
||||||
// orderInfo.setTotalFee(Integer.parseInt(CreditsEventsEnum.PRICE.getValue()) * amount); // 元 HKD
|
// orderInfo.setTotalFee(Integer.parseInt(CreditsEventsEnum.PRICE.getValue()) * amount); // 元 HKD
|
||||||
@@ -63,8 +71,37 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
|||||||
return orderInfo;
|
return orderInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public OrderInfo createOrderByProductId(Integer amount, String paymentType, ProductEnum product) {
|
||||||
|
|
||||||
|
//获取商品信息
|
||||||
|
// Product product = productMapper.selectById(amount);
|
||||||
|
String title;
|
||||||
|
if (product.equals(ProductEnum.CreditsProduct)) {
|
||||||
|
title = "积分购买 X" + amount;
|
||||||
|
} else {
|
||||||
|
title = product.getName();
|
||||||
|
}
|
||||||
|
AuthPrincipalVo userHolder = UserContext.getUserHolder();
|
||||||
|
Long accountId = userHolder.getId();
|
||||||
|
|
||||||
|
//生成订单
|
||||||
|
OrderInfo orderInfo = new OrderInfo();
|
||||||
|
orderInfo.setAccountId(accountId);
|
||||||
|
orderInfo.setTitle(title);
|
||||||
|
orderInfo.setOrderNo(OrderNoUtils.getOrderNo()); // 自定义订单号
|
||||||
|
// orderInfo.setProductId(amount);
|
||||||
|
// orderInfo.setTotalFee(Integer.parseInt(CreditsEventsEnum.PRICE.getValue()) * amount); // 元 HKD
|
||||||
|
orderInfo.setTotalFee((float) (product.getPrice() * amount)); // 元 HKD
|
||||||
|
orderInfo.setOrderStatus(OrderStatusEnum.NOT_PAY.getType()); //未支付
|
||||||
|
orderInfo.setPaymentType(paymentType);
|
||||||
|
baseMapper.insert(orderInfo);
|
||||||
|
|
||||||
|
return orderInfo;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 存储订单二维码
|
* 存储订单二维码
|
||||||
|
*
|
||||||
* @param orderNo
|
* @param orderNo
|
||||||
* @param codeUrl
|
* @param codeUrl
|
||||||
*/
|
*/
|
||||||
@@ -82,6 +119,7 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询订单列表,并倒序查询
|
* 查询订单列表,并倒序查询
|
||||||
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@@ -93,6 +131,7 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据订单号更新订单状态
|
* 根据订单号更新订单状态
|
||||||
|
*
|
||||||
* @param orderNo
|
* @param orderNo
|
||||||
* @param orderStatus
|
* @param orderStatus
|
||||||
*/
|
*/
|
||||||
@@ -112,6 +151,7 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据订单号获取订单状态
|
* 根据订单号获取订单状态
|
||||||
|
*
|
||||||
* @param orderNo
|
* @param orderNo
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -121,7 +161,7 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
|||||||
QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
|
QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
|
||||||
queryWrapper.eq("order_no", orderNo);
|
queryWrapper.eq("order_no", orderNo);
|
||||||
OrderInfo orderInfo = baseMapper.selectOne(queryWrapper);
|
OrderInfo orderInfo = baseMapper.selectOne(queryWrapper);
|
||||||
if(orderInfo == null){
|
if (orderInfo == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return orderInfo.getOrderStatus();
|
return orderInfo.getOrderStatus();
|
||||||
@@ -129,6 +169,7 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询创建超过minutes分钟并且未支付的订单
|
* 查询创建超过minutes分钟并且未支付的订单
|
||||||
|
*
|
||||||
* @param minutes
|
* @param minutes
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -149,6 +190,7 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据订单号获取订单
|
* 根据订单号获取订单
|
||||||
|
*
|
||||||
* @param orderNo
|
* @param orderNo
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -166,6 +208,7 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
|||||||
/**
|
/**
|
||||||
* 根据商品id查询未支付订单
|
* 根据商品id查询未支付订单
|
||||||
* 防止重复创建订单对象
|
* 防止重复创建订单对象
|
||||||
|
*
|
||||||
* @param productId
|
* @param productId
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
@@ -181,16 +224,16 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PageBaseResponse<OrderInfo> getOrderByPage(QueryPageByTimeDTO queryPageByTimeDTO){
|
public PageBaseResponse<OrderInfo> getOrderByPage(QueryPageByTimeDTO queryPageByTimeDTO) {
|
||||||
QueryWrapper<OrderInfo> qw = new QueryWrapper<>();
|
QueryWrapper<OrderInfo> qw = new QueryWrapper<>();
|
||||||
qw.eq("account_id",UserContext.getUserHolder().getId());
|
qw.eq("account_id", UserContext.getUserHolder().getId());
|
||||||
|
|
||||||
String startTime = queryPageByTimeDTO.getStartTime();
|
String startTime = queryPageByTimeDTO.getStartTime();
|
||||||
String endTime = queryPageByTimeDTO.getEndTime();
|
String endTime = queryPageByTimeDTO.getEndTime();
|
||||||
if (StringUtil.isNullOrEmpty(startTime)){
|
if (StringUtil.isNullOrEmpty(startTime)) {
|
||||||
startTime = "2024-02-01 00:00:00";
|
startTime = "2024-02-01 00:00:00";
|
||||||
}
|
}
|
||||||
if (StringUtil.isNullOrEmpty(endTime)){
|
if (StringUtil.isNullOrEmpty(endTime)) {
|
||||||
LocalDateTime now = LocalDateTime.now();
|
LocalDateTime now = LocalDateTime.now();
|
||||||
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
endTime = now.format(dateTimeFormatter);
|
endTime = now.format(dateTimeFormatter);
|
||||||
@@ -206,11 +249,28 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
|||||||
return PageBaseResponse.success(orderInfo);
|
return PageBaseResponse.success(orderInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateOrderNoById(Long id, String orderNo){
|
public void updateOrderNoById(Long id, String orderNo) {
|
||||||
OrderInfo orderInfo = new OrderInfo();
|
OrderInfo orderInfo = new OrderInfo();
|
||||||
orderInfo.setId(id);
|
orderInfo.setId(id);
|
||||||
orderInfo.setOrderNo(orderNo);
|
orderInfo.setOrderNo(orderNo);
|
||||||
|
|
||||||
baseMapper.updateById(orderInfo);
|
baseMapper.updateById(orderInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void updateTotalFeeByOrderNo(String orderNo) {
|
||||||
|
QueryWrapper<PaymentInfo> qw = new QueryWrapper<>();
|
||||||
|
qw.eq("order_no", orderNo);
|
||||||
|
List<PaymentInfo> paymentInfos = paymentInfoMapper.selectList(qw);
|
||||||
|
Float sum = paymentInfos.stream()
|
||||||
|
.map(PaymentInfo::getPayerTotal)
|
||||||
|
.reduce(0f, Float::sum);
|
||||||
|
|
||||||
|
baseMapper.update(
|
||||||
|
new OrderInfo(),
|
||||||
|
new UpdateWrapper<OrderInfo>()
|
||||||
|
.eq("order_no", orderNo)
|
||||||
|
.set("total_fee", sum)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -441,11 +441,11 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
|
|||||||
* 申请退款
|
* 申请退款
|
||||||
*/
|
*/
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public Boolean refundOrder(String orderId, String reason) throws IOException {
|
public Boolean refundOrder(String orderNo, String reason) throws IOException {
|
||||||
|
|
||||||
RefundInfo refundByOrderNo = refundsInfoService.createRefundByOrderNo(orderId, reason);
|
RefundInfo refundByOrderNo = refundsInfoService.createRefundByOrderNo(orderNo, reason);
|
||||||
|
|
||||||
OrdersGetRequest ordersGetRequest = new OrdersGetRequest(orderId);
|
OrdersGetRequest ordersGetRequest = new OrdersGetRequest(orderNo);
|
||||||
PayPalClient payPalClient = new PayPalClient();
|
PayPalClient payPalClient = new PayPalClient();
|
||||||
HttpResponse<com.paypal.orders.Order> ordersGetResponse = null;
|
HttpResponse<com.paypal.orders.Order> ordersGetResponse = null;
|
||||||
ordersGetRequest.authorization("Bearer " + getOAuth());
|
ordersGetRequest.authorization("Bearer " + getOAuth());
|
||||||
@@ -461,7 +461,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
|
|||||||
request.authorization("Bearer " + getOAuth());
|
request.authorization("Bearer " + getOAuth());
|
||||||
request.prefer("return=representation");
|
request.prefer("return=representation");
|
||||||
|
|
||||||
OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(orderId);
|
OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(orderNo);
|
||||||
request.requestBody(buildRefundRequestBody(String.valueOf(orderInfo.getTotalFee()), reason));
|
request.requestBody(buildRefundRequestBody(String.valueOf(orderInfo.getTotalFee()), reason));
|
||||||
HttpResponse<com.paypal.payments.Refund> response = null;
|
HttpResponse<com.paypal.payments.Refund> response = null;
|
||||||
try {
|
try {
|
||||||
@@ -476,7 +476,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
|
|||||||
//进行数据库操作,修改状态为已退款(配合回调和退款查询确定退款成功)
|
//进行数据库操作,修改状态为已退款(配合回调和退款查询确定退款成功)
|
||||||
|
|
||||||
//更新订单状态
|
//更新订单状态
|
||||||
orderInfoService.updateStatusByOrderNo(orderId, OrderStatusEnum.REFUND_SUCCESS);
|
orderInfoService.updateStatusByOrderNo(orderNo, OrderStatusEnum.REFUND_SUCCESS);
|
||||||
|
|
||||||
refundsInfoService.updateRefundForPayPal(
|
refundsInfoService.updateRefundForPayPal(
|
||||||
refundByOrderNo.getId(),
|
refundByOrderNo.getId(),
|
||||||
@@ -485,14 +485,14 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
|
|||||||
AliPayTradeStateEnum.REFUND_SUCCESS.getType()); //退款成功
|
AliPayTradeStateEnum.REFUND_SUCCESS.getType()); //退款成功
|
||||||
|
|
||||||
// 更新积分状态
|
// 更新积分状态
|
||||||
OrderInfo orderByOrderNo = orderInfoService.getOrderByOrderNo(orderId);
|
OrderInfo orderByOrderNo = orderInfoService.getOrderByOrderNo(orderNo);
|
||||||
// creditsService.creditsRefund(orderByOrderNo.getAccountId(), orderByOrderNo.getTotalFee() / Integer.parseInt(CreditsEventsEnum.PRICE.getValue()));
|
// creditsService.creditsRefund(orderByOrderNo.getAccountId(), orderByOrderNo.getTotalFee() / Integer.parseInt(CreditsEventsEnum.PRICE.getValue()));
|
||||||
creditsService.creditsRefund(orderByOrderNo.getAccountId(), (int)(orderByOrderNo.getTotalFee() / Float.parseFloat(CreditsEventsEnum.PRICE.getValue())));
|
creditsService.creditsRefund(orderByOrderNo.getAccountId(), (int)(orderByOrderNo.getTotalFee() / Float.parseFloat(CreditsEventsEnum.PRICE.getValue())), orderNo);
|
||||||
log.info("退款成功");
|
log.info("退款成功");
|
||||||
result = Boolean.TRUE;
|
result = Boolean.TRUE;
|
||||||
} else {
|
} else {
|
||||||
//更新订单状态
|
//更新订单状态
|
||||||
orderInfoService.updateStatusByOrderNo(orderId, OrderStatusEnum.REFUND_ABNORMAL);
|
orderInfoService.updateStatusByOrderNo(orderNo, OrderStatusEnum.REFUND_ABNORMAL);
|
||||||
|
|
||||||
//更新退款单
|
//更新退款单
|
||||||
refundsInfoService.updateRefundForPayPal(
|
refundsInfoService.updateRefundForPayPal(
|
||||||
@@ -571,19 +571,19 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
|
|||||||
|
|
||||||
// 处理当前订单
|
// 处理当前订单
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public void processOrder(String orderId) {
|
public void processOrder(String orderNo) {
|
||||||
// 1、确定当前订单是否已经被扣款
|
// 1、确定当前订单是否已经被扣款
|
||||||
OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(orderId);
|
OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(orderNo);
|
||||||
if (orderInfo.getOrderStatus().equals(OrderStatusEnum.SUCCESS.getType())) {
|
if (orderInfo.getOrderStatus().equals(OrderStatusEnum.SUCCESS.getType())) {
|
||||||
// 直接返回
|
// 直接返回
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// 发起扣款请求
|
// 发起扣款请求
|
||||||
Order capturedOrder = captureOrder(orderId);
|
Order capturedOrder = captureOrder(orderNo);
|
||||||
// 业务处理
|
// 业务处理
|
||||||
if (PayPalOrderStatusEnum.COMPLETED.getStatus().equals(capturedOrder.status())) {
|
if (PayPalOrderStatusEnum.COMPLETED.getStatus().equals(capturedOrder.status())) {
|
||||||
//更新订单状态
|
//更新订单状态
|
||||||
orderInfoService.updateStatusByOrderNo(orderId, OrderStatusEnum.SUCCESS);
|
orderInfoService.updateStatusByOrderNo(orderNo, OrderStatusEnum.SUCCESS);
|
||||||
//记录支付日志
|
//记录支付日志
|
||||||
paymentInfoService.createPaymentInfoForPayPal(capturedOrder);
|
paymentInfoService.createPaymentInfoForPayPal(capturedOrder);
|
||||||
float quantity = orderInfo.getTotalFee() / Float.parseFloat(CreditsEventsEnum.PRICE.getValue());
|
float quantity = orderInfo.getTotalFee() / Float.parseFloat(CreditsEventsEnum.PRICE.getValue());
|
||||||
@@ -593,7 +593,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
|
|||||||
creditsService.insertToCreditsDetail(orderInfo.getAccountId(),
|
creditsService.insertToCreditsDetail(orderInfo.getAccountId(),
|
||||||
CreditsEventsEnum.BUY_CREDITS.getName() + "--PayPal",
|
CreditsEventsEnum.BUY_CREDITS.getName() + "--PayPal",
|
||||||
String.valueOf((Long.parseLong(CreditsEventsEnum.BUY_CREDITS.getValue()) * quantity)),
|
String.valueOf((Long.parseLong(CreditsEventsEnum.BUY_CREDITS.getValue()) * quantity)),
|
||||||
"positive");
|
"positive", orderNo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -637,7 +637,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
|
|||||||
creditsService.insertToCreditsDetail(orderByOrderNo.getAccountId(),
|
creditsService.insertToCreditsDetail(orderByOrderNo.getAccountId(),
|
||||||
CreditsEventsEnum.BUY_CREDITS.getName() + "--Paypal",
|
CreditsEventsEnum.BUY_CREDITS.getName() + "--Paypal",
|
||||||
String.valueOf((Long.parseLong(CreditsEventsEnum.BUY_CREDITS.getValue()) * quantity)),
|
String.valueOf((Long.parseLong(CreditsEventsEnum.BUY_CREDITS.getValue()) * quantity)),
|
||||||
"positive");
|
"positive", orderNo);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,49 @@
|
|||||||
package com.ai.da.service.impl;
|
package com.ai.da.service.impl;
|
||||||
|
|
||||||
|
import com.ai.da.common.context.UserContext;
|
||||||
import com.ai.da.common.enums.PayTypeEnum;
|
import com.ai.da.common.enums.PayTypeEnum;
|
||||||
|
import com.ai.da.common.response.PageBaseResponse;
|
||||||
import com.ai.da.mapper.primary.PaymentInfoMapper;
|
import com.ai.da.mapper.primary.PaymentInfoMapper;
|
||||||
import com.ai.da.mapper.primary.entity.PaymentInfo;
|
import com.ai.da.mapper.primary.entity.PaymentInfo;
|
||||||
import com.ai.da.model.dto.AlipayHKCallbackDTO;
|
import com.ai.da.model.dto.AlipayHKCallbackDTO;
|
||||||
import com.ai.da.service.PaymentInfoService;
|
import com.ai.da.model.dto.QueryPageByTimeDTO;
|
||||||
|
import com.ai.da.model.vo.OrderListVO;
|
||||||
|
import com.ai.da.service.*;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.paypal.orders.Order;
|
import com.paypal.orders.Order;
|
||||||
|
import com.stripe.Stripe;
|
||||||
|
import com.stripe.exception.StripeException;
|
||||||
|
import com.stripe.model.Charge;
|
||||||
|
import com.stripe.model.Invoice;
|
||||||
|
import com.stripe.model.Subscription;
|
||||||
import com.stripe.model.checkout.Session;
|
import com.stripe.model.checkout.Session;
|
||||||
|
import io.netty.util.internal.StringUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, PaymentInfo> implements PaymentInfoService {
|
public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, PaymentInfo> implements PaymentInfoService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private StripeService stripeService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 记录支付日志:微信支付
|
* 记录支付日志:微信支付
|
||||||
* @param plainText
|
* @param plainText
|
||||||
@@ -50,7 +72,6 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
|
|||||||
paymentInfo.setOrderNo(orderNo);
|
paymentInfo.setOrderNo(orderNo);
|
||||||
paymentInfo.setPaymentType(PayTypeEnum.WXPAY.getType());
|
paymentInfo.setPaymentType(PayTypeEnum.WXPAY.getType());
|
||||||
paymentInfo.setTransactionId(transactionId);
|
paymentInfo.setTransactionId(transactionId);
|
||||||
paymentInfo.setTradeType(tradeType);
|
|
||||||
paymentInfo.setTradeState(tradeState);
|
paymentInfo.setTradeState(tradeState);
|
||||||
// 原来的单位是:分 Int 现改为:元 Float
|
// 原来的单位是:分 Int 现改为:元 Float
|
||||||
paymentInfo.setPayerTotal(payerTotal / 100.0F);
|
paymentInfo.setPayerTotal(payerTotal / 100.0F);
|
||||||
@@ -83,7 +104,6 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
|
|||||||
paymentInfo.setOrderNo(orderNo);
|
paymentInfo.setOrderNo(orderNo);
|
||||||
paymentInfo.setPaymentType(PayTypeEnum.ALIPAY.getType());
|
paymentInfo.setPaymentType(PayTypeEnum.ALIPAY.getType());
|
||||||
paymentInfo.setTransactionId(transactionId);
|
paymentInfo.setTransactionId(transactionId);
|
||||||
paymentInfo.setTradeType("电脑网站支付");
|
|
||||||
paymentInfo.setTradeState(tradeStatus);
|
paymentInfo.setTradeState(tradeStatus);
|
||||||
// 原来的单位是分 Int 现改为元 Long
|
// 原来的单位是分 Int 现改为元 Long
|
||||||
paymentInfo.setPayerTotal(totalAmountInt / 100.0F);
|
paymentInfo.setPayerTotal(totalAmountInt / 100.0F);
|
||||||
@@ -107,7 +127,6 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
|
|||||||
paymentInfo.setOrderNo(order.id());
|
paymentInfo.setOrderNo(order.id());
|
||||||
paymentInfo.setPaymentType(PayTypeEnum.PAYPAL.getType());
|
paymentInfo.setPaymentType(PayTypeEnum.PAYPAL.getType());
|
||||||
paymentInfo.setTransactionId(order.id());
|
paymentInfo.setTransactionId(order.id());
|
||||||
paymentInfo.setTradeType("电脑网站支付");
|
|
||||||
paymentInfo.setTradeState(order.status());
|
paymentInfo.setTradeState(order.status());
|
||||||
// todo 确认这里的数据单位是不是元
|
// todo 确认这里的数据单位是不是元
|
||||||
paymentInfo.setPayerTotal(totalAmountFloat);
|
paymentInfo.setPayerTotal(totalAmountFloat);
|
||||||
@@ -139,7 +158,6 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
|
|||||||
paymentInfo.setOrderNo(orderNo);
|
paymentInfo.setOrderNo(orderNo);
|
||||||
paymentInfo.setPaymentType(PayTypeEnum.ALIPAY_HK.getType());
|
paymentInfo.setPaymentType(PayTypeEnum.ALIPAY_HK.getType());
|
||||||
paymentInfo.setTransactionId(transactionId);
|
paymentInfo.setTransactionId(transactionId);
|
||||||
paymentInfo.setTradeType("电脑网站支付");
|
|
||||||
paymentInfo.setTradeState(tradeStatus);
|
paymentInfo.setTradeState(tradeStatus);
|
||||||
paymentInfo.setPayerTotal(totalAmountFloat);
|
paymentInfo.setPayerTotal(totalAmountFloat);
|
||||||
|
|
||||||
@@ -150,10 +168,10 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
|
|||||||
baseMapper.insert(paymentInfo);
|
baseMapper.insert(paymentInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void createOrUpdatePaymentInfoForStripe(Session session){
|
||||||
public void createPaymentInfoForStripe(Session session){
|
|
||||||
String orderId = session.getMetadata().get("orderId");
|
String orderId = session.getMetadata().get("orderId");
|
||||||
String status = session.getStatus();
|
String status = session.getStatus();
|
||||||
|
// 获取transactionId,从sessionId更改为invoiceId
|
||||||
String sessionId = session.getId();
|
String sessionId = session.getId();
|
||||||
Long amountTotal = session.getAmountTotal();
|
Long amountTotal = session.getAmountTotal();
|
||||||
// stripe 的支付金额单位是分
|
// stripe 的支付金额单位是分
|
||||||
@@ -163,7 +181,6 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
|
|||||||
paymentInfo.setOrderNo(orderId);
|
paymentInfo.setOrderNo(orderId);
|
||||||
paymentInfo.setPaymentType(PayTypeEnum.STRIPE.getType());
|
paymentInfo.setPaymentType(PayTypeEnum.STRIPE.getType());
|
||||||
paymentInfo.setTransactionId(sessionId);
|
paymentInfo.setTransactionId(sessionId);
|
||||||
paymentInfo.setTradeType("电脑网站支付");
|
|
||||||
paymentInfo.setTradeState(status);
|
paymentInfo.setTradeState(status);
|
||||||
paymentInfo.setPayerTotal(divide);
|
paymentInfo.setPayerTotal(divide);
|
||||||
Gson gson = new Gson();
|
Gson gson = new Gson();
|
||||||
@@ -173,12 +190,144 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
|
|||||||
baseMapper.insert(paymentInfo);
|
baseMapper.insert(paymentInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Value("${stripe.private-key}")
|
||||||
public PaymentInfo getPaymentInfoByOrderId(String orderId){
|
private String privateKey;
|
||||||
QueryWrapper<PaymentInfo> qw = new QueryWrapper<>();
|
public PaymentInfo createOrUpdatePaymentInfoForStripe(Invoice invoice){
|
||||||
qw.eq("order_no", orderId);
|
Stripe.apiKey = privateKey;
|
||||||
|
// 获取transactionId,从sessionId更改为invoiceId
|
||||||
|
String invoiceId = invoice.getId();
|
||||||
|
|
||||||
return baseMapper.selectOne(qw);
|
QueryWrapper<PaymentInfo> qw = new QueryWrapper<>();
|
||||||
|
qw.eq("transaction_id", invoiceId);
|
||||||
|
PaymentInfo paymentInfo = baseMapper.selectOne(qw);
|
||||||
|
String status = invoice.getStatus();
|
||||||
|
// 判断当前支付是否已经被记录,确保同一个支付不会被重复记录
|
||||||
|
if (Objects.isNull(paymentInfo)){
|
||||||
|
String orderNo;
|
||||||
|
try {
|
||||||
|
if (invoice.getBillingReason().equals("manual")){
|
||||||
|
// 手动创建的发票,针对one-time支付
|
||||||
|
orderNo = invoice.getLines().getData().get(0).getPrice().getMetadata().get("orderId");
|
||||||
|
}else {
|
||||||
|
String subscriptionId = invoice.getSubscription();
|
||||||
|
// 从subscription中获取orderNo
|
||||||
|
orderNo = Subscription.retrieve(subscriptionId).getDescription().replace("AiDA - ", "");
|
||||||
|
}
|
||||||
|
} catch (StripeException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
Long amountTotal;
|
||||||
|
if (status.equals("paid")){
|
||||||
|
amountTotal = invoice.getAmountPaid();
|
||||||
|
}else {
|
||||||
|
amountTotal = invoice.getAmountDue();
|
||||||
|
}
|
||||||
|
|
||||||
|
// stripe 的支付金额单位是分,在我们数据库中金额单位为 元
|
||||||
|
Float divide = new BigDecimal(amountTotal).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP).floatValue();
|
||||||
|
String type = invoice.getBillingReason().equals("subscription_create") ? "new" :
|
||||||
|
invoice.getBillingReason().equals("subscription_cycle") ? "renewal" : invoice.getBillingReason();
|
||||||
|
|
||||||
|
Map<String, String> paymentMethod = stripeService.getPaymentMethodByInvoiceId(invoiceId);
|
||||||
|
|
||||||
|
paymentInfo = new PaymentInfo();
|
||||||
|
paymentInfo.setOrderNo(orderNo);
|
||||||
|
paymentInfo.setPaymentType(PayTypeEnum.STRIPE.getType());
|
||||||
|
paymentInfo.setTransactionId(invoiceId);
|
||||||
|
// 使用invoice的状态
|
||||||
|
paymentInfo.setTradeState(status);
|
||||||
|
paymentInfo.setPayerTotal(divide);
|
||||||
|
Gson gson = new Gson();
|
||||||
|
String json = gson.toJson(invoice);
|
||||||
|
paymentInfo.setContent(json);
|
||||||
|
paymentInfo.setType(type);
|
||||||
|
paymentInfo.setNotified(0);
|
||||||
|
paymentInfo.setPaymentMethod(paymentMethod.get("paymentMethod"));
|
||||||
|
paymentInfo.setLast4(paymentMethod.get("last4"));
|
||||||
|
paymentInfo.setHostedInvoiceUrl(invoice.getHostedInvoiceUrl());
|
||||||
|
paymentInfo.setCreateTime(LocalDateTime.now());
|
||||||
|
|
||||||
|
baseMapper.insert(paymentInfo);
|
||||||
|
}else {
|
||||||
|
paymentInfo.setTradeState(status);
|
||||||
|
paymentInfo.setUpdateTime(LocalDateTime.now());
|
||||||
|
baseMapper.updateById(paymentInfo);
|
||||||
|
}
|
||||||
|
return paymentInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PaymentInfo createOrUpdatePaymentInfoForStripe(Charge charge){
|
||||||
|
Stripe.apiKey = privateKey;
|
||||||
|
QueryWrapper<PaymentInfo> qw = new QueryWrapper<>();
|
||||||
|
qw.eq("transaction_id", charge.getInvoice());
|
||||||
|
PaymentInfo paymentInfo = baseMapper.selectOne(qw);
|
||||||
|
Charge.PaymentMethodDetails paymentMethodDetails = charge.getPaymentMethodDetails();
|
||||||
|
String paymentMethod;
|
||||||
|
String last4 = "N/A";
|
||||||
|
switch (paymentMethodDetails.getType()){
|
||||||
|
case "alipay":
|
||||||
|
paymentMethod = "Alipay";
|
||||||
|
break;
|
||||||
|
case "bancontact":
|
||||||
|
paymentMethod = "BanContact";
|
||||||
|
break;
|
||||||
|
case "card":
|
||||||
|
Charge.PaymentMethodDetails.Card card = paymentMethodDetails.getCard();
|
||||||
|
String brand = card.getBrand();
|
||||||
|
brand = brand.substring(0, 1).toUpperCase() + brand.substring(1);
|
||||||
|
paymentMethod = brand + " " + card.getFunding() + "card";
|
||||||
|
last4 = card.getLast4();
|
||||||
|
break;
|
||||||
|
case "eps":
|
||||||
|
Charge.PaymentMethodDetails.Eps eps = paymentMethodDetails.getEps();
|
||||||
|
paymentMethod = eps.getBank();
|
||||||
|
break;
|
||||||
|
case "giropay":
|
||||||
|
paymentMethod = "GiroPay";
|
||||||
|
break;
|
||||||
|
case "ideal":
|
||||||
|
Charge.PaymentMethodDetails.Ideal ideal = paymentMethodDetails.getIdeal();
|
||||||
|
paymentMethod = ideal.getBank();
|
||||||
|
break;
|
||||||
|
case "link":
|
||||||
|
paymentMethod = "Link";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
paymentMethod = "N/A";
|
||||||
|
}
|
||||||
|
if (Objects.isNull(paymentInfo)){
|
||||||
|
Stripe.apiKey = privateKey;
|
||||||
|
|
||||||
|
Float divide = new BigDecimal(charge.getAmount()).divide(new BigDecimal(100), 2, RoundingMode.HALF_UP).floatValue();
|
||||||
|
paymentInfo = new PaymentInfo();
|
||||||
|
paymentInfo.setOrderNo(charge.getDescription().replace("AiDA - ", ""));
|
||||||
|
paymentInfo.setTransactionId(charge.getInvoice());
|
||||||
|
paymentInfo.setPaymentType(PayTypeEnum.STRIPE.getType());
|
||||||
|
paymentInfo.setTradeState(charge.getStatus());
|
||||||
|
paymentInfo.setPayerTotal(divide);
|
||||||
|
paymentInfo.setNotified(0);
|
||||||
|
paymentInfo.setPaymentMethod(paymentMethod);
|
||||||
|
paymentInfo.setLast4(last4);
|
||||||
|
paymentInfo.setCreateTime(LocalDateTime.now());
|
||||||
|
baseMapper.insert(paymentInfo);
|
||||||
|
}else {
|
||||||
|
paymentInfo.setTradeState(charge.getStatus());
|
||||||
|
paymentInfo.setPaymentMethod(paymentMethod);
|
||||||
|
paymentInfo.setLast4(last4);
|
||||||
|
paymentInfo.setUpdateTime(LocalDateTime.now());
|
||||||
|
baseMapper.updateById(paymentInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
return paymentInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<PaymentInfo> getPaymentInfoByOrderNo(String orderId, String order){
|
||||||
|
QueryWrapper<PaymentInfo> qw = new QueryWrapper<>();
|
||||||
|
qw.eq("order_no", orderId).orderByDesc(order.equals("DESC"),"id");
|
||||||
|
|
||||||
|
return baseMapper.selectList(qw);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -190,4 +339,36 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
|
|||||||
|
|
||||||
baseMapper.updateById(paymentInfo);
|
baseMapper.updateById(paymentInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public PageBaseResponse<OrderListVO> getPaymentInfo(QueryPageByTimeDTO queryPageByTimeDTO){
|
||||||
|
Long accountId = UserContext.getUserHolder().getId();
|
||||||
|
|
||||||
|
String startTime = queryPageByTimeDTO.getStartTime();
|
||||||
|
String endTime = queryPageByTimeDTO.getEndTime();
|
||||||
|
if (StringUtil.isNullOrEmpty(startTime)) {
|
||||||
|
startTime = "2024-02-01 00:00:00";
|
||||||
|
}
|
||||||
|
if (StringUtil.isNullOrEmpty(endTime)) {
|
||||||
|
LocalDateTime now = LocalDateTime.now();
|
||||||
|
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
|
endTime = now.format(dateTimeFormatter);
|
||||||
|
}
|
||||||
|
|
||||||
|
int offset = (queryPageByTimeDTO.getPage() - 1) * queryPageByTimeDTO.getSize();
|
||||||
|
List<OrderListVO> orderListVOS = baseMapper.selectPageOrderList(accountId, startTime, endTime, offset, queryPageByTimeDTO.getSize());
|
||||||
|
|
||||||
|
if (CollectionUtils.isEmpty(orderListVOS)) {
|
||||||
|
return PageBaseResponse.success(new Page<>());
|
||||||
|
}else {
|
||||||
|
int totalCount = baseMapper.queryOrderListTotalCount(accountId, startTime, endTime);
|
||||||
|
IPage<OrderListVO> orderListVOIPage = new Page<>();
|
||||||
|
Integer size = queryPageByTimeDTO.getSize();
|
||||||
|
orderListVOIPage.setSize(size);
|
||||||
|
orderListVOIPage.setRecords(orderListVOS);
|
||||||
|
orderListVOIPage.setCurrent(queryPageByTimeDTO.getPage());
|
||||||
|
orderListVOIPage.setPages((long)Math.ceil((double) totalCount / size));
|
||||||
|
orderListVOIPage.setTotal(totalCount);
|
||||||
|
return PageBaseResponse.success(orderListVOIPage);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -149,7 +149,7 @@ public class SuperResolutionServiceImpl extends ServiceImpl<TaskListMapper, Task
|
|||||||
creditsService.insertToCreditsDetail(accountId,
|
creditsService.insertToCreditsDetail(accountId,
|
||||||
CreditsEventsEnum.SUPER_RESOLUTION.getName(),
|
CreditsEventsEnum.SUPER_RESOLUTION.getName(),
|
||||||
CreditsEventsEnum.SUPER_RESOLUTION.getValue(),
|
CreditsEventsEnum.SUPER_RESOLUTION.getValue(),
|
||||||
"negative");
|
"negative", null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ spring.security.jwtExpiration=8640000000
|
|||||||
spring.security.ignorePaths=/,/favicon.ico,/doc.html,/webjars/**,/swagger-resources,/v2/api-docs,\
|
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/**,/api/paypal/**,/api/credits/**,/api/inquiry/**,/api/tasks/**,/api/python/prepareForSR,/api/alipay-hk/**,/api/portfolio/**,\
|
/api/product/**,/api/ali-pay/**,/api/order-info/**,/api/paypal/**,/api/credits/**,/api/inquiry/**,/api/tasks/**,/api/python/prepareForSR,/api/alipay-hk/**,/api/portfolio/**,\
|
||||||
/api/stripe/**,/api/message/**,/notification/**
|
/api/stripe/**,/api/message/**,/notification/**,/api/affiliate/**
|
||||||
spring.security.authApi=/auth/login
|
spring.security.authApi=/auth/login
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
36
src/main/resources/mapper/primary/AffiliateIncomeMapper.xml
Normal file
36
src/main/resources/mapper/primary/AffiliateIncomeMapper.xml
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.ai.da.mapper.primary.AffiliateIncomeMapper">
|
||||||
|
|
||||||
|
<select id="getPersonalMonthlyIncome" resultType="java.util.Map">
|
||||||
|
SELECT
|
||||||
|
DATE_FORMAT(payment_time, '%m') as yearMonth,
|
||||||
|
SUM(commission) AS totalCommission
|
||||||
|
FROM
|
||||||
|
t_affiliate_income
|
||||||
|
WHERE
|
||||||
|
YEAR(payment_time) = #{year}
|
||||||
|
and affiliate_account_id = #{affiliateAccountId}
|
||||||
|
GROUP BY
|
||||||
|
yearMonth
|
||||||
|
ORDER BY
|
||||||
|
yearMonth
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="getMonthlyAffiliateIncome" resultType="java.util.Map">
|
||||||
|
SELECT
|
||||||
|
DATE_FORMAT(payment_time, '%m') as yearMonth,
|
||||||
|
SUM(amount) AS totalAmount,
|
||||||
|
SUM(commission) AS totalCommission
|
||||||
|
FROM
|
||||||
|
t_affiliate_income
|
||||||
|
WHERE
|
||||||
|
YEAR(payment_time) = #{year}
|
||||||
|
and MONTH(payment_time) = #{month}
|
||||||
|
GROUP BY
|
||||||
|
yearMonth
|
||||||
|
ORDER BY
|
||||||
|
yearMonth
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
16
src/main/resources/mapper/primary/AffiliateMapper.xml
Normal file
16
src/main/resources/mapper/primary/AffiliateMapper.xml
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.ai.da.mapper.primary.AffiliateMapper">
|
||||||
|
|
||||||
|
<select id="getMonthlyApprovedAffiliate" resultType="java.util.Map">
|
||||||
|
SELECT
|
||||||
|
count(*) AS count
|
||||||
|
FROM
|
||||||
|
t_affiliate
|
||||||
|
WHERE
|
||||||
|
YEAR ( create_time ) = #{year}
|
||||||
|
AND MONTH ( create_time ) = #{month}
|
||||||
|
AND status = 'Active'
|
||||||
|
</select>
|
||||||
|
|
||||||
|
</mapper>
|
||||||
42
src/main/resources/mapper/primary/PaymentInfoMapper.xml
Normal file
42
src/main/resources/mapper/primary/PaymentInfoMapper.xml
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.ai.da.mapper.primary.PaymentInfoMapper">
|
||||||
|
<select id="selectPageOrderList" resultType="com.ai.da.model.vo.OrderListVO">
|
||||||
|
SELECT
|
||||||
|
p.id AS id,
|
||||||
|
p.payer_total AS amount,
|
||||||
|
p.payment_type AS paymentMethod,
|
||||||
|
p.trade_state AS state,
|
||||||
|
o.title AS orderType,
|
||||||
|
p.hosted_invoice_url AS invoiceLink,
|
||||||
|
p.create_time
|
||||||
|
FROM
|
||||||
|
`t_payment_info` p
|
||||||
|
LEFT JOIN
|
||||||
|
`t_order_info` o
|
||||||
|
ON
|
||||||
|
p.order_no = o.order_no
|
||||||
|
WHERE
|
||||||
|
o.account_id = #{accountId}
|
||||||
|
AND p.create_time BETWEEN #{startTime} AND #{endTime}
|
||||||
|
ORDER BY
|
||||||
|
p.id DESC
|
||||||
|
LIMIT #{pageSize} OFFSET #{offset};
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<select id="queryOrderListTotalCount" parameterType="map" resultType="int">
|
||||||
|
SELECT
|
||||||
|
COUNT(*)
|
||||||
|
FROM
|
||||||
|
`t_payment_info` p
|
||||||
|
LEFT JOIN
|
||||||
|
`t_order_info` o
|
||||||
|
ON
|
||||||
|
p.order_no = o.order_no
|
||||||
|
WHERE
|
||||||
|
o.account_id = #{accountId}
|
||||||
|
AND p.create_time BETWEEN #{startTime} AND #{endTime};
|
||||||
|
</select>
|
||||||
|
|
||||||
|
|
||||||
|
</mapper>
|
||||||
@@ -148,6 +148,7 @@ remaining.modifications=Remaining modifications are 0
|
|||||||
you.have.participated.in.the.event=You have participated in the event.
|
you.have.participated.in.the.event=You have participated in the event.
|
||||||
only.original.works.can.participate.in.the.event=Sorry, only original works can participate in the event.
|
only.original.works.can.participate.in.the.event=Sorry, only original works can participate in the event.
|
||||||
remaining.credits.insufficient=Your remaining credits are insufficient for this generation. Please recharge.
|
remaining.credits.insufficient=Your remaining credits are insufficient for this generation. Please recharge.
|
||||||
|
you.haven't.subscribed.to.any.products.yet=You haven't subscribed to any products yet
|
||||||
|
|
||||||
# 可能会报异常
|
# 可能会报异常
|
||||||
# Informative:
|
# Informative:
|
||||||
|
|||||||
@@ -143,6 +143,7 @@ remaining.modifications=剩余修改次数为0
|
|||||||
you.have.participated.in.the.event=您已经参与活动。
|
you.have.participated.in.the.event=您已经参与活动。
|
||||||
only.original.works.can.participate.in.the.event=抱歉,只有原创作品能参与活动。
|
only.original.works.can.participate.in.the.event=抱歉,只有原创作品能参与活动。
|
||||||
remaining.credits.insufficient=您的剩余积分不够本次生成消耗,请充值
|
remaining.credits.insufficient=您的剩余积分不够本次生成消耗,请充值
|
||||||
|
you.haven't.subscribed.to.any.products.yet=您还未订阅任何产品
|
||||||
|
|
||||||
# 可能会报异常
|
# 可能会报异常
|
||||||
# Informative:
|
# Informative:
|
||||||
|
|||||||
@@ -27,13 +27,13 @@ paypal.webhook_id=1D107312EX592781K
|
|||||||
##### Stripe
|
##### Stripe
|
||||||
|
|
||||||
# developer
|
# developer
|
||||||
#stripe.private-key=sk_test_51P4ZZL02n1TEydyN8qQHjOA9imsFU7Oxs2HMHGy2urHnnQgSHnZuu5vVP6pKhEACwUpsKNyrbZpdcg5TJWJLRHcY008dEO1fn2
|
stripe.private-key=sk_test_51P4ZZL02n1TEydyN8qQHjOA9imsFU7Oxs2HMHGy2urHnnQgSHnZuu5vVP6pKhEACwUpsKNyrbZpdcg5TJWJLRHcY008dEO1fn2
|
||||||
#stripe.webhook-sign-secret=whsec_e0dBiJngx6qqgJj6yPyJ2A9ouh1Cjv5w
|
stripe.webhook-sign-secret=whsec_e0dBiJngx6qqgJj6yPyJ2A9ouh1Cjv5w
|
||||||
|
|
||||||
# kim - test
|
# kim - test
|
||||||
#stripe.private-key=sk_test_51LwPrxH7nPZ8bkrNj67TFD7sxucaTANs1lf0KGSu1QSJfxYXcnigq2wTaZyZzST7y0fMbhhvaJZ4LjjFhr95M83a00eXrmOTL0
|
#stripe.private-key=sk_test_51LwPrxH7nPZ8bkrNj67TFD7sxucaTANs1lf0KGSu1QSJfxYXcnigq2wTaZyZzST7y0fMbhhvaJZ4LjjFhr95M83a00eXrmOTL0
|
||||||
#stripe.webhook-sign-secret=whsec_GoyVEAaBtuGD5Rt55z83JnPnLDAZTN3u
|
#stripe.webhook-sign-secret=whsec_GoyVEAaBtuGD5Rt55z83JnPnLDAZTN3u
|
||||||
|
|
||||||
# kim - live
|
# kim - live
|
||||||
stripe.private-key=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
|
#stripe.private-key=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
|
||||||
stripe.webhook-sign-secret=whsec_hhGDgdelQRHSg4LmChtQe41crj41eb11
|
#stripe.webhook-sign-secret=whsec_hhGDgdelQRHSg4LmChtQe41crj41eb11
|
||||||
Reference in New Issue
Block a user