添加Affiliate功能

This commit is contained in:
2024-12-16 10:26:02 +08:00
parent efe22de0a0
commit bf8af41f3f
20 changed files with 349 additions and 55 deletions

View File

@@ -104,6 +104,9 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
@Resource
private RedisUtil redisUtil;
@Resource
private StripeService stripeService;
@Override
@Transactional(rollbackFor = Exception.class)
public AccountPreLoginVO preLogin(AccountPreLoginDTO accountDTO) {
@@ -2416,6 +2419,14 @@ public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> impl
if (CollectionUtil.isNotEmpty(accountExtends)) {
response.setAccountExtendList(accountExtends);
}
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"));
}
return response;
}

View File

@@ -5,13 +5,14 @@ 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.ObjectUtils;
import com.ai.da.common.utils.RedisUtil;
import com.ai.da.common.utils.SendEmailUtil;
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;
@@ -22,6 +23,7 @@ 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;
@@ -29,6 +31,7 @@ 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.Objects;
@@ -45,6 +48,9 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
@Resource
private PaymentInfoService paymentInfoService;
@Resource
private SubscriptionInfoMapper subscriptionInfoMapper;
@Resource
private RedisUtil redisUtil;
@@ -60,6 +66,7 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, 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";
@@ -73,9 +80,9 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
public IPage<Affiliate> getAffiliateList(AffiliateQueryDTO affiliateQueryDTO){
QueryWrapper<Affiliate> qw = new QueryWrapper<>();
qw.eq(affiliateQueryDTO.getStatus() != null, "status", affiliateQueryDTO.getStatus());
qw.gt(affiliateQueryDTO.getStartTime() != null, "create_time", affiliateQueryDTO.getStartTime());
qw.lt(affiliateQueryDTO.getEndTime() != null, "create_time", affiliateQueryDTO.getEndTime());
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());
return baseMapper.selectPage(new Page<>(affiliateQueryDTO.getPage(), affiliateQueryDTO.getSize()), qw);
}
@@ -85,7 +92,7 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
qw.eq("account_id", accountId);
Affiliate affiliate = baseMapper.selectOne(qw);
AffiliateVO affiliateVO = CopyUtil.copyObject(affiliate, AffiliateVO.class);
affiliateVO.setLinkViewCount(getAffiliateLinkViewCount(accountId));
affiliateVO.setLinkViewCount(getAffiliateLinkViewCount(affiliate.getId()));
return affiliateVO;
}
@@ -104,6 +111,7 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
affiliate.setApproved(false);
}
affiliate.setUpdateTime(LocalDateTime.now());
baseMapper.updateById(affiliate);
// 2、将批准结果邮件通知用户
Account account = accountService.getById(affiliate.getAccountId());
@@ -171,17 +179,61 @@ public class AffiliateServiceImpl extends ServiceImpl<AffiliateMapper, Affiliate
redisUtil.addToString(RedisUtil.PAYMENT_INFO_LAST_SCAN_TIME, currentTime);
}
public Boolean affiliateLinkViewsIncrease(Long id) {
redisUtil.increaseAffiliateLinkViewCount(id);
public Boolean affiliateLinkViewsIncrease(Long affiliateId) {
redisUtil.increaseAffiliateLinkViewCount(affiliateId);
return Boolean.TRUE;
}
private Long getAffiliateLinkViewCount(Long accountId) {
return redisUtil.getAffiliateLinkViewCount(accountId);
private Long getAffiliateLinkViewCount(Long affiliateId) {
return redisUtil.getAffiliateLinkViewCount(affiliateId);
}
// 查看每个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);
}
});
}
return resp;
}
// todo 每个月给kim发一封邮件统计本月的affiliate等的收入
public void commissionCalculation(){
// 1、总收入(近一个月通过affiliate产生的收入)
// 2、未支付的金额 affiliate表中unpaid的总和
// 3、邀请的新人 查询account表中本月新增并有invitation_id的数量
}

View File

@@ -1,11 +1,17 @@
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.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;
@@ -15,15 +21,19 @@ 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;
@@ -313,11 +323,11 @@ public class PaymentInfoServiceImpl extends ServiceImpl<PaymentInfoMapper, Payme
@Override
public PaymentInfo getPaymentInfoByOrderId(String orderId){
public List<PaymentInfo> getPaymentInfoByOrderNo(String orderId, String order){
QueryWrapper<PaymentInfo> qw = new QueryWrapper<>();
qw.eq("order_no", orderId);
qw.eq("order_no", orderId).orderByDesc(order.equals("DESC"),"id");
return baseMapper.selectOne(qw);
return baseMapper.selectList(qw);
}
@Override
@@ -329,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);
}
}
}

View File

