fuliqi
2025-01-02 73caf5a7072976021f43a764ed2ad73404f4d040
ycl-server/src/main/java/com/ycl/platform/service/impl/TContractServiceImpl.java
@@ -1,94 +1,252 @@
package com.ycl.platform.service.impl;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ycl.handler.CommentWriteHandler;
import com.ycl.handler.CustomCellWriteHandler;
import com.ycl.handler.CustomSheetWriteHandler;
import com.ycl.platform.domain.entity.CalculateMoneyRule;
import com.ycl.platform.domain.entity.CalculateRule;
import com.ycl.platform.domain.entity.TContract;
import com.ycl.platform.domain.query.ContractQuery;
import com.ycl.platform.domain.vo.ContractVO;
import com.ycl.platform.mapper.TContractMapper;
import com.ycl.platform.service.ICalculateRuleService;
import com.ycl.platform.service.ITContractService;
import org.springframework.beans.factory.annotation.Autowired;
import com.ycl.system.AjaxResult;
import com.ycl.system.Result;
import com.ycl.system.page.PageUtil;
import com.ycl.utils.DateUtils;
import com.ycl.utils.SecurityUtils;
import com.ycl.utils.StringUtils;
import enumeration.ContractStatus;
import enumeration.general.RuleDeductCategoryEnum;
import jakarta.servlet.http.HttpServletResponse;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;
/**
 * 【请填写功能名称】Service业务层处理
 *
 *
 * @author ruoyi
 * @date 2024-03-12
 */
