package cn.ezhizao.project.business.housingFund.controller;

import cn.ezhizao.common.utils.PdfUtil;
import cn.ezhizao.common.utils.SecurityUtils;
import cn.ezhizao.common.utils.poi.ExcelUtil;
import cn.ezhizao.framework.aspectj.lang.annotation.Excel;
import cn.ezhizao.framework.aspectj.lang.annotation.Log;
import cn.ezhizao.framework.aspectj.lang.enums.BusinessType;
import cn.ezhizao.framework.web.controller.BaseController;
import cn.ezhizao.framework.web.domain.AjaxResult;
import cn.ezhizao.framework.web.page.TableDataInfo;
import cn.ezhizao.project.business.company.domain.BizCompany;
import cn.ezhizao.project.business.company.service.IBizCompanyService;
import cn.ezhizao.project.business.housingFund.domain.*;
import cn.ezhizao.project.business.housingFund.service.*;
import cn.ezhizao.project.business.salary.domain.BizFinancialSalaryDetail;
import cn.ezhizao.project.business.salary.domain.BizFinancialSalaryDetailEmployee;
import cn.ezhizao.project.business.socialSecurity.domain.BizSocialSecurityConfirm;
import cn.ezhizao.project.business.socialSecurity.domain.BizSocialSecurityConfirmDetail;
import cn.ezhizao.project.business.socialSecurity.domain.BizSocialSecurityConfirmDetailEmployee;
import cn.ezhizao.project.business.workOrder.domain.BizWorkOrderRecord;
import cn.ezhizao.project.business.workOrder.service.IBizWorkOrderRecordService;
import cn.ezhizao.project.system.domain.SysUser;
import cn.ezhizao.project.system.mapper.SysUserMapper;
import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.VerticalAlignment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
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 org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;

import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;


/**
 * @author 周晓
 */
@RestController
@Api(tags = "FinancialHousingFundConfirm数据接口")
@RequestMapping(value = "/business/housingFundConfirm")
public class BizHousingFundConfirmController extends BaseController {

    @Resource
    IBizHousingFundConfirmService housingFundConfirmService;
    @Resource
    IBizCompanyService companyService;
    @Resource
    IBizHousingFundConfirmDetailService housingFundConfirmDetailService;
    @Resource
    IBizHousingFundConfirmDetailEmployeeService housingFundConfirmDetailEmployeeService;
    @Resource
    IBizHousingFundDeclareService housingFundDeclareService;
    @Resource
    IBizHousingFundDeclareDetailService housingFundDeclareDetailService;
    @Resource
    IBizWorkOrderRecordService bizWorkOrderRecordService;

    @Resource
    private SysUserMapper sysUserMapper;

    @Value("${ruoyi.pdfTemplate.url}")
    private String templatePath;

    /**
     * 生成pdf
     */
    @Autowired
    private FreeMarkerConfigurer freeMarkerConfigurer;

    @ApiOperation(value = "根据id查询", notes = "根据id查询")
    @GetMapping("/getById/{id}")
    @ResponseBody
    public AjaxResult getById(@PathVariable Long id) {
        return success(housingFundConfirmService.getById(id));
    }


    @PreAuthorize("@ss.hasPermi('business:housingFundConfirm:view')")
    @PostMapping("/getDetail")
    public AjaxResult getDetail(@RequestBody BizHousingFundConfirmDetail condition) {
        List<BizHousingFundConfirmDetail> details = housingFundConfirmDetailService.getListByBean(condition);
        BizCompany company = companyService.getById(condition.getCompanyId());
        if (details.isEmpty()) {
            // 获取上个月的人员信息
            // 先获取之前的一个月是否已填报，然后获取填报后的工资人员信息
            BizHousingFundConfirmDetail detail = housingFundConfirmDetailService.query()
                    .eq("housing_fund_confirm_id", condition.getHousingFundConfirmId())
                    .lt("concat(year,month)", condition.getYear() + condition.getMonth()).orderByDesc("concat(year, month)").last("limit 1").one();
            if (detail != null) {
                List<BizHousingFundConfirmDetailEmployee> employees = housingFundConfirmDetailEmployeeService.query()
                        .eq("housing_fund_confirm_detail_id", detail.getId()).ne("change_status", 2).list();
                employees.forEach(em->{
                    em.setId(null);
                    em.setChangeStatus(0);});
                condition.setDetails(employees);
            } else {
                condition.setDetails(new ArrayList<>());
            }
            condition.setHousingFundPassword(company.getHousingFundPassword());
            condition.setHousingFundUnitAccount(company.getHousingFundUnitAccount());
            condition.setHousingFundDeductionPassword(company.getHousingFundDeductionPassword());
            condition.setIsPayOnWindow(company.getIsPayOnWindow());
            condition.setIsFirstHousingFund(company.getIsFirstHousingFund());
            return success(condition);
        }
        return success(details.get(0));
    }

