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 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.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 @AllArgsConstructor public class TContractServiceImpl extends ServiceImpl implements ITContractService { private final ICalculateRuleService calculateRuleService; private final CalculateMoneyRuleServiceImpl calculateMoneyRuleService; @Override 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); } } private List getExcelData() { ArrayList 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 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()); save(tContract); // 获取合同Excel规则 List list = new ArrayList<>(); EasyExcel.read(file.getInputStream(), CalculateRule.class, new PageReadListener(list::addAll)).sheet().doRead(); // 遍历父子关系 List 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("操作成功"); } @Override public AjaxResult importRule(MultipartFile file, TContract tContract) throws IOException { // 获取合同Excel规则 List list = new ArrayList<>(); if(file!=null) { EasyExcel.read(file.getInputStream(), CalculateRule.class, new PageReadListener(list::addAll)).sheet().doRead(); // 遍历父子关系 List 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().eq("contract_id", tContract.getId())); // 批量保存规则 calculateRuleService.saveBatch(calculateRulesToSave); } } List 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().eq("contract_id",tContract.getId())); //批量保存考核结果应用规则 calculateMoneyRuleService.saveBatch(moneyRule); } return AjaxResult.success("操作成功"); } @Override public Result selectAll(ContractQuery query) { IPage 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()); } @Override public List selectMoneyRules(Integer contractId) { return calculateMoneyRuleService.selectMoneyRules(contractId); } @Override public List selectUsingContract() { return new LambdaQueryChainWrapper<>(baseMapper) .le(TContract::getStartTime, DateUtils.getDate()) .ge(TContract::getEndTime, DateUtils.getDate()) .list(); } @Override public Result timeRange(Integer unitId) { List 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); } }