package com.jeeplus.finance.projectReport.controller;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.jeeplus.common.TokenProvider;
import com.jeeplus.common.excel.ExcelOptions;
import com.jeeplus.common.excel.annotation.ExportMode;
import com.jeeplus.common.redis.RedisUtils;
import com.jeeplus.common.utils.ResponseUtil;
import com.jeeplus.finance.invoice.util.EasyPoiUtil;
import com.jeeplus.finance.invoice.util.FreemarkerUtil;
import com.jeeplus.finance.invoice.util.SignaturePostUtil;
import com.jeeplus.finance.projectDict.domain.vo.FileDictVo;
import com.jeeplus.finance.projectDict.service.ProjectDictService;
import com.jeeplus.finance.projectDict.service.dto.ProjectDictDto;
import com.jeeplus.finance.projectRecords.domain.CwProjectRecords;
import com.jeeplus.finance.projectRecords.service.CwProjectRecordsService;
import com.jeeplus.finance.projectReport.domain.*;
import com.jeeplus.finance.projectReport.mapper.CwSignatureAnnotatorMapper;
import com.jeeplus.finance.projectReport.mapper.ProjectReportWorkAttachmentMapper;
import com.jeeplus.finance.projectReport.service.CwProjectReportService;
import com.jeeplus.finance.projectReport.service.dto.CwProjectReportDTO;
import com.jeeplus.finance.projectReport.service.dto.CwProjectReportSignatureDTO;
import com.jeeplus.finance.projectReport.service.dto.ProjectContactInfo;
import com.jeeplus.finance.projectReport.service.dto.ProjectReportInfo;
import com.jeeplus.finance.workClientInfo.service.dto.CwWorkClientBaseDTO;
import com.jeeplus.flowable.feign.IFlowableApi;
import com.jeeplus.logging.annotation.ApiLog;
import com.jeeplus.logging.constant.enums.LogTypeEnum;
//import com.jeeplus.pubmodules.oss.domain.WorkAttachment;
import com.jeeplus.sys.domain.WorkAttachmentInfo;
import com.jeeplus.sys.feign.IDictApi;
import com.jeeplus.sys.feign.IUserApi;
import com.jeeplus.sys.feign.IWorkAttachmentApi;
import com.jeeplus.sys.service.dto.UserDTO;
//import com.jeeplus.sys.utils.DictUtils;
//import com.jeeplus.sys.utils.UserUtils;
import freemarker.template.Configuration;
import freemarker.template.Template;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.Period;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author: 王强
 * @create: 2022-11-16 14:15
 **/
@RestController
@Api("财务报告信息")
@RequestMapping(value = "/cwProjectReport")
public class CwProjectReportController {

    @Resource
    private CwProjectReportService projectReportService;
    @Autowired
    private RedisUtils redisUtils;
    @Resource
    private ProjectReportWorkAttachmentMapper attachmentMapper;
    @Autowired
    private IFlowableApi flowTaskService;

    @Resource
    private ProjectDictService projectDictService;
    @Resource
    private CwProjectRecordsService projectRecordsService;

    @ApiLog(value = "归档信息导出")
    @GetMapping("archivedInfoExport")
    @ApiOperation(value = "归档信息导出")
    public void archivedInfoExport(CwProjectReportData reportData,ExcelOptions options, HttpServletResponse response) throws Exception {
        String fileName = options.getFilename();
        String sheetName = options.getSheetName();
        List<ArchivedReportInfo> exportFileDtos = projectReportService.archivedInfoExport(reportData);
        EasyPoiUtil.exportExcel ( exportFileDtos, fileName,  sheetName, ArchivedReportInfo.class, fileName, response );

    }

    /**
     * 保存财务报告信息-流程
     * @param reportData
     * @return
     */
    @ApiLog(value = "保存财务报告信息-流程", type = LogTypeEnum.SAVE)
    //@PreAuthorize("hasAnyAuthority('cwProjectReport:add','cwProjectReport:edit')")
    @PostMapping("saveForm")
    public ResponseEntity saveForm(@Valid @RequestBody CwProjectReportData reportData) throws Exception {
        String id = projectReportService.saveForm(reportData);
        return ResponseUtil.newInstance().add("businessTable", "cw_project_report").add("businessId", id).ok ("操作成功");
    }


    /**
     * 报告号申请所用
     * 保存财务报告信息-流程
     * @param reportData
     * @return
     */
    @ApiLog(value = "保存财务报告信息-流程", type = LogTypeEnum.SAVE)
    //@PreAuthorize("hasAnyAuthority('cwProjectReport:add','cwProjectReport:edit')")
    @PostMapping("saveForm2")
    public ResponseEntity saveForm2(@Valid @RequestBody CwProjectReportData reportData) throws Exception {
        String id = projectReportService.saveForm2(reportData);
        return ResponseUtil.newInstance().add("businessTable", "cw_project_report").add("businessId", id).ok ("操作成功");
    }

    /**
     * 签章附件保存
     * @return
     */
    @ApiLog(value = "签章附件保存", type = LogTypeEnum.SAVE)
    @PostMapping("saveSignFiles")
    public ResponseEntity saveSignFiles(@RequestBody CwProjectReportData reportData) {
        System.out.println("进入controller前");
        UserDTO userDTO = SpringUtil.getBean ( IUserApi.class ).getByToken(TokenProvider.getCurrentToken());
//        UserDTO userDTO = new UserDTO();
        if (CollectionUtil.isEmpty(reportData.getCwFileInfoList())) {
            reportData.setCwFileInfoList(new ArrayList<>());
        }
        System.out.println("进入controller中");
        projectReportService.updateSignatureFiles(reportData.getCwFileInfoList(),userDTO,reportData.getId());
        System.out.println("进入controller后");
        return ResponseEntity.ok("操作成功");
    }

