package cn.palmte.work.controller.backend;

import cn.palmte.work.bean.*;
import cn.palmte.work.model.*;
import cn.palmte.work.pojo.ActHisTask;
import cn.palmte.work.service.*;
import cn.palmte.work.utils.*;
import cn.palmte.work.utils.excel.ExportExcelUtils;
import cn.palmte.work.utils.excel.ExportUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.activiti.engine.HistoryService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.datetime.DateFormatter;
import org.springframework.format.number.NumberStyleFormatter;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.*;
import top.jfunc.common.db.bean.Page;
import top.jfunc.common.utils.CollectionUtil;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 项目管理功能
 *
 * @author xiongshiyan at 2021/10/29 , contact me with email yanshixiong@126.com or phone 15208384257
 */
@Controller
@RequestMapping("/project")
public class ProjectController extends BaseController {
    private static final Logger logger = LoggerFactory.getLogger(ProjectController.class);
    private static final String PROJECT_ID = "projectId";
    private static final String DETAILS = "details";

    private static final int PROJECT_BASE = 19;
    private static final int PROJECT_OTHER = 11;

    @Autowired
    private DeptService deptService;
    @Autowired
    private ProjectService projectService;
    @Autowired
    private ProjectEstimateService projectEstimateService;
    @Autowired
    private ProjectBudgetService projectBudgetService;
    @Autowired
    private ProjectTaskRecordService projectTaskRecordService;
    @Autowired
    private ActProcInsService actProcInsService;
    @Autowired
    private ProjectInstanceRelationRepository projectInstanceRelationRepository;
    @Autowired
    private ProjectFinalSevice projectFinalSevice;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private ActTaskDefService actTaskDefService;
    @Autowired
    private ProjectSettleService projectSettleService;
    @Autowired
    private ProcurementTypeService procurementTypeService;
    @Autowired
    private ProjectSettleIncomeRepository projectSettleIncomeRepository;
    @Autowired
    private ProjectRepository projectRepository;
    @Autowired
    private ActUtil actUtil;
    @Autowired
    private NumSeqService numSeqService;

    /**
     * 项目列表
     */
    @RequestMapping("/list")
    public String list(@RequestParam(value = "keywords", required = false) String keywords,
                       @RequestParam(value = PAGE_NUMBER, defaultValue = DEFAULT_PAGE_NUMBER) int pageNumber,
                       @RequestParam(value = PAGE_SIZE, defaultValue = DEFAULT_PAGE_SIZE) int pageSize,
                       Map<String, Object> model) {
        //当前登录人的角色类型
        model.put("keywords", keywords);
        model.put("adminId", InterfaceUtil.getAdminId());
        model.put("admin", InterfaceUtil.getAdmin());
        model.put("deptList", deptService.findAll());
        ConcurrentHashMap<String, String> searchInfo = getSearchInfo(keywords, model);
        Page<Project> page = projectService.list(searchInfo, pageNumber, pageSize);
        List<Project> list = page.getList();
        if(CollectionUtil.isNotEmpty(list)){
            int offset = (pageNumber - 1) * pageSize;
            for (int i = 0 , size = list.size(); i < size; i++) {
                list.get(i).setTempId(i+1 + offset);
            }
        }
        model.put("pager", page);
        model.put("Utils", FreeMarkerUtil.fromStaticPackage("cn.palmte.work.utils.Utils"));
        ///
        /*Page<Project> myApproveProjects = projectService.findMyApproveProjects(searchInfo, InterfaceUtil.getAdminId(), 1, Integer.MAX_VALUE);
        model.put("hasApproveProjects", CollectionUtil.isNotEmpty(myApproveProjects.getList()) ? "1" : "0");*/
        return "admin/project_list";
    }

    /**
     * 项目导出
     */
    @RequestMapping("/export")
    public void export(@RequestParam(value = "keywords", required = false) String keywords, HttpServletResponse httpServletResponse) throws IOException {
        Map<String, String> searchInfo = getSearchInfo(keywords);
        downloadHeader(httpServletResponse, Utils.generateExcelName("项目报表"), "application/octet-stream");
        String[] headers = {"项目编号", "项目名称", "项目类型", "项目合同金额", "华智产品金额", "其他产品金额", "项目状态", "审核状态", "当前审核人", "项目创建者", "部门名称", "项目开始时间", "项目结束时间", "最后更新时间"};
        String[] exportColumns = {"projectNo", "name", "typeDesc", "contractRound", "huazhiRound", "ziguangRound", "statusDesc", "approveStatusDesc", "approveName", "creatorName", "deptName", "startDateYM", "endDateYM", "lastUpdateTime"};
        ExportUtils.exportToExcel(headers, exportColumns, 1, 10000,
                httpServletResponse.getOutputStream(), (pN, pS) -> projectService.list(searchInfo, pN, pS).getList());
    }

