ycl-server/src/main/java/com/ycl/platform/service/impl/CalculateReportServiceImpl.java
@@ -1,27 +1,50 @@
package com.ycl.platform.service.impl;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ycl.platform.domain.entity.CalculateRecord;
import com.ycl.platform.domain.entity.CalculateReport;
import com.ycl.platform.domain.entity.CalculateRule;
import com.ycl.platform.domain.excel.CalculateExport;
import com.ycl.platform.domain.form.CalculateReportBackfillForm;
import com.ycl.platform.domain.form.CalculateReportForm;
import com.ycl.platform.domain.query.CalculateReportQuery;
import com.ycl.platform.domain.vo.CalculateReportDetailVO;
import com.ycl.platform.domain.vo.CalculateReportVO;
import com.ycl.platform.domain.vo.ContractResultVO;
import com.ycl.platform.mapper.CalculateRecordMapper;
import com.ycl.platform.mapper.CalculateReportMapper;
import com.ycl.platform.service.CalculateReportService;
import com.ycl.platform.service.ICalculateRuleService;
import com.ycl.system.Result;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ycl.platform.domain.form.CalculateReportForm;
import com.ycl.platform.domain.vo.CalculateReportVO;
import com.ycl.platform.domain.query.CalculateReportQuery;
import java.util.List;
import org.apache.commons.lang3.StringUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.ycl.system.entity.SysRole;
import com.ycl.system.entity.SysUser;
import com.ycl.system.page.PageUtil;
import org.springframework.stereotype.Service;
import org.springframework.security.core.context.SecurityContextHolder;
import com.ycl.utils.SecurityUtils;
import enumeration.general.CalculateReportStatusEnum;
import enumeration.general.PublishType;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import java.util.ArrayList;
import org.springframework.util.CollectionUtils;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import lombok.RequiredArgsConstructor;
/**
 * 核算报告 服务实现类
@@ -33,7 +56,8 @@
@RequiredArgsConstructor
public class CalculateReportServiceImpl extends ServiceImpl<CalculateReportMapper, CalculateReport> implements CalculateReportService {
    private final CalculateReportMapper calculateReportMapper;
    private final ICalculateRuleService calculateRuleService;
    private final CalculateRecordMapper calculateRecordMapper;
    /**
     * 添加
@@ -43,6 +67,9 @@
    @Override
    public Result add(CalculateReportForm form) {
        CalculateReport entity = CalculateReportForm.getEntityByForm(form, null);
        Date now = new Date();
        entity.setCreateTime(now);
        entity.setUpdateTime(now);
        if(baseMapper.insert(entity) > 0) {
            return Result.ok("添加成功");
        }
@@ -58,10 +85,11 @@
    public Result update(CalculateReportForm form) {
        CalculateReport entity = baseMapper.selectById(form.getId());
        // 为空抛IllegalArgumentException,做全局异常处理
        Assert.notNull(entity, "记录不存在");
        BeanUtils.copyProperties(form, entity);
        Date now = new Date();
        entity.setUpdateTime(now);
        if (baseMapper.updateById(entity) > 0) {
            return Result.ok("修改成功");
        }
@@ -74,7 +102,7 @@
     * @return
     */
    @Override
    public Result remove(List<String> ids) {
    public Result remove(List<Long> ids) {
        if(baseMapper.deleteBatchIds(ids) > 0) {
            return Result.ok("删除成功");
        }
@@ -87,7 +115,7 @@
     * @return
     */
    @Override
    public Result removeById(String id) {
    public Result removeById(Long id) {
        if(baseMapper.deleteById(id) > 0) {
            return Result.ok("删除成功");
        }
@@ -101,33 +129,47 @@
     */
    @Override
    public Result page(CalculateReportQuery query) {
        IPage<CalculateReport> page = new LambdaQueryChainWrapper<>(baseMapper)
                .orderByDesc(CalculateReport::getCreateTime)
                .page(PageUtil.getPage(query, CalculateReport.class));
        List<CalculateReportVO> vos = page.getRecords().stream()
                .map(
                        entity -> CalculateReportVO.getVoByEntity(entity, null)
                )
                .collect(Collectors.toList());
        return Result.ok().data(vos).total(page.getTotal());
        IPage<CalculateReportVO> page = PageUtil.getPage(query, CalculateReportVO.class);
        //只能看自己单位
        query.setUnitId(SecurityUtils.getUnitId());
        //只能看已发布
        roleControl(query);
        baseMapper.page(query, page);
        page.getRecords().stream().forEach(item -> {
            if (Objects.isNull(item)) {
                item.setCanPublish(Boolean.FALSE);
            } else {
                item.setCanPublish(Boolean.TRUE);
            }
        });
        return Result.ok().data(page.getRecords()).total(page.getTotal());
    }
    /**
     * 根据id查找
     * @param id
     * @param
     * @return
     */
    @Override
    public Result detail(String id) {
        CalculateReport entity = baseMapper.selectById(id);
        Assert.notNull(entity, "记录不存在");
        CalculateReportVO vo = CalculateReportVO.getVoByEntity(entity, null);
        return Result.ok().data(vo);
    public Result detail(CalculateReportQuery query) {
        roleControl(query);
        // 明细列表
        CalculateReportDetailVO detail = baseMapper.getById(query);
        return Result.ok().data(detail);
    }
    private void roleControl(CalculateReportQuery query) {
        List<SysRole> roles = SecurityUtils.getLoginUser().getUser().getRoles();
        SysUser user = SecurityUtils.getLoginUser().getUser();
        if (!user.isAdmin()) {
            for (SysRole role : roles) {
                //菜单的地方增加了一个按钮,角色权限编辑如果勾上了说明只能查看已发布
                if (role.getPermissions().contains("check:contract:role:publish")) {
                    query.setStatus(PublishType.PUBLISHED.getCode());
                }
            }
        }
    }
    /**
     * 列表
     * @return
@@ -136,10 +178,84 @@
    public Result all() {
        List<CalculateReport> entities = baseMapper.selectList(null);
        List<CalculateReportVO> vos = entities.stream()
                .map(
                        entity -> CalculateReportVO.getVoByEntity(entity, null)
                )
                .map(entity -> CalculateReportVO.getVoByEntity(entity, null))
                .collect(Collectors.toList());
        return Result.ok().data(vos);
    }
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result backfill(CalculateReportBackfillForm form) {
//        CalculateReport report = baseMapper.selectById(form.getId());
//        if (Objects.isNull(report)) {
//            throw new RuntimeException("该核算报告不存在");
//        }
//        if (CalculateReportStatusEnum.PUBLISHED.equals(report.getStatus())) {
//            throw new RuntimeException("最新一次核算报告已经发布,无法修改");
//        }
//        CalculateReportBackfillForm.RecordForm latestRecord = form.getRecordList().get(0);
//        CalculateRecord beforeRecord = calculateRecordMapper.selectById(latestRecord.getId());
//        if (Objects.isNull(beforeRecord)) {
//            throw new RuntimeException("最近一次核算记录不存在");
//        }
//        // 计算得到扣款总额(只算最近一条)
//        BigDecimal totalDeduct = report.getDeductMoney().subtract(latestRecord.getDeductMoney()).add(latestRecord.getDeductMoney());
//        report.setDeductMoney(totalDeduct);
//        baseMapper.updateById(report);
//
//        beforeRecord.setDeductMoney(latestRecord.getDeductMoney());
//        calculateRecordMapper.updateById(beforeRecord);
        List<CalculateReportBackfillForm.RecordForm> recordList = form.getRecordList();
        if(!CollectionUtils.isEmpty(recordList)) calculateRecordMapper.updateBatch(recordList);
        return Result.ok("操作成功");
    }
    @Override
    public Result updatePublishStatus(Integer contractId,Integer whichYear) {
        calculateRecordMapper.batchPublish(contractId,whichYear);
        return Result.ok("操作成功");
    }
    @Override
    public Result updatePublishStatusById(Integer id, String status) {
        calculateRecordMapper.updatePublishById(id,status);
        return Result.ok("操作成功");
    }
    @Override
    @SneakyThrows
    public void export(Integer whichYear,Integer whichMonth,Integer whichDay,Integer contractId, HttpServletResponse response) {
        // 获取数据
        List<CalculateExport> list = baseMapper.exportData(whichYear,whichMonth,whichDay,contractId);
        CalculateExport calculateExport = new CalculateExport();
        calculateExport.setRuleName("合计");
        calculateExport.setNum(list.stream().mapToInt(CalculateExport::getNum).sum());
        calculateExport.setScore(list.stream()
                .map(CalculateExport::getScore)
                .reduce(BigDecimal.ZERO, BigDecimal::add) // 计算总和
                .add(BigDecimal.valueOf(100)) // 加上100
                .setScale(1, RoundingMode.HALF_UP));
        list.add(calculateExport);
        list.forEach(item->{
            if("确保录像完整不定期对所有点位录像完整性抽查".equals(item.getRuleName())){
                item.setNum(item.getScore().abs().divide(item.getCalcFraction(),0,RoundingMode.HALF_UP).intValue());
            }
        });
        // 获取规则
        List<CalculateRule> ruleList = calculateRuleService.list(new LambdaQueryWrapper<CalculateRule>().eq(CalculateRule::getContractId, contractId));
        // 输出文件
        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");
        // 增加sheet
        try (ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build()){
            WriteSheet sheet = EasyExcel.writerSheet(0, "核算报告").head(CalculateExport.class).build();
            excelWriter.write(list, sheet);
            WriteSheet sheet2 = EasyExcel.writerSheet(1, "核算规则").head(CalculateRule.class).registerWriteHandler(new LongestMatchColumnWidthStyleStrategy()).build();
            excelWriter.write(ruleList, sheet2);
        }
    }
}