    /**
     * 将复核超期的数据状态改为超期未复核
     * @return
     */
    @ApiLog("将复核超期的数据状态改为超期未复核")
    @GetMapping("updateQualityOverdueStatus")
    public void updateQualityOverdueStatus() throws Exception {
        projectReportService.updateQualityOverdueStatus();
    }

    /**
     * 将在线归档超期的数据状态改为超期未归档
     * @return
     */
    @ApiLog("将在线归档超期的数据状态改为超期未归档")
    @GetMapping("updateOnlineArchiveStatus")
    public void updateOnlineArchiveStatus() throws Exception {
        projectReportService.updateOnlineArchiveStatus();
    }

    /**
     * 将纸质归档超期的数据状态改为超期未归档
     * @return
     */
    @ApiLog("将纸质归档超期的数据状态改为超期未归档")
    @GetMapping("updatePaperArchiveStatus")
    public void updatePaperArchiveStatus() throws Exception {
        projectReportService.updatePaperArchiveStatus();
    }

    /**
     * 查询财务项目信息列表
     * @param projectReportData
     * @param page
     * @return
     */
    @ApiLog("查询财务报告信息列表")
    //@PreAuthorize("hasAuthority('cwProjectReport:list')")
    @GetMapping("list")
    public ResponseEntity<IPage<CwProjectReportData>> data(CwProjectReportData projectReportData, Page<CwProjectReportData> page) throws Exception {
        IPage<CwProjectReportData> result = new Page<CwProjectReportData>();
        result = projectReportService.findList (page,projectReportData);
        result.getRecords().stream().forEach(i -> {

            //当项目经理是跨租户的人员时，则特殊处理
            if (StringUtils.isBlank(i.getProjectMasterName())){
                //根据项目经理id去人员表重查数据
                if (StringUtils.isNotBlank(i.getProjectMasterId())){
                    UserDTO byId = SpringUtil.getBean(IUserApi.class).getById(i.getProjectMasterId());
                    if(null != byId)
                    i.setProjectMasterName(byId.getName());
                }
            }
            if (StringUtils.isBlank(i.getRealHeaderName())){
                //根据项目经理id去人员表重查数据
                if (StringUtils.isNotBlank(i.getProjectMasterId2())){
                    UserDTO byId = SpringUtil.getBean(IUserApi.class).getById(i.getProjectMasterId2());
                    if(null != byId)
                    i.setRealHeaderName(byId.getName());
                }

            }

            // 复核
            if (StringUtils.isNotBlank(i.getRevTaskId()) && StringUtils.isNotBlank(i.getReviewStatus())) {
                if ("2".equals(i.getReviewStatus())) { // “审核中”的数据要获取数据审核人
                    i.setAuditUserIdsRev(flowTaskService.getTaskAuditUsers(i.getRevTaskId()));  // 获取数据审核人
                }
            }

            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            //在线归档超期天数显示调整  纸质归档超期天数显示

            if (StringUtils.isNotBlank(i.getProjectLevel())) {
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

                // 对日期进行空值检查并解析  Optional 对null情况操作
                Optional<LocalDate> startDateOptional = Optional.ofNullable(i.getIssueCompleteTime()).map(date -> LocalDate.parse(format.format(date), formatter));
                Optional<LocalDate> startDate2Optional = Optional.ofNullable(i.getCheckCompleteTime()).map(date -> LocalDate.parse(format.format(date), formatter));

                if (startDateOptional.isPresent() && startDate2Optional.isPresent()) {
                    LocalDate startDate = startDateOptional.get();
                    LocalDate startDate2 = startDate2Optional.get();
                    LocalDate currentDate = LocalDate.now();

                    // 计算日期差
                    Period period = Period.between(startDate, currentDate);
                    Period period2 = Period.between(startDate2, currentDate);

                    // 获取天数差
                    int days = period.getDays();
                    int days2 = period2.getDays();

                    //A级
                    if (i.getProjectLevel().equals("1")) {
                        //计算规则：在线-报告签发审核完成40天后设置为超期。 纸质-报告签发审核完成40天后设置为超期

                        //判断是否超期(流程未开始即流程状态为null)
                        if (days > 40 && null == i.getOnlineArchivingStatus()) {
                            i.setOnlineOverdueDates(days - 40);
                        }
                        if (days2 > 40 && null == i.getPaperArchivingStatus()) {
                            i.setPaperOverdueDates(days2 - 40);
                        }

                    } else if (i.getProjectLevel().equals("2")) {
                        //计算规则：在线-质量复核审核完成40天后设置为超期。 纸质-质量复核审核完成90天后设置为超期
                        if (days > 40 && null == i.getOnlineArchivingStatus()) {
                            i.setOnlineOverdueDates(days - 40);
                        }
                        if (days2 > 90 && null == i.getPaperArchivingStatus()) {
                            i.setPaperOverdueDates(days2 - 90);
                        }
                    }
                }
            }
        });
        return ResponseEntity.ok (result);
    }

