Affiliate功能-数据库表设计更新
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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:";
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ public class AffiliateController {
|
||||
|
||||
@ApiOperation(value = "注册成为affiliate")
|
||||
@GetMapping("/registration")
|
||||
public Response<Boolean> completeGuidance(@RequestParam("promotionMethod") String promotionMethod) {
|
||||
public Response<Boolean> 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<double[]> getPersonalMonthlyIncome(@RequestParam("year")int year) {
|
||||
return Response.success(affiliateService.getPersonalMonthlyIncome(year));
|
||||
}
|
||||
|
||||
@ApiOperation(value = "审批affiliate申请")
|
||||
@GetMapping("/approval")
|
||||
public Response<Boolean> applicationApproval(@RequestParam("id") Long id, @RequestParam("isApproved")Boolean isApproved) {
|
||||
return Response.success(affiliateService.applicationApproval(id, isApproved));
|
||||
}
|
||||
|
||||
@ApiOperation(value = "定时计算佣金")
|
||||
/*@ApiOperation(value = "定时计算佣金")
|
||||
@GetMapping("/testTask")
|
||||
public Response<String> testTask() {
|
||||
affiliateService.updateAffiliateInfoWithPayment();
|
||||
return Response.success("success ");
|
||||
}
|
||||
}*/
|
||||
|
||||
/*@ApiOperation(value = "每月发送结算邮件")
|
||||
@GetMapping("/commissionCalculation")
|
||||
public Response<String> commissionCalculation() {
|
||||
affiliateService.commissionCalculation(null, null);
|
||||
return Response.success("success ");
|
||||
}*/
|
||||
|
||||
@ApiOperation(value = "affiliate链接浏览量增加")
|
||||
@GetMapping("/viewsIncrease")
|
||||
@@ -64,9 +77,9 @@ public class AffiliateController {
|
||||
}
|
||||
|
||||
@ApiOperation(value = "获取每个affiliate产生的收入")
|
||||
@GetMapping("/getEachAffiliateGeneratedRevenue")
|
||||
public Response<List<AffiliateInvitationDetailsVO>> 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<IPage<AffiliateInvitationDetailsVO>> getEachAffiliateGeneratedRevenue(@RequestBody AffiliateQueryDTO affiliateQueryDTO) {
|
||||
return Response.success(affiliateService.getEachAffiliateGeneratedRevenue(affiliateQueryDTO));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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<String> cancelSubscription(@RequestParam String subscriptionId, @RequestParam String reason) {
|
||||
public Response<String> 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<String> getCustomerPaymentMethod(@RequestParam String name, @RequestParam String email) {
|
||||
public Response<List<Map<String,String>>> getCustomerPaymentMethod(@RequestParam String name, @RequestParam String email) {
|
||||
return Response.success(stripeService.getCustomerPaymentMethod(name, email));
|
||||
}
|
||||
|
||||
@ApiOperation("临时 解绑指定用户绑定的所有付款方式")
|
||||
@GetMapping("/detachCustomerAllPaymentMethod")
|
||||
public Response<String> detachCustomerAllPaymentMethod(@RequestParam String name, @RequestParam String email) {
|
||||
return Response.success(stripeService.detachCustomerAllPaymentMethod(name, email));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.ai.da.mapper.primary;
|
||||
|
||||
import com.ai.da.mapper.primary.entity.AffiliateIncome;
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface AffiliateIncomeMapper extends BaseMapper<AffiliateIncome> {
|
||||
|
||||
List<Map<String, Object>> getPersonalMonthlyIncome(Long affiliateAccountId, int year);
|
||||
|
||||
List<Map<String, Object>> getMonthlyAffiliateIncome(int year, int month);
|
||||
}
|
||||
@@ -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<Affiliate> {
|
||||
|
||||
Map<String, Long> getMonthlyApprovedAffiliate(int year, int month);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
@@ -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() + '\'' + ' ' +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -59,4 +59,7 @@ public class AccountLoginVO {
|
||||
// 是否自动续订
|
||||
private boolean isAutoRenewal;
|
||||
|
||||
// 是否是affiliate
|
||||
private boolean isAffiliate = false;
|
||||
|
||||
}
|
||||
|
||||
@@ -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<Affiliate> {
|
||||
|
||||
Boolean registerAsAnAffiliate(String promotionMethod);
|
||||
@@ -17,11 +15,17 @@ public interface AffiliateService extends IService<Affiliate> {
|
||||
|
||||
AffiliateVO personalAffiliateCenter();
|
||||
|
||||
double[] getPersonalMonthlyIncome(int year);
|
||||
|
||||
Boolean applicationApproval(Long id, Boolean isApproved);
|
||||
|
||||
void updateAffiliateInfoWithPayment();
|
||||
|
||||
Boolean affiliateLinkViewsIncrease(Long id);
|
||||
|
||||
List<AffiliateInvitationDetailsVO> getEachAffiliateGeneratedRevenue(Long affiliateId, String startTime, String endTime);
|
||||
IPage<AffiliateInvitationDetailsVO> getEachAffiliateGeneratedRevenue(AffiliateQueryDTO affiliateQueryDTO);
|
||||
|
||||
Affiliate getByAccountId(Long accountId);
|
||||
|
||||
void commissionCalculation(Integer year, Integer month);
|
||||
}
|
||||
|
||||
@@ -44,5 +44,7 @@ public interface StripeService {
|
||||
|
||||
boolean sendRenewalFailEmail(String invoiceId, String subscriptionId, String orderNo);
|
||||
|
||||
String getCustomerPaymentMethod(String name, String email);
|
||||
List<Map<String,String>> getCustomerPaymentMethod(String name, String email);
|
||||
|
||||
String detachCustomerAllPaymentMethod(String name, String email);
|
||||
}
|
||||
|
||||
@@ -107,6 +107,9 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> 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<AccountMapper, Account> 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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<AffiliateMapper, Affiliate
|
||||
@Resource
|
||||
private SubscriptionInfoMapper subscriptionInfoMapper;
|
||||
|
||||
@Resource
|
||||
private AffiliateIncomeMapper affiliateIncomeMapper;
|
||||
|
||||
@Resource
|
||||
private RedisUtil redisUtil;
|
||||
|
||||
@@ -79,10 +85,13 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
|
||||
}
|
||||
|
||||
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());
|
||||
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<AffiliateMapper, Affiliate
|
||||
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);
|
||||
@@ -107,7 +128,7 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
|
||||
affiliate.setApproved(true);
|
||||
affiliate.setLink(CommonConstant.AFFILIATE_LINK + affiliate.getId());
|
||||
} else {
|
||||
affiliate.setStatus("Inactive");
|
||||
affiliate.setStatus("Refused");
|
||||
affiliate.setApproved(false);
|
||||
}
|
||||
affiliate.setUpdateTime(LocalDateTime.now());
|
||||
@@ -142,6 +163,9 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
|
||||
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<>();
|
||||
@@ -155,6 +179,7 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
|
||||
// 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"));
|
||||
@@ -168,6 +193,17 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
|
||||
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);
|
||||
@@ -190,51 +226,69 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
|
||||
|
||||
// 查看每个affiliate带来收入的详情
|
||||
@Override
|
||||
public List<AffiliateInvitationDetailsVO> getEachAffiliateGeneratedRevenue(Long affiliateId, String startTime, String endTime) {
|
||||
List<AffiliateInvitationDetailsVO> resp = new ArrayList<>() ;
|
||||
// 1、从account表中找到所有关联了指定affiliateId的accountId
|
||||
QueryWrapper<Account> qw = new QueryWrapper<>();
|
||||
qw.eq("invitation_code", affiliateId);
|
||||
|
||||
List<Account> accountList = accountService.getBaseMapper().selectList(qw);
|
||||
if (accountList.isEmpty()){
|
||||
return null;
|
||||
} else {
|
||||
accountList.forEach(account -> {
|
||||
// 2、分别找到各个accountId产生的第一笔订阅
|
||||
Long accountId = account.getId();
|
||||
QueryWrapper<SubscriptionInfo> 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<AffiliateInvitationDetailsVO> getEachAffiliateGeneratedRevenue(AffiliateQueryDTO affiliateQueryDTO) {
|
||||
if (Objects.isNull(affiliateQueryDTO.getAffiliateId())){
|
||||
throw new BusinessException("Please specify the affiliate ID.", ResultEnum.PROMPT.getCode());
|
||||
}
|
||||
return resp;
|
||||
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
||||
// 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<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");
|
||||
}
|
||||
|
||||
// 3、邀请的新人 查询account表中,本月新增并有invitation_id的数量
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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<Map<String,String>> getCustomerPaymentMethod(String name, String email){
|
||||
Stripe.apiKey = privateKey;
|
||||
try {
|
||||
String customerId = getCustomer(name, email);
|
||||
Customer customer = Customer.retrieve(customerId);
|
||||
PaymentMethodCollection paymentMethodCollection = customer.listPaymentMethods();
|
||||
List<PaymentMethod> data = paymentMethodCollection.getData();
|
||||
ArrayList<Map<String,String>> resp = new ArrayList<>();
|
||||
data.forEach(paymentMethod -> {
|
||||
Map<String,String> 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<PaymentMethod> 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user