ContractServiceImpl.java 10.4 KB
package vion.service.impl;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.lang.Opt;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.github.yulichang.base.MPJBaseServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import io.github.linpeilie.Converter;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import vion.dto.ContractDTO;
import vion.mapper.ContractMapper;
import vion.model.*;
import vion.service.*;
import vion.vo.ContractVO;
import vion.vo.StoreVO;
import vion.vo.UserVO;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author HlQ
 * @date 2023/11/29
 */
@Service
@RequiredArgsConstructor
public class ContractServiceImpl extends MPJBaseServiceImpl<ContractMapper, Contract> implements IContractService {

    private final IFileService fileService;
    private final IContractPaymentService contractPaymentService;
    private final IRContractStoreService contractStoreService;
    private final IContractLogService contractLogService;
    private final Converter converter;

    @Value("${fileUrl:}")
    private String fileUrl;

    @Override
    public Page<ContractVO> list(ContractDTO dto) {
        Contract contract = converter.convert(dto, new Contract());
        Page<Contract> contractList = this.lambdaQuery(contract)
                .between(ArrayUtil.isAllNotNull(dto.getSignDateStart(), dto.getSignDateEnd()), Contract::getSignDate, dto.getSignDateStart(), dto.getSignDateEnd())
                .orderByDesc(Contract::getEntryTime)
                .page(Page.of(dto.getPageNum(), dto.getPageSize()));
        List<ContractVO> contractVOList = converter.convert(contractList.getRecords(), ContractVO.class);
        // 查出合同关联的项目名
        completeStoreName(contractVOList);
        return Page.<ContractVO>of(contractList.getCurrent(), contractList.getSize(), contractList.getTotal()).setRecords(contractVOList);
    }

    @Override
    public Page<ContractVO> listPart(ContractDTO dto) {
        Contract contract = converter.convert(dto, new Contract());

        List<Long> ids = Opt.ofNullable(dto.getStoreId())
                .map(storeId -> contractStoreService.listObjs(Wrappers.<RContractStore>lambdaQuery().select(RContractStore::getContractId).eq(RContractStore::getStoreId, dto.getStoreId()), o -> Long.valueOf(o.toString())))
                .filter(CollUtil::isNotEmpty)
                .orElse(ListUtil.of(0L));

        Page<Contract> contractList = this.lambdaQuery(contract)
                .select(Contract::getId, Contract::getName, Contract::getContractNo, Contract::getType, Contract::getSignDate, Contract::getWarrantyPeriod, Contract::getFinalDate, Contract::getStatus, Contract::getSaleName, Contract::getCustomerName, Contract::getMaintainSdate, Contract::getMaintainEdate)
                .in(CollUtil.isNotEmpty(ids), Contract::getId, ids)
                .orderByDesc(Contract::getEntryTime)
                .page(Page.of(dto.getPageNum(), dto.getPageSize()));
        List<ContractVO> contractVOList = converter.convert(contractList.getRecords(), ContractVO.class);
        // 查出合同关联的项目名
        completeStoreName(contractVOList);
        return Page.<ContractVO>of(contractList.getCurrent(), contractList.getSize(), contractList.getTotal()).setRecords(contractVOList);
    }

    private void completeStoreName(List<ContractVO> contractVOList) {
        Map<Long, List<Long>> contractStoreIdsMap = Opt.ofEmptyAble(contractVOList)
                .map(list -> list.stream().map(ContractVO::getId).collect(Collectors.toList()))
                .map(contractIds -> contractStoreService.list(Wrappers.<RContractStore>lambdaQuery().in(RContractStore::getContractId, contractIds)))
                .map(contractStoreList -> contractStoreList.stream().collect(Collectors.groupingBy(RContractStore::getContractId, Collectors.mapping(RContractStore::getStoreId, Collectors.toList()))))
                .orElse(MapUtil.empty());

        Opt.of(contractStoreIdsMap)
                .filter(MapUtil::isNotEmpty)
                .map(map -> map.values().stream().flatMap(List::stream).collect(Collectors.toList()))
                .map(storeIds -> Db.listByIds(storeIds, Store.class))
                .map(storeList -> storeList.stream().collect(Collectors.toMap(Store::getId, Function.identity())))
                .ifPresent(storeId2StoreMap -> contractVOList.forEach(contractVO -> {
                    if (contractStoreIdsMap.containsKey(contractVO.getId())) {
                        List<StoreVO> storeVOS = converter.convert(contractStoreIdsMap.get(contractVO.getId()).stream().map(storeId2StoreMap::get).collect(Collectors.toList()), StoreVO.class);
                        contractVO.setStoreVOS(storeVOS);
                    }
                }));
    }