    /**
     * 查询财务项目信息列表
     * @param projectReportData
     * @param page
     * @return
     */
    @ApiLog("查询财务报告信息列表")
    @PreAuthorize("hasAuthority('cwProjectReport:list')")
    @GetMapping("list2")
    public ResponseEntity<IPage<CwProjectReportData>> data2(CwProjectReportData projectReportData, Page<CwProjectReportData> page) throws Exception {
        IPage<CwProjectReportData> result = new Page<CwProjectReportData>();
        result = projectReportService.findList2 (page,projectReportData);
        result.getRecords().stream().forEach(i -> {

            //当项目经理是跨租户的人员时，则特殊处理
            if (StringUtils.isBlank(i.getProjectMasterName())){
                //根据项目经理id去人员表重查数据
                if (StringUtils.isNotBlank(i.getProjectMasterId())){
                    UserDTO byId = SpringUtil.getBean(IUserApi.class).getById(i.getProjectMasterId());
                    if(null != byId)
                        i.setProjectMasterName(byId.getName());
                }
            }
            if (StringUtils.isBlank(i.getRealHeaderName())){
                //根据项目经理id去人员表重查数据
                if (StringUtils.isNotBlank(i.getProjectMasterId2())){
                    UserDTO byId = SpringUtil.getBean(IUserApi.class).getById(i.getProjectMasterId2());
                    if(null != byId)
                        i.setRealHeaderName(byId.getName());
                }

            }

            // 复核
            if (StringUtils.isNotBlank(i.getRevTaskId()) && StringUtils.isNotBlank(i.getReviewStatus())) {
                if ("2".equals(i.getReviewStatus())) { // “审核中”的数据要获取数据审核人
                    i.setAuditUserIdsRev(flowTaskService.getTaskAuditUsers(i.getRevTaskId()));  // 获取数据审核人
                }
            }

            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            //在线归档超期天数显示调整  纸质归档超期天数显示

            if (StringUtils.isNotBlank(i.getProjectLevel())) {
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

                // 对日期进行空值检查并解析  Optional 对null情况操作
                Optional<LocalDate> startDateOptional = Optional.ofNullable(i.getIssueCompleteTime()).map(date -> LocalDate.parse(format.format(date), formatter));
                Optional<LocalDate> startDate2Optional = Optional.ofNullable(i.getCheckCompleteTime()).map(date -> LocalDate.parse(format.format(date), formatter));

                if (startDateOptional.isPresent() && startDate2Optional.isPresent()) {
                    LocalDate startDate = startDateOptional.get();
                    LocalDate startDate2 = startDate2Optional.get();
                    LocalDate currentDate = LocalDate.now();

                    // 计算日期差
                    Period period = Period.between(startDate, currentDate);
                    Period period2 = Period.between(startDate2, currentDate);

                    // 获取天数差
                    int days = period.getDays();
                    int days2 = period2.getDays();

                    //A级
                    if (i.getProjectLevel().equals("1")) {
                        //计算规则：在线-报告签发审核完成40天后设置为超期。 纸质-报告签发审核完成40天后设置为超期

                        //判断是否超期(流程未开始即流程状态为null)
                        if (days > 40 && null == i.getOnlineArchivingStatus()) {
                            i.setOnlineOverdueDates(days - 40);
                        }
                        if (days2 > 40 && null == i.getPaperArchivingStatus()) {
                            i.setPaperOverdueDates(days2 - 40);
                        }

                    } else if (i.getProjectLevel().equals("2")) {
                        //计算规则：在线-质量复核审核完成40天后设置为超期。 纸质-质量复核审核完成90天后设置为超期
                        if (days > 40 && null == i.getOnlineArchivingStatus()) {
                            i.setOnlineOverdueDates(days - 40);
                        }
                        if (days2 > 90 && null == i.getPaperArchivingStatus()) {
                            i.setPaperOverdueDates(days2 - 90);
                        }
                    }
                }
            }
        });
        return ResponseEntity.ok (result);
    }

    /**
     * 获取咨询营业收入(万元)的总和
     * @return
     */
    @ApiLog("获取咨询营业收入(万元)的总和")
    @GetMapping("getTotal")
    public ResponseEntity getTotal() {
        String total = projectReportService.getTotal (  );
        return ResponseEntity.ok (total);
    }