    @PostMapping("/save")
    @ApiOperation(value = "保存", notes = "保存")
    @ResponseBody
    public AjaxResult save(@RequestBody BizHousingFundConfirm financialHousingFundConfirm) {
        return (financialHousingFundConfirm.getId() == null ? housingFundConfirmService.save(financialHousingFundConfirm) : housingFundConfirmService.updateById(financialHousingFundConfirm)) ? success() : error();
    }

    /**
     * 导出公积金模板
     */
    @Log(title = "导出社保模板", businessType = BusinessType.EXPORT)
    @PostMapping("/exportHousingFundTemplate")
    public void exportSalaryTemplate(HttpServletResponse response) throws NoSuchFieldException, IllegalAccessException {
        ExcelUtil<BizHousingFundConfirmDetailEmployee> util = new ExcelUtil<BizHousingFundConfirmDetailEmployee>(BizHousingFundConfirmDetailEmployee.class);
        util.importTemplateExcel(response, "公积金模板");
    }

    @PostMapping("/saveBatch")
    @ApiOperation(value = "批量保存", notes = "批量保存")
    @ResponseBody
    public AjaxResult saveBatch(@RequestBody List<BizHousingFundConfirm> list) {
        return housingFundConfirmService.saveOrUpdateBatch(list) ? success() : error();
    }

    @ApiOperation(value = "删除", notes = "删除")
    @GetMapping("/deleteById/{id}")
    @ResponseBody
    public AjaxResult deleteById(@PathVariable Long id) {
        return housingFundConfirmService.removeById(id) ? success() : error();
    }

    @ApiOperation(value = "批量删除", notes = "批量删除")
    @PostMapping("/batchDelete")
    @ResponseBody
    public AjaxResult batchDelete(@RequestBody List<Long> list) {
        return housingFundConfirmService.removeBatchByIds(list) ? success() : error();
    }

    @ApiOperation(value = "带条件List 分页查询", notes = "带条件List 分页查询")
    @GetMapping("/list")
    @ResponseBody
    @PreAuthorize("@ss.hasPermi('business:housingFundConfirm:list')")
    public TableDataInfo getList(BizHousingFundConfirm conditions) throws NoSuchFieldException, IllegalAccessException {
        String chooseYear = conditions.getYear();
        int nwoYear = LocalDate.now().getYear();
        setTenantId(conditions);
        startPage();
        startOrderBy();
        conditions.setYear(String.valueOf(nwoYear));
        List<BizHousingFundConfirm> list = housingFundConfirmService.getListByBean(conditions);
        if (!list.isEmpty()) {
            Map<String, Object> detailConditions = new HashMap<>();
            if (!chooseYear.equals(nwoYear)) {
                detailConditions.put("year", chooseYear);
            } else {
                detailConditions.put("year", conditions.getYear());
            }

            detailConditions.put("mainIds", list.stream().map(BizHousingFundConfirm::getId).collect(Collectors.toList()));
            List<BizHousingFundConfirmDetail> details = housingFundConfirmDetailService.getList2(detailConditions);
            list.forEach(l -> {
                l.setDetails(details.stream().filter(v -> v.getHousingFundConfirmId().equals(l.getId())).collect(Collectors.toList()));
            });
        }

        return getDataTable(list);
    }

