package com.nantian.cloud.jljc.controller;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nantian.cloud.jljc.entity.*;
import com.nantian.cloud.jljc.service.*;
import com.nantian.cloud.jljc.vo.Query;
import com.nantian.cloud.jljc.vo.QueryCustomReportSummaryVo;
import com.nantian.cloud.jljc.vo.ReportModifyVo;
import com.nantian.cloud.jljc.vo.comAnalysis.EnergyInfoVo;
import com.nantian.sc.cloud.common.core.util.R;
import com.nantian.sc.cloud.common.log.annotation.SysLog;
import com.nantian.sc.cloud.common.minio.service.MinioTemplate;
import com.nantian.sc.cloud.common.security.service.ScUser;
import com.nantian.sc.cloud.common.security.util.SecurityUtils;
import io.minio.errors.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.*;
import org.xmlpull.v1.XmlPullParserException;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;


/**
 * 报表-能源报表信息
 *
 * @date 2020-09-16
 */
@Slf4j
@CrossOrigin
@RestController
@AllArgsConstructor
@RequestMapping("/tReport")
@Api(value = "tReport", tags = "报表-能源报表信息")
public class TReportController {

    final private TReportService tReportService;
    final private TReportEnterpriseService tReportEnterpriseService;
    final private EnterpriseInfoService enterpriseInfoService;
    final private EcAbnormalVolatilityService ecAbnormalVolatilityService;
    final private EpcEnergyAccuracyAnalysisService epcEnergyAccuracyAnalysisService;
    @Autowired
    private MinioTemplate minioTemplate;