@@ -4,6 +4,7 @@ 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.enums.*;
import com.ai.da.common.utils.DateUtil;
import com.ai.da.common.utils.SendEmailUtil;
import com.ai.da.mapper.primary.AccountMapper;
import com.ai.da.mapper.primary.PaymentInfoMapper;
@@ -37,11 +38,9 @@ import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
@SuppressWarnings("LoggingSimilarMessage")
@@ -440,11 +439,9 @@ public class StripeServiceImpl implements StripeService {
@Transactional(rollbackFor = Exception.class)
public SubscriptionInfo createSubscription(Subscription subscription){
// 确认当前subscription是否已经记录
QueryWrapper<SubscriptionInfo> qw = new QueryWrapper<>();
qw.eq("subscription_id", subscription.getId());
SubscriptionInfo subscriptionInfo = subscriptionInfoMapper.selectOne(qw);
if (Objects.isNull(subscriptionInfo)){
SubscriptionInfo subscriptionInfo = getSubscriptionInfoBySubId(subscription.getId());
// SubscriptionInfo subscriptionInfo = subscriptionInfoMapper.selectOne(qw);
if (Objects.isNull(subscriptionInfo)) {
String description = subscription.getDescription();
String orderNo = description.replace("AiDA - ", "");
OrderInfo orderInfo = orderInfoService.getOrderByOrderNo(orderNo);
@@ -459,7 +456,7 @@ public class StripeServiceImpl implements StripeService {
subscriptionInfo.setSubscriptionId(subscription.getId());
subscriptionInfo.setType(interval);
subscriptionInfo.setStatus(subscription.getStatus());
subscriptionInfo.setNextPayDate(changeTimeStampFormat(subscription.getCurrentPeriodEnd(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy_EEEE));
subscriptionInfo.setNextPayDate(DateUtil.changeTimeStampFormat(subscription.getCurrentPeriodEnd(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy_EEEE));
subscriptionInfo.setCurrentPeriodStart(subscription.getCurrentPeriodStart());
subscriptionInfo.setCurrentPeriodEnd(subscription.getCurrentPeriodEnd());
subscriptionInfo.setCreateTime(LocalDateTime.now());
@@ -471,21 +468,34 @@ public class StripeServiceImpl implements StripeService {
return subscriptionInfo;
}
public String changeTimeStampFormat(Long timeStamp, String type, String format){
// 将秒级时间戳转换为毫秒级
if (type.equals("seconds")){
timeStamp = timeStamp * 1000;
public SubscriptionInfo getSubscriptionInfoBySubId(String subId){
QueryWrapper<SubscriptionInfo> qw = new QueryWrapper<>();
qw.eq("subscription_id", subId);
List<SubscriptionInfo> subscriptionInfos = subscriptionInfoMapper.selectList(qw);
if (subscriptionInfos.size() == 1){
return subscriptionInfos.get(0);
}else if (subscriptionInfos.size() > 1) {
// 如果新建了多个订阅则筛选出状态为active的订单
Optional<SubscriptionInfo> activeSubscriptionInfo = subscriptionInfos.stream()
.filter(sub -> sub.getStatus().equals("active"))
.findFirst();
return activeSubscriptionInfo.orElseGet(() -> subscriptionInfos.get(0));
}else {
return null;
}
// 输出格式
SimpleDateFormat outputFormat = new SimpleDateFormat(format, Locale.ENGLISH);
// 创建Date对象
Date date = new Date(timeStamp);
// 格式化输出
return outputFormat.format(date);
}
public String changeTimeStampFormat(LocalDateTime localDate){
return localDate.format(DateTimeFormatter.ofPattern("MMM. dd, yyyy, EEEE", Locale.US));
public SubscriptionInfo getLatestSubscriptionInfoByAccountId(Long accountId){
QueryWrapper<SubscriptionInfo> qw = new QueryWrapper<>();
qw.eq("account_id", accountId);
List<SubscriptionInfo> subscriptionInfos = subscriptionInfoMapper.selectList(qw);
if (subscriptionInfos.isEmpty()){
return null;
}else {
return subscriptionInfos.get(0);
}
}
@Transactional(rollbackFor = Exception.class)
@@ -504,10 +514,10 @@ public class StripeServiceImpl implements StripeService {
}
if (!subscriptionInfo.getCurrentPeriodEnd().equals(subscription.getCurrentPeriodEnd())){
subscriptionInfo.setCurrentPeriodEnd(subscription.getCurrentPeriodEnd());
subscriptionInfo.setNextPayDate(changeTimeStampFormat(subscription.getCurrentPeriodEnd(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy_EEEE));
subscriptionInfo.setNextPayDate(DateUtil.changeTimeStampFormat(subscription.getCurrentPeriodEnd(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy_EEEE));
// 更新账号到期时间
updateAccountValidity(subscriptionInfo.getAccountId(), subscriptionInfo.getCurrentPeriodEnd());
log.info("更新 {} 账号到期时间为:{}", subscriptionInfo.getAccountId(), changeTimeStampFormat(subscriptionInfo.getCurrentPeriodEnd(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy_EEEE));
log.info("更新 {} 账号到期时间为:{}", subscriptionInfo.getAccountId(), DateUtil.changeTimeStampFormat(subscriptionInfo.getCurrentPeriodEnd(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy_EEEE));
flag = true;
}
if (flag){
@@ -526,7 +536,7 @@ public class StripeServiceImpl implements StripeService {
}
// 取消连续订阅 将订阅从pause状态转为cancel状态使用定时器定期检索DB中过期且不续订的订阅
public void cancelSubscription(String subscriptionId) {
public void cancelSubscription(String subscriptionId, String cancelReason) {
Stripe.apiKey = privateKey;
Long accountId = UserContext.getUserHolder().getId();
log.info("用户 {} 申请取消连续订阅 {}", accountId, subscriptionId);
@@ -538,6 +548,9 @@ public class StripeServiceImpl implements StripeService {
try {
Subscription cancel = subscription.cancel();
cancel.getStatus();
// 更新数据库
updateCancelReason(subscriptionId, cancelReason);
} catch (StripeException e) {
log.error("订阅 {} 取消失败, error message : {}", subscription.getId(), e.getMessage());
}
@@ -564,8 +577,9 @@ public class StripeServiceImpl implements StripeService {
try {
Stripe.apiKey = privateKey;
// todo transactionId不再是sessionId而是invoiceId所以这里需要更新
// 根据orderId找到对应的sessionId
String sessionId = paymentInfoService.getPaymentInfoByOrderId(orderNo).getTransactionId();
String sessionId = paymentInfoService.getPaymentInfoByOrderNo(orderNo, "DESC").get(0).getTransactionId();
if (StringUtils.isNotEmpty(sessionId)) { //根据会话编号退款
Session session = Session.retrieve(sessionId);
@@ -628,7 +642,8 @@ public class StripeServiceImpl implements StripeService {
public void checkOrderStatus(String orderNo) {
Stripe.apiKey = privateKey;
// 1、通过orderNo 查询sessionId
PaymentInfo paymentInfo = paymentInfoService.getPaymentInfoByOrderId(orderNo);
// todo transactionId不再是sessionId而是invoiceId所以这里需要更新
PaymentInfo paymentInfo = paymentInfoService.getPaymentInfoByOrderNo(orderNo, "DESC").get(0);
try {
Session session = Session.retrieve(paymentInfo.getTransactionId());
if (Objects.isNull(session)) {
@@ -822,8 +837,8 @@ public class StripeServiceImpl implements StripeService {
emailParamsDTO.setCreateDate(String.valueOf(paymentInfo.getCreateTime()).replace("T", " "));
emailParamsDTO.setQuantity(String.valueOf(1));
emailParamsDTO.setTotalFee(paymentInfo.getPayerTotal().toString());
emailParamsDTO.setLastOrderDate(changeTimeStampFormat(subscriptionInfo.getCurrentPeriodStart(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy));
emailParamsDTO.setEndOfPrepaidTerm(changeTimeStampFormat(subscriptionInfo.getCurrentPeriodEnd(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy));
emailParamsDTO.setLastOrderDate(DateUtil.changeTimeStampFormat(subscriptionInfo.getCurrentPeriodStart(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy));
emailParamsDTO.setEndOfPrepaidTerm(DateUtil.changeTimeStampFormat(subscriptionInfo.getCurrentPeriodEnd(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy));
setSubscriptionParams(paymentInfo, subscriptionInfo, orderByOrderNo, emailParamsDTO);
SendEmailUtil.subscriptionEmailReminder(type, emailParamsDTO, language, account.getUserEmail());
@@ -941,9 +956,9 @@ public class StripeServiceImpl implements StripeService {
emailParamsDTO.setSubscriptionId(subscriptionInfo.getId().toString());
emailParamsDTO.setFailMessage(orderByOrderNo.getNote());
emailParamsDTO.setSubscriptionType(subscriptionInfo.getType());
emailParamsDTO.setStartDate(changeTimeStampFormat(orderByOrderNo.getCreateTime()));
emailParamsDTO.setNextPayDate(changeTimeStampFormat(subscriptionInfo.getCurrentPeriodEnd(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy));
emailParamsDTO.setRenewalTime(changeTimeStampFormat(subscriptionInfo.getCurrentPeriodEnd(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy));
emailParamsDTO.setStartDate(DateUtil.changeTimeStampFormat(orderByOrderNo.getCreateTime()));
emailParamsDTO.setNextPayDate(DateUtil.changeTimeStampFormat(subscriptionInfo.getCurrentPeriodEnd(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy));
emailParamsDTO.setRenewalTime(DateUtil.changeTimeStampFormat(subscriptionInfo.getCurrentPeriodEnd(), "seconds", CommonConstant.TIME_FORMAT_MMM_dd_yyyy));
}
public void subscriptionReminder(){
@@ -1082,6 +1097,14 @@ public class StripeServiceImpl implements StripeService {
return null;
}
public void updateCancelReason(String subscriptionId, String reason){
QueryWrapper<SubscriptionInfo> qw = new QueryWrapper<>();
qw.eq("subscription_id", subscriptionId);
SubscriptionInfo subscriptionInfo = subscriptionInfoMapper.selectOne(qw);
subscriptionInfo.setCancelReason(reason);
subscriptionInfoMapper.updateById(subscriptionInfo);
}
}