    /**
     * 查询财务项目信息列表
     * @param projectReportData
     * @param page
     * @return
     */
    @ApiLog("查询财务报告信息列表")
    @PreAuthorize("hasAuthority('cwProjectReport:list')")
    @GetMapping("list3")
    public ResponseEntity<IPage<CwProjectReportData>> data3(CwProjectReportData projectReportData, Page<CwProjectReportData> page) throws Exception {
        IPage<CwProjectReportData> result = new Page<CwProjectReportData>();
        result = projectReportService.findList3 (page,projectReportData);
        result.getRecords().stream().forEach(i -> {

            //当项目经理是跨租户的人员时，则特殊处理
            if (StringUtils.isBlank(i.getProjectMasterName())){
                //根据项目经理id去人员表重查数据
                if (StringUtils.isNotBlank(i.getProjectMasterId())){
                    UserDTO byId = SpringUtil.getBean(IUserApi.class).getById(i.getProjectMasterId());
                    if(null != byId)
                        i.setProjectMasterName(byId.getName());
                }
            }
            if (StringUtils.isBlank(i.getRealHeaderName())){
                //根据项目经理id去人员表重查数据
                if (StringUtils.isNotBlank(i.getProjectMasterId2())){
                    UserDTO byId = SpringUtil.getBean(IUserApi.class).getById(i.getProjectMasterId2());
                    if(null != byId)
                        i.setRealHeaderName(byId.getName());
                }

            }

            // 复核
            if (StringUtils.isNotBlank(i.getRevTaskId()) && StringUtils.isNotBlank(i.getReviewStatus())) {
                if ("2".equals(i.getReviewStatus())) { // “审核中”的数据要获取数据审核人
                    i.setAuditUserIdsRev(flowTaskService.getTaskAuditUsers(i.getRevTaskId()));  // 获取数据审核人
                }
            }

            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
            //在线归档超期天数显示调整  纸质归档超期天数显示

            if (StringUtils.isNotBlank(i.getProjectLevel())) {
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");

                // 对日期进行空值检查并解析  Optional 对null情况操作
                Optional<LocalDate> startDateOptional = Optional.ofNullable(i.getIssueCompleteTime()).map(date -> LocalDate.parse(format.format(date), formatter));
                Optional<LocalDate> startDate2Optional = Optional.ofNullable(i.getCheckCompleteTime()).map(date -> LocalDate.parse(format.format(date), formatter));

                if (startDateOptional.isPresent() && startDate2Optional.isPresent()) {
                    LocalDate startDate = startDateOptional.get();
                    LocalDate startDate2 = startDate2Optional.get();
                    LocalDate currentDate = LocalDate.now();

                    // 计算日期差
                    Period period = Period.between(startDate, currentDate);
                    Period period2 = Period.between(startDate2, currentDate);

                    // 获取天数差
                    int days = period.getDays();
                    int days2 = period2.getDays();

                    //A级
                    if (i.getProjectLevel().equals("1")) {
                        //计算规则：在线-报告签发审核完成40天后设置为超期。 纸质-报告签发审核完成40天后设置为超期

                        //判断是否超期(流程未开始即流程状态为null)
                        if (days > 40 && null == i.getOnlineArchivingStatus()) {
                            i.setOnlineOverdueDates(days - 40);
                        }
                        if (days2 > 40 && null == i.getPaperArchivingStatus()) {
                            i.setPaperOverdueDates(days2 - 40);
                        }

                    } else if (i.getProjectLevel().equals("2")) {
                        //计算规则：在线-质量复核审核完成40天后设置为超期。 纸质-质量复核审核完成90天后设置为超期
                        if (days > 40 && null == i.getOnlineArchivingStatus()) {
                            i.setOnlineOverdueDates(days - 40);
                        }
                        if (days2 > 90 && null == i.getPaperArchivingStatus()) {
                            i.setPaperOverdueDates(days2 - 90);
                        }
                    }
                }
            }
        });
        return ResponseEntity.ok (result);
    }
    /**
     * 根据id修改状态值status
     * @param data
     * @return
     */
    @ApiOperation(value = "根据id修改状态值status")
    @PostMapping(value = "/updateStatusById")
    public ResponseEntity<String> updateStatusById(@RequestBody CwProjectReportData data) {
        String s = projectReportService.updateStatusById(data);
        return ResponseEntity.ok(s);
    }

    /**
     * 查询客户信息数据
     * @param id
     * @return
     */
    @ApiLog("查询财务报告数据")
    // @PreAuthorize ("hasAnyAuthority('cwProjectReport:view','cwProjectReport:add','cwProjectReport:edit')")
    @GetMapping("queryById")
    public ResponseEntity queryById(@RequestParam("id") String id) {
        CwProjectReportData projectReportData = projectReportService.queryById ( id );
        return ResponseEntity.ok (projectReportData);
    }

    /**
     * 查询客户信息数据
     * @param id
     * @return
     */
    @ApiLog("查询财务报告数据")
    // @PreAuthorize ("hasAnyAuthority('cwProjectReport:view','cwProjectReport:add','cwProjectReport:edit')")
    @GetMapping("queryByIdNew")
    public ResponseEntity queryByIdNew(@RequestParam("id") String id) {
        CwProjectReportData projectReportData = projectReportService.queryByIdNew ( id );
        //查询委托方联系人信息
        if (null != projectReportData) {
            List<ProjectContactInfo> contactInfos = projectReportService.getContactInfos(projectReportData.getProjectId());
            projectReportData.setContactInfos(contactInfos);
            projectReportData.setConstructionParty(contactInfos);
            //查询项目报告信息
            List<ProjectReportInfo> projectReportInfos = projectReportService.getProjectReportInfo(id);
            projectReportData.setProjectReportInfos(projectReportInfos);
        }

        return ResponseEntity.ok (projectReportData);
    }

    /**
     * 根据报告签发id查询信息
     * @param id
     * @return
     */
    @ApiLog("根据报告签发id查询信息")
    // @PreAuthorize ("hasAnyAuthority('cwProjectReport:view','cwProjectReport:add','cwProjectReport:edit')")
    @GetMapping("queryBySignAndIssueId")
    public ResponseEntity queryBySignAndIssueId(@RequestParam("id") String id) {
        CwProjectReportData projectReportData = projectReportService.queryBySignAndIssueId ( id );
        return ResponseEntity.ok (projectReportData);
    }

    /**
     * 根据在线归档id查询信息
     * @param id
     * @return
     */
    @ApiLog("根据在线归档id查询信息")
    @GetMapping("queryByOnlineArchivingId")
    public ResponseEntity queryByOnlineArchivingId(@RequestParam("id") String id) {
        CwProjectReportData projectReportData = projectReportService.queryByOnlineArchivingId ( id );
        return ResponseEntity.ok (projectReportData);
    }

    /**
     * 根据纸质归档id查询信息
     * @param id
     * @return
     */
    @ApiLog("根据纸质归档id查询信息")
    @GetMapping("queryByPaperArchivingId")
    public ResponseEntity queryByPaperArchivingId(@RequestParam("id") String id) {
        CwProjectReportData projectReportData = projectReportService.queryByPaperArchivingId ( id );
        return ResponseEntity.ok (projectReportData);
    }