    @Override
    public ContractVO getVOById(Long id) {
        MPJLambdaWrapper<Contract> wrapper = new MPJLambdaWrapper<Contract>()
                .selectAll(Contract.class)
                .selectCollection(ContractLog.class, ContractVO::getContractLogs)
                .leftJoin(ContractLog.class, ContractLog::getContractId, Contract::getId)
                .eq(Contract::getId, id);
        return this.selectJoinOne(ContractVO.class, wrapper);
    }

    @Override
    public ContractVO getByNo(String no) {
        Contract contract = this.lambdaQuery()
                .select(Contract::getId, Contract::getName, Contract::getContractNo, Contract::getType, Contract::getSignDate, Contract::getWarrantyPeriod, Contract::getFinalDate, Contract::getStatus, Contract::getSaleName, Contract::getCustomerName)
                .eq(Contract::getContractNo, no)
                .one();
        ContractVO contractVO = converter.convert(contract, new ContractVO());
        Assert.notNull(contractVO, "合同不存在");
        MPJLambdaWrapper<RContractStore> wrapper = new MPJLambdaWrapper<RContractStore>()
                .select(Store::getId, Store::getName)
                .leftJoin(Store.class, Store::getId, RContractStore::getStoreId)
                .eq(RContractStore::getContractId, contract.getId());
        List<StoreVO> storeVOS = contractStoreService.selectJoinList(StoreVO.class, wrapper);
        contractVO.setStoreVOS(storeVOS);
        return contractVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String updateById(Long id, String contractNo, ContractDTO dto) {
        Contract exitContract = null;
        if (ObjUtil.isNotNull(id)) {
            exitContract = this.getById(id);
        } else if (StrUtil.isNotBlank(contractNo)) {
            exitContract = this.lambdaQuery().eq(Contract::getContractNo, contractNo).one();
        }
        Assert.notNull(exitContract, "合同不存在");

        Contract contract = converter.convert(dto, new Contract());
        contract.setId(exitContract.getId());
        contractPaymentService.calMoney(exitContract, contract);
        if (this.updateById(contract)) {
            UserVO userVO = (UserVO) StpUtil.getTokenSession().get("curLoginUser");

            ContractLog contractLog = new ContractLog();
            contractLog.setContractId(contract.getId());
            if (dto.getStatus() == 1) {
                contractLog.setContent("合同:已签订");
            } else if (dto.getStatus() == 2) {
                contractLog.setContent("合同:已到货");
            } else if (dto.getStatus() == 3) {
                contractLog.setContent("合同:系统验收");
            } else if (dto.getStatus() == 4) {
                contractLog.setContent("合同:项目验收");
            } else if (dto.getStatus() == 5) {
                contractLog.setContent("合同:质保");
            } else if (dto.getStatus() == 6) {
                contractLog.setContent("合同:维保");
            }
            contractLog.setOperator(userVO.getId());
            contractLogService.save(contractLog);

            Opt.ofNullable(dto.getFiles())
                    .ifPresent(fileList ->
                            Arrays.stream(fileList).forEach(infile -> {
                                //上传url地址
                                String orgName = infile.getOriginalFilename();
                                String fileName = orgName.substring(0, orgName.lastIndexOf("."));
                                String fileExt = orgName.substring(orgName.lastIndexOf("."));
                                String filename = fileName + "_" + DateUtil.format(new Date(), "yyyyMMdd_HHmmss") + fileExt;
                                String path = fileUrl + FileUtil.FILE_SEPARATOR + "contract" + FileUtil.FILE_SEPARATOR + contract.getId() + FileUtil.FILE_SEPARATOR + filename;
                                File file = FileUtil.touch(path);
                                try {
                                    infile.transferTo(file);
                                } catch (IOException e) {
                                    log.error("保存文件出错", e);
                                }

                                FileInfo fileInfo = new FileInfo();
                                fileInfo.setStoreId(-1L);
                                fileInfo.setSourceId(contract.getId());
                                fileInfo.setSourceType(5);
                                fileInfo.setName(filename);
                                fileInfo.setUrl(path);
                                fileInfo.setType(FileUtil.extName(file));
                                fileInfo.setSha256(SecureUtil.sha256(file).toUpperCase());
                                fileInfo.setUploader(userVO.getUsername());
                                fileService.save(fileInfo);
                            }));
            return "更新成功";
        } else {
            return "更新失败";
        }
    }
}