master
wujingtao 2 years ago
parent 418d391d2f
commit 867f84e44d

@ -0,0 +1,29 @@
package com.baiye.modules.settlement.dao;
import com.baiye.modules.settlement.entity.CallSettlement;
import com.baiye.modules.telemarkting.entity.AllCallInfo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* @author wujingtao
* @date 2022/06/08
*/
@Repository
public interface CallCostRepository extends JpaRepository<CallSettlement, Long>, JpaSpecificationExecutor<CallSettlement> {
/**
* id
*
* @param beginTime
* @param endTime
* @param memberId
* @return
*/
@Query(value = "select * from tb_call_settlement d where d.create_time>= DATE_FORMAT( ?1, '%Y-%m-%d') and d.create_time<=DATE_FORMAT( ?2, '%Y-%m-%d') and d.member_id = ?3", nativeQuery = true)
List<CallSettlement> queryAllByTimeAndMemberId(String beginTime, String endTime, Long memberId);
}

@ -0,0 +1,57 @@
package com.baiye.modules.settlement.entity;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
/**
* @author wujingtao
* @date 2022/06/06
*/
@Getter
@Setter
@Entity
@Table(name = "tb_call_settlement")
@EntityListeners(AuditingEntityListener.class)
public class CallSettlement implements Serializable {
private static final long serialVersionUID = -7076844789226595546L;
@Id
@ApiModelProperty(value = "主键id自动递增")
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "breathe_total_duration")
@ApiModelProperty(value = "通话时长")
private Long breatheTotalDuration;
@Column(name = "deduct_duration")
@ApiModelProperty(value = "扣减时长")
private Long deductDuration;
@Column(name = "deduct_amount")
@ApiModelProperty(value = "扣减金额")
private Double deductAmount;
@Column(name = "estimate_amount")
@ApiModelProperty(value = "预扣金额")
private Double estimateAmount;
@Column(name = "member_id")
@ApiModelProperty(value = "人员id")
private Long memberId;
@Column(name = "company_id")
@ApiModelProperty(value = "所属公司")
private Long companyId;
@Column(name = "create_time")
@ApiModelProperty(value = "创建时间")
private Date createTime;
}

@ -0,0 +1,17 @@
package com.baiye.modules.settlement.service;
import com.baiye.modules.settlement.entity.CallSettlement;
import java.util.List;
/**
* @author wujingtao
* @date 2022/06/06
*/
public interface CallCostService {
/**
*
*
*/
void callCost() throws Exception;
}