    /**
     * 项目导出
     */
    @RequestMapping("/exportAll")
    public void exportAll(HttpServletResponse response, Integer id) throws IOException {
        Project project = projectRepository.findOne(id);
//        downloadHeader(httpServletResponse, Utils.generateExcelName("项目信息总表"), "application/vnd.ms-excel");
        response.setHeader("Content-Disposition", "attachment;filename=".concat(Utils.generateExcelName("项目信息总表")));
//        response.setHeader("Content-Disposition", "attachment;filename*=UTF-8''" + java.net.URLEncoder.encode("项目信息总表", "UTF-8"));
        response.setHeader("Connection", "close");
        response.setHeader("Content-Type", "application/vnd.ms-excel");
        ServletOutputStream outputStream = response.getOutputStream();
        ExportExcelUtils exportExcelUtils = new ExportExcelUtils();
        String[] headers0 = {"部门名称", "项目编号", "项目名称", "项目类型", "项目计划开始时间", "项目计划结束时间", "垫资模式", "项目把握度", "行业场景应用", "客户名称", "终端客户名称", "合同金额", "项目毛利", "项目毛利率", "华智产品金额", "汇智产品金额", "华三产品金额", "其他产品金额", "价值及风险"};
        String[] columns0 = {"deptName", "projectNo", "name", "typeDesc", "startDate", "endDate", "underwrittenModeDesc", "certainty", "industryScenario", "customer", "terminalCustomer", "contractAmount", "grossProfit", "grossProfitMargin", "huazhiProductAmount", "huizhiProductAmount", "huasanProductAmount", "ziguangOtherAmount", "valueRisk"};
        exportExcelUtils.exportProjectExcel(headers0, columns0, project, "yyyy-MM-dd", 0, "项目基本信息", outputStream);
        String[] headers1 = {"项目负责人", "预计合同签订时间", "项目计划招标时间", "是否二次合作", "签单方式", "项目解决方案", "垫资利息", "垫资峰值", "主合同收款条款", "主合具体解决方案", "计收计划"};
        String[] columns1 = {"principal", "contractTime", "bidsTime", "isSecond", "signType", "resolvePlan", "advanceInterestAmount", "advancePeakAmount", "mainContractCollectionTerms", "mainContractResolvePlan", "calculationCollection"};
        exportExcelUtils.exportProjectExcel(headers1, columns1, project, "yyyy-MM-dd", 0, "项目其他信息", outputStream);
        BudgetBean budgetBean = projectBudgetService.getBudget(project);
        if (project.getStatus() < 5) {
            exportExcelUtils.end(outputStream);
            return;
        }
        List<ProjectBudgetPlanDetail> projectBudgetPlanDetails = projectBudgetService.getProjectBudgetPlanDetails(project);
        CashFlowBean cashFlowBean = projectBudgetService.getCashFlowBean(project, projectBudgetPlanDetails);
        exportExcelUtils.exportBudgetExcel(budgetBean, cashFlowBean, 0, "项目预算信息", outputStream, project.getOtherName());
        //收入明细
        List<ProjectBudgetIncomeDetail> budgetIncomeDetail = projectBudgetService.getBudgetIncomeDetail(project);
        Integer incomeTotalAmount = projectBudgetService.getBudgetIncomeAmount(project);
        String[] headers2 = {"序号", "类别", "名称", "单位", "数量", "单价", "税率(%)", "含税总金额(元)", "不含税金额(元)"};
        String[] columns2 = {"tempId", "type", "name", "unit", "amount", "price", "taxRate", "totalTaxInclude", "totalTaxExclude"};
        exportExcelUtils.exportIncomeDetailExcel(headers2, columns2, project, budgetBean, budgetIncomeDetail, incomeTotalAmount, "yyyy-MM-dd", 0, "收入明细表", outputStream);
        //成本明细
        List<ProjectBudgetCostDetail> budgetCostDetail = projectBudgetService.getBudgetCostDetail(project);
        Integer costTotalAmount = projectBudgetService.getBudgetCostAmount(project);
        List<ProcurementType> procurementTypes = procurementTypeService.allProcurementTypeList();
        Map<Integer, String> procurementMap = procurementTypes.stream().collect(Collectors.toMap(ProcurementType::getId, ProcurementType::getName));
        String[] headers3 = {"序号", "大类", "类别", "名称", "单位", "数量", "单价", "税率(%)", "含税总金额(元)", "不含税金额(元)"};
        String[] columns3 = {"tempId", "type", "category", "name", "unit", "amount", "price", "taxRate", "totalTaxInclude", "totalTaxExclude"};
        exportExcelUtils.exportCostDetailExcel(headers3, columns3, project, budgetBean, budgetCostDetail, costTotalAmount, procurementMap, "yyyy-MM-dd", 0, "采购成本明细表", outputStream);
        //项目管理成本明细
        List<ProjectBudgetCostProjectManageDetail> budgetCostProjectManageDetail = projectBudgetService.getBudgetCostProjectManageDetail(project);
        Integer costProjectManageTotalAmount = projectBudgetService.getBudgetCostProjectManageAmount(project);
        String[] headers4 = {"序号", "财务费用类别", "业务项目", "项目明细", "单位", "数量", "单价", "总金额(元)", "预估计算防范", "预估依据", "备注"};
        String[] columns4 = {"tempId", "type", "name", "detail", "unit", "amount", "price", "total", "predictMethod", "predictWhy", "remark"};
        exportExcelUtils.exportCostManageDetailExcel(headers4, columns4, project, budgetBean, budgetCostProjectManageDetail, costProjectManageTotalAmount, "yyyy-MM-dd", 0, "项目管理成本表", outputStream);
        //资金计划明细
//        ProjectBudgetPlanDetail projectBudgetPlanDetailTotalTitle = projectBudgetService.getProjectBudgetPlanDetailTotalTitle(project,
//                budgetIncomeDetail,
//                budgetCostDetail,
//                budgetCostProjectManageDetail,
//                projectBudgetPlanDetails);
        ProjectBudgetPlanDetail projectBudgetPlanDetailTotal = projectBudgetService.getProjectBudgetPlanDetailTotal(project, projectBudgetPlanDetails);
        String[] headers5 = {"月份", "设备支出", "工程支出（含服务+施工+其他）", "经营性开支", "保证金支出", "支出合计", "销售收款", "保证金收款", "收款合计", "资金余额", "资金利息", "垫资计划", "还款计划"};
        String[] row5 = {"month", "deviceCost", "engineerCost", "projectManageCost", "earnestMoneyCost", "totalCost", "saleIncome", "earnestMoneyIncome", "totalIncome", "fundBalance", "capitalInterest", "underwrittenPlan", "repaymentPlan"};
        exportExcelUtils.exportPlanDetailExcel(headers5, row5, project, budgetBean, projectBudgetPlanDetails, projectBudgetPlanDetailTotal, "yyyy-MM-dd", 0, "资金计划表", outputStream);

        List<String> timeList = projectSettleIncomeRepository.findAllByProjectIdAndGroupByTime(project.getId());
        for (String time : timeList) {
            SettleBean settleBean = projectSettleService.getMonthSettle(project, time);
            FormerBean formerBean = projectSettleService.getFormerSettle(project, time);
            FormerBean currentBean = projectSettleService.getCurrentSettleBytime(project, time);
            exportExcelUtils.exportSettleExcel(budgetBean, cashFlowBean, formerBean, settleBean, currentBean, 0, "项目结算信息" + time, outputStream, project.getOtherName());
        }
        FinalBean finalBean = projectFinalSevice.getFinal(project);
        if (project.getStatus() >= 15) {
            FormerBean settleBean = projectSettleService.getCurrentSettle(project, "");
            exportExcelUtils.exportFinalExcel(budgetBean, cashFlowBean, settleBean, finalBean, 0, "项目决算信息", outputStream, project.getOtherName());
        }
        exportExcelUtils.end(outputStream);
    }


