| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- package com.izouma.nineth.service;
- import cn.hutool.core.util.ZipUtil;
- import com.alibaba.excel.EasyExcel;
- import com.izouma.nineth.domain.*;
- import com.izouma.nineth.dto.SandPaySettle;
- import com.izouma.nineth.dto.UserBankCard;
- import com.izouma.nineth.dto.UserWithdraw;
- import com.izouma.nineth.enums.BalanceType;
- import com.izouma.nineth.enums.CollectionSource;
- import com.izouma.nineth.enums.OrderStatus;
- import com.izouma.nineth.exception.BusinessException;
- import com.izouma.nineth.repo.*;
- import com.izouma.nineth.service.storage.StorageService;
- import com.izouma.nineth.utils.DateTimeUtils;
- import lombok.AllArgsConstructor;
- import lombok.extern.slf4j.Slf4j;
- import org.apache.commons.io.IOUtils;
- import org.apache.commons.lang3.RandomStringUtils;
- import org.apache.commons.lang3.StringUtils;
- import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
- import org.apache.poi.ss.usermodel.Row;
- import org.apache.poi.ss.usermodel.Sheet;
- import org.apache.poi.ss.usermodel.Workbook;
- import org.apache.poi.ss.usermodel.WorkbookFactory;
- import org.apache.poi.util.TempFile;
- import org.springframework.stereotype.Service;
- import org.springframework.web.bind.annotation.RequestPart;
- import org.springframework.web.multipart.MultipartFile;
- import javax.servlet.http.HttpServletResponse;
- import javax.transaction.Transactional;
- import java.io.*;
- import java.math.BigDecimal;
- import java.math.RoundingMode;
- import java.time.LocalDate;
- import java.time.LocalDateTime;
- import java.time.temporal.ChronoUnit;
- import java.util.ArrayList;
- import java.util.Arrays;
- import java.util.List;
- import java.util.Optional;
- import java.util.regex.Pattern;
- import java.util.stream.Collectors;
- import java.util.zip.ZipEntry;
- import java.util.zip.ZipOutputStream;
- @Service
- @Slf4j
- @AllArgsConstructor
- public class UserBalanceService {
- private final UserBalanceRepo userBalanceRepo;
- private final BalanceRecordRepo balanceRecordRepo;
- private final OrderRepo orderRepo;
- private final AssetRepo assetRepo;
- private final UserBankCardRepo userBankCardRepo;
- private final SettleRecordRepo settleRecordRepo;
- private final StorageService storageService;
- private final ExportWithdrawRepo exportWithdrawRepo;
- public void settle(LocalDate start, LocalDate end) {
- for (long i = 0; i <= ChronoUnit.DAYS.between(start, end); i++) {
- LocalDate date = start.plusDays(i);
- if (settleRecordRepo.findByDate(date).isPresent()) {
- throw new BusinessException(DateTimeUtils.format(date, "yyyy-MM-dd") + "已经结算过");
- }
- }
- for (long i = 0; i <= ChronoUnit.DAYS.between(start, end); i++) {
- LocalDate date = start.plusDays(i);
- settle(date);
- }
- }
- public void settle(LocalDate date) {
- if (settleRecordRepo.findByDate(date).isPresent()) {
- throw new BusinessException(DateTimeUtils.format(date, "yyyy-MM-dd") + "已经结算过");
- }
- List<Order> orders = orderRepo.findByCreatedAtBetweenAndSourceAndStatusIn(date.atStartOfDay(),
- date.atTime(23, 59, 59, 9999), CollectionSource.TRANSFER,
- Arrays.asList(OrderStatus.PROCESSING, OrderStatus.FINISH));
- BigDecimal totalAmount = BigDecimal.ZERO;
- BigDecimal royaltiesAmount = BigDecimal.ZERO;
- BigDecimal serviceChargeAmount = BigDecimal.ZERO;
- for (Order order : orders) {
- Asset asset = assetRepo.findById(order.getAssetId()).orElseThrow(new BusinessException("藏品不存在"));
- UserBalance userBalance = userBalanceRepo.findById(asset.getUserId()).orElse(null);
- if (userBalance == null) {
- userBalance = userBalanceRepo.saveAndFlush(new UserBalance(asset.getUserId(), BigDecimal.ZERO, BigDecimal.ZERO));
- }
- BigDecimal amount = order.getTotalPrice()
- .subtract(order.getGasPrice())
- .multiply(BigDecimal.valueOf(100 - order.getRoyalties() - order.getServiceCharge()))
- .divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
- totalAmount = totalAmount.add(order.getTotalPrice());
- royaltiesAmount = order.getTotalPrice()
- .subtract(order.getGasPrice())
- .multiply(BigDecimal.valueOf(order.getRoyalties()))
- .divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
- serviceChargeAmount = order.getTotalPrice()
- .subtract(order.getGasPrice())
- .multiply(BigDecimal.valueOf(order.getServiceCharge()))
- .divide(new BigDecimal("100"), 2, RoundingMode.HALF_UP);
- userBalance.setLastBalance(userBalance.getBalance());
- userBalance.setBalance(userBalance.getBalance().add(amount));
- userBalanceRepo.saveAndFlush(userBalance);
- balanceRecordRepo.save(BalanceRecord.builder()
- .time(LocalDateTime.now())
- .userId(asset.getUserId())
- .orderId(order.getId())
- .amount(amount)
- .balance(userBalance.getBalance())
- .lastBalance(userBalance.getLastBalance())
- .type(BalanceType.SELL)
- .build());
- }
- settleRecordRepo.save(new SettleRecord(date, orders.size(), totalAmount, royaltiesAmount, serviceChargeAmount));
- }
- @Transactional
- public ExportWithdraw exportWithdraw(String remark) throws IOException, InvalidFormatException {
- List<UserBalance> balanceList = userBalanceRepo.findByBalanceGreaterThan(BigDecimal.ZERO);
- List<UserWithdraw> withdrawList = new ArrayList<>();
- balanceList.forEach(userBalance -> {
- userBankCardRepo.findByUserId(userBalance.getUserId()).stream().findFirst()
- .ifPresent(userBankCard -> withdrawList.add(new UserWithdraw(userBalance.getUserId(), userBankCard.getRealName(),
- userBankCard.getBankNo(), userBalance.getBalance())));
- });
- File tmpDir = TempFile.createTempDirectory("export_" + RandomStringUtils.randomAlphabetic(8));
- File file1 = new File(tmpDir, DateTimeUtils.format(LocalDate.now(), "yyyyMMdd") + "结算.xlsx");
- File file2 = new File(tmpDir, DateTimeUtils.format(LocalDate.now(), "yyyyMMdd") + "结算导入.xls");
- EasyExcel.write(file1, UserWithdraw.class)
- .sheet("sheet").doWrite(withdrawList);
- InputStream inputStream = getClass().getResourceAsStream("/批量付款到对私银行账户模板.xls");
- Workbook workbook = WorkbookFactory.create(inputStream);
- Sheet sheet = workbook.getSheetAt(0);
- for (int i = 0; i < withdrawList.size(); i++) {
- Row row = Optional.ofNullable(sheet.getRow(i + 1)).orElse(sheet.createRow(i + 1));
- Optional.ofNullable(row.getCell(1))
- .orElse(row.createCell(1))
- .setCellValue(withdrawList.get(i).getName());
- Optional.ofNullable(row.getCell(2))
- .orElse(row.createCell(2))
- .setCellValue(withdrawList.get(i).getBankNo());
- Optional.ofNullable(row.getCell(3))
- .orElse(row.createCell(3))
- .setCellValue(withdrawList.get(i).getAmount().doubleValue());
- Optional.ofNullable(row.getCell(4))
- .orElse(row.createCell(4))
- .setCellValue(withdrawList.get(i).getUserId());
- }
- inputStream.close();
- FileOutputStream os = new FileOutputStream(file2);
- workbook.write(os);
- workbook.close();
- File zipFile = ZipUtil.zip(tmpDir);
- String url = storageService.uploadFromInputStream(new FileInputStream(zipFile),
- "upload/" + DateTimeUtils.format(LocalDateTime.now(), "yyyyMMddHHmm") + "_" + RandomStringUtils.randomNumeric(8) + ".zip");
- ExportWithdraw exportWithdraw = exportWithdrawRepo.save(new ExportWithdraw(url, remark));
- for (UserBalance userBalance : balanceList) {
- BigDecimal amount = userBalance.getBalance();
- userBalance.setLastBalance(userBalance.getBalance());
- userBalance.setBalance(BigDecimal.ZERO);
- userBalanceRepo.saveAndFlush(userBalance);
- balanceRecordRepo.save(BalanceRecord.builder()
- .time(LocalDateTime.now())
- .userId(userBalance.getUserId())
- .amount(amount.negate())
- .balance(BigDecimal.ZERO)
- .lastBalance(userBalance.getLastBalance())
- .type(BalanceType.WITHDRAW)
- .build());
- }
- tmpDir.delete();
- zipFile.delete();
- return exportWithdraw;
- }
- @Transactional
- public void importFail(MultipartFile withdrawFile, MultipartFile settleFile) throws IOException {
- List<SandPaySettle> failSettleList = EasyExcel.read(settleFile.getInputStream())
- .head(SandPaySettle.class).sheet()
- .doReadSync();
- failSettleList = failSettleList.stream()
- .filter(s -> "失败".equals(s.getStatus().trim()))
- .collect(Collectors.toList());
- List<UserWithdraw> withdrawList = EasyExcel.read(withdrawFile.getInputStream())
- .head(UserWithdraw.class).sheet()
- .doReadSync();
- List<UserWithdraw> failWithdraw = new ArrayList<>();
- for (SandPaySettle sandPaySettle : failSettleList) {
- List<UserWithdraw> list;
- if (StringUtils.isNotBlank(sandPaySettle.getRemark()) && Pattern.matches("^\\d+$", sandPaySettle.getRemark().trim())) {
- Long userId = Long.parseLong(sandPaySettle.getRemark().trim());
- list = withdrawList.stream().filter(i -> i.getUserId().equals(userId))
- .collect(Collectors.toList());
- } else {
- list = withdrawList.stream().filter(i -> i.getBankNo().equals(sandPaySettle.getBankNo())
- && i.getName().equals(sandPaySettle.getName())
- && i.getAmount().compareTo(sandPaySettle.getAmount()) == 0)
- .collect(Collectors.toList());
- }
- if (list.size() != 1) {
- throw new BusinessException("不唯一:" + sandPaySettle.getName() + "," + sandPaySettle.getBankNo());
- } else {
- failWithdraw.add(list.get(0));
- }
- }
- for (UserWithdraw withdraw : failWithdraw) {
- UserBalance userBalance = userBalanceRepo.findById(withdraw.getUserId())
- .orElse(new UserBalance(withdraw.getUserId(), BigDecimal.ZERO, BigDecimal.ZERO));
- userBalance.setLastBalance(userBalance.getBalance());
- userBalance.setBalance(userBalance.getBalance().add(withdraw.getAmount()));
- userBalanceRepo.saveAndFlush(userBalance);
- balanceRecordRepo.save(BalanceRecord.builder()
- .time(LocalDateTime.now())
- .userId(userBalance.getUserId())
- .amount(withdraw.getAmount())
- .balance(userBalance.getBalance())
- .lastBalance(userBalance.getLastBalance())
- .type(BalanceType.RETURN)
- .build());
- }
- }
- }
|