@ -0,0 +1,192 @@
package com.baiye.modules.settlement.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.baiye.constant.DefaultNumberConstants;
import com.baiye.modules.security.service.OnlineUserService;
import com.baiye.modules.settlement.dao.CallCostRepository;
import com.baiye.modules.settlement.entity.CallSettlement;
import com.baiye.modules.settlement.service.CallCostService;
import com.baiye.modules.system.domain.MessageNotification;
import com.baiye.modules.system.domain.PayTemplate;
import com.baiye.modules.system.domain.PayTemplateUser;
import com.baiye.modules.system.domain.User;
import com.baiye.modules.system.repository.MessageNotificationRepository;
import com.baiye.modules.system.repository.PayTemplateRepository;
import com.baiye.modules.system.repository.PayTemplateUserRepository;
import com.baiye.modules.system.repository.UserRepository;
import com.baiye.modules.system.service.CompanyService;
import com.baiye.modules.system.service.UserMessageService;
import com.baiye.modules.system.service.dto.CompanyDto;
import com.baiye.modules.telemarkting.dao.AllCallInfoRepository;
import com.baiye.modules.telemarkting.entity.AllCallInfo;
import com.baiye.util.DateTimeUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author wujingtao
* @date 2022/06/06
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class CallCostServiceImpl implements CallCostService {
private final PayTemplateUserRepository payTemplateUserRepository;
private final PayTemplateRepository payTemplateRepository;
private final AllCallInfoRepository allCallInfoRepository;
private final CallCostRepository callCostRepository;
private final CompanyService companyService;
private final UserRepository userRepository;
private final MessageNotificationRepository messageNotificationRepository;
private final UserMessageService userMessageService;
private final OnlineUserService onlineUserService;
private final double price = 0.18;
/**
*
* 1.线
* 2.
* 3.
*/
@Async
@Override
public void callCost() throws Exception {
//查看这些人员 在套餐时间内 的总时长是否超出 注意套餐 是否已经刷新,重新计算
//1.查看当前日期是否在套餐时间范围,
//2.查看前一天扣减表。有数据说明已经超出,做扣减,入库--
List<PayTemplateUser> byDay = payTemplateUserRepository.findByDay(DateUtil.today());
if (byDay.size() <= 0) {
return;
}
for (PayTemplateUser info : byDay) {
long userId = info.getUserId();
Long companyId = userRepository.findUserById(userId).getCompanyId();
//查询套餐的时长
PayTemplate payTemplate = selectCombo(info.getPayTemplateId());
int callDuration = payTemplate.getCallDuration();
//查询套餐时间范围内 通话总时长
List<AllCallInfo> list = allCallInfoRepository.queryAllByTimeAndMemberId(DateUtil.formatDateTime(info.getBeginTime()), DateUtil.formatDateTime(info.getEndTime()), userId);
if (CollUtil.isEmpty(byDay)) {
log.info(" 用户 {} ,没有通话记录", userId);
return;
}
int duration = list.stream().mapToInt(AllCallInfo::getDuration).sum();
if (duration > callDuration) {
//账户余额
CompanyDto companyById = companyService.findCompanyById(companyId);
deduction(info, list, companyId, companyById);
}
}
}
/**
*
*
* @param info
* @param list
* @param companyId
*/
@Transactional(rollbackFor = Exception.class)
public void deduction(PayTemplateUser info, List<AllCallInfo> list, Long companyId, CompanyDto companyById) throws Exception {
long userId = info.getUserId();
Double userBalance = companyById.getUserBalance();
//查看时间内 是否有过扣减
List<CallSettlement> callSettlements = callCostRepository.queryAllByTimeAndMemberId(DateUtil.formatDateTime(info.getBeginTime()), DateUtil.formatDateTime(info.getEndTime()), userId);
if (callSettlements.size() > 0) {
//按日期倒序
List<CallSettlement> callSettlementSort = callSettlements.stream().sorted(Comparator.comparing(CallSettlement::getCreateTime).reversed()).collect(Collectors.toList());
//最近的一次预扣减金额
double estimateAmount = callSettlementSort.get(0).getEstimateAmount();
//今天的通话时长
List<AllCallInfo> allCallInfos = list.stream().filter(c -> DateTimeUtil.betweenByMonth(c.getCreateTime(), DateUtil.date())).collect(Collectors.toList());
if (allCallInfos.size() != 1) {
log.info("当日 {} ,用户 {} ,没有通话记录", DateUtil.today(), userId);
} else {
//今日通话时长
int duration1 = allCallInfos.get(0).getDuration();
double deductAmount = NumberUtil.mul(duration1, price);
//今日计算预扣
double estimateAmountToDay = getEstimateAmount(list);
//余额足够
if (estimateAmount + userBalance > deductAmount + estimateAmountToDay) {
companyService.updateUserBalanceByCompanyId(deductAmount + estimateAmountToDay - estimateAmount, companyId);
} else {
//不够的情况 不加预扣
if (estimateAmount + userBalance > deductAmount) {
companyService.updateUserBalanceByCompanyId(deductAmount - estimateAmount, companyId);
// TODO: 2022/6/8 0008 发送通知
MessageNotification messageNotification = new MessageNotification();
messageNotification.setMessageTitle("充值提醒");
messageNotification.setMessageType(2);
messageNotification.setUserId(companyById.getUserId());
messageNotification.setMessageContext("您的账号余额已不足,及时充值");
MessageNotification notification = messageNotificationRepository.save(messageNotification);
userMessageService.createUserMessage(Collections.singletonList(companyById.getUserId()), notification, DefaultNumberConstants.TWO_NUMBER);
} else {
//不足以扣款
companyService.updateUserBalanceByCompanyId(deductAmount - estimateAmount, companyId);
// TODO: 2022/6/8 0008 下线 修改用户状态
User userById = userRepository.findUserById(userId);
userRepository.updateStatusById(Boolean.FALSE, userId);
onlineUserService.kickOutForUsername(userById.getUsername());
}
}
}
}
}
/**
*
*
* @param payTemplateId
* @return
*/
private PayTemplate selectCombo(Long payTemplateId) {
return payTemplateRepository.findById(payTemplateId).orElseGet(PayTemplate::new);
}
/**
*
*
* @param list
* @return
*/
private Double getEstimateAmount(List<AllCallInfo> list) {
List<AllCallInfo> sortList = list.stream().sorted(Comparator.comparing(AllCallInfo::getCreateTime).reversed()).collect(Collectors.toList());
//取最近的7天数据 去最大和最小值求平均数
List<AllCallInfo> list1 = sortList.subList(0, 7);
List<Integer> collect = list1.stream().map(AllCallInfo::getDuration).sorted().collect(Collectors.toList());
int sumScore = 0;
int sumTimes = 0;
for (int i = 0; i < collect.size(); i++) {
if (collect.get(i).equals(collect.get(0)) || collect.get(i).equals(collect.get(collect.size() - 1))) {
continue;
} else {
sumScore += collect.get(i);
sumTimes++;
}
}
return NumberUtil.mul((double) (sumScore / sumTimes), price);
}
}