    /**
     * 根据项目id查询外审附件信息
     * @param projectId  项目id
     * @param id  当前阶段的id
     * @return
     */
    @ApiOperation(value = "根据项目id查询外审附件信息")
    @GetMapping(value = "/getAttachmentList")
    public ResponseEntity<List<FileDictVo>> getAttachmentList(@RequestParam String projectId, @RequestParam String id,@RequestParam String type){
        //根据项目id查询项目信息
        CwProjectRecords project = projectRecordsService.getById(projectId);
        ProjectDictDto projectDictDto = new ProjectDictDto();
        List<String> sortList = Lists.newArrayList();
        sortList.add("11");
        sortList.add("12");
        sortList.add("13");
        if(StringUtils.isNotBlank(project.getProjectType())){
            projectDictDto.setAttachmentProjectType(project.getProjectType());
        }
//        projectDictDto.setAttachmentProjectType("2");

        projectDictDto.setProjectLevel(project.getProjectLevel());
        projectDictDto.setAttachmentProjectSort(project.getReportType());
        projectDictDto.setSortList(sortList);
        List<FileDictVo> list = projectDictService.getFileDictList(projectDictDto,projectId,id,type);
        return ResponseEntity.ok(list);
    }
    /**
     * 查询客户信息数据  报告号申请流程所用
     * @param id
     * @return
     */
    @ApiLog("查询财务报告数据")
    // @PreAuthorize ("hasAnyAuthority('cwProjectReport:view','cwProjectReport:add','cwProjectReport:edit')")
    @GetMapping("queryById2")
    public ResponseEntity queryById2(@RequestParam("id") String id) {
        CwProjectReportData projectReportData = projectReportService.queryById2 ( id );
        return ResponseEntity.ok (projectReportData);
    }

    /**
     * 下载报告审核单
     * @param response
     * @param id
     */
    @RequestMapping(value="downloadCwReportAuditTpl")
    @ResponseBody
    public void downloadCwReportAuditTpl(HttpServletResponse response,@RequestParam("id") String id)  {
        Map data = projectReportService.getAuditInfoMap(response, id );

        //模板对象
        Template template=null;
        //下载文件地址
        String filePath = null;
        if(System.getProperty("os.name").toLowerCase().contains("win")){
            filePath = this.getClass().getResource("/").getPath()+"/freemarker";
        }else{
            filePath = "/mnt/project/cloud/freemarker";
        }
        //freemaker模板路径
        File path = new File(filePath);
        Configuration cfg = new Configuration();
        try {
            cfg.setDirectoryForTemplateLoading(path);
            //选择对应的ftl文件
            template = cfg.getTemplate("cwAudit.ftl","UTF-8");

            File docFile = new File("报告审核单.xls");
            FreemarkerUtil.generateFile(data,template,docFile);
            com.jeeplus.finance.invoice.util.ResponseUtil.docResponse("报告审核单.xls",docFile,response);
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if(System.getProperty("os.name").toLowerCase().contains("win")){
                //获取tomcat的路径
                String tomcatFilePath=System.getProperty("catalina.home");
                //删除tomcat目录下的处理后的文件信息
                File tomcatFile = new File(tomcatFilePath+"/bin/"+"报告审核单.xls");
                if (tomcatFile.isFile()) {
                    tomcatFile.delete();
                }
            }else{
                //删除目录下的处理后的文件信息
                File tomcatFile = new File("/mnt/project/cloud/"+"报告审核单.xls");
                if (tomcatFile.isFile()) {
                    tomcatFile.delete();
                }
            }
        }

    }

    /**
     * 删除业务提问
     * @param ids
     * @return
     */
    @ApiLog(value = "删除财务报告信息", type = LogTypeEnum.SAVE)
    @PreAuthorize ("hasAuthority('cwProjectReport:del')")
    @DeleteMapping("delete")
    public ResponseEntity delete(String ids,String projectId) {
        return projectReportService.deleteByIds(ids, projectId);
    }

    /**
     * 查询客户信息列表
     * @param cwWorkClientBaseDTO
     * @param page
     * @return
     * @throws Exception
     */
    @ApiLog("查询客户信息列表")
    @PreAuthorize("hasAuthority('cwProjectReport:clineList')")
    @GetMapping("clineList")
    public ResponseEntity<IPage<CwWorkClientBaseDTO>> data(CwWorkClientBaseDTO cwWorkClientBaseDTO, Page<CwWorkClientBaseDTO> page, String projectId) throws Exception {
        IPage<CwWorkClientBaseDTO> result = new Page<CwWorkClientBaseDTO>();
        result = projectReportService.findClineList (page,cwWorkClientBaseDTO,projectId);
        return ResponseEntity.ok (result);
    }