    /**
     * 判断企业是否进行报表设置
     */
    @GetMapping("/isSetting")
    @SysLog("判断企业是否进行能报报表设置")
    @ApiOperation(value = "判断企业是否进行报表设置", notes = "判断企业是否进行报表设置")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "year", value = "年份", required = true, dataType = "string", paramType = "path"),
            @ApiImplicitParam(name = "enterpriseCode", value = "企业社会信用编码", required = true, dataType = "string", paramType = "path")
    })
    public R isSetting(String year, String enterpriseCode) {
        if (year == null || "".equals(year)) {
            return R.failed("报表设置失败，年度不能为空");
        }
        if (enterpriseCode == null || "".equals(enterpriseCode)) {
            return R.failed("报表设置失败，企业信用编码不能为空");
        }

        Map<String, Object> map = new HashMap();
        map.put("year", year);

        if(Integer.parseInt(year)<=2019){ //历史数据不管报表设置
            map.put("type", 1);
            return R.ok(map);
        }

        //获取能源报表信息
        TReport report = tReportService.getInfoByType(enterpriseCode, year, "1");
        if (report == null) {
            map.put("type", 0);
            map.put("text", year + "年 报表设置未完成，请前去设置");
            return R.ok(map);
        }

        //查询企业基本信息设置
        TReportEnterprise enterprise = tReportEnterpriseService.getEnterpriseByReportId(report.getId());
        if (enterprise == null) {
            map.put("type", 0);
            map.put("text", year + "年 报表设置【企业基本信息】未完成，请前去设置");
            return R.ok(map);
        }

        //查询主要产品设置
        if (enterprise.getProductinfos() == null || StrUtil.isBlank(enterprise.getProductinfos())) {
            map.put("type", 0);
            map.put("text", year + "年 报表设置【主要产品】未完成，请前去设置");
            return R.ok(map);
        }

        //查询指标设定设置
        if (enterprise.getIndicators() == null || StrUtil.isBlank(enterprise.getIndicators())) {
            map.put("type", 0);
            map.put("text", year + "年 报表设置【指标设定】未完成，请前去设置");
            return R.ok(map);
        }

        //查询用能种类设置
        if (enterprise.getEnergyTypes() == null || StrUtil.isBlank(enterprise.getEnergyTypes())) {
            map.put("type", 0);
            map.put("text", year + "年 报表设置【用能种类】未完成，请前去设置");
            return R.ok(map);
        }

        map.put("type", 1);
        map.put("text", year + "年 报表设置已完成");
        return R.ok(map);
    }

    /**
     * 审核报表
     */
    @GetMapping("/auditorJudge")
    @SysLog("能报报表退回功能")
    @ApiOperation(value = "报表退回功能", notes = "报表退回功能")
    @ApiImplicitParam(name = "tReport", value = "报表对象（报表id比传）", required = false, dataType = "json", paramType = "path")
    public R updateByAuditorJudge(TReport tReport) {
        List<TReport> list = tReportService.listByAuditorJudge(tReport);
        if(list!=null && list.size()>0){ //有报表不通过，所有报表退回
            boolean b = false;
            ScUser u = SecurityUtils.getUser();
            List<TReport> report = tReportService.list(new QueryWrapper<>(new TReport())
                    .eq("enterprise_code",tReport.getEnterpriseCode())
                    .eq("year",tReport.getYear())
                    .eq("report_status","3")
                    .eq("del_flag","1"));
            for (int i = 0; i < report.size(); i++) {
                TReport tReport1 = report.get(i);
                tReport1.setAuditStatus("4");
                tReport1.setReportStatus("2"); //报表已填写
                report.set(i,auditInfo(tReport1,u));
            }
            if(report!=null && report.size()>0){
                b = tReportService.updateBatchById(report);
            }
            return b ? R.ok("企业有报表不通过，所有报表退回成功！") : R.ok();
        }
        return R.ok();
    }

    /**
     * 审核报表
     */
    @PostMapping("/auditor")
    @SysLog("审核能报报表")
    @ApiOperation(value = "审核报表", notes = "审核报表")
    @ApiImplicitParam(name = "tReport", value = "报表对象（报表id比传）", required = false, dataType = "json", paramType = "path")
    public R updateByAuditor(@RequestBody String reportAuditor) {
        /*if (tReport.getYear() == null || "".equals(tReport.getYear())) {
            return R.failed("审核报表失败，年度不能为空！");
        }
        if (tReport.getEnterpriseCode() == null || "".equals(tReport.getEnterpriseCode())) {
            return R.failed("审核报表失败，企业编码不能为空！");
        }
        if (tReport.getType() == null || "".equals(tReport.getType())) {
            return R.failed("审核报表失败，报表类型不能为空！");
        }

        //获取报表本年的能源报表信息
        TReport o = tReportService.getInfoByType(tReport.getEnterpriseCode(), tReport.getYear()+"", tReport.getType());
        if(o==null){
            return R.failed("审核报表失败，报表不存在！");
        }*/
        TReport tReport = JSONObject.parseObject(reportAuditor, TReport.class);
        if (tReport.getId() == null) {
            return R.failed("审核报表失败，报表id不存在！");
        }

        boolean b = false;
        ScUser u = SecurityUtils.getUser();
        if("all".equals(tReport.getType())){ //一键通过报表，或一键退回报表
            List<TReport> report = tReportService.list(new QueryWrapper<>(new TReport())
                    .eq("enterprise_code",tReport.getEnterpriseCode())
                    .eq("year",tReport.getYear())
                    .eq("report_status","3")
                    .eq("del_flag","1"));
            for (int i = 0; i < report.size(); i++) {
                TReport tReport1 = report.get(i);
                tReport1.setAuditStatus(tReport.getAuditStatus());
                if("4".equals(tReport.getAuditStatus())){ //退回
                    tReport1.setReportStatus("2"); //报表已填写
                }
                report.set(i,auditInfo(tReport1,u));
            }
            if(report!=null && report.size()>0){
                b = tReportService.updateBatchById(report);
            }
        }else{ //通过或退回单张报表
            if("4".equals(tReport.getAuditStatus())){ //退回
                tReport.setReportStatus("2"); //报表已填写
            }
            b = tReportService.updateById(auditInfo(tReport,u));
        }
        return b ? R.ok("2".equals(tReport.getAuditStatus()) ? "已审核" : "已退回") : R.failed("审核失败");
    }

    public TReport auditInfo(TReport r, ScUser u){
        TReport report = new TReport();
        report.setId(r.getId());
        report.setReportStatus(r.getReportStatus());
        if(u.getDeptId().toString().contains("0000")){ //省级部门审核
            report.setAuditDate3(new Date());
            report.setAuditorId3((long) u.getId());
            report.setAuditor3(u.getUsername());
            report.setAuditStatus3(r.getAuditStatus());
            report.setAuditRemark3(r.getAuditRemark());
        }else if(u.getDeptId().toString().contains("00")){ //州市部门审核
            report.setAuditDate2(new Date());
            report.setAuditorId2((long) u.getId());
            report.setAuditor2(u.getUsername());
            report.setAuditStatus2(r.getAuditStatus());
            report.setAuditRemark2(r.getAuditRemark());
            report.setProvStatus("1"); //报表一旦审核，省级部门即可查看
        }else{ //区县部门审核
            report.setAuditDate(new Date());
            report.setAuditorId((long) u.getId());
            report.setAuditor(u.getUsername());
            report.setAuditStatus(r.getAuditStatus());
            report.setAuditRemark(r.getAuditRemark());
        }
        return report;
    }

    /**
     * 超期申请查询
     *
     * @param
     * @return R
     */
    @GetMapping("/queryModify")
    @SysLog("能报超期申请查询")
    @ApiOperation(value = "超期申请查询", notes = "超期申请查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "分页", required = false, dataType = "json", paramType = "path"),
            @ApiImplicitParam(name = "cmpName", value = "企业名称", required = false, dataType = "json", paramType = "path"),
            @ApiImplicitParam(name = "status", value = "审核状态（1待审核，2审核通过，3审核不通过）", required = false, dataType = "json", paramType = "path"),
    })
    public R queryModify(Page page, String cmpName, String status) {
        IPage<ReportModifyVo> reportModify = tReportService.getModifyRecords(page, cmpName, status);
        return R.ok(reportModify);
    }

    /**
     * 企业端申请超期修改报表
     */
    @PostMapping("/cmpModify")
    @SysLog("企业端申请超期修改能报报表")
    @ApiOperation(value = "企业端申请超期修改报表", notes = "企业端申请超期修改报表")
    @ApiImplicitParam(name = "tReport", value = "报表对象（报表主键id、企业超期申请原因modifyComments）", required = false, dataType = "json", paramType = "path")
    public R cmpModify(@RequestBody TReport tReport) {
        if (tReport.getId() == null) {
            return R.failed("报表id为空，申请修改报表失败！");
        }
        TReport report = tReportService.getById(tReport.getId());
        if (report == null) {
            return R.failed("报表不存在，申请修改报表失败！");
        }
        ScUser u = SecurityUtils.getUser();
        report.setUserid(u.getId());
        report.setUpdateTime(new Date());
        report.setModifyTime(new Date());
        report.setModifyFlag("1"); //超期申请
        report.setModifyAuditStatus("1"); //超期申请待审核
        report.setModifyComments(tReport.getModifyComments());
        return R.ok(tReportService.updateById(report));
    }

    /**
     * 政府端审核超期修改申请
     */
    @PostMapping("/govModify")
    @SysLog("政府端审核超期修改能报报表申请")
    @ApiOperation(value = "政府端审核超期修改申请", notes = "政府端审核超期修改申请")
    @ApiImplicitParam(name = "tReport", value = "报表对象（报表主键id、超期申请审核状态modifyAuditStatus(1：超期申请待审核，2：超期申请通过，3：超期申请失败)、审批超期申请回复意见modifyAuditRemark）", required = false, dataType = "json", paramType = "path")
    public R govModify(@RequestBody TReport tReport) {
        if (tReport.getId() == null) {
            return R.failed("报表id为空，审核超期修改申请失败！");
        }
        TReport report = tReportService.getById(tReport.getId());
        if (report == null) {
            return R.failed("报表不存在，审核超期修改申请失败！");
        }
        if ("2".equals(tReport.getModifyAuditStatus())) {
            report.setReportStatus("2");  //报表状态改为 已填写
        }
        ScUser u = SecurityUtils.getUser();
        report.setUserid(u.getId());
        report.setModifyAuditStatus(tReport.getModifyAuditStatus());
        report.setUpdateTime(new Date());
        report.setModifyAuditRemark(tReport.getModifyAuditRemark());
        return R.ok(tReportService.updateById(report));
    }


    /**
     * 分页查询
     *
     * @param page    分页对象
     * @param tReport 能源报表
     * @return
     */
    @GetMapping("/page")
    @SysLog("分页能源报表")
    @ApiOperation(value = "分页能源报表", notes = "分页能源报表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "分页对象", required = false, dataType = "json", paramType = "path"),
            @ApiImplicitParam(name = "tReport", value = "报表对象（year 必传）", required = false, dataType = "json", paramType = "path")
    })
    public R getPage(Page page, TReport tReport) {
        //return R.ok(energyIndexService.page(page, Wrappers.query(energyIndex)));
        if (tReport.getYear() == null) {
            return R.failed("查询条件year为空！");
        }
        tReport.setDelFlag("1"); //筛选未删除项
        if(StringUtils.isEmpty(tReport.getEnterpriseCode())){
            tReport.setEnterpriseCode(SecurityUtils.getUser().getEnterpriseCode());
        }
        return R.ok(tReportService.page(page, Wrappers.query(tReport)));
    }

    /**
     * 分页查询
     *
     * @param page    分页对象
     * @param tReport 能源报表
     * @return
     */
    @GetMapping("/getPageByGov")
    @SysLog("分页能源报表")
    @ApiOperation(value = "分页能源报表", notes = "分页能源报表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "分页对象", required = false, dataType = "json", paramType = "path"),
            @ApiImplicitParam(name = "tReport", value = "报表对象（year 必传）", required = false, dataType = "json", paramType = "path")
    })
    public R getPageByGov(Page page, TReport tReport) {
        //return R.ok(energyIndexService.page(page, Wrappers.query(energyIndex)));
        if (tReport.getYear() == null) {
            return R.failed("查询条件year为空！");
        }
        if (tReport.getEnterpriseCode() == null) {
            return R.failed("查询条件企业社会信用编码为空！");
        }
        tReport.setDelFlag("1"); //筛选未删除项
        ScUser u = SecurityUtils.getUser();
        /*if(u.getId()!=null){
            tReport.setUserid(u.getId());
        }*/
        //tReport.setEnterpriseCode(u.getEnterpriseCode());

        IPage report = tReportService.page(page, Wrappers.query(tReport));

        int jgzh = 0; //不是加工转换企业
        //获取报表设置的企业信息
        TReportEnterprise enterpriseSetting = tReportEnterpriseService.getEnterpriseInfo(tReport.getEnterpriseCode(), tReport.getYear().toString());
        EnterpriseInfo enterprise = enterpriseInfoService.getInfoByCode(tReport.getEnterpriseCode());
        if (enterpriseSetting != null) {
            //ProcessingLink 是否为加工转换企业取值，2不是，1是
            if ("1".equals(enterpriseSetting.getProcessingLink())) { //该企业是加工转换企业
                jgzh = 1;
            }
        } else {
            //没有进行报表设置的企业，需从企业信息表中获取是否为加工转换企业
            if (enterprise != null) {
                //Jgzh 是否为加工转换企业取值，2不是，1是
                if ("1".equals(enterprise.getJgzh())) { //该企业是加工转换企业
                    jgzh = 1;
                }
            }
        }


        Map<String, Object> map = new HashMap();
        map.put("report", report);
        map.put("proLink", jgzh);
        return R.ok(map);
    }


    /**
     * 分页查询
     *
     * @param page  分页对象
     * @param query 能源报表
     * @return
     */
    @GetMapping("/queryState")
    @SysLog("分页能源报表（政府端")
    @ApiOperation(value = "分页能源报表（政府端）", notes = "分页能源报表（政府端）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "分页对象", required = false, dataType = "json", paramType = "path"),
            @ApiImplicitParam(name = "query", value = "报表对象（year 必传）", required = false, dataType = "json", paramType = "path")
    })
    public R queryState(Page page, Query query) {
        if (query.getYear() == null) {
            return R.failed("查询条件year为空！");
        }
        //政府端查看能源报表列表，增加数据权限
        return R.ok(tReportService.queryState(page, query));
    }

    @GetMapping("/getNoAuditPage")
    @SysLog("分页能源报表（政府端）")
    @ApiOperation(value = "分页能源报表（政府端）", notes = "分页能源报表（政府端）")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "分页对象", required = false, dataType = "json", paramType = "path"),
            @ApiImplicitParam(name = "query", value = "报表对象（year 必传）", required = false, dataType = "json", paramType = "path")
    })
    public R getNoAuditPage(Page page, Query query) {
        if (query.getYear() == null) {
            return R.failed("查询条件year为空！");
        }
        //政府端查看能源报表列表，增加数据权限
        return R.ok(tReportService.getNoAuditPage(page, query));
    }

    /**
     * 能源利用状况报告上报情况汇总
     */
    @GetMapping("/totalByReport")
    @SysLog("能源利用状况报告上报情况汇总")
    @ApiOperation(value = "能源利用状况报告上报情况汇总", notes = "能源利用状况报告上报情况汇总")
    @ApiImplicitParam(name = "year", value = "年份", required = true, dataType = "string", paramType = "path")
    public R totalByReport(String year, String area) {
        if (year == null || "".equals(year)) {
            return R.failed("查询条件year为空！");
        }
        return R.ok(tReportService.totalByReport(year,area));
    }

    /**
     * 自定义查询
     *
     * @param page  自定义查询分页对象
     * @param query 自定义查询
     * @return
     */
    @GetMapping("/queryCustom")
    @SysLog("分页能报自定义查询")
    @ApiOperation(value = "分页自定义查询", notes = "分页自定义查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "分页对象", required = false, dataType = "json", paramType = "path"),
            @ApiImplicitParam(name = "query", value = "报表对象（year 必传）", required = false, dataType = "json", paramType = "path")
    })
    public R queryCustom(Page page, Query query) {
        if (query.getYear() == null) {
            return R.failed("查询条件year为空！");
        }
        //政府端自定义查询，增加数据权限
         IPage page1=tReportService.queryCustom(page, query);
        return R.ok(page1);
    }

    @GetMapping("/queryCustomRank")
    @SysLog("能报自定义查询")
    @ApiOperation(value = "能报自定义查询", notes = "能报自定义查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "分页对象", required = false, dataType = "json", paramType = "path"),
            @ApiImplicitParam(name = "Query", value = "查询条件（企业名称name、地区area、企业类别type、行业industry、" +
                    "年份year、查询内容1 id、显示样式 id2(1地区,2行业,3企业)、变化率范围low1,high1、数值范围low2,high2、指标编码source）", required = false, dataType = "json", paramType = "path")
    })
    public R queryCustomRank(Page page,Query query) {
        if("35".equals(query.getId())){ //35产品产量
            if(query.getSource() == null || "".equals(query.getSource())){
                return R.failed("指标编码不能为空！");
            }
        }
        return R.ok(tReportService.queryCustomRank(page,query));
    }

    @GetMapping("/queryCustomReport")
    @SysLog("分页自定义查询能报、监察、在线监测数据")
    @ApiOperation(value = "分页自定义查询能报、监察、在线监测数据", notes = "分页自定义查询能报、监察、在线监测数据")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "page", value = "分页对象", required = false, dataType = "json", paramType = "path"),
            @ApiImplicitParam(name = "query", value = "查询对象（综合能耗比较符号(1＜ ,2≤ ,3＞ ,4≥)state，综合能耗source，主要产品product，能耗级别item，企业类别type" +
                    "企业名称name，地区数组areaArr，行业数组tradeArr，开始时间startTime，结束时间endTime，能报状态（1未填写,2已填写,3已上报）nbState，" +
                    "监察完成情况（0已完成,1未完成）jnState，超限情况（1能报超限,2监察超限,3在线监测超限）num）", required = false, dataType = "json", paramType = "path")
    })
    public R queryCustomReport(Page page, Query query) {

        String[] areaArr = query.getAreaArr().split(",");
        String[] tradeArr = query.getTradeArr().split(",");

        if ((!StringUtils.isEmpty(query.getEndTime()) && !StringUtils.isEmpty(query.getStartTime())) ||
                areaArr.length > 1 || tradeArr.length > 1 || query.getAreaArr().contains("530000")) { //时间区间、多地区、多行业为查询汇总数据
            List<QueryCustomReportSummaryVo> result = new ArrayList<>();
            if(StringUtils.isEmpty(query.getStartTime())){
                query.setStartTime(query.getEndTime());
            }
            for(int i=0; i<= Integer.parseInt(query.getEndTime())-Integer.parseInt(query.getStartTime()); i++) {
                //设置查询年份
                query.setYear(Integer.parseInt(query.getStartTime())+i);

                if (areaArr.length > 1 && tradeArr.length > 1) {
                    //选择多地区、多行业，自定义查询能报、监察、在线监测汇总数据
                    for (String trade : tradeArr) { //多行业
                        query.setIndustry(trade);
                        getCustomReportSummaryByArea(page, query, areaArr, result); //多地区
                    }
                } else if (areaArr.length > 1) {
                    //选择多地区，自定义查询能报、监察、在线监测汇总数据
                    if(tradeArr.length==1){ //单行业
                        query.setIndustry(tradeArr[0]);
                    }
                    getCustomReportSummaryByArea(page, query, areaArr, result); //多地区
                } else if (tradeArr.length > 1) {
                    //选择多行业，自定义查询能报、监察、在线监测汇总数据
                    for (String trade : tradeArr) { //多行业
                        query.setIndustry(trade);
                        customReportByArea(query, areaArr, result); //单地区
                    }
                } else {
                    if(tradeArr.length==1){ //单行业
                        query.setIndustry(tradeArr[0]);
                    }
                    customReportByArea(query, areaArr, result); //单地区
                }
            }
            return R.ok(result);
        } else {
            //自定义查询能报、监察、在线监测数据
            if(areaArr.length == 1){
                if (areaArr[0].contains("0000")) { //省
                    query.setPArea(StrUtil.subWithLength(areaArr[0], 0, 2)); //截取前2位
                } else if (areaArr[0].contains("00")) {  //州市
                    query.setPArea(StrUtil.subWithLength(areaArr[0], 0, 4)); //截取前4位
                }else{ //区县
                    query.setPArea(areaArr[0]);
                    query.setArea(areaArr[0]);
                }
            }
            if (tradeArr.length == 1) {
                query.setIndustry(tradeArr[0]);
            }

            Map<String, Object> map = new HashMap<String, Object>();
            IPage<Map<String, Object>> list = tReportService.queryCustomReport(page, query);
            map.put("list",list);

            query.setYear(Integer.parseInt(query.getEndTime()));
            List<QueryCustomReportSummaryVo> summary = tReportService.queryCustomReportSummary(query);
            map.put("summary",summary);
            return R.ok(map);
        }
    }

    //单地区 若地区码为530000，就查询16个地州的数据
    private void customReportByArea(Query query, String[] areaArr, List<QueryCustomReportSummaryVo> result) {
        boolean flag = false; //不是云南
        if (areaArr.length == 1) { //单地区
            //query.setArea(areaArr[0]);
            if (query.getAreaArr().contains("530000")) { //编码为云南，查16个地州
                flag = true; //是云南
                query.setPArea("530000");
            } else {
                setPArea(query, areaArr[0]);
            }
        }
        if (flag) { //是云南
            List<QueryCustomReportSummaryVo> maps = tReportService.queryCustomReportSummaryByAllArea(query);
            if (maps.size() > 0) {
                result.addAll(maps);
            }
        } else {
            List<QueryCustomReportSummaryVo> maps = tReportService.queryCustomReportSummary(query);
            if (maps.size() > 0) {
                result.addAll(maps);
            }
        }
    }

    //设置查询条件的地区编码
    private void setPArea(Query query, String area) {
        query.setPArea(area.replaceAll("0000","").replaceAll("00",""));
    }

    //根据多地区 自定义查询能报、监察、在线监测汇总数据
    private void getCustomReportSummaryByArea(Page page, Query query, String[] areaArr, List<QueryCustomReportSummaryVo> result) {
        for (String area : areaArr) {//地区
            setPArea(query, area);
            query.setArea(area);
            List<QueryCustomReportSummaryVo> maps = tReportService.queryCustomReportSummary( query);
            if (maps.size() > 0) {
                result.addAll(maps);
            }
        }
    }

    @GetMapping("/queryCustomEnterprise")
    @SysLog("自定义查询的企业信息")
    @ApiOperation(value = "自定义查询的企业信息", notes = "自定义查询的企业信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "epc", value = "企业编码", required = false, dataType = "json", paramType = "path"),
            @ApiImplicitParam(name = "year", value = "年份", required = false, dataType = "json", paramType = "path")
    })
    public R queryCustomEnterprise(String epc,String year){
        if(epc==null || "".equals(epc)){
            return R.failed("企业信用编码不能为空！");
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy");
        Date date = new Date();
        String newYear = sdf.format(date);
        //报表设置没有获取企业信息的话，从企业基本信息取出
        return R.ok(tReportEnterpriseService.queryCustomEnterprise(epc,year==null||"".equals(year)?newYear:year));
    }

    /**
     * 信息
     *
     * @param tReportId
     * @return R
     */
    @SysLog("通过ID查询报表-能源报表信息")
    @ApiOperation(value = "通过ID查询报表-能源报表信息", notes = "通过ID查询报表-能源报表信息")
    @ApiImplicitParam(name = "tReportId", value = "报表-能源报表信息id", required = true, paramType = "path", dataType = "int")
    @GetMapping("/{tReportId}")
    public R getById(@PathVariable("tReportId") Integer tReportId) {
        return R.ok(tReportService.getById(tReportId));
    }

    /**
     * 信息
     *
     * @param year,type
     * @return R
     */
    @SysLog("通过ID查询报表-能源报表信息")
    @ApiOperation(value = "通过ID查询报表-能源报表信息", notes = "通过ID查询报表-能源报表信息")
    @ApiImplicitParams(
            {@ApiImplicitParam(name = "year", value = "报表-year", required = true, paramType = "path", dataType = "int"),
                    @ApiImplicitParam(name = "type", value = "报表类型1，2，3，4，5", required = true, paramType = "path", dataType = "int")

            })
    @GetMapping("/queryByYear")
    public R queryByYear(Integer year, String type) {
        TReport r = new TReport();
        r.setYear(year);
        r.setType(type);
        r.setDelFlag("1");
        ScUser u = SecurityUtils.getUser();
        r.setEnterpriseCode(u.getEnterpriseCode());
        return R.ok(tReportService.getOne(Wrappers.query(r)));
    }

    @SysLog("根据企业、年份和报表类型查询能报信息")
    @GetMapping("/queryByYearByCmp")
    public R queryByYearByCmp(Integer year, String type, String enterpriseCode) {
        TReport r = new TReport();
        r.setYear(year);
        r.setType(type);
        r.setDelFlag("1");
        //ScUser u= SecurityUtils.getUser();
        r.setEnterpriseCode(enterpriseCode);
        return R.ok(tReportService.getOne(Wrappers.query(r)));
    }

    /**
     * 保存
     *
     * @param tReport
     * @return R
     */
    @SysLog("保存报表-能源报表信息（企业端）")
    @ApiOperation(value = "保存报表-能源报表信息（企业端）", notes = "新增报表-能源报表信息（企业端）")
    @ApiImplicitParam(name = "tReport", value = "报表-能源报表信息", required = true, dataType = "json", paramType = "path")
    @PostMapping("/save")
    public R save(@RequestBody TReport tReport) {
        ScUser u = SecurityUtils.getUser();
        if (u.getId() != null) {
            tReport.setUserid(u.getId());
        }
        //tReport.setDeptId(u.getDeptId());
        //获取企业信息
        String enterpriseCode = StringUtils.isNotEmpty(tReport.getEnterpriseCode()) ? tReport.getEnterpriseCode() : u.getEnterpriseCode();
        EnterpriseInfo info = enterpriseInfoService.getInfoByCode(enterpriseCode);
        //企业端新增信息，添加deptid
        tReport.setDeptId(info != null && info.getRegionCode()!=null ? Integer.parseInt(info.getRegionCode()) : u.getDeptId());
        tReport.setDelFlag("1");
        tReport.setUpdateTime(new Date());
        return R.ok(tReportService.save(tReport));
    }

    /**
     * 修改
     *
     * @param tReport
     * @return R
     */
    @SysLog("修改报表-能源报表信息信息")
    @ApiOperation(value = "修改报表-能源报表信息信息", notes = "修改报表-能源报表信息信息")
    @ApiImplicitParam(name = "tReport", value = "报表-能源报表信息", required = true, dataType = "json", paramType = "path")
    @PutMapping
    public R updateById(@RequestBody TReport tReport) {
        ScUser u = SecurityUtils.getUser();
        if (u.getId() != null) {
            tReport.setUserid(u.getId());
        }
        tReport.setUpdateTime(new Date());
        return R.ok(tReportService.updateById(tReport));
    }

    /**
     * 删除
     *
     * @param tReportId
     * @return R
     */
    @SysLog("删除报表-能源报表信息")
    @ApiOperation(value = "删除报表-能源报表信息", notes = "删除报表-能源报表信息信息")
    @ApiImplicitParam(name = "tReportId", value = "报表-能源报表信息信息ID", required = true, dataType = "int", paramType = "path")
    @DeleteMapping("/{tReportId}")
    public R removeById(@PathVariable("tReportId") Long tReportId) {
        TReport tReport = tReportService.getById(tReportId);
        ScUser u = SecurityUtils.getUser();
        if (u.getId() != null) {
            tReport.setUserid(u.getId());
        }
        tReport.setDelFlag("4");
        tReport.setUpdateTime(new Date());
        return R.ok(tReportService.updateById(tReport));
    }

    @SysLog("删除报表信息")
    @ApiOperation(value = "删除报表信息", notes = "删除报表信息")
    @ApiImplicitParam(name = "tReport", value = "报表-能源报表信息", required = true, dataType = "json", paramType = "path")
    @PostMapping("/remove")
    public R removeReport(@RequestBody TReport tReport) {
        String type = tReport.getType();
        String tableName = "";
        if("2".equals(type)){
            type = "2,2-1";
            tableName = "表2,表2-1";
        }else if("3".equals(type)){
            type = "3,3-1";
            tableName = "表3,表3-1";
        }else if("全部".equals(type)){
            type = "";
        }else if(StringUtils.isNotEmpty(type)){
            tableName = "表" + type;
        }
        //删除企业报表
        List<TReport> reportList = tReportService.list(new QueryWrapper<>(new TReport())
                .eq("del_flag", "1")
                .eq("enterprise_code", tReport.getEnterpriseCode())
                .eq("year", tReport.getYear())
                .in(StringUtils.isNotEmpty(type), "type", type.split(",")));
        int count = 0;
        if(reportList.size()>0){
            for (TReport report : reportList) {
                report.setDelFlag("4");
                count += tReportService.updateById(report) ? 1 : 0;
            }
            //删除报表对应的波动分析、准确性分析
            ecAbnormalVolatilityService.removeInfoByReport( tableName, tReport);
            epcEnergyAccuracyAnalysisService.removeInfoByReport( tableName, tReport);
        }
        return R.ok(count);
    }

    /**
     * 定时任务，将州市级报表上送至省级
     */
    //@Scheduled(cron = "0/30 * * * * ?") //每20秒执行一次
    //@Scheduled(cron = "0 0 0 10/1 3,4 ?") //3月至4月，每月的10号开始，一天执行一次
    //@Scheduled(cron = "0 0 1 1 4 ? ") //每年的4月1日 1时0分0秒执行
    @ApiOperation(value = "定时任务，将州市级报表上送至省级", notes = "定时任务，将州市级报表上送至省级")
    public void province() {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String date = df.format(new Date());
        log.info(date+"：定时任务执行了，开始将州市级报表上送至省级...");
        //地区未审核报表记录
        tReportService.noProvStatusLog();
        //定时将 滞留在州市级的报表上送至省级
        int i = tReportService.upProvStatus(date);
        log.info(date+"：定时任务结束了，成功将 "+ i +" 张州市级报表上送至省级！");
    }

    @SysLog("获取报告退回原因")
    @GetMapping("/returnDetail")
    @ApiOperation(value = "获取报告退回原因", notes = "获取报告退回原因")
    public R returnDetail(String epc, String year){
        return R.ok(tReportService.getReturnDetail(epc,year));
    }

    @GetMapping("/getEnergyData")
    @ResponseBody
    @SysLog("重点用能附表（1-3）")
    @ApiOperation(value = "重点用能附表（1-3）", notes = "重点用能附表（1-3）")
    public R getEnergyData(HttpServletResponse response) throws IOException {

        try {
            List<EnergyInfoVo> excelData = tReportService.getEnergyData();
            writeExcel(response, excelData);
        } catch (Exception e) {
            System.out.println(e);
        }
        return null;
    }

    @GetMapping("/renewRegion")
    @SysLog("能报-更新企业所属地区")
    public R renewReportRegion(String enterpriseCode, String regionCode) {
        if(StringUtils.isEmpty(enterpriseCode) || StringUtils.isEmpty(regionCode)){
            return R.failed("企业编码与地区编码不能为空！");
        }
        tReportService.renewReportRegion(enterpriseCode,regionCode);
        return R.ok("更新成功！");
    }


    private void writeExcel(HttpServletResponse response,List<EnergyInfoVo> data1) throws InvalidPortException, InvalidEndpointException, IOException, InvalidKeyException, NoSuchAlgorithmException, InsufficientDataException, InvalidArgumentException, InternalException, NoResponseException, InvalidBucketNameException, XmlPullParserException, ErrorResponseException {
        InputStream is = minioTemplate.getObject("jljc", "重点用能附表（1-3）.xlsx");
        XSSFWorkbook xSSFWorkbook = null;
        XSSFSheet xSSFSheet = null;

        //组装合并单元格数据
        List<Integer> list1 = new ArrayList<Integer>();
        int pos = 0;
        for (int i = 0; i < data1.size(); i++) {
            if (i == 0) {
                list1.add(1);
                pos = 0;
            } else {
                if (Objects.equals(data1.get(i).getId(),data1.get(i-1).getId())) {
                    list1.set(pos,list1.get(pos) + 1);
                    list1.add(0);
                } else {
                    // 不相等push 1
                    list1.add(1);
                    pos = i;
                }
            }
        }
        try {
            xSSFWorkbook = new XSSFWorkbook(is);
            xSSFSheet = xSSFWorkbook.getSheetAt(0);

        } catch (Exception e1) {
            e1.printStackTrace();
        }

        if (xSSFSheet != null) {
            try {
                //写数据
                XSSFFont font = xSSFWorkbook.createFont();
                CellStyle style = xSSFWorkbook.createCellStyle();
                font.setFontName("方正仿宋_GBK");
                style.setFont(font);
                style.setWrapText(true);//自動換行
                style.setVerticalAlignment(style.getVerticalAlignmentEnum().CENTER);//设置居中
                style.setAlignment(HorizontalAlignment.CENTER);
                style.setBorderBottom(BorderStyle.THIN);//边框
                style.setBorderLeft(BorderStyle.THIN);
                style.setBorderRight(BorderStyle.THIN);
                style.setBorderTop(BorderStyle.THIN);
                
                //构建每行的数据内容
                int rowNum = 5;
                for (EnergyInfoVo data : data1) {
                    if (data == null) {
                        continue;
                    }
                    //输出行数据
                    Row row = xSSFSheet.createRow(rowNum++);

                    if (list1.get(rowNum-6)>1 && rowNum<=data1.size()+5){
                        int a = (rowNum+list1.get(rowNum-6))-2;
                        for(int t=0; t<=12; t++){
                            xSSFSheet.addMergedRegion(new CellRangeAddress(rowNum-1, a, t, t));
                        }
                    }

                    int cellNum = 0;
                    Cell cell;
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getId() ? "" : data.getId().toString());
                    cell.setCellStyle(style);
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getCmpName() ? "" : data.getCmpName());
                    cell.setCellStyle(style);
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getEnterpriseCode() ? "" : data.getEnterpriseCode());
                    cell.setCellStyle(style);
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getName() ? "" : data.getName());
                    cell.setCellStyle(style);
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getTrade() ? "" : data.getTrade());
                    cell.setCellStyle(style);
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getArea() ? "" : data.getArea());
                    cell.setCellStyle(style);
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getTcdDl() ? "" : data.getTcdDl());
                    cell.setCellStyle(style);
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getTcdDj() ? "" : data.getTcdDj());
                    cell.setCellStyle(style);
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getEle() ? "" : data.getEle());
                    cell.setCellStyle(style);
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getCoal() ? "" : data.getCoal());
                    cell.setCellStyle(style);
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getYieldDn() ? "" : data.getYieldDn());
                    cell.setCellStyle(style);
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getYieldJq() ? "" : data.getYieldJq());
                    cell.setCellStyle(style);
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getYieldIn() ? "" : data.getYieldIn());
                    cell.setCellStyle(style);
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getProductName() ? "" : data.getProductName());
                    cell.setCellStyle(style);
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getCapacity() ? "" : data.getCapacity());
                    cell.setCellStyle(style);
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getYield() ? "" : data.getYield());
                    cell.setCellStyle(style);
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getEnergy() ? "" : data.getEnergy());
                    cell.setCellStyle(style);
                    cell = row.createCell(cellNum++);
                    cell.setCellValue(null == data.getUnitEnergy() ? "" : data.getUnitEnergy());
                }

                OutputStream output = response.getOutputStream(); // 读取的文件路径
                response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode("重点用能附表（1-3）.xlsx", "UTF-8"));
                response.setCharacterEncoding("UTF-8");
                response.setContentType("charset=GBK");
                xSSFWorkbook.write(output);
                output.close();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (null != is) {
                        is.close();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }


}
