fuliqi
2024-08-23 620a580dbfee0d438b4505f77c9a232332f53849
ycl-server/src/main/java/com/ycl/platform/service/impl/TContractServiceImpl.java
@@ -1,26 +1,35 @@
package com.ycl.platform.service.impl;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.write.merge.LoopMergeStrategy;
import com.alibaba.excel.read.listener.PageReadListener;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.alibaba.fastjson2.JSON;
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 com.ycl.system.AjaxResult;
import com.ycl.system.Result;
import com.ycl.system.page.PageUtil;
import com.ycl.utils.DateUtils;
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.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.multipart.MultipartFile;
@@ -28,8 +37,10 @@
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;
/**
 * 【请填写功能名称】Service业务层处理
@@ -42,33 +53,25 @@
public class TContractServiceImpl extends ServiceImpl<TContractMapper, TContract> implements ITContractService {
    private final ICalculateRuleService calculateRuleService;
    private final YwUnitServiceImpl ywUnitService;
    private final CalculateMoneyRuleServiceImpl calculateMoneyRuleService;
    @Override
    public void importTemplate(HttpServletResponse response) {
        try {
            List<CalculateRule> list = getExcelData();
            ArrayList<String> arrayList = new ArrayList<>();
            arrayList.add("扣指定分数");
            arrayList.add("分数乘以数量");
            arrayList.add("除以数量后乘以分数");
            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");
            // 第一列、第二列上下合并3行
            LoopMergeStrategy loopMergeStrategy1 = new LoopMergeStrategy(3, 0);
            LoopMergeStrategy loopMergeStrategy2 = new LoopMergeStrategy(3, 1);
            EasyExcel.write(response.getOutputStream(), CalculateRule.class)
                    .registerWriteHandler(loopMergeStrategy1)
                    .registerWriteHandler(loopMergeStrategy2)
                    // 自适应列宽
                    .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
                    // 下拉框
                    .registerWriteHandler(new CustomSheetWriteHandler(arrayList))
                    .registerWriteHandler(new CustomSheetWriteHandler(Arrays.asList("扣指定分数", "分数乘以数量", "除以数量后乘以分数")))
                    .registerWriteHandler(new CustomCellWriteHandler())
                    // 标注
                    .registerWriteHandler(new CommentWriteHandler())
                    .sheet("合同导入模板").doWrite(list);
                    .sheet("合同导入模板")
                    .doWrite(getExcelData());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
@@ -76,68 +79,57 @@
    private List<CalculateRule> getExcelData() {
        ArrayList<CalculateRule> list = new ArrayList<>();
        CalculateRule calculateRule1 = new CalculateRule();
        calculateRule1.setId(1L);
        calculateRule1.setRuleName("视频平均在线率");
        calculateRule1.setRuleDesc("(1)视频在线率=视频在线数量÷前端服务配置数(应扣除不可抗力或与中标人服务无关造成的掉线除外。)");
        calculateRule1.setRuleCondition("≥98%");
        calculateRule1.setDeductCategory(RuleDeductCategoryEnum.DEDUCT_POINTS);
        calculateRule1.setCalcFraction(0.00);
        list.add(calculateRule1);
        CalculateRule calculateRule2 = new CalculateRule();
        calculateRule2.setRuleDesc("(2)视频平均在线率:当月每日视频在线率的平均值。");
        calculateRule2.setRuleCondition("95%≤视频平均在线率<98%");
        calculateRule2.setDeductCategory(RuleDeductCategoryEnum.DEDUCT_POINTS);
        calculateRule2.setCalcFraction(5.00);
        list.add(calculateRule2);
        CalculateRule calculateRule3 = new CalculateRule();
        calculateRule3.setRuleDesc("(3)视频在线率保留整数并且向下取整。");
        calculateRule3.setRuleCondition("90%≤视频平均在线率<95%");
        calculateRule3.setDeductCategory(RuleDeductCategoryEnum.DEDUCT_POINTS);
        calculateRule3.setCalcFraction(10.00);
        list.add(calculateRule3);
        CalculateRule calculateRule4 = new CalculateRule();
        calculateRule4.setId(2L);
        calculateRule4.setRuleName("前端感知源治理工作");
        calculateRule4.setRuleDesc("时钟同步(超过±3秒为不合格)");
        calculateRule4.setRuleCondition("视频监控摄像机时钟不同步,24小时内未修复的");
        calculateRule4.setDeductCategory(RuleDeductCategoryEnum.MULTIPLY_POINTS_BY_QUANTITY);
        calculateRule4.setCalcFraction(0.1);
        list.add(calculateRule4);
        CalculateRule calculateRule7 = new CalculateRule();
        calculateRule7.setRuleDesc("…………");
        calculateRule7.setRuleCondition("…………");
        list.add(calculateRule7);
        CalculateRule calculateRule6 = new CalculateRule();
        calculateRule6.setRuleDesc("…………");
        calculateRule6.setRuleCondition("…………");
        list.add(calculateRule6);
        CalculateRule calculateRule5 = new CalculateRule();
        calculateRule5.setId(3L);
        calculateRule5.setRuleName("后台系统的保障");
        calculateRule5.setRuleDesc("在个别设备故障但不影响该功能模块整体应用情况下,须在72小时以内排除故障。");
        calculateRule5.setRuleCondition("单次故障时长若超出144小时以后,每超出12小时(不足12小时按12小时计)");
        calculateRule5.setDeductCategory(RuleDeductCategoryEnum.MULTIPLY_POINTS_AFTER_DIVIDING_QUANTITY);
        calculateRule5.setCalcFraction(2.00);
        calculateRule5.setCalcUnit(12);
        list.add(calculateRule5);
        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,"前端感知源治理工作","时钟同步",24D,null,RuleDeductCategoryEnum.MULTIPLY_POINTS_BY_QUANTITY,0.1);
        setTemplateRule(list,null,"前端感知源治理工作","OSD标识",24D,null,RuleDeductCategoryEnum.MULTIPLY_POINTS_BY_QUANTITY,0.1);
        setTemplateRule(list,null,"前端感知源治理工作","一机一档",24D,null,RuleDeductCategoryEnum.MULTIPLY_POINTS_BY_QUANTITY,0.1);
        setTemplateRule(list,3,"存储故障","因存储设备、云存储软件等引起平台不能正常查看历史图像,须在24小时排除故障,单次故障在24小时以内",24D,null,RuleDeductCategoryEnum.MULTIPLY_POINTS_BY_QUANTITY,0.5);
        setTemplateRule(list,null,"存储故障","因存储设备、云存储软件等引起平台不能正常查看历史图像,须在24小时排除故障,单次故障在48小时以内",48D,25D,RuleDeductCategoryEnum.MULTIPLY_POINTS_BY_QUANTITY,1.0);
        setTemplateRule(list,null,"存储故障","因视频或者图片丢失导致重要案事件不能回放或查看",null,null,RuleDeductCategoryEnum.MULTIPLY_POINTS_BY_QUANTITY,2.0);
        setTemplateRule(list,4,"对于前端点位异常情况的处理","镜头故障或污染或树枝遮挡或枪机视角偏移正常角度或补光灯应亮未亮,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,5,"确保录像完整不定期对所有点位录像完整性抽查","每路视频累计丢失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,6,"确保图片完整不定期对所有人脸车辆以及智能前端抓拍的图片完整性抽查","发现后台存储不能调取前端设备图片",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
    @Transactional
    @SneakyThrows
    public AjaxResult importData(MultipartFile file, TContract tContract) {
        // 保存合同
        tContract.setCreateTime(DateUtils.getNowDate());
        tContract.setDeleted("0");
        save(tContract);
        List<CalculateRule> list = calculateRuleService.readExcel(file);
        // 获取合同Excel规则
        List<CalculateRule> list = new ArrayList<>();
        EasyExcel.read(file.getInputStream(), CalculateRule.class, new PageReadListener<CalculateRule>(list::addAll)).sheet().doRead();
        // 遍历父子关系
        List<CalculateRule> calculateRulesToSave = new ArrayList<>();
        CalculateRule fu1 = new CalculateRule();
        CalculateRule fu2 = new CalculateRule();
        boolean fuNew = true;
        for (CalculateRule calculateRule : list) {
            // 判断数据完整性
            if (ObjectUtils.isEmpty(calculateRule.getDeductCategory())) {
@@ -152,47 +144,60 @@
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                return AjaxResult.warn("请填写" + calculateRule.getRuleName() + calculateRule.getRuleCondition() + "扣分数值");
            }
            // 保存父规则获取父id
            // 保存规则
            if (StringUtils.isNotBlank(calculateRule.getRuleName())) {
                CalculateRule one = new CalculateRule();
                one.setParentId(0L);
                one.setContractId(tContract.getId().intValue());
                one.setRuleName(calculateRule.getRuleName());
                one.setCreateTime(DateUtils.getNowDate());
                one.setDeleted(0);
                calculateRuleService.save(one);
                fu1 = one;
                fuNew = true;
                calculateRule.setContractId(tContract.getId().intValue());
                calculateRule.setCreateTime(DateUtils.getNowDate());
                calculateRule.setUpdateTime(DateUtils.getNowDate());
                calculateRulesToSave.add(calculateRule);
            }
            // 保存第二层父规则获取第二层父id
            if (StringUtils.isNotBlank(calculateRule.getRuleDesc())) {
                CalculateRule two = new CalculateRule();
                two.setContractId(tContract.getId().intValue());
                two.setParentId(fu1.getId());
                two.setRuleDesc(calculateRule.getRuleDesc());
                two.setCreateTime(DateUtils.getNowDate());
                two.setDeleted(0);
                calculateRuleService.save(two);
                fu2 = two;
                fuNew = false;
            }
            calculateRule.setContractId(tContract.getId().intValue());
            calculateRule.setCreateTime(DateUtils.getNowDate());
            calculateRule.setDeleted(0);
            calculateRule.setParentId(fuNew ? fu1.getId() : fu2.getId());
            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("操作成功");
    }
    @Override
    public List<TContract> selectAll() {
        return list(new LambdaQueryWrapper<TContract>()
                .orderByDesc(TContract::getCreateTime))
                .stream().peek(
                        tContract -> tContract.setUnitName(ywUnitService.getById(tContract.getUnitId()).getUnitName())
                ).toList();
    public Result selectAll(ContractQuery query) {
        IPage<ContractVO> page = PageUtil.getPage(query, ContractVO.class);
        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());
    }
    @Override
    public List<CalculateMoneyRule> selectMoneyRules(Integer contractId) {
        return calculateMoneyRuleService.selectMoneyRules(contractId);
    }
    @Override
    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);
    }
}