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:
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);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.ai.da.service;
|
||||
|
||||
|
||||
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.mapper.primary.entity.OrderInfo;
|
||||
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 amount, String paymentType, ProductEnum product);
|
||||
|
||||
void saveCodeUrl(String orderNo, String codeUrl);
|
||||
|
||||
List<OrderInfo> listOrderByCreateTimeDesc();
|
||||
@@ -28,4 +31,7 @@ public interface OrderInfoService extends IService<OrderInfo> {
|
||||
PageBaseResponse<OrderInfo> getOrderByPage(QueryPageByTimeDTO queryPageByTimeDTO);
|
||||
|
||||
void updateOrderNoById(Long id, String orderNo);
|
||||
|
||||
void updateTotalFeeByOrderNo(String orderNo);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,13 +1,19 @@
|
||||
package com.ai.da.service;
|
||||
|
||||
import com.ai.da.common.response.PageBaseResponse;
|
||||
import com.ai.da.mapper.primary.entity.PaymentInfo;
|
||||
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.stripe.model.checkout.Session;
|
||||
import com.stripe.model.Charge;
|
||||
import com.stripe.model.Invoice;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface PaymentInfoService {
|
||||
public interface PaymentInfoService extends IService<PaymentInfo> {
|
||||
|
||||
void createPaymentInfo(String plainText);
|
||||
|
||||
@@ -17,9 +23,13 @@ public interface PaymentInfoService {
|
||||
|
||||
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);
|
||||
|
||||
PageBaseResponse<OrderListVO> getPaymentInfo(QueryPageByTimeDTO queryPageByTimeDTO);
|
||||
}
|
||||
|
||||
@@ -1,15 +1,50 @@
|
||||
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.HttpServletResponse;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface StripeService {
|
||||
|
||||
String pay(Integer quantity, String returnUrl);
|
||||
String pay(ProductPurchaseDTO productPurchaseDTO);
|
||||
|
||||
Boolean notify(HttpServletRequest request);
|
||||
|
||||
SubscriptionInfo getLatestSubscriptionInfoByAccountId(Long accountId);
|
||||
|
||||
String refund(String amount, String orderId, String reason);
|
||||
|
||||
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
|
||||
private RedisUtil redisUtil;
|
||||
|
||||
@Resource
|
||||
private StripeService stripeService;
|
||||
|
||||
@Resource
|
||||
private AffiliateService affiliateService;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public AccountPreLoginVO preLogin(AccountPreLoginDTO accountDTO) {
|
||||
@@ -2418,6 +2424,19 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
|
||||
response.setAccountExtendList(accountExtends);
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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(),
|
||||
CreditsEventsEnum.BUY_CREDITS.getName() + "--Alipay",
|
||||
String.valueOf((Long.parseLong(CreditsEventsEnum.BUY_CREDITS.getValue()) * quantity)),
|
||||
"positive");
|
||||
"positive",
|
||||
orderByOrderNo.getOrderNo());
|
||||
} finally {
|
||||
//要主动释放锁
|
||||
lock.unlock();
|
||||
@@ -320,7 +321,8 @@ public class AliPayServiceImpl implements AliPayService {
|
||||
creditsService.insertToCreditsDetail(orderByOrderNo.getAccountId(),
|
||||
CreditsEventsEnum.BUY_CREDITS.getName() + "--Alipay",
|
||||
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);
|
||||
// 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 {
|
||||
log.info("调用失败,返回码 ===> " + response.getCode() + ", 返回描述 ===> " + response.getMsg());
|
||||
|
||||
@@ -248,7 +248,8 @@ public class AlipayHKServiceImpl implements AlipayHKService {
|
||||
creditsService.insertToCreditsDetail(orderByOrderNo.getAccountId(),
|
||||
CreditsEventsEnum.BUY_CREDITS.getName() + "--AlipayHK",
|
||||
String.valueOf((Long.parseLong(CreditsEventsEnum.BUY_CREDITS.getValue()) * quantity)),
|
||||
"positive");
|
||||
"positive",
|
||||
orderByOrderNo.getOrderNo());
|
||||
log.info("用户:{} 积分信息更新成功",orderByOrderNo.getAccountId());
|
||||
} finally {
|
||||
//要主动释放锁
|
||||
|
||||
@@ -216,6 +216,8 @@ public class CollectionElementServiceImpl extends ServiceImpl<CollectionElementM
|
||||
collectionElementMapper.deleteBatchIds(ids);
|
||||
}
|
||||
|
||||
/** 该方法已不再使用 */
|
||||
@Deprecated
|
||||
@Override
|
||||
public GenerateCollectionItemVO generatePrint(CollectionGeneratePrintDTO generatePrintDTO) {
|
||||
Long userId = UserContext.getUserHolder().getId();
|
||||
@@ -914,7 +916,7 @@ public class CollectionElementServiceImpl extends ServiceImpl<CollectionElementM
|
||||
generate.setAccountId(userId);
|
||||
generate.setLevel1Type(CollectionLevel1TypeEnum.PRINT_BOARD.getRealName());
|
||||
generate.setGenerateType("synthesis");
|
||||
generate.setModelName("Image Synthesis Model");
|
||||
// generate.setModelName("Image Synthesis Model");
|
||||
generate.setCreateDate(DateUtil.getByTimeZone(timeZone));
|
||||
return generate;
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
|
||||
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 newCredits = new BigDecimal(CreditsEventsEnum.BUY_CREDITS.getValue()).multiply(new BigDecimal(quantity));
|
||||
BigDecimal subtracted = existingCredits.subtract(newCredits);
|
||||
@@ -111,7 +111,7 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
|
||||
insertToCreditsDetail(accountId,
|
||||
CreditsEventsEnum.REFUND.getName() + "--Stripe",
|
||||
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->减
|
||||
*/
|
||||
@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();
|
||||
Account account = accountMapper.selectById(accountId);
|
||||
// BigDecimal finalCredits;
|
||||
@@ -137,6 +137,7 @@ public class CreditsServiceImpl extends ServiceImpl<CreditsDetailMapper, Credits
|
||||
creditsDetail.setAccountId(accountId);
|
||||
creditsDetail.setChangeEvent(changeEvent);
|
||||
creditsDetail.setChangedCredits(changeCredits);
|
||||
creditsDetail.setTaskId(orderNo);
|
||||
// creditsDetail.setCredits(finalCredits);
|
||||
creditsDetail.setCredits(account.getCredits());
|
||||
creditsDetail.setCreateTime(LocalDateTime.now());
|
||||
|
||||
@@ -289,7 +289,7 @@ public class GenerateServiceImpl extends ServiceImpl<GenerateMapper, Generate> i
|
||||
if (b) creditsService.insertToCreditsDetail(accountId,
|
||||
CreditsEventsEnum.TO_PRODUCT_IMAGE.getName(),
|
||||
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,
|
||||
CreditsEventsEnum.RELIGHT.getName(),
|
||||
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.enums.CreditsEventsEnum;
|
||||
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.utils.OrderNoUtils;
|
||||
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.entity.OrderInfo;
|
||||
import com.ai.da.mapper.primary.entity.PaymentInfo;
|
||||
import com.ai.da.model.dto.QueryPageByTimeDTO;
|
||||
import com.ai.da.model.vo.AuthPrincipalVo;
|
||||
import com.ai.da.service.OrderInfoService;
|
||||
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.service.impl.ServiceImpl;
|
||||
import io.netty.util.internal.StringUtil;
|
||||
@@ -34,9 +38,13 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
||||
@Resource
|
||||
private ProductMapper productMapper;
|
||||
|
||||
@Resource
|
||||
private PaymentInfoMapper paymentInfoMapper;
|
||||
|
||||
@Override
|
||||
public OrderInfo createOrderByProductId(Integer amount, String paymentType) {
|
||||
|
||||
|
||||
//查找已存在但未支付的订单
|
||||
/*OrderInfo orderInfo = this.getNoPayOrderByProductId(amount, paymentType);
|
||||
if( orderInfo != null){
|
||||
@@ -51,7 +59,7 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
||||
//生成订单
|
||||
OrderInfo orderInfo = new OrderInfo();
|
||||
orderInfo.setAccountId(accountId);
|
||||
orderInfo.setTitle("积分购买 X" + amount );
|
||||
orderInfo.setTitle("积分购买 X" + amount);
|
||||
orderInfo.setOrderNo(OrderNoUtils.getOrderNo()); //订单号 ??
|
||||
// orderInfo.setProductId(amount);
|
||||
// orderInfo.setTotalFee(Integer.parseInt(CreditsEventsEnum.PRICE.getValue()) * amount); // 元 HKD
|
||||
@@ -63,8 +71,37 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, 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 codeUrl
|
||||
*/
|
||||
@@ -82,6 +119,7 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
||||
|
||||
/**
|
||||
* 查询订单列表,并倒序查询
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
@@ -93,6 +131,7 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
||||
|
||||
/**
|
||||
* 根据订单号更新订单状态
|
||||
*
|
||||
* @param orderNo
|
||||
* @param orderStatus
|
||||
*/
|
||||
@@ -112,6 +151,7 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
||||
|
||||
/**
|
||||
* 根据订单号获取订单状态
|
||||
*
|
||||
* @param orderNo
|
||||
* @return
|
||||
*/
|
||||
@@ -121,7 +161,7 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
||||
QueryWrapper<OrderInfo> queryWrapper = new QueryWrapper<>();
|
||||
queryWrapper.eq("order_no", orderNo);
|
||||
OrderInfo orderInfo = baseMapper.selectOne(queryWrapper);
|
||||
if(orderInfo == null){
|
||||
if (orderInfo == null) {
|
||||
return null;
|
||||
}
|
||||
return orderInfo.getOrderStatus();
|
||||
@@ -129,6 +169,7 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
||||
|
||||
/**
|
||||
* 查询创建超过minutes分钟并且未支付的订单
|
||||
*
|
||||
* @param minutes
|
||||
* @return
|
||||
*/
|
||||
@@ -149,6 +190,7 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
||||
|
||||
/**
|
||||
* 根据订单号获取订单
|
||||
*
|
||||
* @param orderNo
|
||||
* @return
|
||||
*/
|
||||
@@ -166,6 +208,7 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
||||
/**
|
||||
* 根据商品id查询未支付订单
|
||||
* 防止重复创建订单对象
|
||||
*
|
||||
* @param productId
|
||||
* @return
|
||||
*/
|
||||
@@ -181,16 +224,16 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageBaseResponse<OrderInfo> getOrderByPage(QueryPageByTimeDTO queryPageByTimeDTO){
|
||||
public PageBaseResponse<OrderInfo> getOrderByPage(QueryPageByTimeDTO queryPageByTimeDTO) {
|
||||
QueryWrapper<OrderInfo> qw = new QueryWrapper<>();
|
||||
qw.eq("account_id",UserContext.getUserHolder().getId());
|
||||
qw.eq("account_id", UserContext.getUserHolder().getId());
|
||||
|
||||
String startTime = queryPageByTimeDTO.getStartTime();
|
||||
String endTime = queryPageByTimeDTO.getEndTime();
|
||||
if (StringUtil.isNullOrEmpty(startTime)){
|
||||
if (StringUtil.isNullOrEmpty(startTime)) {
|
||||
startTime = "2024-02-01 00:00:00";
|
||||
}
|
||||
if (StringUtil.isNullOrEmpty(endTime)){
|
||||
if (StringUtil.isNullOrEmpty(endTime)) {
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||
endTime = now.format(dateTimeFormatter);
|
||||
@@ -206,11 +249,28 @@ public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo
|
||||
return PageBaseResponse.success(orderInfo);
|
||||
}
|
||||
|
||||
public void updateOrderNoById(Long id, String orderNo){
|
||||
public void updateOrderNoById(Long id, String orderNo) {
|
||||
OrderInfo orderInfo = new OrderInfo();
|
||||
orderInfo.setId(id);
|
||||
orderInfo.setOrderNo(orderNo);
|
||||
|
||||
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)
|
||||
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();
|
||||
HttpResponse<com.paypal.orders.Order> ordersGetResponse = null;
|
||||
ordersGetRequest.authorization("Bearer " + getOAuth());
|
||||
@@ -461,7 +461,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
|
||||
request.authorization("Bearer " + getOAuth());
|
||||
request.prefer("return=representation");
|
||||
|
||||
OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(orderId);
|
||||
OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(orderNo);
|
||||
request.requestBody(buildRefundRequestBody(String.valueOf(orderInfo.getTotalFee()), reason));
|
||||
HttpResponse<com.paypal.payments.Refund> response = null;
|
||||
try {
|
||||
@@ -476,7 +476,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
|
||||
//进行数据库操作,修改状态为已退款(配合回调和退款查询确定退款成功)
|
||||
|
||||
//更新订单状态
|
||||
orderInfoService.updateStatusByOrderNo(orderId, OrderStatusEnum.REFUND_SUCCESS);
|
||||
orderInfoService.updateStatusByOrderNo(orderNo, OrderStatusEnum.REFUND_SUCCESS);
|
||||
|
||||
refundsInfoService.updateRefundForPayPal(
|
||||
refundByOrderNo.getId(),
|
||||
@@ -485,14 +485,14 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
|
||||
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(), (int)(orderByOrderNo.getTotalFee() / Float.parseFloat(CreditsEventsEnum.PRICE.getValue())));
|
||||
creditsService.creditsRefund(orderByOrderNo.getAccountId(), (int)(orderByOrderNo.getTotalFee() / Float.parseFloat(CreditsEventsEnum.PRICE.getValue())), orderNo);
|
||||
log.info("退款成功");
|
||||
result = Boolean.TRUE;
|
||||
} else {
|
||||
//更新订单状态
|
||||
orderInfoService.updateStatusByOrderNo(orderId, OrderStatusEnum.REFUND_ABNORMAL);
|
||||
orderInfoService.updateStatusByOrderNo(orderNo, OrderStatusEnum.REFUND_ABNORMAL);
|
||||
|
||||
//更新退款单
|
||||
refundsInfoService.updateRefundForPayPal(
|
||||
@@ -571,19 +571,19 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
|
||||
|
||||
// 处理当前订单
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void processOrder(String orderId) {
|
||||
public void processOrder(String orderNo) {
|
||||
// 1、确定当前订单是否已经被扣款
|
||||
OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(orderId);
|
||||
OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(orderNo);
|
||||
if (orderInfo.getOrderStatus().equals(OrderStatusEnum.SUCCESS.getType())) {
|
||||
// 直接返回
|
||||
return;
|
||||
}
|
||||
// 发起扣款请求
|
||||
Order capturedOrder = captureOrder(orderId);
|
||||
Order capturedOrder = captureOrder(orderNo);
|
||||
// 业务处理
|
||||
if (PayPalOrderStatusEnum.COMPLETED.getStatus().equals(capturedOrder.status())) {
|
||||
//更新订单状态
|
||||
orderInfoService.updateStatusByOrderNo(orderId, OrderStatusEnum.SUCCESS);
|
||||
orderInfoService.updateStatusByOrderNo(orderNo, OrderStatusEnum.SUCCESS);
|
||||
//记录支付日志
|
||||
paymentInfoService.createPaymentInfoForPayPal(capturedOrder);
|
||||
float quantity = orderInfo.getTotalFee() / Float.parseFloat(CreditsEventsEnum.PRICE.getValue());
|
||||
@@ -593,7 +593,7 @@ public class PayPalCheckoutServiceImpl implements PayPalCheckoutService {
|
||||
creditsService.insertToCreditsDetail(orderInfo.getAccountId(),
|
||||
CreditsEventsEnum.BUY_CREDITS.getName() + "--PayPal",
|
||||
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(),
|
||||
CreditsEventsEnum.BUY_CREDITS.getName() + "--Paypal",
|
||||
String.valueOf((Long.parseLong(CreditsEventsEnum.BUY_CREDITS.getValue()) * quantity)),
|
||||
"positive");
|
||||
"positive", orderNo);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,27 +1,49 @@
|
||||
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.response.PageBaseResponse;
|
||||
import com.ai.da.mapper.primary.PaymentInfoMapper;
|
||||
import com.ai.da.mapper.primary.entity.PaymentInfo;
|
||||
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.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.google.gson.Gson;
|
||||
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 io.netty.util.internal.StringUtil;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
@Service
|
||||
@Slf4j
|
||||
public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, PaymentInfo> implements PaymentInfoService {
|
||||
|
||||
@Resource
|
||||
private StripeService stripeService;
|
||||
|
||||
/**
|
||||
* 记录支付日志:微信支付
|
||||
* @param plainText
|
||||
@@ -50,7 +72,6 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
|
||||
paymentInfo.setOrderNo(orderNo);
|
||||
paymentInfo.setPaymentType(PayTypeEnum.WXPAY.getType());
|
||||
paymentInfo.setTransactionId(transactionId);
|
||||
paymentInfo.setTradeType(tradeType);
|
||||
paymentInfo.setTradeState(tradeState);
|
||||
// 原来的单位是:分 Int 现改为:元 Float
|
||||
paymentInfo.setPayerTotal(payerTotal / 100.0F);
|
||||
@@ -83,7 +104,6 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
|
||||
paymentInfo.setOrderNo(orderNo);
|
||||
paymentInfo.setPaymentType(PayTypeEnum.ALIPAY.getType());
|
||||
paymentInfo.setTransactionId(transactionId);
|
||||
paymentInfo.setTradeType("电脑网站支付");
|
||||
paymentInfo.setTradeState(tradeStatus);
|
||||
// 原来的单位是分 Int 现改为元 Long
|
||||
paymentInfo.setPayerTotal(totalAmountInt / 100.0F);
|
||||
@@ -107,7 +127,6 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
|
||||
paymentInfo.setOrderNo(order.id());
|
||||
paymentInfo.setPaymentType(PayTypeEnum.PAYPAL.getType());
|
||||
paymentInfo.setTransactionId(order.id());
|
||||
paymentInfo.setTradeType("电脑网站支付");
|
||||
paymentInfo.setTradeState(order.status());
|
||||
// todo 确认这里的数据单位是不是元
|
||||
paymentInfo.setPayerTotal(totalAmountFloat);
|
||||
@@ -139,7 +158,6 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
|
||||
paymentInfo.setOrderNo(orderNo);
|
||||
paymentInfo.setPaymentType(PayTypeEnum.ALIPAY_HK.getType());
|
||||
paymentInfo.setTransactionId(transactionId);
|
||||
paymentInfo.setTradeType("电脑网站支付");
|
||||
paymentInfo.setTradeState(tradeStatus);
|
||||
paymentInfo.setPayerTotal(totalAmountFloat);
|
||||
|
||||
@@ -150,10 +168,10 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
|
||||
baseMapper.insert(paymentInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createPaymentInfoForStripe(Session session){
|
||||
public void createOrUpdatePaymentInfoForStripe(Session session){
|
||||
String orderId = session.getMetadata().get("orderId");
|
||||
String status = session.getStatus();
|
||||
// 获取transactionId,从sessionId更改为invoiceId
|
||||
String sessionId = session.getId();
|
||||
Long amountTotal = session.getAmountTotal();
|
||||
// stripe 的支付金额单位是分
|
||||
@@ -163,7 +181,6 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
|
||||
paymentInfo.setOrderNo(orderId);
|
||||
paymentInfo.setPaymentType(PayTypeEnum.STRIPE.getType());
|
||||
paymentInfo.setTransactionId(sessionId);
|
||||
paymentInfo.setTradeType("电脑网站支付");
|
||||
paymentInfo.setTradeState(status);
|
||||
paymentInfo.setPayerTotal(divide);
|
||||
Gson gson = new Gson();
|
||||
@@ -173,12 +190,144 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
|
||||
baseMapper.insert(paymentInfo);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PaymentInfo getPaymentInfoByOrderId(String orderId){
|
||||
QueryWrapper<PaymentInfo> qw = new QueryWrapper<>();
|
||||
qw.eq("order_no", orderId);
|
||||
@Value("${stripe.private-key}")
|
||||
private String privateKey;
|
||||
public PaymentInfo createOrUpdatePaymentInfoForStripe(Invoice invoice){
|
||||
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
|
||||
@@ -190,4 +339,36 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
|
||||
|
||||
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,
|
||||
CreditsEventsEnum.SUPER_RESOLUTION.getName(),
|
||||
CreditsEventsEnum.SUPER_RESOLUTION.getValue(),
|
||||
"negative");
|
||||
"negative", null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user