    /**
     * 新增，至项目概算
     */
    @RequestMapping("/add")
    public String add(Map<String, Object> model) {
        Dept one = deptService.findUserDept(InterfaceUtil.getAdmin());
        String projectNo = numSeqService.generate();
        model.put("projectNo", projectNo);
        model.put("dept", one);
        model.put("projectId",-1);
        return "admin/project_estimate_add";
    }

    /**
     * 新增概算项目 保存草稿
     */
    @RequestMapping("/estimateAddSave")
    public String estimateAddSave(Project project, EstimateBean estimateBean, Map<String, Object> model) {
        projectEstimateService.estimateAddSave(project, estimateBean, InterfaceUtil.getAdmin(), ApproveStatusEnum.APPROVAL_UNCOMMIT);
        return "redirect:/project/list";
    }

    /**
     * 新增概算项目 保存并提交审核
     */
    @RequestMapping("/estimateAddSaveAndApprove")
    public String estimateAddSaveAndApprove(Project project, EstimateBean estimateBean, Map<String, Object> model) throws Exception {
        projectEstimateService.estimateAddSaveAndApprove(project, estimateBean, InterfaceUtil.getAdmin());
        return "redirect:/project/list";
    }

    /**
     * 去编辑概算项目页面
     */
    @RequestMapping("/edit")
    public String edit(@RequestParam("id") int id, Map<String, Object> model) {
        Project project = projectService.getProject(id);
        model.put("project", project);
        EstimateBean estimateBean = projectEstimateService.getEstimate(project);
        model.put("estimateBean", estimateBean);
        //freemarker可以利用的静态方法
        model.put("Utils", FreeMarkerUtil.fromStaticPackage("cn.palmte.work.utils.Utils"));
        return "admin/project_estimate_edit";
    }