    /**
     * 签章链接
     * @param cwProjectReportData
     * @return
     */
    @ApiLog(value = "签章链接", type = LogTypeEnum.SAVE)
    @PostMapping("saveFlowableParam")
    public ResponseEntity<String> saveFlowableParam(@Valid @RequestBody CwProjectReportData cwProjectReportData) {
        //查询报告文件信息（电子章）
//        List<WorkAttachment> fileList = attachmentMapper.selectWorkAttachmentByReportId(cwProjectReportData.getId());
        // 有电子章的附件时，走签章流程
//        if (CollectionUtil.isNotEmpty(fileList)) {
//            CwProjectReportData cwProjectReportDto = projectReportService.queryById(cwProjectReportData.getId());
//            // 获取签章页面url
//            String mobile = UserUtils.getCurrentUserDTO().getMobile();
//            String signatureContractUrl = SignaturePostUtil.getSignatureContractUrl(cwProjectReportDto.getSignatureContractId(), mobile);
//            // 将数据存储到redis中，key为contractId
//            cwProjectReportData.getCommitParamDTO().setVars(cwProjectReportDto);
//            redisUtils.set("cw_report_signature_" + cwProjectReportDto.getSignatureContractId(),cwProjectReportData.getCommitParamDTO());
//            redisUtils.expire("cw_report_signature_" + cwProjectReportDto.getSignatureContractId(),24, TimeUnit.HOURS);
//            return ResponseEntity.ok(signatureContractUrl);
//        } else {
//            // 没有电子章的附件时，走正常审核流程
//            // 流程审核通过
//            projectReportService.commitFlowable(cwProjectReportData);
//            return ResponseEntity.ok("操作成功");
//        }

        CwProjectReportData cwProjectReportDto = projectReportService.queryById(cwProjectReportData.getId());
        // 获取签章页面url
        String mobile = SpringUtil.getBean ( IUserApi.class ).getByToken(TokenProvider.getCurrentToken()).getMobile();
        String signatureContractUrl = SignaturePostUtil.getSignatureContractUrl(cwProjectReportDto.getSignatureContractId(), mobile);
        // 将数据存储到redis中，key为contractId
        if("1".equals(cwProjectReportDto.getSignatureType())) {
            redisUtils.set("cw_report_signature_" + cwProjectReportDto.getSignatureContractId(),cwProjectReportDto.getSid1());
        }
        if("2".equals(cwProjectReportDto.getSignatureType())) {
            redisUtils.set("cw_report_signature_" + cwProjectReportDto.getSignatureContractId(),cwProjectReportDto.getSid2());
        }
        redisUtils.expire("cw_report_signature_" + cwProjectReportDto.getSignatureContractId(),24, TimeUnit.HOURS);
        return ResponseEntity.ok(signatureContractUrl);
    }

    /**
     * 签章流程送审
     * @param cwProjectReportData
     * @return
     */
    @ApiLog(value = "签章流程送审", type = LogTypeEnum.SAVE)
    @PostMapping("saveData")
    @Transactional(rollbackFor = Exception.class)
    public ResponseEntity<String> saveData(@Valid @RequestBody CwProjectReportData cwProjectReportData) {
        // 修改报告表的 “签字注师1” 和 “签字注师2”
        if (ObjectUtil.isNotEmpty(cwProjectReportData)) {
            CwProjectReport cwProjectReport = new CwProjectReport();
            cwProjectReport.setId(cwProjectReportData.getId());
            if (StringUtils.isNotBlank(cwProjectReportData.getSignatureAnnotator1())) {
                cwProjectReport.setSignatureAnnotator1(cwProjectReportData.getSignatureAnnotator1());
            }
            if (StringUtils.isNotBlank(cwProjectReportData.getSignatureAnnotator2())) {
                cwProjectReport.setSignatureAnnotator2(cwProjectReportData.getSignatureAnnotator2());
            }
            if (StringUtils.isNotBlank(cwProjectReportData.getIndustry())) {
                cwProjectReport.setIndustry(cwProjectReportData.getIndustry());
            }
            if (StringUtils.isNotBlank(cwProjectReportData.getBusinessObjects())) {
                cwProjectReport.setBusinessObjects(cwProjectReportData.getBusinessObjects());
            }
            projectReportService.updateAnnotatorById(cwProjectReport);
        }
        if ("3".equals(cwProjectReportData.getSignatureType())) {
            // 实体公章流程
            String signatureId = projectReportService.getSignature(cwProjectReportData);
            return ResponseUtil.newInstance().add("businessTable", "cw_project_report_signature").add("businessId", signatureId).ok ("操作成功");
        } else {
            //查询报告文件信息（电子章）
            //List<WorkAttachment> fileList = attachmentMapper.selectWorkAttachmentByReportId(cwProjectReportData.getId());
            List<WorkAttachmentInfo> fileList = SpringUtil.getBean ( IWorkAttachmentApi.class ).selectWorkAttachmentByAttachmentId(cwProjectReportData.getId());
            if (CollectionUtil.isNotEmpty(fileList)) {
                // 有电子章的附件时，走签章流程
                Map<String, Object> signatureContractId = projectReportService.createSignatureContractId(cwProjectReportData);
                boolean bool = (boolean)signatureContractId.get("success");
                if (bool) {
                    String signatureId = projectReportService.getSignature(cwProjectReportData);
                    return ResponseUtil.newInstance().add("businessTable", "cw_project_report_signature").add("businessId", signatureId).ok ("操作成功");
                }
                return ResponseEntity.badRequest().body((String) signatureContractId.get("message"));
            } else {
                // 没有电子章的附件时，走正常审核流程
                String signatureId = projectReportService.getSignature(cwProjectReportData);
                return ResponseUtil.newInstance().add("businessTable", "cw_project_report_signature").add("businessId", signatureId).ok ("操作成功");
            }
        }
    }

    /**
     * 根据签章表id查询报告数据
     * @param id
     * @return
     */
    @ApiLog("根据签章表id查询报告数据")
    @PreAuthorize ("hasAnyAuthority('cwProjectReport:view','cwProjectReport:add','cwProjectReport:edit')")
    @GetMapping("queryBySignatureId")
    public ResponseEntity queryBySignatureId(@RequestParam("id") String id) {
        CwProjectReportData projectReportData = projectReportService.queryBySignatureId ( id );
        return ResponseEntity.ok (projectReportData);
    }

    /**
     * 根据签章表id查询数据
     * @param id
     * @return
     */
    @ApiLog("根据签章表id查询数据")
    @PreAuthorize ("hasAnyAuthority('cwProjectReport:view','cwProjectReport:add','cwProjectReport:edit')")
    @GetMapping("findBySignatureId")
    public ResponseEntity findBySignatureId(@RequestParam("id") String id) {
        CwProjectReportSignature cwProjectReportSignature = projectReportService.findBySignatureId ( id );
        return ResponseEntity.ok (cwProjectReportSignature);
    }