    @ApiOperation("保存detail")
    @PostMapping("/saveDetail")
    @ResponseBody
    @PreAuthorize("@ss.hasPermi('business:housingFundConfirm:edit')")
    @Transactional(rollbackFor = Exception.class)
    @Log(title = "填写社保人员信息", businessType = BusinessType.UPDATE)
    public AjaxResult saveDetail(@RequestBody BizHousingFundConfirmDetail detail) {
        detail.setVerifierTime(new Date());
        detail.setVerifierId(SecurityUtils.getUserId());
        // 判断之前是否有保存一个明细
        BizHousingFundConfirmDetail conditions = new BizHousingFundConfirmDetail();
        conditions.setHousingFundConfirmId(detail.getHousingFundConfirmId());
        conditions.setYear(detail.getYear());
        conditions.setMonth(detail.getMonth());
        if (!housingFundConfirmDetailService.getListByBean(conditions).isEmpty()) {
            return error("该月已添加人员信息,请刷新列表。");
        }

        BizCompany company = companyService.getById(detail.getCompanyId());
        company.setHousingFundPassword(detail.getHousingFundPassword());
        company.setHousingFundUnitAccount(detail.getHousingFundUnitAccount());
        company.setHousingFundDeductionPassword(detail.getHousingFundDeductionPassword());
        company.setIsPayOnWindow(detail.getIsPayOnWindow());
        company.setIsFirstHousingFund(1);
        companyService.updateById(company);

        return toAjax(housingFundConfirmDetailService.save(detail) && addRecord(detail.getHousingFundConfirmId(), detail.getYear(), detail.getMonth(), SecurityUtils.getUserId(), "填写社保人员信息"));
    }

    @PreAuthorize("@ss.hasPermi('business:housingFundConfirm:edit')")
    @PostMapping("/updateDetail")
    @Transactional(rollbackFor = Exception.class)
    @Log(title = "修改公积金人员信息", businessType = BusinessType.UPDATE)
    public AjaxResult updateDetail(@RequestBody BizHousingFundConfirmDetail detail) {
        BizCompany company = companyService.getById(detail.getCompanyId());
        company.setHousingFundPassword(detail.getHousingFundPassword());
        company.setHousingFundUnitAccount(detail.getHousingFundUnitAccount());
        company.setHousingFundDeductionPassword(detail.getHousingFundDeductionPassword());
        company.setIsPayOnWindow(detail.getIsPayOnWindow());
        company.setIsFirstHousingFund(1);
        companyService.updateById(company);

        // 获取上个月的人员信息
        List<BizHousingFundConfirmDetailEmployee> employees = detail.getDetails().stream().filter(v ->  v.getChangeStatus()==null||v.getChangeStatus() != 2).collect(Collectors.toList());;
        BizHousingFundConfirmDetail old = housingFundConfirmDetailService.query()
                .eq("housing_fund_confirm_id", detail.getHousingFundConfirmId()).lt("concat(year,month)", detail.getYear() + detail.getMonth()).orderByDesc("concat(year, month)").last("limit 1").one();
        List<BizHousingFundConfirmDetailEmployee> oldEmployees;
        if (old != null) {
            oldEmployees = housingFundConfirmDetailEmployeeService.query()
                    .eq("housing_fund_confirm_detail_id", old.getId()).ne("change_status", 2).list();
        } else {
            oldEmployees = new ArrayList<>();
        }

        for (BizHousingFundConfirmDetailEmployee employee : detail.getDetails()) {
            if (oldEmployees.stream().noneMatch(v -> v.getPhone().equals(employee.getPhone()) && v.getEmployeeName().equals(employee.getEmployeeName()))) {
                if (employee.getChangeStatus() == 2) {
                    employee.setDeleted(1);
                } else {
                    employee.setChangeStatus(1);
                }
            }
        }
        return toAjax(housingFundConfirmDetailService.updateById(detail) && addRecord(detail.getHousingFundConfirmId(), detail.getYear(), detail.getMonth(), SecurityUtils.getUserId(), "修改公积金人员信息"));
    }

    @ApiOperation("获取之前的员工信息")
    @PostMapping("/getPrevEmployee")
    @ResponseBody
    @PreAuthorize("@ss.hasPermi('business:housingFundConfirm:query')")
    public AjaxResult getPrevEmployee(@RequestBody BizHousingFundConfirmDetail entity) {
        BizHousingFundConfirmDetail detail = housingFundConfirmDetailService.query().eq("housing_fund_confirm_id", entity.getHousingFundConfirmId()).lt("concat(year,month)", entity.getYear() + entity.getMonth()).orderByDesc("concat(year, month)").last("limit 1").one();
        if (detail != null) {
            List<BizHousingFundConfirmDetailEmployee> employees = housingFundConfirmDetailEmployeeService.query().eq("housing_fund_confirm_detail_id", detail.getId()).list();
            return success(employees);
        }
        return success(new ArrayList<>());
    }