    /**
     * 编辑概算项目保存
     */
    @RequestMapping("/estimateEditSave")
    public String estimateEditSave(Project project, EstimateBean estimateBean, Map<String, Object> model) {
        Project projectInDb = projectService.getProject(project.getId());
        projectEstimateService.estimateEditSave(project, projectInDb, estimateBean, InterfaceUtil.getAdmin(), ApproveStatusEnum.APPROVAL_UNCOMMIT);
        return "redirect:/project/list";
    }

    /**
     * 编辑概算项目保存并提交审批
     */
    @RequestMapping("/estimateEditSaveAndApprove")
    public String estimateEditSaveAndApprove(Project project, EstimateBean estimateBean, Map<String, Object> model) throws Exception {
        Project projectInDb = projectService.getProject(project.getId());
        projectEstimateService.estimateEditSaveAndApprove(project, projectInDb, estimateBean, InterfaceUtil.getAdmin());
        return "redirect:/project/list";
    }

    /**
     * 进项目预算页面
     */
    @RequestMapping("/budgetEdit")
    public String budget(@RequestParam("id") int id, Map<String, Object> model) {
        Project project = projectService.getProject(id);
        model.put("project", project);

        model.put("planStartStr", project.getPlanStartStr());
        model.put("planStartDate", project.getPlanStartStr());
        model.put("planEndStr", project.getPlanEndStr());
        model.put("planEndDate", project.getPlanEndStr());
        EstimateBean estimateBean = projectEstimateService.getEstimate(project);
        model.put("estimateBean", estimateBean);

        //采购类型
        model.put("procurementTypes", procurementTypeService.allProcurementTypeList());
        BudgetBean budgetBean = projectBudgetService.getBudget(project);
        //预算主页面数据
        model.put("budgetBean", budgetBean);
        //收入明细
        List<ProjectBudgetIncomeDetail> budgetIncomeDetail = projectBudgetService.getBudgetIncomeDetail(project);
        model.put("incomeDetails", budgetIncomeDetail);
        model.put("incomeTotalAmount", projectBudgetService.getBudgetIncomeAmount(project));
        //成本明细
        List<ProjectBudgetCostDetail> budgetCostDetail = projectBudgetService.getBudgetCostDetail(project);
        model.put("costDetails", budgetCostDetail);
        model.put("costTotalAmount", projectBudgetService.getBudgetCostAmount(project));
        //项目管理成本明细
        List<ProjectBudgetCostProjectManageDetail> budgetCostProjectManageDetail = projectBudgetService.getBudgetCostProjectManageDetail(project);
        model.put("costProjectManageDetails", budgetCostProjectManageDetail);
        model.put("costProjectManageTotalAmount", projectBudgetService.getBudgetCostProjectManageAmount(project));
        List<ProjectBudgetPlanDetail> projectBudgetPlanDetails = projectBudgetService.getProjectBudgetPlanDetails(project);
        //资金计划明细
        model.put("projectBudgetPlanDetails", projectBudgetPlanDetails);
        //资金计划总【上面汇总表第一行】
        model.put("projectBudgetPlanDetailTotalTitle", projectBudgetService.getProjectBudgetPlanDetailTotalTitle(project,
                budgetIncomeDetail,
                budgetCostDetail,
                budgetCostProjectManageDetail,
                projectBudgetPlanDetails));
        //资金计划总【上面汇总表第二行】
        model.put("projectBudgetPlanDetailTotal", projectBudgetService.getProjectBudgetPlanDetailTotal(project, projectBudgetPlanDetails));
        //资金计划表中的统计信息【下面资金小表】
        model.put("underwrittenPlanStatistic", projectBudgetService.getProjectUnderwrittenPlanStatisticBean(projectBudgetPlanDetails));
        //现金表
        model.put("cashFlowBean", projectBudgetService.getCashFlowBean(project, projectBudgetPlanDetails));
        //freemarker可以利用的静态方法
        model.put("Utils", FreeMarkerUtil.fromStaticPackage("cn.palmte.work.utils.Utils"));
        return "admin/project_budget_edit";
    }