@ -46,6 +46,11 @@ public class PayTemplate implements Serializable {
@NotNull(message = "金额不能为空", groups = {AddGroup.class})
private Double amount;
@Column(name = "call_duration")
@ApiModelProperty(value = "通话时长")
@NotNull(message = "通话时长不能为空", groups = {AddGroup.class})
private Integer callDuration;
@Column(name = "packageDay")
@ApiModelProperty(value = "套餐天数")
@NotNull(message = "套餐天数不能为空", groups = {AddGroup.class})

@ -3,6 +3,7 @@ package com.baiye.modules.system.repository;
import com.baiye.modules.system.domain.PayTemplateUser;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
@ -11,4 +12,13 @@ import java.util.List;
public interface PayTemplateUserRepository extends JpaRepository<PayTemplateUser, Long>, JpaSpecificationExecutor<PayTemplateUser> {
List<PayTemplateUser> findByUserId(Long userId);
/**
*
*
* @param day
* @return
*/
@Query(value = "select * from tb_pay_template_user where DATE_FORMAT( begin_time, '%Y-%m-%d') < ?1 AND DATE_FORMAT( end_time, '%Y-%m-%d') > ?1 ", nativeQuery = true)
List<PayTemplateUser> findByDay(String day);
}

@ -31,23 +31,25 @@ public interface AllCallInfoRepository extends JpaRepository<AllCallInfo, Long>,
/**
*
*
* @param recordFlag
* @param recordFileDownloadUrl
* @param id
*/
@Modifying
@Query(value = "update AllCallInfo d set d.recordFlag =?1 , d.recordFileDownloadUrl = ?2 where d.id =?3")
void updateByRecord(Integer recordFlag, String recordFileDownloadUrl,Long id);
void updateByRecord(Integer recordFlag, String recordFileDownloadUrl, Long id);
/**
*
*
* @param status
* @param duration
* @param id
*/
@Modifying
@Query(value = "update AllCallInfo d set d.status =?1 , d.duration = ?2 where d.id =?3")
void updateByDurationAndStatus(Integer status, Integer duration,Long id);
void updateByDurationAndStatus(Integer status, Integer duration, Long id);
/**
@ -92,9 +94,22 @@ public interface AllCallInfoRepository extends JpaRepository<AllCallInfo, Long>,
/**
* 线
*
* @param clueId
* @return
*/
@Query(value = "select a from AllCallInfo a where a.clueId = ?1 order by a.createTime desc ")
List<AllCallInfo> findAllByClueId(Long clueId);
/**
* id
*
* @param beginTime
* @param endTime
* @param memberId
* @return
*/
@Query(value = "select * from tb_call_info d where d.create_time>=?1 and d.create_time<?2 and d.member_id = ?3", nativeQuery = true)
List<AllCallInfo> queryAllByTimeAndMemberId(String beginTime, String endTime, Long memberId);
}

Loading…
Cancel
Save