    @PreAuthorize("@ss.hasPermi('business:housingFundConfirm:verify')")
    @PostMapping("/verifyDetail")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult verifyDetail(@RequestBody BizHousingFundConfirmDetail detail) {
        boolean bool = true;
        detail.setVerifierId(SecurityUtils.getUserId());
        if (detail.getStatus().equals(3)) {
            BizHousingFundConfirm housingFundConfirm = housingFundConfirmService.getById(detail.getHousingFundConfirmId());
            QueryWrapper<BizHousingFundDeclare> qw = new QueryWrapper<>();
            qw.eq("work_order_id", housingFundConfirm.getWorkOrderId());

            BizHousingFundDeclare bizHousingFundDeclare = housingFundDeclareService.getOne(qw);
            if (bizHousingFundDeclare != null) {
                QueryWrapper<BizHousingFundDeclareDetail> kqw = new QueryWrapper<>();
                kqw.eq("housing_fund_declare_id", bizHousingFundDeclare.getId());
                kqw.eq("year", detail.getYear());
                kqw.eq("month", detail.getMonth());
                BizHousingFundDeclareDetail housingFundDeclareDetail =
                        housingFundDeclareDetailService.getOne(kqw);
                if (housingFundDeclareDetail == null) {
                    housingFundDeclareDetail = new BizHousingFundDeclareDetail();
                }
                housingFundDeclareDetail.setHousingFundDeclareId(bizHousingFundDeclare.getId());
                housingFundDeclareDetail.setYear(detail.getYear());
                housingFundDeclareDetail.setMonth(detail.getMonth());
                housingFundDeclareDetail.setCompanyId(detail.getCompanyId());
                housingFundDeclareDetail.setStatus(housingFundDeclareDetail.getStatus() != null && housingFundDeclareDetail.getStatus() > 1 ? housingFundDeclareDetail.getStatus() : 1);

                if (housingFundDeclareDetail.getId() == null) {
                    bool = housingFundDeclareDetailService.save(housingFundDeclareDetail);
                } else {
                    bool = housingFundDeclareDetailService.updateById(housingFundDeclareDetail);
                }
            }
            bool = bool && addRecord(detail.getHousingFundConfirmId(), detail.getYear(), detail.getMonth(), SecurityUtils.getUserId(), "公积金人员信息审核通过");
//            return bool;
        } else {
            bool = bool && addRecord(detail.getHousingFundConfirmId(), detail.getYear(), detail.getMonth(), SecurityUtils.getUserId(), "公积金人员信息审核不通过");
        }
        bool = bool && housingFundConfirmDetailService.updateById(detail);
        return toAjax(bool);
    }

    @PreAuthorize("@ss.hasPermi('business:housingFundConfirm:return')")
    @PostMapping("/turnBackDetail")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult turnBackDetail(@RequestBody BizHousingFundConfirmDetail detail) {
        // 先判断是否社保申报完成，申报完成状态不能进行工资退回
        BizHousingFundDeclareDetail financialReceiveTicketDetail = housingFundDeclareDetailService.query().eq("company_id", detail.getCompanyId()).eq("year", detail.getYear()).eq("month", detail.getMonth()).one();
        if (financialReceiveTicketDetail != null && financialReceiveTicketDetail.getStatus() == 3) {
            return error("请先进行公积金申报退回操作再进行人员信息退回。");
        } else {
            detail.setStatus(2);
        }
        return toAjax(housingFundConfirmDetailService.updateById(detail) && addRecord(detail.getHousingFundConfirmId(), detail.getYear(), detail.getMonth(), SecurityUtils.getUserId(), "公积金人员退回"));
    }