    /**
     * 进行项目预算保存
     */
    @RequestMapping("/budgetEditSave")
    public String budgetEditSave(Project project, BindingResult bindingResult, BudgetBean budgetBean, Map<String, Object> model) {
        Project projectInDb = projectService.getProject(project.getId());
        projectBudgetService.budgetEditSave(project, projectInDb, budgetBean, InterfaceUtil.getAdmin(), ApproveStatusEnum.APPROVAL_UNCOMMIT);
        return "redirect:/project/list";
    }

    /**
     * 进行项目预算保存并提交审核
     */
    @RequestMapping("/budgetEditSaveAndApprove")
    public String budgetEditSaveAndApprove(Project project, BudgetBean budgetBean, Map<String, Object> model) throws Exception {
        Project projectInDb = projectService.getProject(project.getId());
        projectBudgetService.budgetEditSaveAndApprove(project, projectInDb, budgetBean, InterfaceUtil.getAdmin());
        return "redirect:/project/list";
    }

    /**
     * 保存收入明细
     */
    @RequestMapping("/budgetEditSaveIncomeDetail")
    @ResponseBody
    public ResponseMsg budgetEditSaveIncomeDetail(@RequestBody String body) {
        JSONObject jsonObject = JSON.parseObject(body);
        JSONArray details = jsonObject.getJSONArray(DETAILS);
        List<ProjectBudgetIncomeDetailTemp> detailList = new ArrayList<>(details.size());
        for (int i = 0; i < details.size(); i++) {
            ProjectBudgetIncomeDetailTemp detail = details.getObject(i, ProjectBudgetIncomeDetailTemp.class);
            detailList.add(detail);
        }

        Project project = projectService.getProject(jsonObject.getInteger(PROJECT_ID));

        projectBudgetService.saveBudgetIncomeDetailTemp(project, detailList);

        return ResponseMsg.buildSuccessMsg("成功");
    }

    /**
     * 保存成本明细
     */
    @RequestMapping("/budgetEditSaveCostDetail")
    @ResponseBody
    public ResponseMsg budgetEditSaveCostDetail(@RequestBody String body) {
        JSONObject jsonObject = JSON.parseObject(body);
        JSONArray details = jsonObject.getJSONArray(DETAILS);
        List<ProjectBudgetCostDetailTemp> detailList = new ArrayList<>(details.size());
        for (int i = 0; i < details.size(); i++) {
            ProjectBudgetCostDetailTemp detail = details.getObject(i, ProjectBudgetCostDetailTemp.class);
            detailList.add(detail);
        }

        Project project = projectService.getProject(jsonObject.getInteger(PROJECT_ID));

        projectBudgetService.saveBudgetCostDetailTemp(project, detailList);

        return ResponseMsg.buildSuccessMsg("成功");
    }

    /**
     * 保存项目管理成本明细
     */
    @RequestMapping("/budgetEditSaveCostProjectManageDetail")
    @ResponseBody
    public ResponseMsg budgetEditSaveCostProjectManageDetail(@RequestBody String body) {
        JSONObject jsonObject = JSON.parseObject(body);
        JSONArray details = jsonObject.getJSONArray(DETAILS);
        List<ProjectBudgetCostProjectManageDetailTemp> detailList = new ArrayList<>(details.size());
        for (int i = 0; i < details.size(); i++) {
            ProjectBudgetCostProjectManageDetailTemp detail = details.getObject(i, ProjectBudgetCostProjectManageDetailTemp.class);
            if(detail.getType() == 3 || "3".equals(detail.getName1()) || "8".equals(detail.getName1())) {
                detail.setName(detail.getName2());
                detail.setIsDiy(1);
            } else {
                if ("1".equals(detail.getName1())) {
                    detail.setName("人工费");
                } else if ("2".equals(detail.getName1())) {
                    detail.setName("总部支撑人力费用");
                } else if ("4".equals(detail.getName1())) {
                    detail.setName("人员差旅费");
                } else if ("5".equals(detail.getName1())) {
                    detail.setName("业务费用");
                } else if ("6".equals(detail.getName1())) {
                    detail.setName("商务及专项验收费用");
                } else if ("7".equals(detail.getName1())) {
                    detail.setName("办公费用");
                }
                detail.setIsDiy(0);
            }
            detailList.add(detail);
        }

        Project project = projectService.getProject(jsonObject.getInteger(PROJECT_ID));

        projectBudgetService.saveBudgetCostProjectManageDetailTemp(project, detailList);

        return ResponseMsg.buildSuccessMsg("成功");
    }