@Service
public class TContractServiceImpl implements ITContractService
{
    @Autowired
    private TContractMapper tContractMapper;
@AllArgsConstructor
public class TContractServiceImpl extends ServiceImpl<TContractMapper, TContract> implements ITContractService {
    /**
     * 查询【请填写功能名称】
     *
     * @param id 【请填写功能名称】主键
     * @return 【请填写功能名称】
     */
    private final ICalculateRuleService calculateRuleService;
    private final CalculateMoneyRuleServiceImpl calculateMoneyRuleService;
    @Override
    public TContract selectTContractById(Long id)
    {
        return tContractMapper.selectTContractById(id);
    public void importTemplate(HttpServletResponse response) {
        try {
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("导入合同模板", StandardCharsets.UTF_8).replace("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
            EasyExcel.write(response.getOutputStream(), CalculateRule.class)
                    // 自适应列宽
                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                    // 下拉框
                    .registerWriteHandler(new CustomSheetWriteHandler(Arrays.asList("扣指定分数", "分数乘以数量", "除以数量后乘以分数")))
                    .registerWriteHandler(new CustomCellWriteHandler())
                    // 标注
                    .registerWriteHandler(new CommentWriteHandler())
                    .sheet("合同导入模板")
                    .doWrite(getExcelData());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    /**
     * 查询【请填写功能名称】列表
     *
     * @param tContract 【请填写功能名称】
     * @return 【请填写功能名称】
     */
    private List<CalculateRule> getExcelData() {
        ArrayList<CalculateRule> list = new ArrayList<>();
        setTemplateRule(list,1,"设备平均在线率","≥98%",null,98D,RuleDeductCategoryEnum.DEDUCT_POINTS,0.00);
        setTemplateRule(list,null,"设备平均在线率","95%≤设备平均在线率<98%",97D,95D,RuleDeductCategoryEnum.DEDUCT_POINTS,5.00);
        setTemplateRule(list,null,"设备平均在线率","90%≤设备平均在线率<95%",94D,90D,RuleDeductCategoryEnum.DEDUCT_POINTS,10.00);
        setTemplateRule(list,null,"设备平均在线率","<90%",89D,null,RuleDeductCategoryEnum.DEDUCT_POINTS,20.00);
        setTemplateRule(list,2,"前端感知源治理工作","时钟同步",null,25D,RuleDeductCategoryEnum.MULTIPLY_POINTS_BY_QUANTITY,0.1);
        setTemplateRule(list,null,"前端感知源治理工作","OSD标识",null,25D,RuleDeductCategoryEnum.MULTIPLY_POINTS_BY_QUANTITY,0.1);
        setTemplateRule(list,null,"前端感知源治理工作","一机一档",null,25D,RuleDeductCategoryEnum.MULTIPLY_POINTS_BY_QUANTITY,0.1);
        setTemplateRule(list,3,"对于前端点位异常情况的处理","镜头故障或污染或树枝遮挡或枪机视角偏移正常角度或补光灯应亮未亮,24小时后未修复的",48D,25D,RuleDeductCategoryEnum.MULTIPLY_POINTS_BY_QUANTITY,0.5);
        setTemplateRule(list,null,"对于前端点位异常情况的处理","镜头故障或污染或树枝遮挡或枪机视角偏移正常角度或补光灯应亮未亮,48小时后未修复的",null,49D,RuleDeductCategoryEnum.MULTIPLY_POINTS_BY_QUANTITY,1.0);
        setTemplateRule(list,4,"确保录像完整不定期对所有点位录像完整性抽查","每路视频累计丢失10分钟(含)以内",10D,null,RuleDeductCategoryEnum.MULTIPLY_POINTS_BY_QUANTITY,0.2);
        setTemplateRule(list,null,"确保录像完整不定期对所有点位录像完整性抽查","丢失10-60 分钟(含)",60D,9D,RuleDeductCategoryEnum.MULTIPLY_POINTS_BY_QUANTITY,0.5);
        setTemplateRule(list,null,"确保录像完整不定期对所有点位录像完整性抽查","丢失1 小时-4 小时(含)",240D,59D,RuleDeductCategoryEnum.MULTIPLY_POINTS_BY_QUANTITY,1.0);
        setTemplateRule(list,null,"确保录像完整不定期对所有点位录像完整性抽查","丢失4 小时-12 小时(含)",720D,539D,RuleDeductCategoryEnum.MULTIPLY_POINTS_BY_QUANTITY,1.5);
        setTemplateRule(list,null,"确保录像完整不定期对所有点位录像完整性抽查","丢失12 小时以上",null,719D,RuleDeductCategoryEnum.MULTIPLY_POINTS_BY_QUANTITY,2.0);
        setTemplateRule(list,5,"确保图片完整不定期对所有人脸车辆以及智能前端抓拍的图片完整性抽查","发现后台存储不能调取前端设备图片",null,null,RuleDeductCategoryEnum.MULTIPLY_POINTS_BY_QUANTITY,2.0);
        return list;
    }
    private static void setTemplateRule(ArrayList<CalculateRule> list,Integer id,String ruleName,String condition,Double max,Double min,RuleDeductCategoryEnum deductCategoryEnum,Double calcFraction) {
        CalculateRule calculateRule = new CalculateRule();
        calculateRule.setId(id);
        calculateRule.setRuleName(ruleName);
        calculateRule.setRuleCondition(condition);
        calculateRule.setMax(max);
        calculateRule.setMin(min);
        calculateRule.setDeductCategory(deductCategoryEnum);
        calculateRule.setCalcFraction(calcFraction);
        list.add(calculateRule);
    }
    @Override
    public List<TContract> selectTContractList(TContract tContract)
    {
        return tContractMapper.selectTContractList(tContract);
    @Transactional
    @SneakyThrows
    public AjaxResult importData(MultipartFile file, TContract tContract) {
        // 保存合同
        tContract.setCreateTime(DateUtils.getNowDate());
        save(tContract);
        // 获取合同Excel规则
        List<CalculateRule> list = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), CalculateRule.class, new PageReadListener<CalculateRule>(list::addAll)).sheet().doRead();
        // 遍历父子关系
        List<CalculateRule> calculateRulesToSave = new ArrayList<>();
        for (CalculateRule calculateRule : list) {
            // 判断数据完整性
            if (ObjectUtils.isEmpty(calculateRule.getDeductCategory())) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.warn("请选择" + calculateRule.getRuleName() + calculateRule.getRuleCondition() + "扣分方式");
            }
            if (RuleDeductCategoryEnum.MULTIPLY_POINTS_AFTER_DIVIDING_QUANTITY.equals(calculateRule.getDeductCategory()) && ObjectUtils.isEmpty(calculateRule.getCalcUnit())) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.warn("请填写" + calculateRule.getRuleName() + calculateRule.getRuleCondition() + "除以数量");
            }
            if(ObjectUtils.isEmpty(calculateRule.getCalcFraction())) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.warn("请填写" + calculateRule.getRuleName() + calculateRule.getRuleCondition() + "扣分数值");
            }
            // 保存规则
            if (StringUtils.isNotBlank(calculateRule.getRuleName())) {
                calculateRule.setContractId(tContract.getId().intValue());
                calculateRule.setCreateTime(DateUtils.getNowDate());
                calculateRule.setUpdateTime(DateUtils.getNowDate());
                calculateRulesToSave.add(calculateRule);
            }
        }
        // 批量保存规则
        calculateRuleService.saveBatch(calculateRulesToSave);
        //批量保存考核结果应用规则
        calculateMoneyRuleService.saveBatch(JSON.parseArray(tContract.getRuleList(), CalculateMoneyRule.class).stream().peek(
                calculateMoneyRule -> calculateMoneyRule.setContractId(tContract.getId().intValue())
        ).collect(Collectors.toList()));
        return AjaxResult.success("操作成功");
    }
    /**
     * 新增【请填写功能名称】
     *
     * @param tContract 【请填写功能名称】
     * @return 结果
     */
    @Override
    public int insertTContract(TContract tContract)
    {
        return tContractMapper.insertTContract(tContract);
    public AjaxResult importRule(MultipartFile file, TContract tContract) throws IOException {
        // 获取合同Excel规则
        List<CalculateRule> list = new ArrayList<>();
        if(file!=null) {
            EasyExcel.read(file.getInputStream(), CalculateRule.class, new PageReadListener<CalculateRule>(list::addAll)).sheet().doRead();
            // 遍历父子关系
            List<CalculateRule> calculateRulesToSave = new ArrayList<>();
            for (CalculateRule calculateRule : list) {
                // 判断数据完整性
                if (ObjectUtils.isEmpty(calculateRule.getDeductCategory())) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return AjaxResult.warn("请选择" + calculateRule.getRuleName() + calculateRule.getRuleCondition() + "扣分方式");
                }
                if (RuleDeductCategoryEnum.MULTIPLY_POINTS_AFTER_DIVIDING_QUANTITY.equals(calculateRule.getDeductCategory()) && ObjectUtils.isEmpty(calculateRule.getCalcUnit())) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return AjaxResult.warn("请填写" + calculateRule.getRuleName() + calculateRule.getRuleCondition() + "除以数量");
                }
                if (ObjectUtils.isEmpty(calculateRule.getCalcFraction())) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return AjaxResult.warn("请填写" + calculateRule.getRuleName() + calculateRule.getRuleCondition() + "扣分数值");
                }
                // 保存规则
                if (StringUtils.isNotBlank(calculateRule.getRuleName())) {
                    calculateRule.setContractId(tContract.getId().intValue());
                    calculateRule.setCreateTime(DateUtils.getNowDate());
                    calculateRule.setUpdateTime(DateUtils.getNowDate());
                    calculateRulesToSave.add(calculateRule);
                }
            }
            if (!CollectionUtils.isEmpty(calculateRulesToSave)) {
                //删除原规则
                calculateRuleService.remove(new QueryWrapper<CalculateRule>().eq("contract_id", tContract.getId()));
                // 批量保存规则
                calculateRuleService.saveBatch(calculateRulesToSave);
            }
        }
        List<CalculateMoneyRule> moneyRule = JSON.parseArray(tContract.getRuleList(), CalculateMoneyRule.class).stream().peek(
                calculateMoneyRule -> calculateMoneyRule.setContractId(tContract.getId().intValue())
        ).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(moneyRule)) {
            //删除原规则
            calculateMoneyRuleService.remove(new QueryWrapper<CalculateMoneyRule>().eq("contract_id",tContract.getId()));
            //批量保存考核结果应用规则
            calculateMoneyRuleService.saveBatch(moneyRule);
        }
        return AjaxResult.success("操作成功");
    }
    /**
     * 修改【请填写功能名称】
     *
     * @param tContract 【请填写功能名称】
     * @return 结果
     */
    @Override
    public int updateTContract(TContract tContract)
    {
        return tContractMapper.updateTContract(tContract);
    public Result selectAll(ContractQuery query) {
        IPage<ContractVO> page = PageUtil.getPage(query, ContractVO.class);
        query.setUnitId(SecurityUtils.getUnitId());
        baseMapper.getPage(page, query);
        page.getRecords().stream().forEach(contract -> {
            Date now = new Date();
            if (now.before(contract.getStartTime())) {
                contract.setStatus(ContractStatus.NOT_START);
            } else if (now.after(contract.getEndTime())) {
                contract.setStatus(ContractStatus.FINISHED);
            } else {
                contract.setStatus(ContractStatus.ACTIVE);
            }
        });
        return Result.ok().data(page.getRecords()).total(page.getTotal());
    }
    /**
     * 批量删除【请填写功能名称】
     *
     * @param ids 需要删除的【请填写功能名称】主键
     * @return 结果
     */
    @Override
    public int deleteTContractByIds(Long[] ids)
    {
        return tContractMapper.deleteTContractByIds(ids);
    public List<CalculateMoneyRule> selectMoneyRules(Integer contractId) {
        return calculateMoneyRuleService.selectMoneyRules(contractId);
    }
    /**
     * 删除【请填写功能名称】信息
     *
     * @param id 【请填写功能名称】主键
     * @return 结果
     */
    @Override
    public int deleteTContractById(Long id)
    {
        return tContractMapper.deleteTContractById(id);
    public List<TContract> selectUsingContract() {
        return new LambdaQueryChainWrapper<>(baseMapper)
                .le(TContract::getStartTime, DateUtils.getDate())
                .ge(TContract::getEndTime, DateUtils.getDate())
                .list();
    }
    @Override
    public Result timeRange(Integer unitId) {
        List<TContract> unitContractList = new LambdaQueryChainWrapper<>(baseMapper)
                .select(TContract::getId, TContract::getName, TContract::getStartTime, TContract::getEndTime)
                .eq(TContract::getUnitId, unitId)
                .ge(TContract::getEndTime, new Date())
                .list();
        return Result.ok().data(unitContractList);
    }
}