    @PreAuthorize("@ss.hasPermi('business:housingFundConfirm:edit')")
    @PostMapping("/checkEmployees")
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult checkEmployees(@RequestBody BizHousingFundConfirmDetail detail) {
        List<BizHousingFundConfirmDetailEmployee> employees = detail.getDetails().stream().filter(v ->  v.getChangeStatus()==null||v.getChangeStatus() != 2).collect(Collectors.toList());
        BizHousingFundConfirmDetail old = housingFundConfirmDetailService.query().eq("housing_fund_confirm_id", detail.getHousingFundConfirmId()).lt("concat(year,month)", detail.getYear() + detail.getMonth()).orderByDesc("concat(year, month)").last("limit 1").one();
        if (old == null) {
            // 第一次不判断是否相同
            return success(true);
        }
        List<BizHousingFundConfirmDetailEmployee> oldEmployees = housingFundConfirmDetailEmployeeService.query().eq("housing_fund_confirm_detail_id", old.getId()).list();
        // 判断是否有删除
        if (oldEmployees.stream().anyMatch(v -> employees.stream().noneMatch(e -> e.getEmployeeName().equals(v.getEmployeeName()) && e.getPhone().equals(v.getPhone())))) {
            // 判断为有删除变更
            return success(false);
        }
        // 判断是否有新增变更
        if (employees.stream().anyMatch(v -> oldEmployees.stream().noneMatch(e -> e.getEmployeeName().equals(v.getEmployeeName()) && e.getPhone().equals(v.getPhone())))) {
            // 判断是否有新增变更
            return success(false);
        }
        return success(true);
    }

    private boolean addRecord(Long mainId, String year, String month, Long recorderId, String description) {
        // 没拆分合同单价
        BizHousingFundConfirm housingFundConfirm = housingFundConfirmService.getById(mainId);
        Long workOrderId = housingFundConfirm.getWorkOrderId();
        List<BizWorkOrderRecord> records = bizWorkOrderRecordService.query().eq("work_order_id", workOrderId).eq("year", year).eq("month", month).eq("from_id", 0).list();
        if (records.isEmpty()) {
            // 新增一条记录
            BizWorkOrderRecord record = new BizWorkOrderRecord();
            record.setMonth(month);
            record.setYear(year);
            record.setTenantId(getTenantId());
            record.setWorkOrderId(workOrderId);
            record.setCompanyId(housingFundConfirm.getCompanyId());
            record.setStatus(1);
            record.setStatusDescript(description);
            record.setRecorderId(recorderId);
            return bizWorkOrderRecordService.save(record);
        } else {
            // 新增一条子记录
            Long fromId = records.get(0).getId();
            BizWorkOrderRecord fromRecord = records.get(0);
            BizWorkOrderRecord record = new BizWorkOrderRecord();
            record.setFromId(fromId);
            record.setMonth(fromRecord.getMonth());
            record.setCompanyId(housingFundConfirm.getCompanyId());
            record.setYear(fromRecord.getYear());
            record.setTenantId(fromRecord.getTenantId());
            record.setWorkOrderId(fromRecord.getWorkOrderId());
            record.setStatus(fromRecord.getStatus());
            record.setStatusDescript(fromRecord.getStatusDescript());
            record.setRecorderId(fromRecord.getRecorderId());

            fromRecord.setMonth(month);
            fromRecord.setYear(year);
            fromRecord.setTenantId(getTenantId());
            fromRecord.setWorkOrderId(workOrderId);
            fromRecord.setCompanyId(housingFundConfirm.getCompanyId());
            fromRecord.setStatus(1);
            fromRecord.setStatusDescript(description);
            fromRecord.setRecorderId(recorderId);
            return bizWorkOrderRecordService.save(record) &&
                    bizWorkOrderRecordService.updateById(fromRecord);
        }
    }

    @Log(title = "公积金导入", businessType = BusinessType.IMPORT)
    @PreAuthorize("@ss.hasPermi('business:housingFundConfirm:import')")
    @PostMapping("/importData")
    public AjaxResult importData(MultipartFile file, @RequestParam String year, @RequestParam String month) throws Exception {
        ExcelUtil<BizHousingFundConfirmDetailEmployee> util = new ExcelUtil<>(BizHousingFundConfirmDetailEmployee.class);
        List<BizHousingFundConfirmDetailEmployee> detailList = util.importExcel(file.getInputStream());

        // 获取 入Excel 表头字段
        List<String> excelHeaders = util.readExcelHeaders(file.getInputStream());

        //获取实体类字段
        List<String> names = getExcelAnnotatedFields(BizHousingFundConfirmDetailEmployee.class);
        //如果不存在模板中的字段，返回错误
        if (!excelHeaders.containsAll(names)) {
            return error("导入数据与模板不匹配！");
        }
        String message = housingFundConfirmService.importHousingFundCon(detailList, year, month, getTenantId() == null ? 0 : getTenantId());
        return success(message);
    }