    /**
     * 保存项资金计划明细
     */
    @RequestMapping("/budgetEditSaveBudgetPlanDetail")
    @ResponseBody
    public ResponseMsg budgetEditSaveBudgetPlanDetail(@RequestBody String body) {
        JSONObject jsonObject = JSON.parseObject(body);
        JSONArray details = jsonObject.getJSONArray(DETAILS);
        List<ProjectBudgetPlanDetailTemp> detailList = new ArrayList<>(details.size());
        for (int i = 0; i < details.size(); i++) {
            ProjectBudgetPlanDetailTemp detail = details.getObject(i, ProjectBudgetPlanDetailTemp.class);
            detailList.add(detail);
        }

        Project project = projectService.getProject(jsonObject.getInteger(PROJECT_ID));

        projectBudgetService.saveBudgetPlanDetailTemp(project, detailList);

        return ResponseMsg.buildSuccessMsg("成功");
    }


    /**
     * 待我审核项目列表
     */
    @RequestMapping("/listApprove")
    public String listApprove(@RequestParam(value = "keywords", required = false) String keywords,
                              @RequestParam(value = PAGE_NUMBER, defaultValue = DEFAULT_PAGE_NUMBER) int pageNumber,
                              @RequestParam(value = PAGE_SIZE, defaultValue = DEFAULT_PAGE_SIZE) int pageSize,
                              Map<String, Object> model) {
        //当前登录人的角色类型
        model.put("keywords", keywords);
        model.put("deptList", deptService.findAll());
        ConcurrentHashMap<String, String> searchInfo = getSearchInfo(keywords, model);
        model.put("pager", projectService.findMyApproveProjects(searchInfo, InterfaceUtil.getAdminId(), pageNumber, pageSize));
        model.put("Utils", FreeMarkerUtil.fromStaticPackage("cn.palmte.work.utils.Utils"));
        return "admin/project_list_approve";
    }

    /**
     * 待我审核项目导出
     */
    @RequestMapping("/exportApprove")
    public void exportApprove(@RequestParam(value = "keywords", required = false) String keywords, HttpServletResponse httpServletResponse) throws IOException {
        Map<String, String> searchInfo = getSearchInfo(keywords);
        downloadHeader(httpServletResponse, Utils.generateExcelName("待我审核项目报表"), "application/octet-stream");
        String[] headers = {"项目编号", "项目名称", "项目类型", "项目合同金额", "华智产品金额", "其他产品金额", "项目状态", "审核状态", "当前审核人", "项目创建者", "部门名称", "项目开始时间", "项目结束时间", "最后更新时间"};
        String[] exportColumns = {"projectNo", "name", "typeDesc", "contractRound", "huazhiRound", "ziguangRound", "statusDesc", "approveStatusDesc", "approveName", "creatorName", "deptName", "startDate", "endDate", "lastUpdateTime"};
        ExportUtils.exportToExcel(headers, exportColumns, 1, 10000,
                httpServletResponse.getOutputStream(), (pN, pS) -> projectService.findMyApproveProjects(searchInfo, InterfaceUtil.getAdminId(), pN, pS).getList());
    }

