diff --git a/src/main/java/com/ai/da/common/task/PaymentTask.java b/src/main/java/com/ai/da/common/task/PaymentTask.java index 656e3a23..40450055 100644 --- a/src/main/java/com/ai/da/common/task/PaymentTask.java +++ b/src/main/java/com/ai/da/common/task/PaymentTask.java @@ -2,16 +2,14 @@ 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.AliPayService; -import com.ai.da.service.OrderInfoService; -import com.ai.da.service.PayPalCheckoutService; -import com.ai.da.service.StripeService; +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 @@ -24,6 +22,10 @@ public class PaymentTask { @Resource private StripeService stripeService; + @Resource + private AffiliateService affiliateService; + + // 考虑删除该定时任务(原因:之后的订单列允许用户查看发票,发票未过期时仍可以支付,所以不需要手动使订单过期) // @Scheduled(cron = "0/30 * * * * ?") public void orderConfirmForStripe() throws SerializeException { @@ -89,8 +91,31 @@ public class PaymentTask { } // 每天凌晨检查subscription中有哪些已过期,更新状态 - @Scheduled(cron = "0 0 0 * * ?") - public void checkSubscriptionExpiration(){ - stripeService.checkSubscriptionExpiration(); +// @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); + } + } + } diff --git a/src/main/java/com/ai/da/common/utils/RedisUtil.java b/src/main/java/com/ai/da/common/utils/RedisUtil.java index d3ba2a93..7e0d9578 100644 --- a/src/main/java/com/ai/da/common/utils/RedisUtil.java +++ b/src/main/java/com/ai/da/common/utils/RedisUtil.java @@ -279,7 +279,7 @@ public class RedisUtil { redisTemplate.expire(redisKey, 5, TimeUnit.MINUTES); } - public final static String PAYMENT_INFO_LAST_SCAN_TIME = "PaymentInfoLastScanTime:"; + public final static String PAYMENT_INFO_LAST_SCAN_TIME = "PaymentInfoLastScanTime"; public final static String AFFILIATE_LINK_VIEW_KEY = "AffiliateLink:view:"; diff --git a/src/main/java/com/ai/da/controller/AffiliateController.java b/src/main/java/com/ai/da/controller/AffiliateController.java index f980dd10..1be751ac 100644 --- a/src/main/java/com/ai/da/controller/AffiliateController.java +++ b/src/main/java/com/ai/da/controller/AffiliateController.java @@ -28,7 +28,7 @@ public class AffiliateController { @ApiOperation(value = "注册成为affiliate") @GetMapping("/registration") - public Response completeGuidance(@RequestParam("promotionMethod") String promotionMethod) { + public Response completeGuidance(@RequestParam(value = "promotionMethod", required = false) String promotionMethod) { return Response.success(affiliateService.registerAsAnAffiliate(promotionMethod)); } @@ -44,18 +44,31 @@ public class AffiliateController { return Response.success(affiliateService.personalAffiliateCenter()); } + @ApiOperation(value = "获取个人佣金图表数据") + @GetMapping("/getPersonalMonthlyIncome") + public Response getPersonalMonthlyIncome(@RequestParam("year")int year) { + return Response.success(affiliateService.getPersonalMonthlyIncome(year)); + } + @ApiOperation(value = "审批affiliate申请") @GetMapping("/approval") public Response applicationApproval(@RequestParam("id") Long id, @RequestParam("isApproved")Boolean isApproved) { return Response.success(affiliateService.applicationApproval(id, isApproved)); } - @ApiOperation(value = "定时计算佣金") + /*@ApiOperation(value = "定时计算佣金") @GetMapping("/testTask") public Response testTask() { affiliateService.updateAffiliateInfoWithPayment(); return Response.success("success "); - } + }*/ + + /*@ApiOperation(value = "每月发送结算邮件") + @GetMapping("/commissionCalculation") + public Response commissionCalculation() { + affiliateService.commissionCalculation(null, null); + return Response.success("success "); + }*/ @ApiOperation(value = "affiliate链接浏览量增加") @GetMapping("/viewsIncrease") @@ -64,9 +77,9 @@ public class AffiliateController { } @ApiOperation(value = "获取每个affiliate产生的收入") - @GetMapping("/getEachAffiliateGeneratedRevenue") - public Response> getEachAffiliateGeneratedRevenue(@RequestParam("id") Long id, @RequestParam(required = false) String startTime, @RequestParam(required = false) String endTime) { - return Response.success(affiliateService.getEachAffiliateGeneratedRevenue(id, startTime, endTime)); + @PostMapping("/getEachAffiliateGeneratedRevenue") + public Response> getEachAffiliateGeneratedRevenue(@RequestBody AffiliateQueryDTO affiliateQueryDTO) { + return Response.success(affiliateService.getEachAffiliateGeneratedRevenue(affiliateQueryDTO)); } diff --git a/src/main/java/com/ai/da/controller/StripeController.java b/src/main/java/com/ai/da/controller/StripeController.java index ede043d6..82c5e1cc 100644 --- a/src/main/java/com/ai/da/controller/StripeController.java +++ b/src/main/java/com/ai/da/controller/StripeController.java @@ -19,6 +19,7 @@ import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import java.io.IOException; import java.util.List; +import java.util.Map; @Api(tags = "Stripe模块") @Slf4j @@ -70,7 +71,7 @@ public class StripeController { @ApiOperation("取消订阅") @GetMapping("/cancelSubscription") - public Response cancelSubscription(@RequestParam String subscriptionId, @RequestParam String reason) { + public Response cancelSubscription(@RequestParam String subscriptionId, @RequestParam(required = false) String reason) { stripeService.cancelSubscription(subscriptionId, reason); return Response.success("success"); } @@ -101,8 +102,14 @@ public class StripeController { @ApiOperation("临时 查询指定用户绑定的付款方式") @GetMapping("/getCustomerPaymentMethod") - public Response getCustomerPaymentMethod(@RequestParam String name, @RequestParam String email) { + public Response>> getCustomerPaymentMethod(@RequestParam String name, @RequestParam String email) { return Response.success(stripeService.getCustomerPaymentMethod(name, email)); } + @ApiOperation("临时 解绑指定用户绑定的所有付款方式") + @GetMapping("/detachCustomerAllPaymentMethod") + public Response detachCustomerAllPaymentMethod(@RequestParam String name, @RequestParam String email) { + return Response.success(stripeService.detachCustomerAllPaymentMethod(name, email)); + } + } diff --git a/src/main/java/com/ai/da/mapper/primary/AffiliateIncomeMapper.java b/src/main/java/com/ai/da/mapper/primary/AffiliateIncomeMapper.java new file mode 100644 index 00000000..d0a7d6ce --- /dev/null +++ b/src/main/java/com/ai/da/mapper/primary/AffiliateIncomeMapper.java @@ -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 { + + List> getPersonalMonthlyIncome(Long affiliateAccountId, int year); + + List> getMonthlyAffiliateIncome(int year, int month); +} diff --git a/src/main/java/com/ai/da/mapper/primary/AffiliateMapper.java b/src/main/java/com/ai/da/mapper/primary/AffiliateMapper.java index 314a0952..3974b904 100644 --- a/src/main/java/com/ai/da/mapper/primary/AffiliateMapper.java +++ b/src/main/java/com/ai/da/mapper/primary/AffiliateMapper.java @@ -3,5 +3,9 @@ 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 { + + Map getMonthlyApprovedAffiliate(int year, int month); } diff --git a/src/main/java/com/ai/da/mapper/primary/entity/AffiliateIncome.java b/src/main/java/com/ai/da/mapper/primary/entity/AffiliateIncome.java new file mode 100644 index 00000000..eb8ce12c --- /dev/null +++ b/src/main/java/com/ai/da/mapper/primary/entity/AffiliateIncome.java @@ -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; + +} diff --git a/src/main/java/com/ai/da/model/dto/AffiliateQueryDTO.java b/src/main/java/com/ai/da/model/dto/AffiliateQueryDTO.java index 5498964b..79fac3e7 100644 --- a/src/main/java/com/ai/da/model/dto/AffiliateQueryDTO.java +++ b/src/main/java/com/ai/da/model/dto/AffiliateQueryDTO.java @@ -1,6 +1,7 @@ package com.ai.da.model.dto; import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; import lombok.Data; import lombok.EqualsAndHashCode; @@ -8,6 +9,23 @@ import lombok.EqualsAndHashCode; @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() + '\'' + ' ' + + '}'; + } } diff --git a/src/main/java/com/ai/da/model/vo/AccountLoginVO.java b/src/main/java/com/ai/da/model/vo/AccountLoginVO.java index 8033057b..d514dc8d 100644 --- a/src/main/java/com/ai/da/model/vo/AccountLoginVO.java +++ b/src/main/java/com/ai/da/model/vo/AccountLoginVO.java @@ -59,4 +59,7 @@ public class AccountLoginVO { // 是否自动续订 private boolean isAutoRenewal; + // 是否是affiliate + private boolean isAffiliate = false; + } diff --git a/src/main/java/com/ai/da/service/AffiliateService.java b/src/main/java/com/ai/da/service/AffiliateService.java index 768bb214..9ceb1cb1 100644 --- a/src/main/java/com/ai/da/service/AffiliateService.java +++ b/src/main/java/com/ai/da/service/AffiliateService.java @@ -7,8 +7,6 @@ import com.ai.da.model.vo.AffiliateVO; import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.extension.service.IService; -import java.util.List; - public interface AffiliateService extends IService { Boolean registerAsAnAffiliate(String promotionMethod); @@ -17,11 +15,17 @@ public interface AffiliateService extends IService { AffiliateVO personalAffiliateCenter(); + double[] getPersonalMonthlyIncome(int year); + Boolean applicationApproval(Long id, Boolean isApproved); void updateAffiliateInfoWithPayment(); Boolean affiliateLinkViewsIncrease(Long id); - List getEachAffiliateGeneratedRevenue(Long affiliateId, String startTime, String endTime); + IPage getEachAffiliateGeneratedRevenue(AffiliateQueryDTO affiliateQueryDTO); + + Affiliate getByAccountId(Long accountId); + + void commissionCalculation(Integer year, Integer month); } diff --git a/src/main/java/com/ai/da/service/StripeService.java b/src/main/java/com/ai/da/service/StripeService.java index f0a95a7c..978b7c41 100644 --- a/src/main/java/com/ai/da/service/StripeService.java +++ b/src/main/java/com/ai/da/service/StripeService.java @@ -44,5 +44,7 @@ public interface StripeService { boolean sendRenewalFailEmail(String invoiceId, String subscriptionId, String orderNo); - String getCustomerPaymentMethod(String name, String email); + List> getCustomerPaymentMethod(String name, String email); + + String detachCustomerAllPaymentMethod(String name, String email); } diff --git a/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java b/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java index 74ccd3f2..5840852e 100644 --- a/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/AccountServiceImpl.java @@ -107,6 +107,9 @@ public class AccountServiceImpl extends ServiceImpl impl @Resource private StripeService stripeService; + @Resource + private AffiliateService affiliateService; + @Override @Transactional(rollbackFor = Exception.class) public AccountPreLoginVO preLogin(AccountPreLoginDTO accountDTO) { @@ -2428,6 +2431,10 @@ public class AccountServiceImpl extends ServiceImpl impl response.setAutoRenewal(subscriptionInfo.getStatus().equals("active")); } + Affiliate affiliate = affiliateService.getByAccountId(accountId); + if (!Objects.isNull(affiliate) && affiliate.getStatus().equals("Active")) { + response.setAffiliate(true); + } return response; } diff --git a/src/main/java/com/ai/da/service/impl/AffiliateServiceImpl.java b/src/main/java/com/ai/da/service/impl/AffiliateServiceImpl.java index a249b08d..220aefe6 100644 --- a/src/main/java/com/ai/da/service/impl/AffiliateServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/AffiliateServiceImpl.java @@ -7,6 +7,8 @@ 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.*; @@ -31,9 +33,10 @@ import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.math.BigDecimal; import java.time.LocalDateTime; -import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Objects; +import java.util.function.Function; @Service @Slf4j @@ -51,6 +54,9 @@ public class AffiliateServiceImpl extends ServiceImpl getAffiliateList(AffiliateQueryDTO affiliateQueryDTO){ + log.info("parameter => {}", affiliateQueryDTO.toString()); QueryWrapper qw = new QueryWrapper<>(); - qw.eq(!StringUtils.isNullOrEmpty(affiliateQueryDTO.getStatus()), "status", affiliateQueryDTO.getStatus()); - qw.gt(!StringUtils.isNullOrEmpty(affiliateQueryDTO.getStartTime()), "create_time", affiliateQueryDTO.getStartTime()); - qw.lt(!StringUtils.isNullOrEmpty(affiliateQueryDTO.getEndTime()), "create_time", affiliateQueryDTO.getEndTime()); + 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); } @@ -96,6 +105,18 @@ public class AffiliateServiceImpl extends ServiceImpl> 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); @@ -107,7 +128,7 @@ public class AffiliateServiceImpl extends ServiceImpl { // 2、根据order_no查付款用户id OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(paymentInfo.getOrderNo()); + if (Objects.isNull(orderInfo)){ + return; + } Long accountId = orderInfo.getAccountId(); // 3、查该用户之前是否有初次订阅的订单 QueryWrapper qwOrderInfo = new QueryWrapper<>(); @@ -155,6 +179,7 @@ public class AffiliateServiceImpl extends ServiceImpl 0){ // 分配新用户首次订阅所付费用的25%作为佣金 BigDecimal commission = BigDecimal.valueOf(payerTotal).multiply(new BigDecimal("0.25")); @@ -168,6 +193,17 @@ public class AffiliateServiceImpl extends ServiceImpl getEachAffiliateGeneratedRevenue(Long affiliateId, String startTime, String endTime) { - List resp = new ArrayList<>() ; - // 1、从account表中找到所有关联了指定affiliateId的accountId - QueryWrapper qw = new QueryWrapper<>(); - qw.eq("invitation_code", affiliateId); - - List accountList = accountService.getBaseMapper().selectList(qw); - if (accountList.isEmpty()){ - return null; - } else { - accountList.forEach(account -> { - // 2、分别找到各个accountId产生的第一笔订阅 - Long accountId = account.getId(); - QueryWrapper subscriptionInfoQueryWrapper = new QueryWrapper<>(); - subscriptionInfoQueryWrapper.eq("account_id", accountId) - .and(s -> s.eq("status", "active").or().eq("status", "canceled")) - .gt(!StringUtils.isNullOrEmpty(startTime) ,"create_time", startTime) - .lt(!StringUtils.isNullOrEmpty(endTime) ,"create_time", endTime).last("limit 1"); - - SubscriptionInfo subscriptionInfo = subscriptionInfoMapper.selectOne(subscriptionInfoQueryWrapper); - // 2、分别第一笔订阅的付款信息 - if (!Objects.isNull(subscriptionInfo)){ - PaymentInfo paymentInfo = paymentInfoService.getPaymentInfoByOrderNo(subscriptionInfo.getOrderNo(), "ASC").get(0); - AffiliateInvitationDetailsVO affiliateInvitationDetailsVO = new AffiliateInvitationDetailsVO(); - affiliateInvitationDetailsVO.setAccountId(accountId); - affiliateInvitationDetailsVO.setUsername(account.getUserName()); - affiliateInvitationDetailsVO.setFirstSubscriptionPaymentAmount(paymentInfo.getPayerTotal()); - affiliateInvitationDetailsVO.setCommission(BigDecimal.valueOf(paymentInfo.getPayerTotal()).multiply(new BigDecimal("0.25")).floatValue()); - affiliateInvitationDetailsVO.setTime(subscriptionInfo.getCreateTime()); - resp.add(affiliateInvitationDetailsVO); - } - }); + public IPage getEachAffiliateGeneratedRevenue(AffiliateQueryDTO affiliateQueryDTO) { + if (Objects.isNull(affiliateQueryDTO.getAffiliateId())){ + throw new BusinessException("Please specify the affiliate ID.", ResultEnum.PROMPT.getCode()); } - return resp; + + QueryWrapper 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 affiliateIncomePage = affiliateIncomeMapper.selectPage(new Page<>(affiliateQueryDTO.getPage(), affiliateQueryDTO.getSize()), affiliateIncomeQueryWrapper); + return affiliateIncomePage.convert((Function) 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; + }); } - // todo 每个月给kim发一封邮件统计本月的affiliate等的收入 - public void commissionCalculation(){ - // 1、总收入(近一个月通过affiliate产生的收入) + public void commissionCalculation(Integer year, Integer month) { + if (Objects.isNull(year)) { + year = LocalDateTime.now().getYear(); + } + if (Objects.isNull(month)) { + month = LocalDateTime.now().getMonthValue(); + } - // 2、未支付的金额 affiliate表中unpaid的总和 + List> monthlyAffiliateIncome = affiliateIncomeMapper.getMonthlyAffiliateIncome(year, month); + // 1、总收入(近一个月通过affiliate产生的收入),未支付的金额 affiliate表中unpaid的总和 + Double totalAmount = 0.0; + Double totalCommission = 0.0; + if (!monthlyAffiliateIncome.isEmpty()){ + Map monthlyIncome = monthlyAffiliateIncome.get(0); + totalAmount = (Double) monthlyIncome.get("totalAmount"); + totalCommission = (Double) monthlyIncome.get("totalCommission"); + } - // 3、邀请的新人 查询account表中,本月新增并有invitation_id的数量 + // 2、本月新注册的Affiliate + Map 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 queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("account_id", accountId).orderByDesc("id").last("limit 1"); + + return baseMapper.selectOne(queryWrapper); } diff --git a/src/main/java/com/ai/da/service/impl/StripeServiceImpl.java b/src/main/java/com/ai/da/service/impl/StripeServiceImpl.java index 3d776186..f16bbb85 100644 --- a/src/main/java/com/ai/da/service/impl/StripeServiceImpl.java +++ b/src/main/java/com/ai/da/service/impl/StripeServiceImpl.java @@ -1004,8 +1004,8 @@ public class StripeServiceImpl implements StripeService { try { OrderInfo orderInfo = orderInfoService.createOrderByProductId(1, PayTypeEnum.STRIPE.getType(), ProductEnum.DailySubscription); - String customerId = getCustomer(name, email); -/* String paymentMethodCode = "pm_card_mastercard"; +// String customerId = getCustomer(name, email); + String paymentMethodCode = "pm_card_mastercard"; PaymentMethod paymentMethod = PaymentMethod.retrieve(paymentMethodCode); String customerId = getCustomer(name, email); @@ -1014,14 +1014,14 @@ public class StripeServiceImpl implements StripeService { PaymentMethodAttachParams attachParams = PaymentMethodAttachParams.builder() .setCustomer(customerId) .build(); - paymentMethod.attach(attachParams);*/ + paymentMethod.attach(attachParams); // 设置默认付款方式 Customer updatedCustomer = Customer.retrieve(customerId); CustomerUpdateParams params = CustomerUpdateParams.builder() .setInvoiceSettings( CustomerUpdateParams.InvoiceSettings.builder() -// .setDefaultPaymentMethod(paymentMethod.getId()) + .setDefaultPaymentMethod(paymentMethod.getId()) .build() ) .build(); @@ -1081,19 +1081,54 @@ public class StripeServiceImpl implements StripeService { } } - public String getCustomerPaymentMethod(String name, String email){ + public List> getCustomerPaymentMethod(String name, String email){ Stripe.apiKey = privateKey; try { String customerId = getCustomer(name, email); Customer customer = Customer.retrieve(customerId); PaymentMethodCollection paymentMethodCollection = customer.listPaymentMethods(); List data = paymentMethodCollection.getData(); + ArrayList> resp = new ArrayList<>(); + data.forEach(paymentMethod -> { + Map map = new HashMap<>(); + if (paymentMethod.getType().equals("card")){ + map.put(paymentMethod.getId(),paymentMethod.getCard().getLast4()); + }else { + map.put(paymentMethod.getId(),null); + } + resp.add(map); + }); - // todo 方向: 向用户添加了多种付款方式,更改默认的付款方式后,默认付款方式付款失败后是否自动使用其他付款方式付款? + return resp; + // 方向: 向用户添加了多种付款方式,更改默认的付款方式后,默认付款方式付款失败后是否自动使用其他付款方式付款? // 如果是的,则需要删除能成功的付款方式,保留唯一失败的付款方式进行续订付款失败测试 } catch (StripeException e) { throw new RuntimeException(e); } + + } + + public String detachCustomerAllPaymentMethod(String name, String email){ + Stripe.apiKey = privateKey; + // 方向: 向用户添加了多种付款方式,更改默认的付款方式后,默认付款方式付款失败后是否自动使用其他付款方式付款? + // 如果是的,则需要删除能成功的付款方式,保留唯一失败的付款方式进行续订付款失败测试 + try { + String customerId = getCustomer(name, email); + Customer customer = Customer.retrieve(customerId); + PaymentMethodCollection paymentMethodCollection = customer.listPaymentMethods(); + List data = paymentMethodCollection.getData(); + data.forEach(paymentMethod -> { + try { + PaymentMethod retrieve = PaymentMethod.retrieve(paymentMethod.getId()); + PaymentMethodDetachParams params = PaymentMethodDetachParams.builder().build(); + retrieve.detach(params); + } catch (StripeException e) { + throw new RuntimeException(e); + } + }); + } catch (StripeException e) { + throw new RuntimeException(e); + } return null; } @@ -1102,8 +1137,10 @@ public class StripeServiceImpl implements StripeService { qw.eq("subscription_id", subscriptionId); SubscriptionInfo subscriptionInfo = subscriptionInfoMapper.selectOne(qw); - subscriptionInfo.setCancelReason(reason); - subscriptionInfoMapper.updateById(subscriptionInfo); + if (!Objects.isNull(subscriptionInfo)) { + subscriptionInfo.setCancelReason(reason); + subscriptionInfoMapper.updateById(subscriptionInfo); + } } diff --git a/src/main/resources/mapper/primary/AffiliateIncomeMapper.xml b/src/main/resources/mapper/primary/AffiliateIncomeMapper.xml new file mode 100644 index 00000000..bac4a547 --- /dev/null +++ b/src/main/resources/mapper/primary/AffiliateIncomeMapper.xml @@ -0,0 +1,36 @@ + + + + + + + + + diff --git a/src/main/resources/mapper/primary/AffiliateMapper.xml b/src/main/resources/mapper/primary/AffiliateMapper.xml new file mode 100644 index 00000000..8dbe92da --- /dev/null +++ b/src/main/resources/mapper/primary/AffiliateMapper.xml @@ -0,0 +1,16 @@ + + + + + + +