    public List<String> getExcelAnnotatedFields(Class<?> clazz) {
        Field[] fields = clazz.getDeclaredFields();
        List<String> result = new ArrayList<>();
        for (Field field : fields) {
            if (field.isAnnotationPresent(Excel.class)) {
                Excel excelAnnotation = field.getAnnotation(Excel.class);
                String fieldName = excelAnnotation.name();
                result.add(fieldName);
            }
        }
        return result;
    }


    /**
     * 导出列表
     */
    @PreAuthorize("@ss.hasPermi('business:housingFundConfirm:export')")
    @Log(title = "个税详情", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, BizHousingFundConfirm housingFundConfirm) throws NoSuchFieldException, IllegalAccessException {
        setTenantId(housingFundConfirm);
        startOrderBy();
        List<BizHousingFundConfirm> list = housingFundConfirmService.getListByBean(housingFundConfirm);
        for (BizHousingFundConfirm l : list) {
            l.setCurrentPeriod(housingFundConfirm.getYear() + "-" + housingFundConfirm.getMonth());
            BizHousingFundConfirmDetail detail = new BizHousingFundConfirmDetail();
            detail.setHousingFundConfirmId(l.getId());
            detail.setYear(housingFundConfirm.getYear());
            detail.setMonth(housingFundConfirm.getMonth());
            List<BizHousingFundConfirmDetail> details = housingFundConfirmDetailService.getListByBean(detail);
            if (details.size() == 0) {
                l.setStatusText("未开始");
                l.setServiceName("");
            } else {
                detail = details.get(0);
                SysUser sysUser = sysUserMapper.selectUserById(detail.getVerifierId());
                l.setServiceName(sysUser == null ? "" : sysUser.getNickName());
                switch (detail.getStatus()) {
                    case 0:
                        l.setStatusText("未开始");
                        break;
                    case 2:
                        l.setStatusText("待审核");
                        break;
                    case 3:
                        l.setStatusText("已完成");
                        break;
                    case 4:
                        l.setStatusText("驳回待处理");
                        break;
                    default:
                        break;
                }
            }
        }
        ExcelUtil<BizHousingFundConfirm> util = new ExcelUtil<BizHousingFundConfirm>(BizHousingFundConfirm.class);
        util.exportExcel(response, list, "社保人员确认数据");
    }