    /**
     * 审核页面
     */
    @RequestMapping("/approve")
    public String approve(@RequestParam(value = KEYWORDS, required = false) String keywords,
                          @RequestParam("id") int id, @RequestParam("type") int type,@RequestParam String listFrom,
                          Map<String, Object> model) {
        Project project = projectService.getProject(id);
        model.put("type",type);

        //项目信息
        model.put("adminId", InterfaceUtil.getAdminId());
        model.put("project", project);
        model.put("listFrom", listFrom);

        model.put("planStartStr", project.getPlanStartStr());
        model.put("planStartDate", project.getPlanStartStr());
        model.put("planEndStr", project.getPlanEndStr());
        model.put("planEndDate", project.getPlanEndStr());

        //概算信息
        EstimateBean estimateBean = projectEstimateService.getEstimate(project);
        model.put("estimateBean", estimateBean);

        //预算信息
        BudgetBean budgetBean = projectBudgetService.getBudget(project);
        model.put("procurementTypes", procurementTypeService.allProcurementTypeList());
        model.put("budgetBean", budgetBean);
        //收入明细
        model.put("incomeDetails", projectBudgetService.getBudgetIncomeDetail(project));
        model.put("incomeTotalAmount", projectBudgetService.getBudgetIncomeAmount(project));
        //成本明细
        model.put("costDetails", projectBudgetService.getBudgetCostDetail(project));
        model.put("costTotalAmount", projectBudgetService.getBudgetCostAmount(project));
        //项目管理成本明细
        model.put("costProjectManageDetails", projectBudgetService.getBudgetCostProjectManageDetail(project));
        model.put("costProjectManageTotalAmount", projectBudgetService.getBudgetCostProjectManageAmount(project));
        List<ProjectBudgetPlanDetail> projectBudgetPlanDetails = projectBudgetService.getProjectBudgetPlanDetails(project);
        //资金计划明细
        model.put("projectBudgetPlanDetails", projectBudgetPlanDetails);
        //资金计划总【上面汇总表】
        model.put("projectBudgetPlanDetailTotal", projectBudgetService.getProjectBudgetPlanDetailTotal(project, projectBudgetPlanDetails));
        //资金计划表中的统计信息【下面资金小表】
        model.put("underwrittenPlanStatistic", projectBudgetService.getProjectUnderwrittenPlanStatisticBean(projectBudgetPlanDetails));
        //现金表
        model.put("cashFlowBean", projectBudgetService.getCashFlowBean(project, projectBudgetPlanDetails));

        //结算信息
        model.put("keywords",keywords);
        ConcurrentHashMap<String, String> searchInfo = getSearchInfo(keywords,model);
        String time;
        if (!searchInfo.containsKey("time")) {
            ProjectSettleIncome projectSettleIncome = projectSettleIncomeRepository.findNewByProjectId(id);
            if(null != projectSettleIncome){
                time = projectSettleIncome.getTime();
            }else {
                time = "";
            }
            model.put("time", time);
            model.put("check", 1);
        } else {
            model.put("check", 0);
            time = searchInfo.get("time");
        }
        model.put("formerBean", projectSettleService.getFormerSettle(project, time));
        model.put("monthBean", projectSettleService.getMonthSettleByTime(project, time));
        model.put("currentBean", projectSettleService.getCurrentSettleBytime(project, time));

        //决算信息
        model.put("finalBean", projectFinalSevice.getFinal(project));

        //freemarker可以利用的静态方法
        model.put("Utils", FreeMarkerUtil.fromStaticPackage("cn.palmte.work.utils.Utils"));

        //审核记录
        List<ProjectTaskRecord> list = projectTaskRecordService.list(id);
        String huiQianFile = "";
        if (!list.isEmpty()) {
            Optional<ProjectTaskRecord> first = list.stream().filter(r -> StrKit.notBlank(r.getFileUrl())).max(Comparator.comparingInt(ProjectTaskRecord::getId));
            if (first.isPresent()) {
                huiQianFile = first.get().getFileUrl();
            }
            model.put("taskRecords", list);
        }
        model.put("huiQianFile", huiQianFile);
        //当前审批任务
        Task currentTask = actUtil.getCurrentTask(project.getId());
        model.put("currentTaskName", currentTask==null ? "" : currentTask.getName());

        return "admin/project_approve";
    }

    /**
     * 审批完成任务
     */
    @ResponseBody
    @RequestMapping("/completeTask/{projectId}/{approvetype}")
    public ResponseMsg completeTask(@PathVariable int projectId,@PathVariable int approvetype, @RequestBody String json) {
        return projectService.completeTask(projectId, json,approvetype);
    }


    /**
     * 预算审批 跳到执行董事审批任务
     */
    @ResponseBody
    @RequestMapping("/skipTask/{projectId}/{approvetype}")
    public ResponseMsg skipTask(@PathVariable int projectId, @PathVariable int approvetype,  @RequestBody String json) {
        return projectService.skipTask(projectId, json, approvetype);
    }

    /**
     * 查看审核流程
     */
    @RequestMapping("/taskRecords/{projectId}")
    public String taskRecords(@PathVariable int projectId, Map<String, Object> model) {
        model.put(PROJECT_ID, projectId);
        List<ProjectTaskRecord> list = projectTaskRecordService.list(projectId);
        if (list != null && !list.isEmpty()) {
            model.put("list", list);
        }

        List<ProjectInstanceRelation> relationList = projectInstanceRelationRepository.findByProjectIdOrderByCreateTimeDesc(projectId);
        if (relationList != null && !relationList.isEmpty()) {
            String procInsId = relationList.get(0).getProcessInsId();

            List<ActHisTask> hisTaskList = actTaskDefService.hisTaskList(procInsId);
            model.put("taskList", hisTaskList);

            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(procInsId).singleResult();
            if (historicProcessInstance != null) {
                model.put("procDefName", historicProcessInstance.getProcessDefinitionName());
            }
        }

        return "admin/project_task_record_list";
    }

    /**
     * 流程实列图片
     */
    @RequestMapping("/procInsPng/{projectId}")
    public void png(HttpServletResponse response, @PathVariable(PROJECT_ID) int projectId) throws Exception {
        List<ProjectInstanceRelation> relationList = projectInstanceRelationRepository.findByProjectIdOrderByCreateTimeDesc(projectId);
        if (relationList == null || relationList.isEmpty()) {
            return;
        }
        actProcInsService.createProcInsPng(response, relationList.get(0).getProcessInsId());
    }