    /**
     * 根据id修改签章表状态值status
     * @param data
     * @return
     */
    @ApiOperation(value = "根据id修改签章表状态值status")
    @PostMapping(value = "/updateSignatureStatusById")
    public ResponseEntity<String> updateSignatureStatusById(@RequestBody CwProjectReportSignatureDTO data) {
        String s = projectReportService.updateSignatureStatusById(data);
        return ResponseEntity.ok(s);
    }

    /**
     * 根据id修改签章表状态值status
     * @return
     */
    @ApiOperation(value = "根据id修改签章表状态值status")
    @PostMapping(value = "/aaa")
    public ResponseEntity<String> updateSignatureStatusById() {
        String s = "projectReportService.updateSignatureStatusById(data);";
        return ResponseEntity.ok(s);
    }

    /**
     * 根据id修改签字注师状态值status
     * @return
     */
    @ApiOperation(value = "根据id修改签字注师状态值status")
    @PostMapping(value = "updateSigStatusById")
    public ResponseEntity<String> updateSigStatusById(@RequestBody CwProjectReport data) {
        String s = projectReportService.updateSigStatusById(data);
        return ResponseEntity.ok(s);
    }



    /**
     * 导出分所报销数据
     * @param cwProjectReportData
     * @param page
     * @param response
     * @throws Exception
     */
    @ApiLog("导出报告数据信息")
    @GetMapping("export")
    @ApiOperation(value = "导出报告数据信息excel")
    public void exportFile(CwProjectReportData cwProjectReportData, Page <CwProjectReportData> page, ExcelOptions options, HttpServletResponse response) throws Exception {
        String fileName = options.getFilename ( );

        List<CwProjectReportData> result;
        if ( ExportMode.current.equals ( options.getMode ( ) ) ) {
            result = projectReportService.findList ( page, cwProjectReportData ).getRecords();
        } else if ( ExportMode.selected.equals ( options.getMode ( ) ) ) {
            result = projectReportService.findList ( page, cwProjectReportData ).getRecords().stream ( ).filter ( info ->
                    options.getSelectIds ( ).contains ( info.getId ( ) )
            ).collect ( Collectors.toList ( ) );
        } else {
            page.setSize ( -1 );
            page.setCurrent ( 0 );
            result = projectReportService.findList ( page, cwProjectReportData ).getRecords();
        }
        if(result.size()>0){
            for (CwProjectReportData info : result) {
//                if(StringUtils.isNotBlank(info.getStatus())){
//                    info.setStatus(DictUtils.getDictLabel(info.getStatus(), "cw_status", ""));
//                }
                if(StringUtils.isNotBlank(info.getReviewStatus())){
                    info.setReviewStatus(SpringUtil.getBean ( IDictApi.class ).getDictLabel(info.getReviewStatus(), "cw_status", ""));
                }
                if ("1".equals(info.getSignatureType())) {
                    if(StringUtils.isNotBlank(info.getStatus1())){
                        info.setStatus1(SpringUtil.getBean ( IDictApi.class ).getDictLabel(info.getStatus1(), "cw_status", ""));
                    }
                }
                if ("2".equals(info.getSignatureType())) {
                    if(StringUtils.isNotBlank(info.getStatus2())){
                        info.setStatus1(SpringUtil.getBean ( IDictApi.class ).getDictLabel(info.getStatus2(), "cw_project_report_sign_status", ""));
                    }
                }
                if ("3".equals(info.getSignatureType())) {
                    if(StringUtils.isNotBlank(info.getStatus3())){
                        info.setStatus1(SpringUtil.getBean ( IDictApi.class ).getDictLabel(info.getStatus3(), "cw_project_report_sign_status", ""));
                    }
                }

            }
        }
        EasyPoiUtil.exportExcel ( result, "报告信息",  options.getSheetName ( ), CwProjectReportData.class, fileName, response );
    }



    /**
     * 根据报告签章id查询签章审核节点信息
     * @param id
     * @return
     */
    @ApiLog("根据报告签章id查询签章审核节点信息")
    @GetMapping("getAuditNodeByReportId")
    public ResponseEntity getAuditNodeByReportId(@RequestParam("id") String id) {
        Map<String, Object> auditNodeByReportId = projectReportService.getAuditNodeByReportId(id);
        return ResponseEntity.ok (auditNodeByReportId);
    }



    /**
     * 根据报告签章id查询签章审核节点信息
     * @param id
     * @return
     */
    @ApiLog("根据报告签章id查询签章审核节点信息")
    @GetMapping("getSignatureTypeById")
    public ResponseEntity getSignatureTypeById(@RequestParam("id") String id,@RequestParam("signatureType") String signatureType) {
        Map<String, Object> signatureTypeById = projectReportService.getSignatureTypeById(id, signatureType);
        return ResponseEntity.ok (signatureTypeById);
    }

    /**
     * 根据客户id查询关联报告
     * @param clientId
     * @param cwProjectReport
     * @return
     * @throws Exception
     */
    @GetMapping("getIdByClientId")
    @ApiOperation(value = "根据客户id查询关联报告")
    public ResponseEntity<List<CwProjectReport>> getIdByClientId(String clientId, CwProjectReport cwProjectReport) throws Exception {
        List<CwProjectReport> cwProjectReportList = projectReportService.getIdByClientId(clientId, cwProjectReport);
        return ResponseEntity.ok(cwProjectReportList);
    }

