CommissionService.java 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225
  1. package com.izouma.awesomeAdmin.service;
  2. import com.izouma.awesomeAdmin.config.Constants;
  3. import com.izouma.awesomeAdmin.domain.*;
  4. import com.izouma.awesomeAdmin.dto.CommissionOrder;
  5. import com.izouma.awesomeAdmin.dto.CommissionOverview;
  6. import com.izouma.awesomeAdmin.dto.CommissionDetail;
  7. import com.izouma.awesomeAdmin.dto.JuniorDTO;
  8. import com.izouma.awesomeAdmin.enums.OrderStatus;
  9. import com.izouma.awesomeAdmin.exception.BusinessException;
  10. import com.izouma.awesomeAdmin.repo.*;
  11. import com.izouma.awesomeAdmin.utils.Translator;
  12. import lombok.AllArgsConstructor;
  13. import org.springframework.beans.BeanUtils;
  14. import org.springframework.data.domain.Page;
  15. import org.springframework.data.domain.PageImpl;
  16. import org.springframework.data.domain.Pageable;
  17. import org.springframework.data.jpa.domain.Specification;
  18. import org.springframework.stereotype.Service;
  19. import javax.persistence.criteria.Predicate;
  20. import java.math.BigDecimal;
  21. import java.math.RoundingMode;
  22. import java.time.LocalDateTime;
  23. import java.util.ArrayList;
  24. import java.util.List;
  25. import java.util.Optional;
  26. import java.util.stream.Collectors;
  27. @Service
  28. @AllArgsConstructor
  29. public class CommissionService {
  30. private CommissionRecordRepo commissionRecordRepo;
  31. private UserRepo userRepo;
  32. private OrderRepo orderRepo;
  33. private ProductRepo productRepo;
  34. private JuniorContributionRepo juniorContributionRepo;
  35. private SysConfigService sysConfigService;
  36. private UserBalanceService userBalanceService;
  37. private CommissionStatRepo commissionStatRepo;
  38. public CommissionOverview overview(Long userId) {
  39. User user = userRepo.findById(userId).orElseThrow(new BusinessException(Translator.toLocale("user.not_found")));
  40. User superior = null;
  41. if (user.getSuperiorId() != null) {
  42. superior = userRepo.findById(user.getSuperiorId()).orElse(null);
  43. }
  44. List<CommissionRecord> commissionRecords = commissionRecordRepo.findByUserId(userId);
  45. List<User> juniors = userRepo.findBySuperiorId(userId);
  46. BigDecimal total = BigDecimal.ZERO;
  47. BigDecimal withdraw = BigDecimal.ZERO;
  48. BigDecimal available = BigDecimal.ZERO;
  49. for (CommissionRecord commissionRecord : commissionRecords) {
  50. total = total.add(commissionRecord.getAmount());
  51. }
  52. return CommissionOverview.builder()
  53. .total(total)
  54. .withdraw(withdraw)
  55. .available(available)
  56. .juniorCount(juniors.size())
  57. .orderCount(commissionRecordRepo.countByUserId(userId))
  58. .superior(Optional.ofNullable(superior).map(User::getNickname).orElse(null))
  59. .build();
  60. }
  61. public CommissionDetail detail(Long userId) {
  62. List<CommissionRecord> commissionRecords = commissionRecordRepo.findByUserId(userId);
  63. BigDecimal total = BigDecimal.ZERO;
  64. BigDecimal withdraw = BigDecimal.ZERO;
  65. BigDecimal available = BigDecimal.ZERO;
  66. BigDecimal notChecked = BigDecimal.ZERO;
  67. for (CommissionRecord commissionRecord : commissionRecords) {
  68. total = total.add(commissionRecord.getAmount());
  69. }
  70. return new CommissionDetail(total, withdraw, available, notChecked);
  71. }
  72. public Page<CommissionOrder> commissionOrders(Long userId, String status, Pageable pageable) {
  73. Page<CommissionRecord> page = commissionRecordRepo
  74. .findAll((Specification<CommissionRecord>) (root, criteriaQuery, criteriaBuilder) -> {
  75. List<Predicate> predicates = new ArrayList<>();
  76. predicates.add(criteriaBuilder.equal(root.get("userId"), userId));
  77. if ("NOT_PAID".equals(status)) {
  78. predicates.add(criteriaBuilder.equal(root.join("order").get("status"), OrderStatus.NOT_PAID));
  79. } else if ("PAID".equals(status)) {
  80. predicates.add(root.join("order").get("status")
  81. .in(OrderStatus.NOT_CONFIRMED,
  82. OrderStatus.CONFIRMED,
  83. OrderStatus.NOT_SHIPPED,
  84. OrderStatus.SHIPPED,
  85. OrderStatus.SELLING,
  86. OrderStatus.SOLD_NOT_PAID,
  87. OrderStatus.SOLD_NOT_CONFIRMED,
  88. OrderStatus.SOLD,
  89. OrderStatus.NOT_SHIPPED,
  90. OrderStatus.SHIPPED,
  91. OrderStatus.RECEIVED));
  92. } else if ("FINISH".equals(status)) {
  93. predicates.add(root.join("order").get("status")
  94. .in(OrderStatus.CONFIRMED, OrderStatus.SELLING, OrderStatus.SOLD,
  95. OrderStatus.NOT_SHIPPED, OrderStatus.SHIPPED, OrderStatus.RECEIVED));
  96. }
  97. return criteriaQuery.where(predicates.toArray(new Predicate[0]))
  98. .orderBy(criteriaBuilder.desc(root.get("createdAt"))).getRestriction();
  99. }, pageable);
  100. List<CommissionOrder> commissionOrders = new ArrayList<>();
  101. for (CommissionRecord commissionRecord : page.getContent()) {
  102. Order order = orderRepo.findById(commissionRecord.getOrderId()).orElse(null);
  103. if (order != null) {
  104. Product product = productRepo.findById(order.getProductId()).orElse(null);
  105. if (product != null) {
  106. CommissionOrder commissionOrder = CommissionOrder.builder()
  107. .orderId(commissionRecord.getOrderId())
  108. .createdAt(order.getCreatedAt())
  109. .juniorId(commissionRecord.getJuniorId())
  110. .commission(commissionRecord.getAmount())
  111. .pic(product.getPic().isEmpty()
  112. ? null : product.getPic().get(0))
  113. .name(product.getName())
  114. .price(order.getTotalPrice())
  115. .build();
  116. commissionOrders.add(commissionOrder);
  117. }
  118. }
  119. }
  120. return new PageImpl<>(commissionOrders, pageable, page.getTotalElements());
  121. }
  122. public void doCommission(Long userId, Order sellerOrder, BigDecimal commissionRate) {
  123. User user = userRepo.findById(userId)
  124. .orElseThrow(new BusinessException(Translator.toLocale("record.not_found")));
  125. if (user.getSuperiorId() != null) {
  126. User superior = userRepo.findById(user.getSuperiorId()).orElse(null);
  127. if (superior != null) {
  128. BigDecimal money = sellerOrder.getTotalPrice().multiply(commissionRate)
  129. .setScale(2, RoundingMode.HALF_UP);
  130. userBalanceService.modify(superior.getId(), null, money, Constants.BalanceRemark.COMMISSION,
  131. null, null, null);
  132. commissionRecordRepo.save(CommissionRecord.builder()
  133. .userId(superior.getId())
  134. .juniorId(userId)
  135. .orderId(sellerOrder.getId())
  136. .amount(money)
  137. .build());
  138. JuniorContribution juniorContribution = juniorContributionRepo.findByUserIdAndJuniorId(superior.getId(), userId)
  139. .orElse(new JuniorContribution(superior.getId(), userId));
  140. juniorContribution.setOrderNum(juniorContribution.getOrderNum() + 1);
  141. juniorContribution.setOrderSum(juniorContribution.getOrderSum().add(sellerOrder.getTotalPrice()));
  142. juniorContribution.setCommissionNum(juniorContribution.getCommissionNum() + 1);
  143. juniorContribution.setCommissionSum(juniorContribution.getCommissionSum().add(money));
  144. juniorContributionRepo.save(juniorContribution);
  145. CommissionStat commissionStat = commissionStatRepo.findByUserId(superior.getId())
  146. .orElse(new CommissionStat(superior.getId()));
  147. commissionStat.setCommissionNum(commissionStat.getCommissionNum() + 1);
  148. commissionStat.setCommissionSum(commissionStat.getCommissionSum().add(money));
  149. commissionStatRepo.save(commissionStat);
  150. }
  151. }
  152. }
  153. public void invite(Long superiorId, Long juniorId) {
  154. CommissionStat commissionStat = commissionStatRepo.findByUserId(superiorId)
  155. .orElse(new CommissionStat(superiorId));
  156. commissionStat.setInviteNum((int) userRepo.countBySuperiorId(superiorId));
  157. commissionStatRepo.save(commissionStat);
  158. JuniorContribution juniorContribution = juniorContributionRepo.findByUserIdAndJuniorId(superiorId, juniorId)
  159. .orElse(new JuniorContribution(superiorId, juniorId));
  160. juniorContributionRepo.save(juniorContribution);
  161. }
  162. public CommissionStat userCommissionStat(Long userId) {
  163. return commissionStatRepo.findByUserId(userId).orElse(new CommissionStat(userId));
  164. }
  165. public Page<CommissionRecord> records(Long id, LocalDateTime start, LocalDateTime end, Pageable pageable) {
  166. Page<CommissionRecord> page;
  167. if (start != null && end != null) {
  168. page = commissionRecordRepo.findByUserIdAndCreatedAtBetweenOrderByCreatedAtDesc(id, start, end, pageable);
  169. } else {
  170. page = commissionRecordRepo.findByUserIdOrderByCreatedAtDesc(id, pageable);
  171. }
  172. List<Long> userIds = page.getContent().stream().map(CommissionRecord::getJuniorId).collect(Collectors.toList());
  173. if (!userIds.isEmpty()) {
  174. List<User> users = userRepo.findAllById(userIds);
  175. page.getContent().forEach(commissionRecord -> {
  176. users.stream().filter(user -> user.getId().equals(commissionRecord.getJuniorId()))
  177. .findFirst().ifPresent(user -> {
  178. JuniorDTO dto = new JuniorDTO(user);
  179. commissionRecord.setJunior(dto);
  180. });
  181. });
  182. }
  183. List<Long> orderIds = page.getContent().stream().map(CommissionRecord::getOrderId).collect(Collectors.toList());
  184. if (!orderIds.isEmpty()) {
  185. List<Order> orders = orderRepo.findAllById(orderIds);
  186. page.getContent().forEach(commissionRecord -> {
  187. orders.stream().filter(order -> order.getId().equals(commissionRecord.getOrderId()))
  188. .findFirst().ifPresent(commissionRecord::setOrder);
  189. });
  190. }
  191. return page;
  192. }
  193. public Page<JuniorContribution> juniorContributions(Long userId, Pageable pageable) {
  194. Page<JuniorContribution> page = juniorContributionRepo.findByUserId(userId, pageable);
  195. List<Long> userIds = page.getContent().stream().map(JuniorContribution::getJuniorId)
  196. .collect(Collectors.toList());
  197. if (!userIds.isEmpty()) {
  198. List<User> users = userRepo.findAllById(userIds);
  199. page.getContent().forEach(juniorContribution -> {
  200. users.stream().filter(user -> user.getId().equals(juniorContribution.getJuniorId()))
  201. .findFirst().ifPresent(user -> {
  202. JuniorDTO dto = new JuniorDTO(user);
  203. juniorContribution.setJunior(dto);
  204. });
  205. });
  206. }
  207. return page;
  208. }
  209. }