    @ApiOperation("导出公积金人员信息")
    @PostMapping("/exportHousingFundConfirmExcel")
    public void exportDetailExcel(@RequestParam Long id, HttpServletResponse response) {
        BizHousingFundConfirmDetail housingFundConfirm = housingFundConfirmDetailService.getById(id);
        BizCompany company;

        if (null != housingFundConfirm) {
            Map<String, Object> map = new HashMap<>();
//            BizHousingFundConfirmDetailEmployee map = new BizHousingFundConfirmDetailEmployee();
            map.put("housingFundConfirmDetailId", housingFundConfirm.getId());
//            map.setHousingFundConfirmDetailId(housingFundConfirm.getId());
            List<BizHousingFundConfirmDetailEmployee> financialSalaryDetailEmployeeList = housingFundConfirmDetailEmployeeService.getList(map);
            housingFundConfirm.setDetails(financialSalaryDetailEmployeeList);
            company = companyService.getById(housingFundConfirm.getCompanyId());
        } else {
            return;
        }
        ExcelWriter writer = cn.hutool.poi.excel.ExcelUtil.getWriter(true);
        writer.merge(0, 0, 0, 4, "公积金人员信息", true);
        writer.merge(1, 1, 0, 2, company.getName(), false);
        writer.merge(1, 1, 3, 4, housingFundConfirm.getYear() + "年 第" + housingFundConfirm.getMonth() + "期", false);
        writer.writeCellValue(0, 2, "员工名");
        writer.writeCellValue(1, 2, "电话号码");
        writer.writeCellValue(2, 2, "基数");
        writer.writeCellValue(3, 2, "比例");
        writer.writeCellValue(4, 2, "备注");

        int row = 0;
        for (int i = 0; i < housingFundConfirm.getDetails().size(); i++) {
            writer.writeCellValue(0, i + 3, housingFundConfirm.getDetails().get(i).getEmployeeName());
            writer.writeCellValue(1, i + 3, housingFundConfirm.getDetails().get(i).getPhone());
            writer.writeCellValue(2, i + 3, housingFundConfirm.getDetails().get(i).getCardinalNumber());
            writer.writeCellValue(3, i + 3, housingFundConfirm.getDetails().get(i).getRatio());
            writer.writeCellValue(4, i + 3, housingFundConfirm.getDetails().get(i).getRemark());

            row = i + 1;
        }

        // 默认的，未添加alias的属性也会写出，如果想只写出加了别名的字段，可以调用此方法排除之
        writer.setOnlyAlias(true);
        // 设置列宽行高
        writer.setDefaultRowHeight(22);

        // 设置所有列宽自适应
        writer.autoSizeColumnAll();
        // 设置 列宽
        writer.setColumnWidth(0, 10);
        writer.setColumnWidth(1, 15);
        writer.setColumnWidth(2, 10);
        writer.setColumnWidth(3, 10);
        writer.setColumnWidth(4, 10);

        //设置标题单元格 样式
        Font headFont = writer.createFont();
        // 设置字体大小，加载到样式中
        headFont.setFontHeightInPoints((short) 11);
        headFont.setFontName("楷体_GB2312");
        headFont.setBold(true);
        CellStyle headCellStyle = writer.getStyleSet().getHeadCellStyle();
        headCellStyle.setFont(headFont);
        headCellStyle.setAlignment(HorizontalAlignment.CENTER);
        headCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        //设置普通单元格 样式
        Font contentFont = writer.createFont();
        // 设置字体大小，加载到样式中
        contentFont.setFontHeightInPoints((short) 11);
        contentFont.setFontName("宋体");
        CellStyle cellstyle = writer.getStyleSet().getCellStyle();
        cellstyle.setFont(contentFont);
        cellstyle.setAlignment(HorizontalAlignment.CENTER);
        cellstyle.setVerticalAlignment(VerticalAlignment.CENTER);
        writer.setRowHeight(1, 22);
        // headSize 为表格 标题 和 表头所占的 行数
        int headSize = 3;

        //out为OutputStream，需要写出到的目标流 response为HttpServletResponse对象
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        //test.xls是弹出下载对话框的文件名，不能为中文，中文请自行编码
        response.setHeader("Content-Disposition", "attachment;filename=test.xlsx");
        ServletOutputStream out = null;
        try {
            out = response.getOutputStream();
        } catch (IOException e) {
            e.printStackTrace();
        }
        writer.flush(out, true);
        // 关闭writer，释放内存
        writer.close();
        //此处记得关闭输出Servlet流
        IoUtil.close(out);
    }

    @ApiOperation("打印公积金人员信息")
    @PostMapping("/printDetailPdf")
    public void SocialSecurityPdf(@RequestParam Long id, HttpServletResponse response) throws IOException, TemplateException {
        BizHousingFundConfirmDetail housingFundConfirm = housingFundConfirmDetailService.getById(id);
        BizCompany company;

        if (null != housingFundConfirm) {
            Map<String, Object> map = new HashMap<>();
            map.put("housingFundConfirmDetailId", housingFundConfirm.getId());
            List<BizHousingFundConfirmDetailEmployee> financialSalaryDetailEmployeeList = housingFundConfirmDetailEmployeeService.getList(map);
            housingFundConfirm.setDetails(financialSalaryDetailEmployeeList);
            company = companyService.getById(housingFundConfirm.getCompanyId());
            housingFundConfirm.setCompanyName(company.getName());
            housingFundConfirm.setTime(housingFundConfirm.getYear() + "年" + " " + "第" + housingFundConfirm.getMonth() + "期");

        } else {
            return;
        }
        Map<String, Object> paramMap = new HashMap<>();
        paramMap.put("housingFundConfirm", housingFundConfirm);
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
        Writer out = new StringWriter();
        //获取模板地址
        Template template = freeMarkerConfigurer.getConfiguration().getTemplate("housingFundTemplate.html");
        template.process(paramMap, out);
        out.flush();
        out.close();
        String templateContent = out.toString();
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/pdf");
        String fileName = "公积金人员信息表";
        response.setHeader("Content-Disposition", "filename=" + new String(fileName.getBytes()));
        byte[] resources = PdfUtil.html2Pdf(templateContent);
        ServletOutputStream outputStream = response.getOutputStream();
        outputStream.write(resources);
        outputStream.close();
    }
}