    /**
     * 根据项目id查询关联报告
     * @param projectId
     * @param cwProjectReport
     * @return
     * @throws Exception
     */
    @GetMapping("getIdByProjectId")
    @ApiOperation(value = "根据项目id查询关联报告")
    public ResponseEntity<List<CwProjectReport>> getIdByProjectId(String projectId, CwProjectReport cwProjectReport) throws Exception {
        List<CwProjectReport> cwProjectReportList = projectReportService.getIdByProjectId(projectId, cwProjectReport);
        return ResponseEntity.ok(cwProjectReportList);
    }

    /**
     * 根据合同id查询关联报告
     * @param contractId
     * @param cwProjectReport
     * @return
     * @throws Exception
     */
    @GetMapping("getIdByContractId")
    @ApiOperation(value = "根据合同id查询关联报告")
    public ResponseEntity<List<CwProjectReport>> getIdByContractId(String contractId, CwProjectReport cwProjectReport) throws Exception {
        List<CwProjectReport> cwProjectReportList = projectReportService.getIdByContractId(contractId, cwProjectReport);
        return ResponseEntity.ok(cwProjectReportList);
    }

    /**
     * 生成报告归档信息
     * @param reportId
     * @return
     * @throws Exception
     */
    @GetMapping("saveReportArchive")
    @ApiOperation(value = "生成报告归档信息")
    public ResponseEntity saveReportArchive(String reportId) throws Exception {
        projectReportService.saveReportArchive(reportId);
        return ResponseEntity.ok("操作成功");
    }

    /**
     * 撤回签章
     * @param reportId
     * @return
     * @throws Exception
     */
    @GetMapping("rebackSign")
    @ApiOperation(value = "撤回签章")
    public ResponseEntity rebackSign(String reportId) throws Exception {
        projectReportService.rebackSign(reportId);
        return ResponseEntity.ok("操作成功");
    }

    /**
     * 撤回复核签章
     * @param reportId
     * @return
     * @throws Exception
     */
    @GetMapping("rebackReviewSign")
    @ApiOperation(value = "撤回签章")
    public ResponseEntity rebackReviewSign(String reportId) throws Exception {
        projectReportService.rebackReviewSign(reportId);
        return ResponseEntity.ok("操作成功");
    }

    /**
     * 数据导入(临时)
     * @param file
     * @param response
     * @return
     * @throws IOException
     */
    @GetMapping("/importExcel")
    @ApiOperation(value = "事务所审计清单表导入")
    public ResponseEntity importExcel(@RequestParam(value = "file", required = false) MultipartFile file, HttpServletResponse response) throws IOException {
        ArrayList<CwProjectReportDTO> arrayList = new ArrayList<>();
        HashMap<String,String> hashMap = new HashMap<>();
        List<CwProjectReportDTO> listA = new ArrayList<>();
        listA=EasyPoiUtil.importExcel(file, 0, 2, CwProjectReportDTO.class);
        projectReportService.importDecide(listA);
        return ResponseEntity.ok(arrayList);
    }


    /**
     * 发起修改签字注师流程
     */
    @ApiOperation(value = "发起修改签字注师流程")
    @PostMapping(value = "saveSignatureAnnotator")
    public ResponseEntity saveSignatureAnnotator(@RequestBody CwProjectReportData reportData) throws Exception {
        String id = projectReportService.saveSignatureAnnotator(reportData);
        return ResponseUtil.newInstance().add("businessTable", "cw_project_report_signature_annotator").add("businessId", id).ok ("操作成功");

    }

    /**
     * 报告-修改签字注师   同意
     */
    @ApiOperation(value = "报告-修改签字注师   同意")
    @PostMapping("/updateAgree")
    public ResponseEntity saveReturnAgree(@RequestBody CwProjectReport report) throws Exception{
        String s = projectReportService.updateAgree(report);
        return ResponseUtil.newInstance().add("businessTable", "cw_project_report_signature_annotator").add("businessId", report.getId()).ok ("操作成功");
    }



    /**
     * 查找修改签字注师历史记录
     */
    @ApiOperation(value = "查找修改签字注师记录")
    @GetMapping("getSignatureAnnotatorList")
    public ResponseEntity<List<CwSignatureAnnotator>> getSignatureAnnotatorList(String reportId){
        List<CwSignatureAnnotator> cwSignatureAnnotators=projectReportService.getSignatureAnnotatorList(reportId);
        return ResponseEntity.ok(cwSignatureAnnotators);
    }

    /**
     * 根据id查找修改签字注师数据
     */
    @ApiOperation(value = "根据id查找修改签字注师数据")
    @GetMapping("getSigById")
    public ResponseEntity getSigById(@RequestParam("id") String id) {
        CwSignatureAnnotator cwProjectReportSignature = projectReportService.getSigById ( id );
        return ResponseEntity.ok (cwProjectReportSignature);
    }

    /**
     * 修改签字注师退回状态
     */
    @ApiOperation(value = "修改签字注师退回状态")
    @PostMapping("updateStatusByIdSig")
    public ResponseEntity updateStatusByIdSig(@RequestBody CwProjectReport report) {
        projectReportService.updateStatusByIdSig(report);
        return ResponseEntity.ok ("修改成功");
    }

    /**
     * 修改签字注师流程终止
     */
    @ApiOperation(value = "修改签字注师流程终止")
    @PostMapping("/returnRequest")
    public ResponseEntity returnRequest(@RequestBody CwProjectReport report) throws Exception{
        projectReportService.returnRequest(report.getId());
        return ResponseEntity.ok("操作完成");
    }




}