    /**
     * 进入选择页面
     */
    @RequestMapping("/selectRoleUser")
    public String selectRoleUser(@RequestParam int projectId, Map<String, Object> model) {
        model.put("project", projectService.getProject(projectId));
        return "admin/project_select_role_user";
    }
    /**
     * 获取当前所有的角色和角色下的用户，根据项目决定是否check
     */
    @RequestMapping("/roleUsers")
    @ResponseBody
    public ResponseMsg roleUsers(@RequestParam int projectId) {
        /*{ id:1, pId:0, name:"随意勾选 1", open:true},
        { id:11, pId:1, name:"随意勾选 1-1", open:true},
        { id:12, pId:1, name:"随意勾选 1-2", open:true},
        { id:2, pId:0, name:"随意勾选 2", checked:true, open:true},
        { id:21, pId:2, name:"随意勾选 2-1"},
        { id:22, pId:2, name:"随意勾选 2-2", open:true},
        { id:23, pId:2, name:"随意勾选 2-3"}*/
        List<ZTreeNode> zTreeNodes = projectService.getZTreeNodes(projectId);
        return ResponseMsg.buildSuccessData(zTreeNodes);
    }

    /**
     * 保存项目与用户的关系
     */
    @RequestMapping("/saveSelectRoleUser")
    @ResponseBody
    public ResponseMsg saveSelectRoleUser(@RequestBody String body) {
        /*{ id:1, pId:0, name:"随意勾选 1", open:true},
        { id:11, pId:1, name:"随意勾选 1-1", open:true},
        { id:12, pId:1, name:"随意勾选 1-2", open:true},
        { id:2, pId:0, name:"随意勾选 2", checked:true, open:true},
        { id:21, pId:2, name:"随意勾选 2-1"},
        { id:22, pId:2, name:"随意勾选 2-2", open:true},
        { id:23, pId:2, name:"随意勾选 2-3"}*/
        JSONObject jsonObject = JSON.parseObject(body);
        Integer projectId = jsonObject.getInteger(PROJECT_ID);
        JSONArray array = jsonObject.getJSONArray("ids");
        String[] ids = new String[array.size()];
        for (int i = 0; i < array.size(); i++) {
            ids[i] = array.getString(i);
        }
        projectService.saveProjectVisible(projectId, ids);
        return ResponseMsg.buildSuccessMsg("成功");
    }


    /**
     * 删除草稿状态下的概算项目
     */
    @GetMapping("/deleteProject/{id}")
    @ResponseBody
    public ResponseMsg deleteProject(@PathVariable int id) {
        return projectService.deleteProject(id);
    }

    @InitBinder
    public void initBinder(WebDataBinder webDataBinder) {
        webDataBinder.addCustomFormatter(new DateFormatter("yyyy-MM-dd"));
        webDataBinder.addCustomFormatter(new NumberStyleFormatter());
    }

    /**
     * 保存项目与用户的关系
     */
    @RequestMapping("/checkName")
    @ResponseBody
    public ResponseMsg checkName(@RequestParam String name,@RequestParam int id) {
        Project project = projectRepository.findByProjectName(name);
        if (project != null && id != project.getId()) {
            return ResponseMsg.buildFailedMsg("失败");
        }
        return ResponseMsg.buildSuccessMsg("成功");
    }

    /**
     * 验证项目编号
     */
    @RequestMapping("/checkProjectNo")
    @ResponseBody
    public ResponseMsg checkProjectNo(@RequestParam String projectNo, @RequestParam int id) {
        Project project = projectRepository.findByProjectNo(projectNo);
        if (project != null && id != project.getId()) {
            return ResponseMsg.buildFailedMsg("失败");
        }
        return ResponseMsg.buildSuccessMsg("成功");
    }

    /**
     * 修改项目编号
     */
    @RequestMapping("/editProjectNo")
    @ResponseBody
    public ResponseMsg editProjectNo(@RequestParam String projectNo, @RequestParam int id) {
        Project project = projectRepository.findByProjectNo(projectNo);
        if (project != null && id != project.getId()) {
            return ResponseMsg.buildFailedMsg("修改失败，该项目编号已存在");
        }
        Project current = projectRepository.findOne(id);
        if (current == null) {
            return ResponseMsg.buildFailedMsg("修改失败，该项目不存在");
        }
        projectRepository.updateProjectNo(projectNo, id);
        return ResponseMsg.buildSuccessMsg("修改成功");
    }

    /**
     * 项目提交审核
     */
    @RequestMapping("/saveApprove")
    @ResponseBody
    public ResponseMsg saveApprove(int id) throws Exception {
        Project project = projectRepository.findOne(id);
        projectService.saveApprove(project, InterfaceUtil.getAdmin());

        return ResponseMsg.buildSuccessMsg("提交成功");
    }
}
