Merge remote-tracking branch 'origin/dev/dev' into dev/dev
This commit is contained in:
@@ -51,7 +51,7 @@ public class MyTaskScheduler {
|
||||
|
||||
// 定时任务,每十五天执行一次
|
||||
// @Scheduled(cron = "0 0 0 ? * MON")
|
||||
// @Scheduled(cron = "0 0 0 */15 * ?")
|
||||
@Scheduled(cron = "0 0 0 */15 * ?")
|
||||
public void checkExpiry() {
|
||||
// 检测正式用户是否快要过期
|
||||
QueryWrapper<Account> qw = new QueryWrapper<>();
|
||||
@@ -85,7 +85,7 @@ public class MyTaskScheduler {
|
||||
}
|
||||
}
|
||||
}
|
||||
// @Scheduled(cron = "0 0 9 * * ?")
|
||||
@Scheduled(cron = "0 0 9 * * ?")
|
||||
public void sendTrialOrderExcelToManagements() {
|
||||
// 获取前一天日期
|
||||
LocalDate yesterday = LocalDate.now().minusDays(1);
|
||||
|
||||
@@ -31,14 +31,14 @@ public class AccountTask {
|
||||
accountService.refreshCreditsWeekly();
|
||||
}
|
||||
|
||||
// @Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes
|
||||
@Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes
|
||||
public void getPaidUser() {
|
||||
// 获取code-create 表中 指定日期之后 订单状态为wc-processing的订单
|
||||
accountService.extendValidityForCC();
|
||||
}
|
||||
|
||||
// 每天凌晨0点执行一次
|
||||
// @Scheduled(cron = "0 0 0 * * ?")
|
||||
@Scheduled(cron = "0 0 0 * * ?")
|
||||
public void cancelActivityBenefits() {
|
||||
// 1、查询当前所有参与了活动且过期的用户
|
||||
List<Account> accountList = accountService.getExpiredUserBySystemUser(4);
|
||||
@@ -51,7 +51,7 @@ public class AccountTask {
|
||||
}
|
||||
|
||||
// 每天检测正式用户到期情况,每天凌晨0点执行
|
||||
// @Scheduled(cron = "0 0 0 * * ?")
|
||||
@Scheduled(cron = "0 0 0 * * ?")
|
||||
public void paidUserToVisitor() {
|
||||
// 1、查询当前已过期正式用户或试用用户
|
||||
List<Account> accountList = accountService.getExpiredUserBySystemUser(1);
|
||||
@@ -68,7 +68,7 @@ public class AccountTask {
|
||||
/**
|
||||
* 将Code-Create上注册的用户添加为AiDA的游客
|
||||
*/
|
||||
// @Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes
|
||||
@Scheduled(cron = "0 */5 * * * *") // Run every 5 minutes
|
||||
public void registerUserToVisitor() {
|
||||
accountService.registerUserToVisitor();
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ public class PaymentTask {
|
||||
@Resource
|
||||
private PayPalCheckoutService payPalCheckoutService;
|
||||
|
||||
// @Scheduled(cron = "0/30 * * * * ?")
|
||||
@Scheduled(cron = "0/30 * * * * ?")
|
||||
public void orderConfirmForPaypal() throws SerializeException {
|
||||
|
||||
// log.info("PayPal orderConfirm 被执行......");
|
||||
|
||||
@@ -635,8 +635,10 @@ public class SendEmailUtil {
|
||||
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");
|
||||
log.info("邮件发送至{} 发送失败###{}", receiverAddress, e.toString());
|
||||
log.error(e.getMessage());
|
||||
// 这里不再抛出异常 失败就不发,保证后续正常运行
|
||||
// throw new BusinessException("failed.to.send.mail");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -835,9 +837,9 @@ public class SendEmailUtil {
|
||||
|
||||
public static void subscriptionEmailReminder(String type, SubscriptionEmailParamsDTO subscriptionEmailParamsDTO, String language, String receiverAddress) {
|
||||
try {
|
||||
// String merchantEmail = "kimwong@code-create.com.hk";
|
||||
String merchantEmail = "kimwong@code-create.com.hk";
|
||||
String developer = "xupei3360@163.com";
|
||||
String[] receiverEmail = {/*merchantEmail, */developer};
|
||||
String[] receiverEmail = {merchantEmail, developer};
|
||||
Credential cred = new Credential(SECRET_ID, SECRET_KEy);
|
||||
// 实例化一个http选项,可选的,没有特殊需求可以跳过
|
||||
HttpProfile httpProfile = new HttpProfile();
|
||||
@@ -1010,7 +1012,7 @@ public class SendEmailUtil {
|
||||
template.setTemplateID(CREDITS_PURCHASE_MERCHANT);
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
// 设置试用订单相关数据
|
||||
jsonObject.put("userName", username);
|
||||
jsonObject.put("username", username);
|
||||
jsonObject.put("quantity", quantity);
|
||||
jsonObject.put("totalFee", amount);
|
||||
|
||||
|
||||
@@ -220,7 +220,7 @@ public interface AccountService extends IService<Account> {
|
||||
|
||||
Boolean unbindGoogle();
|
||||
|
||||
void updateAccountValidity(Long accountId, Long currentPeriodEnd);
|
||||
boolean updateAccountValidity(Long accountId, Long currentPeriodEnd);
|
||||
|
||||
void updateUserRoleAndCredits(Long accountId, String type);
|
||||
|
||||
|
||||
@@ -36,4 +36,6 @@ public interface CreditsService extends IService<CreditsDetail> {
|
||||
void preInsert(Long accountId, String changeEventName, String taskId, Boolean isPreInsert, String changedCredits);
|
||||
|
||||
void updateChangedCredits(String accountId, String taskId);
|
||||
|
||||
CreditsDetail queryDetailByTaskId(String taskId);
|
||||
}
|
||||
|
||||
@@ -1335,7 +1335,7 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
|
||||
config.addDataSourceProperty("cachePrepStmts", "true");
|
||||
config.addDataSourceProperty("prepStmtCacheSize", "250");
|
||||
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
|
||||
config.addDataSourceProperty("maxLifetime", 300000);
|
||||
config.addDataSourceProperty("maxLifetime", 50000);
|
||||
dataSource = new HikariDataSource(config);
|
||||
}
|
||||
|
||||
@@ -2745,12 +2745,16 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
|
||||
return result;
|
||||
}
|
||||
|
||||
public void updateAccountValidity(Long accountId, Long currentPeriodEnd){
|
||||
public boolean updateAccountValidity(Long accountId, Long currentPeriodEnd){
|
||||
// 不管当前用户的账号是否到期,都根据付款信息重置账号到期时间
|
||||
Account account = accountMapper.selectById(accountId);
|
||||
account.setValidEndTime(currentPeriodEnd * 1000);
|
||||
|
||||
accountMapper.updateById(account);
|
||||
if (account.getValidEndTime().equals(currentPeriodEnd * 1000)){
|
||||
return false;
|
||||
}else {
|
||||
account.setValidEndTime(currentPeriodEnd * 1000);
|
||||
accountMapper.updateById(account);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public void updateUserRoleAndCredits(Long accountId, String type){
|
||||
|
||||
@@ -76,9 +76,9 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
|
||||
affiliate.setPromotionMethod(promotionMethod);
|
||||
baseMapper.insert(affiliate);
|
||||
// 邮件通知审批者
|
||||
// String merchantEmail = "kimwong@code-create.com.hk";
|
||||
String merchantEmail = "kimwong@code-create.com.hk";
|
||||
String developer = "xupei3360@163.com";
|
||||
String[] receiverEmail = {/*merchantEmail, */developer};
|
||||
String[] receiverEmail = {merchantEmail, developer};
|
||||
SendEmailUtil.affiliateEmailReminder(receiverEmail, new AffiliateEmailParamsDTO(userHolder.getUsername(), promotionMethod), "new");
|
||||
}else {
|
||||
throw new BusinessException("You have registered an Affiliate", ResultEnum.PROMPT.getCode());
|
||||
@@ -313,9 +313,9 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
|
||||
affiliateEmailParamsDTO.setUnpaidEarnings(totalCommission.toString());
|
||||
affiliateEmailParamsDTO.setPaidEarnings("0");
|
||||
|
||||
// String merchantEmail = "kimwong@code-create.com.hk";
|
||||
String merchantEmail = "kimwong@code-create.com.hk";
|
||||
String developer = "xupei3360@163.com";
|
||||
String[] receiverEmail = {/*merchantEmail, */developer};
|
||||
String[] receiverEmail = {merchantEmail, developer};
|
||||
// 邮件通知
|
||||
SendEmailUtil.affiliateEmailReminder(receiverEmail, affiliateEmailParamsDTO, "summary");
|
||||
}
|
||||
|
||||
@@ -318,4 +318,10 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
|
||||
|
||||
}
|
||||
|
||||
public CreditsDetail queryDetailByTaskId(String taskId) {
|
||||
QueryWrapper<CreditsDetail> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("task_id", taskId);
|
||||
return baseMapper.selectOne(queryWrapper);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,10 +9,7 @@ import com.ai.da.common.utils.SendEmailUtil;
|
||||
import com.ai.da.mapper.primary.AccountMapper;
|
||||
import com.ai.da.mapper.primary.PaymentInfoMapper;
|
||||
import com.ai.da.mapper.primary.SubscriptionInfoMapper;
|
||||
import com.ai.da.mapper.primary.entity.OrderInfo;
|
||||
import com.ai.da.mapper.primary.entity.PaymentInfo;
|
||||
import com.ai.da.mapper.primary.entity.RefundInfo;
|
||||
import com.ai.da.mapper.primary.entity.SubscriptionInfo;
|
||||
import com.ai.da.mapper.primary.entity.*;
|
||||
import com.ai.da.model.dto.ProductPurchaseDTO;
|
||||
import com.ai.da.model.dto.SubscriptionEmailParamsDTO;
|
||||
import com.ai.da.service.*;
|
||||
@@ -24,6 +21,7 @@ import com.stripe.Stripe;
|
||||
import com.stripe.exception.SignatureVerificationException;
|
||||
import com.stripe.exception.StripeException;
|
||||
import com.stripe.model.*;
|
||||
import com.stripe.model.Product;
|
||||
import com.stripe.model.checkout.Session;
|
||||
import com.stripe.net.Webhook;
|
||||
import com.stripe.param.*;
|
||||
@@ -42,6 +40,7 @@ import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@SuppressWarnings("LoggingSimilarMessage")
|
||||
@Service
|
||||
@@ -140,6 +139,9 @@ public class StripeServiceImpl implements StripeService {
|
||||
// one-time 手动创建发票;订阅会自动创建invoice
|
||||
sessionBuilder.setInvoiceCreation(SessionCreateParams.InvoiceCreation.builder().setEnabled(Boolean.TRUE).build());
|
||||
}
|
||||
// sessionBuilder.setPaymentMethodConfiguration("pmc_1QIKyq02n1TEydyNKVEYvhW7");
|
||||
// sessionBuilder.addPaymentMethodType(SessionCreateParams.PaymentMethodType.ALIPAY);
|
||||
// sessionBuilder.addPaymentMethodType(SessionCreateParams.PaymentMethodType.CARD);
|
||||
sessionBuilder.setCustomer(customerId);
|
||||
sessionBuilder.setSuccessUrl(productPurchaseDTO.getReturnUrl());//可自定义成功页面
|
||||
sessionBuilder.setLocale(account.getLanguage().equals("CHINESE_SIMPLIFIED") ? SessionCreateParams.Locale.ZH : SessionCreateParams.Locale.EN);
|
||||
@@ -151,7 +153,12 @@ public class StripeServiceImpl implements StripeService {
|
||||
sessionBuilder.putMetadata("orderId", orderId); //通过订单号关联用于检索支付信息(可选)
|
||||
|
||||
Session session = Session.create(sessionBuilder.build());
|
||||
log.info("sessionId:" + session.getId()); //退款方式1:拿到sessionId入库,退款的时候根据这个id找到PaymentIntent的id然后发起退款
|
||||
List<String> paymentMethodTypes = session.getPaymentMethodTypes();
|
||||
log.info("paymentMethodTypes: {}", paymentMethodTypes);
|
||||
|
||||
Session.PaymentMethodConfigurationDetails paymentMethodConfigurationDetails = session.getPaymentMethodConfigurationDetails();
|
||||
log.info("paymentMethodConfigurationDetails ID: {}", paymentMethodConfigurationDetails.getId());
|
||||
log.info("sessionId:{}", session.getId()); //退款方式1:拿到sessionId入库,退款的时候根据这个id找到PaymentIntent的id然后发起退款
|
||||
|
||||
// 更新order信息
|
||||
orderInfoService.updateOrderNoById(orderInfo.getId(), orderId);
|
||||
@@ -350,6 +357,11 @@ public class StripeServiceImpl implements StripeService {
|
||||
|
||||
// 发送续订失败邮件
|
||||
response = sendRenewalFailEmail(invoice.getId(), null, paymentInfo.getOrderNo());
|
||||
}else {
|
||||
// 新增支付信息
|
||||
PaymentInfo paymentInfoFail = paymentInfoService.createOrUpdatePaymentInfoForStripe(invoice);
|
||||
// 发送新订阅失败邮件
|
||||
response = sendEmail(paymentInfoFail.getOrderNo());
|
||||
}
|
||||
}
|
||||
}else if (stripeObject instanceof Charge) {
|
||||
@@ -387,22 +399,26 @@ public class StripeServiceImpl implements StripeService {
|
||||
// 当订单状态处于未支付或超时已关闭时,更新订单状态,其他状态均不更新订单状态
|
||||
if (!OrderStatusEnum.NOT_PAY.getType().equals(orderStatus) && !OrderStatusEnum.TIMEOUT_CLOSED.getType().equals(orderStatus)) {
|
||||
log.info("订单状态 : {}", orderStatus);
|
||||
return;
|
||||
}else {
|
||||
//更新订单状态
|
||||
orderInfoService.updateStatusByOrderNo(orderId, OrderStatusEnum.SUCCESS);
|
||||
log.info("Stripe 订单:{} 状态更新成功", orderId);
|
||||
}
|
||||
//更新订单状态
|
||||
orderInfoService.updateStatusByOrderNo(orderId, OrderStatusEnum.SUCCESS);
|
||||
log.info("Stripe 订单:{} 状态更新成功", orderId);
|
||||
|
||||
if (orderByOrderNo.getTitle().startsWith("积分购买")){
|
||||
float quantity = totalAmount / ProductEnum.CreditsProduct.getPrice();
|
||||
// 更新积分
|
||||
creditsService.buyCredits(orderByOrderNo.getAccountId(), quantity);
|
||||
// 添加积分变更记录
|
||||
creditsService.insertToCreditsDetail(orderByOrderNo.getAccountId(),
|
||||
CreditsEventsEnum.BUY_CREDITS.getName() + "--Stripe",
|
||||
String.valueOf((Long.parseLong(CreditsEventsEnum.BUY_CREDITS.getValue()) * quantity)),
|
||||
"positive", orderId);
|
||||
log.info("用户:{} 积分信息更新成功", orderByOrderNo.getAccountId());
|
||||
// 查询当前订单的积分是否已添加
|
||||
CreditsDetail creditsDetail = creditsService.queryDetailByTaskId(orderId);
|
||||
if (Objects.isNull(creditsDetail)){
|
||||
float quantity = totalAmount / ProductEnum.CreditsProduct.getPrice();
|
||||
// 更新积分
|
||||
creditsService.buyCredits(orderByOrderNo.getAccountId(), quantity);
|
||||
// 添加积分变更记录
|
||||
creditsService.insertToCreditsDetail(orderByOrderNo.getAccountId(),
|
||||
CreditsEventsEnum.BUY_CREDITS.getName() + "--Stripe",
|
||||
String.valueOf((Long.parseLong(CreditsEventsEnum.BUY_CREDITS.getValue()) * quantity)),
|
||||
"positive", orderId);
|
||||
log.info("用户:{} 积分信息更新成功", orderByOrderNo.getAccountId());
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.info(e.getMessage());
|
||||
@@ -468,11 +484,13 @@ public class StripeServiceImpl implements StripeService {
|
||||
subscriptionInfo.setCreateTime(LocalDateTime.now());
|
||||
subscriptionInfoMapper.insert(subscriptionInfo);
|
||||
|
||||
// 更新账号到期时间
|
||||
accountService.updateAccountValidity(subscriptionInfo.getAccountId(), subscriptionInfo.getCurrentPeriodEnd());
|
||||
|
||||
// 更新账号身份和积分
|
||||
accountService.updateUserRoleAndCredits(subscriptionInfo.getAccountId(), interval);
|
||||
if (subscriptionInfo.getStatus().equals("active")){
|
||||
log.info("创建订阅更新账号信息");
|
||||
// 更新账号到期时间
|
||||
boolean b = accountService.updateAccountValidity(subscriptionInfo.getAccountId(), subscriptionInfo.getCurrentPeriodEnd());
|
||||
// 更新账号身份和积分
|
||||
if (b) accountService.updateUserRoleAndCredits(subscriptionInfo.getAccountId(), interval);
|
||||
}
|
||||
}
|
||||
return subscriptionInfo;
|
||||
}
|
||||
@@ -498,7 +516,7 @@ public class StripeServiceImpl implements StripeService {
|
||||
|
||||
public SubscriptionInfo getLatestSubscriptionInfoByAccountId(Long accountId){
|
||||
QueryWrapper<SubscriptionInfo> qw = new QueryWrapper<>();
|
||||
qw.eq("account_id", accountId);
|
||||
qw.eq("account_id", accountId).orderByDesc("id");
|
||||
List<SubscriptionInfo> subscriptionInfos = subscriptionInfoMapper.selectList(qw);
|
||||
if (subscriptionInfos.isEmpty()){
|
||||
return null;
|
||||
@@ -524,6 +542,7 @@ public class StripeServiceImpl implements StripeService {
|
||||
if (!subscriptionInfo.getCurrentPeriodEnd().equals(subscription.getCurrentPeriodEnd())){
|
||||
subscriptionInfo.setCurrentPeriodEnd(subscription.getCurrentPeriodEnd());
|
||||
subscriptionInfo.setNextPayDate(DateUtil.changeTimeStampFormat(subscription.getCurrentPeriodEnd(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy_EEEE));
|
||||
log.info("更新订阅更新账号信息");
|
||||
// 更新账号到期时间
|
||||
accountService.updateAccountValidity(subscriptionInfo.getAccountId(), subscriptionInfo.getCurrentPeriodEnd());
|
||||
// 更新账号身份和积分
|
||||
@@ -531,6 +550,12 @@ public class StripeServiceImpl implements StripeService {
|
||||
log.info("更新 {} 账号到期时间为:{}", subscriptionInfo.getAccountId(), DateUtil.changeTimeStampFormat(subscriptionInfo.getCurrentPeriodEnd(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy_EEEE));
|
||||
flag = true;
|
||||
}
|
||||
if (subscriptionInfo.getStatus().equals("active")){
|
||||
// 更新账号到期时间
|
||||
boolean b = accountService.updateAccountValidity(subscriptionInfo.getAccountId(), subscriptionInfo.getCurrentPeriodEnd());
|
||||
// 更新账号身份和积分
|
||||
if (b) accountService.updateUserRoleAndCredits(subscriptionInfo.getAccountId(), subscriptionInfo.getType());
|
||||
}
|
||||
if (flag){
|
||||
subscriptionInfo.setUpdateTime(LocalDateTime.now());
|
||||
subscriptionInfoMapper.updateById(subscriptionInfo);
|
||||
@@ -541,8 +566,8 @@ public class StripeServiceImpl implements StripeService {
|
||||
// 取消连续订阅 将订阅从pause状态转为cancel状态(使用定时器,定期检索DB中,过期且不续订的订阅)
|
||||
public void cancelSubscription(String subscriptionId, String cancelReason) {
|
||||
Stripe.apiKey = privateKey;
|
||||
log.info("cancel subscription");
|
||||
Long accountId = UserContext.getUserHolder().getId();
|
||||
log.info("用户 {} 申请取消连续订阅 {}", accountId, subscriptionId);
|
||||
com.ai.da.mapper.primary.entity.Account account = accountMapper.selectById(accountId);
|
||||
List<Subscription> subscriptions = getSubscription(account.getUserName(), account.getUserEmail());
|
||||
// 获取status = active的订阅
|
||||
@@ -551,7 +576,7 @@ public class StripeServiceImpl implements StripeService {
|
||||
try {
|
||||
Subscription cancel = subscription.cancel();
|
||||
cancel.getStatus();
|
||||
|
||||
log.info("用户 {} 申请取消连续订阅 {}", accountId, subscriptionId);
|
||||
// 更新数据库
|
||||
updateCancelReason(subscriptionId, cancelReason);
|
||||
} catch (StripeException e) {
|
||||
@@ -809,10 +834,20 @@ public class StripeServiceImpl implements StripeService {
|
||||
SubscriptionEmailParamsDTO emailParamsDTO = new SubscriptionEmailParamsDTO();
|
||||
QueryWrapper<SubscriptionInfo> qwSI = new QueryWrapper<>();
|
||||
qwSI.eq("subscription_id", subscriptionId);
|
||||
SubscriptionInfo subscriptionInfo = subscriptionInfoMapper.selectOne(qwSI);
|
||||
if (Objects.isNull(subscriptionInfo)) {
|
||||
List<SubscriptionInfo> subscriptionInfoList = subscriptionInfoMapper.selectList(qwSI);
|
||||
SubscriptionInfo subscriptionInfo;
|
||||
if (subscriptionInfoList.isEmpty()){
|
||||
return false;
|
||||
}else {
|
||||
List<SubscriptionInfo> activeSubscriptions = subscriptionInfoList.stream()
|
||||
.filter(subscription -> "active".equals(subscription.getStatus()))
|
||||
.collect(Collectors.toList());
|
||||
if (activeSubscriptions.isEmpty()){
|
||||
return false;
|
||||
}
|
||||
subscriptionInfo = activeSubscriptions.get(0);
|
||||
}
|
||||
|
||||
QueryWrapper<PaymentInfo> qwPI = new QueryWrapper<>();
|
||||
qwPI.eq("order_no", subscriptionInfo.getOrderNo()).orderByDesc("id");
|
||||
List<PaymentInfo> paymentInfos = paymentInfoMapper.selectList(qwPI);
|
||||
|
||||
Reference in New Issue
Block a user