package com.yh.saas.plugin.news.service.impl;

import ch.qos.logback.classic.Logger;
import com.alipay.sofa.runtime.api.annotation.SofaReference;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.winsea.svc.base.base.entity.*;
import com.winsea.svc.base.base.service.*;
import com.winsea.svc.base.base.util.DateUtils;
import com.winsea.svc.base.base.view.DeptInfoView;
import com.winsea.svc.base.security.entity.User;
import com.winsea.svc.base.security.util.AuthSecurityUtils;
import com.yh.saas.plugin.news.command.*;
import com.yh.saas.plugin.news.constant.CircularConstant;
import com.yh.saas.plugin.news.entity.CircularManagementInfo;
import com.yh.saas.plugin.news.entity.CircularManagementReceive;
import com.yh.saas.plugin.news.enums.CircularStatusEnum;
import com.yh.saas.plugin.news.mapper.NewsCircularManagementInfoMapper;
import com.yh.saas.plugin.news.service.INewsCircularManagementInfoService;
import com.yh.saas.plugin.news.service.INewsCircularManagementReceiveService;
import com.yh.saas.plugin.news.service.INewsOperationHisService;
import com.yh.saas.plugin.news.util.thread.ExcelCellAutoHeight;
import com.yh.saas.plugin.news.vo.CircularManagementInfoVo;
import com.yh.saas.plugin.news.vo.CircularManagementReceiveVo;
import com.yh.saas.plugin.news.vo.DeptInfoVo;
import com.winsea.svc.notice.entity.NoticeTaskInfo;
import com.winsea.svc.notice.entity.base.BaseNotice;
import com.winsea.svc.notice.service.INoticeService;
import com.winsea.svc.notice.service.INoticeTaskService;
import com.yh.saas.common.support.util.IdGenerator;
import com.yh.saas.common.support.util.query.QueryUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.httpclient.util.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.Footer;
import org.apache.poi.ss.usermodel.Header;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.net.URLDecoder;
import java.text.DecimalFormat;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * <p>
 * 记录体系通函管理表 服务实现类
 * </p>
 *
 * @author wxg
 * @since 2019-10-15
 */
@Service
public class NewsCircularManagementInfoServiceImpl
        extends ServiceImpl<NewsCircularManagementInfoMapper, CircularManagementInfo>
        implements INewsCircularManagementInfoService {
    Logger log = (Logger) LoggerFactory.getLogger(this.getClass());

    @Value("${file-root-path}")
    private String localPath;

    @Autowired
    private INewsCircularManagementReceiveService circularManagementReceiveService;

    @SofaReference
    private ICommonRoleService commonRoleService;

    @SofaReference
    private ICommonStaffRoleService staffRoleService;

    @SofaReference
    private ICommonStaffService staffService;

    @SofaReference
    private ICommonVesselService vesselService;

    @SofaReference
    private ICommonDepartmentService commonDepartmentService;

    @Autowired
    private INewsOperationHisService operationHisService;

    @SofaReference
    private INoticeTaskService taskService;

    /**
     * 导出通知通函一览
     * @param example
     * @return
     */
    @Override
    public void exportCircularManagementInfoList(
            CircularManagementInfoSearchCommand example, HttpServletResponse response) {

        Page<CircularManagementInfoVo> queryCircularManagementInfoList = this.queryCircularManagementInfoList(example);
        List<CircularManagementInfoVo> records = queryCircularManagementInfoList.getRecords();

        SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd");

        User user = AuthSecurityUtils.getCurrentUserInfo();

        CommonStaff staff = staffService.selectById(user.getUserId());

        // 1.Excel的头部信息
        String headerTitle = "";

        // 2.创建一个webbook 对应一个Excel文件
        HSSFWorkbook wb = new HSSFWorkbook();

        // 3.在webbook中添加一个sheet，对应Excel文件中的sheet
        HSSFSheet sheet;

        sheet = wb.createSheet("信息传递记录表");

        Header header = sheet.getHeader();
        //自定义页眉,并设置页眉 左中右显示信息
        header.setLeft(HSSFHeader.fontSize((short) 12) + "信息传递控制程序");
        header.setRight(HSSFHeader.fontSize((short) 12) + "ZYHY-SMS-MP03");
        //设置页交
        Footer footer = sheet.getFooter();
        footer.setLeft(HSSFHeader.fontSize((short) 12) +"天津中运海运集团有限公司");
        footer.setCenter(HSSFHeader.fontSize((short) 12) +"版次：4.0");
        footer.setRight(HSSFHeader.fontSize((short) 12) +"页次："+ HSSFFooter.page()+"/"+HSSFFooter.numPages());

        // 4.设置打印参数
        sheet.setMargin(HSSFSheet.TopMargin,  1.0);
        sheet.setMargin(HSSFSheet.BottomMargin,  1.0);
        sheet.setMargin(HSSFSheet.LeftMargin,  0.4);
        sheet.setMargin(HSSFSheet.RightMargin,  0.4);

        // 不显示网格
        sheet.setDisplayGridlines(false);
        // 设置水平居中
        sheet.setHorizontallyCenter(true);

        /**************** 数据行样式 start ****************/

        HSSFFont fontCompany = wb.createFont();
        fontCompany.setFontName("宋体");
        fontCompany.setFontHeightInPoints((short) 16);
        // 设置字体加粗
        fontCompany.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);

        HSSFFont fontDetailTitle = wb.createFont();
        fontDetailTitle.setFontName("宋体");
        fontDetailTitle.setFontHeightInPoints((short) 14);
        // 设置字体加粗
        fontDetailTitle.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);

        // 明细字体
        HSSFFont fontDetail = wb.createFont();
        fontDetail.setFontName("宋体");
        fontDetail.setFontHeightInPoints((short) 12);

        // 明细字体
        HSSFFont fontRemark = wb.createFont();
        fontRemark.setFontName("宋体");
        fontRemark.setFontHeightInPoints((short) 10);

        // 信息样式(表头)
        HSSFCellStyle styleTitle = wb.createCellStyle();
        // 指定单元格居中对齐
        styleTitle.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        // 指定单元格垂直居中对齐
        styleTitle.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        // 指定单元格自动换行
        styleTitle.setWrapText(true);
        // 设置单元格字体
        styleTitle.setFont(fontDetailTitle);
        // 右边框
        styleTitle.setBorderRight(HSSFCellStyle.BORDER_NONE);
        // 左边框
        styleTitle.setBorderLeft(HSSFCellStyle.BORDER_NONE);
        // 上边框
        styleTitle.setBorderTop(HSSFCellStyle.BORDER_NONE);
        // 下边框
        styleTitle.setBorderBottom(HSSFCellStyle.BORDER_NONE);

        // 信息样式(12边框中)
        HSSFCellStyle styleDetail = wb.createCellStyle();
        // 指定单元格居中对齐
        styleDetail.setAlignment(HSSFCellStyle.ALIGN_CENTER);
        // 指定单元格垂直居中对齐
        styleDetail.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        // 指定单元格自动换行
        styleDetail.setWrapText(true);
        // 设置单元格字体
        styleDetail.setFont(fontDetail);
        // 右边框
        styleDetail.setBorderRight(HSSFCellStyle.BORDER_THIN);
        // 左边框
        styleDetail.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        // 上边框
        styleDetail.setBorderTop(HSSFCellStyle.BORDER_THIN);
        // 下边框
        styleDetail.setBorderBottom(HSSFCellStyle.BORDER_THIN);

        // 信息样式(12边框左)
        HSSFCellStyle styleDetailLeft = wb.createCellStyle();
        // 指定单元格居中对齐
        styleDetailLeft.setAlignment(HSSFCellStyle.ALIGN_LEFT);
        // 指定单元格垂直居中对齐
        styleDetailLeft.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        // 指定单元格自动换行
        styleDetailLeft.setWrapText(true);
        // 设置单元格字体
        styleDetailLeft.setFont(fontDetail);
        // 右边框
        styleDetailLeft.setBorderRight(HSSFCellStyle.BORDER_THIN);
        // 左边框
        styleDetailLeft.setBorderLeft(HSSFCellStyle.BORDER_THIN);
        // 上边框
        styleDetailLeft.setBorderTop(HSSFCellStyle.BORDER_THIN);
        // 下边框
        styleDetailLeft.setBorderBottom(HSSFCellStyle.BORDER_THIN);

        // 信息样式(12边框左)
        HSSFCellStyle styleRemark = wb.createCellStyle();
        // 指定单元格居中对齐
        styleRemark.setAlignment(HSSFCellStyle.ALIGN_LEFT);
        // 指定单元格垂直居中对齐
        styleRemark.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
        // 指定单元格自动换行
        styleRemark.setWrapText(true);
        // 设置单元格字体
        styleRemark.setFont(fontRemark);
        // 右边框
        styleRemark.setBorderRight(HSSFCellStyle.BORDER_NONE);
        // 左边框
        styleRemark.setBorderLeft(HSSFCellStyle.BORDER_NONE);
        // 上边框
        styleRemark.setBorderTop(HSSFCellStyle.BORDER_NONE);
        // 下边框
        styleRemark.setBorderBottom(HSSFCellStyle.BORDER_NONE);

        /**************** 数据行样式 end ****************/

        // 设置列宽
        sheet.setColumnWidth(0, 1 * 256 + 184);
        sheet.setColumnWidth(1, 5 * 256 + 184);
        sheet.setColumnWidth(2, 22 * 256 + 184);
        sheet.setColumnWidth(3, 15 * 256 + 184);
        sheet.setColumnWidth(4, 15 * 256 + 184);
        sheet.setColumnWidth(5, 15 * 256 + 184);
        sheet.setColumnWidth(6, 60 * 256 + 184);
        sheet.setColumnWidth(7, 15 * 256 + 184);
        sheet.setColumnWidth(8, 15 * 256 + 184);
        sheet.setColumnWidth(9, 1 * 256 + 184);


        // 创建单元格对象
        HSSFCell cell = null;

        // 创建打印设置对象
        HSSFPrintSetup ps = sheet.getPrintSetup();
        // 打印方向，true：横向，false：纵向(默认)
        ps.setLandscape(true);
        // // 打印质量
        // ps.setVResolution((short) 700)
        // 设置缩放比例
        ps.setScale((short) 80);
        // 纸张类型
        ps.setPaperSize(HSSFPrintSetup.A4_PAPERSIZE);

        int rownum = 1;

        HSSFRow row = sheet.createRow((int) rownum);
        row.setHeightInPoints(55);
        cell = row.createCell(1);
        cell.setCellStyle(styleTitle);
        cell.setCellValue("信息传递记录表");
        sheet.addMergedRegion(new CellRangeAddress(rownum, rownum, (short) 1, (short) 8));
        for (int i = 2; i < 9; i++) {
            cell = row.createCell(i);
            cell.setCellStyle(styleTitle);
        }
        rownum++;

        HSSFRow row1 = sheet.createRow(rownum);
        row1.setHeightInPoints(30);
        cell = row1.createCell(1);
        cell.setCellStyle(styleDetail);
        cell.setCellValue("序号");
        cell = row1.createCell(2);
        cell.setCellStyle(styleDetail);
        cell.setCellValue("信息名称");
        cell = row1.createCell(3);
        cell.setCellStyle(styleDetail);
        cell.setCellValue("传递部门");
        cell = row1.createCell(4);
        cell.setCellStyle(styleDetail);
        cell.setCellValue("传递方式");
        cell = row1.createCell(5);
        cell.setCellStyle(styleDetail);
        cell.setCellValue("传递时间");
        cell = row1.createCell(6);
        cell.setCellStyle(styleDetail);
        cell.setCellValue("接收部门");
        cell = row1.createCell(7);
        cell.setCellStyle(styleDetail);
        cell.setCellValue("接收时间");
        cell = row1.createCell(8);
        cell.setCellStyle(styleDetail);
        cell.setCellValue("记录人");
        rownum++;

        if(CollectionUtils.isNotEmpty(records)){
            int num = 1;
            //该条单据明细
            CircularManagementInfoVo info = new CircularManagementInfoVo();
            for(CircularManagementInfoVo detail : records){
                info = this.getInfoById(detail.getId());

                String vesselAndDeptName = "";
                List<CommonDepartment> departmentList = info.getReceiveDept().get(0).getDepartmentList();
                List<CommonVessel> receiveVessel = info.getReceiveVessel();
                //部门和船舶数
                int deptNo = departmentList.size() + receiveVessel.size();
                //选择的部门或船舶数量
                int choose = 0;
                for(CommonDepartment dept : departmentList){
                    if(null != dept.getChangeFlag()){
                        vesselAndDeptName += dept.getDeptName() + "/";
                        choose++;
                    }

                }
                for(CommonVessel vessel : receiveVessel){
                    if(!StringUtils.equals("0",vessel.getClientFlag())){
                        vesselAndDeptName += vessel.getVesselName() + "/";
                        choose++;
                    }

                }
                if(deptNo == choose){
                    vesselAndDeptName = "所有船舶/部门";
                }
                if(StringUtils.isNotEmpty(vesselAndDeptName) && vesselAndDeptName.charAt(vesselAndDeptName.length()-1) == '/'){
                    vesselAndDeptName = vesselAndDeptName.substring(0,vesselAndDeptName.length()-1);
                }
                float f = 25f;
                float f1 = ExcelCellAutoHeight.getExcelCellAutoHeight(detail.getTheme(), 8f, 25f);
                if (f < f1) {
                    f = f1;
                }
                f1 = ExcelCellAutoHeight.getExcelCellAutoHeight(vesselAndDeptName, 	30f, 25f);
                if (f < f1) {
                    f = f1;
                }
                HSSFRow row2 = sheet.createRow(rownum);
                row2.setHeightInPoints(f);
                cell = row2.createCell(1);
                cell.setCellStyle(styleDetail);
                cell.setCellValue(num);
                cell = row2.createCell(2);
                cell.setCellStyle(styleDetailLeft);
                cell.setCellValue(detail.getTheme());
                cell = row2.createCell(3);
                cell.setCellStyle(styleDetail);
                cell.setCellValue(detail.getDeptName());
                cell = row2.createCell(4);
                cell.setCellStyle(styleDetail);
                cell.setCellValue("系统");
                cell = row2.createCell(5);
                cell.setCellStyle(styleDetail);
                cell.setCellValue(sd.format(detail.getDateOfIssue()));
                cell = row2.createCell(6);
                cell.setCellStyle(styleDetailLeft);
                cell.setCellValue(vesselAndDeptName);
                cell = row2.createCell(7);
                cell.setCellStyle(styleDetail);
                if(null != detail.getValidityPeriod()){

                    cell.setCellValue(sd.format(detail.getValidityPeriod()));
                }else{
                    cell.setCellValue("永久有效");

                }
                cell = row2.createCell(8);
                cell.setCellStyle(styleDetail);
                cell.setCellValue(staff.getStaffName());
                num++;
                rownum++;

            }
        }

        HSSFRow row3 = sheet.createRow((int) rownum);
        row3.setHeightInPoints(30);
        cell = row3.createCell(1);
        cell.setCellStyle(styleRemark);
        cell = row3.createCell(2);
        cell.setCellStyle(styleRemark);
        cell.setCellValue("注：本表由信息记录人记录并保存，保存期1年。");
        sheet.addMergedRegion(new CellRangeAddress(rownum, rownum, (short) 2, (short) 8));
        for (int i = 3; i < 9; i++) {
            cell = row.createCell(i);
            cell.setCellStyle(styleRemark);
        }

        String path = null;
        String tempPath = null;
        String excelPath = null;

        try {

            // 取得绝对路径
            tempPath = URLDecoder.decode((localPath), "utf-8");

            // EXCEL路径
            excelPath = "/web/temp/repair/" + DateUtil.formatDate(new Date(), DateUtils.DATE_FMT_YYYYMMDD_NS) + '/'
                    + UUID.randomUUID().toString().replaceAll("-", "");

            path = tempPath + excelPath + '/' + "信息传递记录表" + ".xls";

        } catch (Exception e) {
            log.debug(e.getMessage());
        }
        // 下载
        download(path, response, wb);

    }

    /**
     * 一览查询
     *
     * @param example
     * @return
     */
    @Override
    public Page<CircularManagementInfoVo> queryCircularManagementInfoList(
            CircularManagementInfoSearchCommand example) {
        if (StringUtils.isBlank(example.getCompId())) {
            example.setCompId(AuthSecurityUtils.getCurrentUserInfo().getCompId());
        }
        // 将参数类转化成实体类
        CircularManagementInfo circularManagementInfo = new CircularManagementInfo();
        BeanUtils.copyProperties(example, circularManagementInfo);

        // 查询列表
        Wrapper<CircularManagementInfo> itemWrapper = QueryUtils.convertExampleToWrapper(circularManagementInfo);
        if (StringUtils.isNotBlank(example.getCreateUserId())) {
            itemWrapper.eq("create_user_id", example.getCreateUserId());
        }
        if (StringUtils.isNotBlank(circularManagementInfo.getSearchKeyword())) {
            itemWrapper.andNew(
                    CircularManagementInfo.QueryFields.THEME + " like {0} OR "
                            + CircularManagementInfo.QueryFields.CIRCULAR_CODE + " like {0}",
                    "%" + circularManagementInfo.getSearchKeyword() + "%");
        }

        if (example.getStartDate() != null) {
            itemWrapper.andNew("date_of_issue >= {0}", example.getStartDate());
        }
        if (example.getEndDate() != null) {
            itemWrapper.andNew("date_of_issue <= {0}", example.getEndDate());
        }
        if (StringUtils.isBlank(example.getOrderColunm())) {
            itemWrapper.orderBy(CircularManagementInfo.QueryFields.STATUS_ID, true);
            itemWrapper.orderBy(CircularManagementInfo.QueryFields.DATE_OF_ISSUE, false);
        }
        Page<CircularManagementInfo> pageList = this.selectPage(circularManagementInfo.getQueryPage(), itemWrapper);

        // 循环列表将实体类转换成VO
        Page<CircularManagementInfoVo> resultList = new Page<>();
        List<CircularManagementInfoVo> voList = new ArrayList<>();
        pageList.getRecords().forEach(item -> {
            CircularManagementInfoVo circularManagementInfoVo = new CircularManagementInfoVo();
            BeanUtils.copyProperties(item, circularManagementInfoVo);

            if (StringUtils.isNotBlank(circularManagementInfoVo.getAttachmentPath())) {
                String[] attachmentPaths = circularManagementInfoVo.getAttachmentPath().split(",");
                circularManagementInfoVo.setAttachmentNum(String.valueOf(attachmentPaths.length));
            } else {
                circularManagementInfoVo.setAttachmentNum("0");
            }

            voList.add(circularManagementInfoVo);
        });
        resultList.setRecords(voList);
        resultList.setTotal(pageList.getTotal());
        resultList.setCurrent(pageList.getCurrent());
        resultList.setSize(pageList.getSize());

        return resultList;
    }

    /**
     * 查询明细
     *
     * @param id
     * @return
     */
    @Override
    public CircularManagementInfoVo getInfoById(String id) {
        // 查询详情
        CircularManagementInfoVo circularManagementInfoVo = new CircularManagementInfoVo();
        CircularManagementInfo circularManagementInfo = this.selectById(id);
        List<DeptInfoView> deptInfoVoList = commonDepartmentService.getDeptList(null, "asc", AuthSecurityUtils.getCurrentUserInfo().getTenantId());
        List<CommonVessel> vesselList = vesselService.getVesselList(AuthSecurityUtils.getCurrentUserInfo().getCompId(), null, "asc");
        //默认都放null(没选择)
        if(CollectionUtils.isNotEmpty(deptInfoVoList)) {
        	for(DeptInfoView  deptInfo : deptInfoVoList) {
        		deptInfo.getDepartmentList().forEach(dept -> {
                        dept.setChangeFlag(null);
                });
        	}
        }
        // 将实体类转化成VO
        BeanUtils.copyProperties(circularManagementInfo, circularManagementInfoVo);
        // 把需要反馈的船舶变成1
        if (StringUtils.isNotBlank(circularManagementInfo.getVesselIds())) {
            List<String> vesselIds = Arrays.asList(circularManagementInfo.getVesselIds().split(","));
            if (CollectionUtils.isNotEmpty(vesselIds)) {
                vesselList.forEach(vessel -> {
                    if (vesselIds.contains(vessel.getVesselId())) {
                        vessel.setClientFlag("1");
                    }
                });
            }
        }
        // 把不需要反馈船舶变成2
        if (StringUtils.isNotBlank(circularManagementInfo.getNoFeedbackVesselIds())) {
        	List<String> vesselIds = Arrays.asList(circularManagementInfo.getNoFeedbackVesselIds().split(","));
        	if (CollectionUtils.isNotEmpty(vesselIds)) {
        		vesselList.forEach(vessel -> {
        			if (vesselIds.contains(vessel.getVesselId())) {
        				vessel.setClientFlag("2");
        			}
        		});
        	}
        }
        // 把需要反馈的部门变成true
        if (StringUtils.isNotBlank(circularManagementInfo.getDeptIds())) {
            List<String> deptIds = Arrays.asList(circularManagementInfo.getDeptIds().split(","));
            if (CollectionUtils.isNotEmpty(deptIds)) {
                for (DeptInfoView deptInfoVo : deptInfoVoList) {
                    deptInfoVo.getDepartmentList().forEach(dept -> {
                        if (deptIds.contains(dept.getDeptId())) {
                            dept.setChangeFlag(true);
                        }
                    });
                }
            }
        }
        // 把不需要反馈的部门变成false
        if (StringUtils.isNotBlank(circularManagementInfo.getNoFeedbackDeptIds())) {
        	List<String> deptIds = Arrays.asList(circularManagementInfo.getNoFeedbackDeptIds().split(","));
        	if (CollectionUtils.isNotEmpty(deptIds)) {
        		for (DeptInfoView deptInfoVo : deptInfoVoList) {
        			deptInfoVo.getDepartmentList().forEach(dept -> {
        				if (deptIds.contains(dept.getDeptId())) {
        					dept.setChangeFlag(false);
        				}
        			});
        		}
        	}
        }


        circularManagementInfoVo.setReceiveVessel(vesselList);
        circularManagementInfoVo.setReceiveDept(deptInfoVoList);
        return circularManagementInfoVo;
    }

    /**
     * 新增保存
     *
     * @param example
     * @return
     */
    @Override
    public String saveCircularManagementInfo(CircularManagementInfoSaveCommand example) {
        if (StringUtils.isBlank(example.getCompId())) {
            example.setCompId(AuthSecurityUtils.getCurrentUserInfo().getCompId());
        }

        // 将参数类转化成实体类
        CircularManagementInfo circularManagementInfo = new CircularManagementInfo();
        BeanUtils.copyProperties(example, circularManagementInfo);
        circularManagementInfo.setId(IdGenerator.generateLongIncrId());
        circularManagementInfo.setStatusId(CircularStatusEnum.WAITSEND.getFlag());
        circularManagementInfo.setStatus(CircularStatusEnum.WAITSEND.getName());
        circularManagementInfo.setStatusEn(CircularStatusEnum.WAITSEND.getNameEn());
        getVesselIdAndDeptId(example, circularManagementInfo);// 取得选中的船舶和部门
        // 保存信息
        this.insert(circularManagementInfo);
        return circularManagementInfo.getId();
    }

    /**
     * 编辑保存
     *
     * @param example
     * @return
     */
    @Override
    public String updateCircularManagementInfo(CircularManagementInfoSaveCommand example) {
        if (StringUtils.isBlank(example.getCompId())) {
            example.setCompId(AuthSecurityUtils.getCurrentUserInfo().getCompId());
        }

        // 将参数类转化成实体类
        CircularManagementInfo circularManagementInfo = new CircularManagementInfo();
        BeanUtils.copyProperties(example, circularManagementInfo);
        getVesselIdAndDeptId(example, circularManagementInfo);// 取得选中的船舶和部门
        // 保存信息
        this.updateById(circularManagementInfo);
        return circularManagementInfo.getId();
    }

    /**
     * 插入发送的船舶和部门ids
     *
     * @param example
     * @param circularManagementInfo
     */
    private void getVesselIdAndDeptId(CircularManagementInfoSaveCommand example, CircularManagementInfo circularManagementInfo) {

        List<CircularManagementReceive> tempReceive = getVesselTypeReceive(example.getReceiveVessel(), new CircularManagementReceive());
        if (CollectionUtils.isNotEmpty(tempReceive)) {
            circularManagementInfo.setVesselIds(tempReceive.stream().map(CircularManagementReceive::getVesselDeptId).collect(Collectors.joining(",")));
        }else{
            circularManagementInfo.setVesselIds("");
        }
        // 取得不需要反馈的船舶
        List<CircularManagementReceive> tempReceive1 = getNoFeedbackVesselTypeReceive(example.getReceiveVessel(), new CircularManagementReceive());
        if (CollectionUtils.isNotEmpty(tempReceive1)) {
        	circularManagementInfo.setNoFeedbackVesselIds(tempReceive1.stream().map(CircularManagementReceive::getVesselDeptId).collect(Collectors.joining(",")));
        }else{
            circularManagementInfo.setNoFeedbackVesselIds("");
        }
        // 取得需要反馈的部门信息
        List<CircularManagementReceive> tempReceive2 = getDeptTypeReceive(example.getReceiveDept(), new CircularManagementReceive());
        if (CollectionUtils.isNotEmpty(tempReceive2)) {
            circularManagementInfo.setDeptIds(tempReceive2.stream().map(CircularManagementReceive::getVesselDeptId).collect(Collectors.joining(",")));
        }else{
            circularManagementInfo.setDeptIds("");
        }
        // 取得不需要反馈的部门信息
        List<CircularManagementReceive> tempReceive3 = getNoFeedbackDeptTypeReceive(example.getReceiveDept(), new CircularManagementReceive());
        if (CollectionUtils.isNotEmpty(tempReceive3)) {
        	circularManagementInfo.setNoFeedbackDeptIds(tempReceive3.stream().map(CircularManagementReceive::getVesselDeptId).collect(Collectors.joining(",")));
        }else{
            circularManagementInfo.setNoFeedbackDeptIds("");
        }
    }

    @Override
    public void moveCircularManagementInfo(String id) {
        this.deleteById(id);
    }

    /**
     * 发送
     *
     * @param example
     */
    @Override
    public void sendCircularManagementInfo(CircularManagementInfoSendCommand example) {
        // 查询通知通函信息
        CircularManagementReceive circularManagementReceive = new CircularManagementReceive();
        CircularManagementInfo circularManagementInfo = this.selectById(example.getId());
        circularManagementInfo.setStatusId(CircularStatusEnum.SENDED.getFlag());
        circularManagementInfo.setStatus(CircularStatusEnum.SENDED.getName());
        circularManagementInfo.setStatusEn(CircularStatusEnum.SENDED.getNameEn());
        this.updateById(circularManagementInfo);
        // 通知通函接收信息
        BeanUtils.copyProperties(circularManagementInfo, circularManagementReceive);
        circularManagementReceive.setCircularId(circularManagementInfo.getId());
        circularManagementReceive.setStatusId(CircularStatusEnum.WAITRECEIVE.getFlag());
        circularManagementReceive.setStatus(CircularStatusEnum.WAITRECEIVE.getName());
        circularManagementReceive.setStatusEn(CircularStatusEnum.WAITRECEIVE.getNameEn());

        List<CircularManagementReceive> receiveList = new ArrayList<>();
        List<CircularManagementReceive> tempReceive;
        // 取得需反馈的接收船舶信息
        tempReceive = getVesselTypeReceive(example.getReceiveVessel(), circularManagementReceive);
        if (CollectionUtils.isNotEmpty(tempReceive)) {
            receiveList.addAll(tempReceive);
        }
        // 取得不需反馈的接收船舶信息
        tempReceive = getNoFeedbackVesselTypeReceive(example.getReceiveVessel(), circularManagementReceive);
        if (CollectionUtils.isNotEmpty(tempReceive)) {
        	receiveList.addAll(tempReceive);
        }

        // 取得需要反馈的接收部门信息
        tempReceive = getDeptTypeReceive(example.getReceiveDept(), circularManagementReceive);
        if (CollectionUtils.isNotEmpty(tempReceive)) {
            receiveList.addAll(tempReceive);
        }
        // 取得不需要反馈的接收部门信息
        tempReceive = getNoFeedbackDeptTypeReceive(example.getReceiveDept(), circularManagementReceive);
        if (CollectionUtils.isNotEmpty(tempReceive)) {
        	receiveList.addAll(tempReceive);
        }
        // 保存信息
        circularManagementReceiveService.insertBatch(receiveList);

//        NotificationStaffTodoTask task = new NotificationStaffTodoTask();
//        task.setBusinessId(circularManagementInfo.getId()).setBusinessType(CircularConstant.CIRCULAR).setBusinessCode(CircularConstant.CIRCULAR_MANAGEMENT_RECEIVE)
//                .setMessageTitle(CircularConstant.CIRCULAR_MANAGEMENT_RECEIVE_CH).setMessageContent(
//                MessageFormat.format(CircularConstant.CIRCULAR_MESSAGE_01, circularManagementInfo.getDeptName(), circularManagementInfo.getTheme()));

        NoticeTaskInfo noticeTask = new NoticeTaskInfo();
        noticeTask.setCompId(circularManagementInfo.getCompId());
        noticeTask.setBusinessCode(CircularConstant.CIRCULAR_MANAGEMENT_RECEIVE);
        noticeTask.setBusinessType(CircularConstant.CIRCULAR);
        noticeTask.setMessageContent(MessageFormat.format(CircularConstant.CIRCULAR_MESSAGE_01,
                circularManagementInfo.getDeptName(), circularManagementInfo.getTheme()));

        // 创建通知通函待接收任务
        createCircularManagementTask(receiveList, noticeTask);
    }

    /**
     * 取得需反馈船舶
     *
     * @param vesselList
     * @param circularManagementReceive
     * @return
     */
    private List<CircularManagementReceive> getVesselTypeReceive(List<CommonVessel> vesselList, CircularManagementReceive circularManagementReceive) {
        List<CircularManagementReceive> receiveList = new ArrayList<>();
        CircularManagementReceive circularReceive;
        if (null != vesselList) {
            // 筛出选中的
            List<CommonVessel> checkList = vesselList.stream().filter(e -> "1".equals(e.getClientFlag())).collect(Collectors.toList());
            for (CommonVessel request : checkList) {
                circularReceive = new CircularManagementReceive();
                BeanUtils.copyProperties(circularManagementReceive, circularReceive);
                circularReceive.setId(IdGenerator.generateLongIncrId());
                circularReceive.setVesselDeptType("1");
                circularReceive.setVesselDeptId(request.getVesselId());
                circularReceive.setVesselDeptName(request.getVesselName());
                receiveList.add(circularReceive);
            }
        }
        return receiveList;
    }
    /**
     * 取得接收不需要反馈船舶
     *
     * @param vesselList
     * @param circularManagementReceive
     * @return
     */
    private List<CircularManagementReceive> getNoFeedbackVesselTypeReceive(List<CommonVessel> vesselList, CircularManagementReceive circularManagementReceive) {
    	List<CircularManagementReceive> receiveList = new ArrayList<>();
    	CircularManagementReceive circularReceive;
    	if (null != vesselList) {
    		// 筛出选中的
    		List<CommonVessel> checkList = vesselList.stream().filter(e -> "2".equals(e.getClientFlag())).collect(Collectors.toList());
    		for (CommonVessel request : checkList) {
    			circularReceive = new CircularManagementReceive();
    			BeanUtils.copyProperties(circularManagementReceive, circularReceive);
    			circularReceive.setId(IdGenerator.generateLongIncrId());
    			circularReceive.setVesselDeptType("1");
    			circularReceive.setVesselDeptId(request.getVesselId());
    			circularReceive.setVesselDeptName(request.getVesselName());
    			receiveList.add(circularReceive);
    		}
    	}
    	return receiveList;
    }

    /**
     * 取得需反馈接收部门
     *
     * @param deptList
     * @param circularManagementReceive
     * @return
     */
    private List<CircularManagementReceive> getDeptTypeReceive(List<DeptInfoVo> deptList, CircularManagementReceive circularManagementReceive) {
        List<CircularManagementReceive> receiveList = new ArrayList<>();
        CircularManagementReceive circularReceive;
        if (null != deptList) {
            List<CommonDepartment> checkList = new ArrayList<>();
            Map<String, String> compMap = new HashMap<>();
            for (DeptInfoVo request : deptList) {
                // 取出选中的部门
                if (CollectionUtils.isNotEmpty(request.getDepartmentList())) {
                    checkList.addAll(request.getDepartmentList().stream().filter(e -> (null != e.getChangeFlag() && e.getChangeFlag())).collect(Collectors.toList()));
                }
                compMap.put(request.getCompId(), request.getCompName());
            }
            if (CollectionUtils.isNotEmpty(checkList)) {
                for (CommonDepartment department : checkList) {
                    circularReceive = new CircularManagementReceive();
                    BeanUtils.copyProperties(circularManagementReceive, circularReceive);
                    circularReceive.setId(IdGenerator.generateLongIncrId());
                    circularReceive.setCompId(department.getUnderCompId());
                    circularReceive.setCompName(compMap.get(department.getUnderCompId()));
                    circularReceive.setVesselDeptType("2");
                    circularReceive.setVesselDeptId(department.getDeptId());
                    circularReceive.setVesselDeptName(department.getDeptName());
                    receiveList.add(circularReceive);
                }
            }
        }
        return receiveList;
    }
    /**
     * 取得不需要反馈的接收部门
     *
     * @param deptList
     * @param circularManagementReceive
     * @return
     */
    private List<CircularManagementReceive> getNoFeedbackDeptTypeReceive(List<DeptInfoVo> deptList, CircularManagementReceive circularManagementReceive) {
    	List<CircularManagementReceive> receiveList = new ArrayList<>();
    	CircularManagementReceive circularReceive;
    	if (null != deptList) {
    		List<CommonDepartment> checkList = new ArrayList<>();
    		Map<String, String> compMap = new HashMap<>();
    		for (DeptInfoVo request : deptList) {
    			// 取出选中的部门
    			if (CollectionUtils.isNotEmpty(request.getDepartmentList())) {
    				checkList.addAll(request.getDepartmentList().stream().filter(e -> (null != e.getChangeFlag() && !e.getChangeFlag())).collect(Collectors.toList()));
                }
                compMap.put(request.getCompId(), request.getCompName());
            }

            if (CollectionUtils.isNotEmpty(checkList)) {
                for (CommonDepartment department : checkList) {
                    circularReceive = new CircularManagementReceive();
                    BeanUtils.copyProperties(circularManagementReceive, circularReceive);
                    circularReceive.setId(IdGenerator.generateLongIncrId());
                    circularReceive.setCompId(department.getUnderCompId());
                    circularReceive.setCompName(compMap.get(department.getUnderCompId()));
                    circularReceive.setVesselDeptType("2");
                    circularReceive.setVesselDeptId(department.getDeptId());
                    circularReceive.setVesselDeptName(department.getDeptName());
                    receiveList.add(circularReceive);
                }
            }

        }
        return receiveList;
    }

    /**
     * 退回通知通函
     *
     * @param example
     */
    @Override
    public void backCircularManagementInfo(CircularManagementReceiveCommand example) {
        String id = example.getId();
        CircularManagementReceive circularManagementReceive = new CircularManagementReceive();
        circularManagementReceive.setId(id);
        circularManagementReceive.setStatusId(CircularStatusEnum.RETURNED.getFlag());
        circularManagementReceive.setStatus(CircularStatusEnum.RETURNED.getName());
        circularManagementReceive.setStatusEn(CircularStatusEnum.RETURNED.getNameEn());

        // 更新通知通函接收状态
        circularManagementReceiveService.updateById(circularManagementReceive);

        // 查询通知通函接收信息
        circularManagementReceive = circularManagementReceiveService.selectById(id);

        Wrapper<CircularManagementReceive> itemWrapper = new EntityWrapper<>();
        itemWrapper.eq(CircularManagementReceive.QueryFields.CIRCULAR_ID, circularManagementReceive.getCircularId());
        int countAllItem = circularManagementReceiveService.selectCount(itemWrapper);// 查询所有发送的通知
        itemWrapper.eq(CircularManagementReceive.QueryFields.STATUS_ID, CircularStatusEnum.RECEIVED.getFlag());
        int countItem = circularManagementReceiveService.selectCount(itemWrapper);

        CircularManagementInfo circularManagementInfo = new CircularManagementInfo();
        circularManagementInfo.setId(circularManagementReceive.getCircularId());

        if (countAllItem - countItem > 0) {
            DecimalFormat decimalFormat = new DecimalFormat("##%");
            // 通知通函部分接收
            circularManagementInfo.setStatusId(CircularStatusEnum.PARTRECEIVED.getFlag());
            circularManagementInfo.setStatus(CircularStatusEnum.PARTRECEIVED.getName()  + countItem + "/" + countAllItem);
            circularManagementInfo.setStatusEn(CircularStatusEnum.PARTRECEIVED.getNameEn()  + countItem + "/" + countAllItem);
        } else {
            // 通知通函已发送
            circularManagementInfo.setStatusId(CircularStatusEnum.ALLRECEIVED.getFlag());
            circularManagementInfo.setStatus(CircularStatusEnum.ALLRECEIVED.getName());
            circularManagementInfo.setStatusEn(CircularStatusEnum.ALLRECEIVED.getNameEn());
        }
        // 更新通知通函状态
        this.updateById(circularManagementInfo);
        CircularManagementInfo info = this.selectById(circularManagementReceive.getCircularId());
        // 插入退回的消息
//        NotificationStaffTodoTask task = new NotificationStaffTodoTask();
//        task.setBusinessId(circularManagementReceive.getCircularId()).setBusinessType(CircularConstant.CIRCULAR).setBusinessCode(CircularConstant.CIRCULAR_MANAGEMENT_RECEIVE)
//                .setMessageTitle(CircularConstant.CIRCULAR_MANAGEMENT_RECEIVE_CH).setMessageContent(
//                MessageFormat.format(CircularConstant.CIRCULAR_MESSAGE_02, info.getTheme(), info.getDeptName()));


        NoticeTaskInfo noticeTask = new NoticeTaskInfo();
        noticeTask.setCompId(circularManagementInfo.getCompId());
        noticeTask.setBusinessCode(CircularConstant.CIRCULAR_MANAGEMENT_RECEIVE);
        noticeTask.setBusinessType(CircularConstant.CIRCULAR);
        noticeTask.setMessageContent(MessageFormat.format(CircularConstant.CIRCULAR_MESSAGE_02, info.getTheme(), info.getDeptName()));

        // 插入退回任务
        createCircularManagementTask(Arrays.asList(circularManagementReceive), noticeTask);
        operationHisService.saveOperationHis(id, "退回：", example.getRemark(), null);
    }

    /**
     * 查询接收通知通函信息列表
     *
     * @param example
     * @return
     */
    @Override
    public List<CircularManagementReceiveVo> queryCircularManagementReceiveListById(CircularManagementReceiveSearchCommand example) {
        List<CircularManagementReceiveVo> receiveList = new ArrayList<>();
        CircularManagementReceiveVo circularManagementReceiveVo;

        // 查询通知通函接收列表
        Wrapper<CircularManagementReceive> detailWrapper = new EntityWrapper<>();
        detailWrapper.eq(CircularManagementReceive.QueryFields.CIRCULAR_ID, example.getId());
        if (StringUtils.isNotBlank(example.getOrderColunm())) {
            detailWrapper.orderBy(example.getOrderColunm(), !StringUtils.equals(example.getOrder(), "desc"));
        } else {
            detailWrapper.orderBy(CircularManagementReceive.QueryFields.STATUS_ID, true);
        }
        List<CircularManagementReceive> detailList = circularManagementReceiveService.selectList(detailWrapper);
        int receiveNum = 0;// 已接收
        int waitReceiveNum = 0;// 待接收
        int returnedNum = 0;// 已退回
        for (CircularManagementReceive receiveInfo : detailList) {
            circularManagementReceiveVo = new CircularManagementReceiveVo();
            // 将实体类转化成VO
            BeanUtils.copyProperties(receiveInfo, circularManagementReceiveVo);
            if (CircularStatusEnum.RECEIVED.getFlag().equals(receiveInfo.getStatusId())) {
                receiveNum++;
            } else if (CircularStatusEnum.WAITRECEIVE.getFlag().equals(receiveInfo.getStatusId())) {
                waitReceiveNum++;
            } else if (CircularStatusEnum.RETURNED.getFlag().equals(receiveInfo.getStatusId())) {
                returnedNum++;
            }
            if (StringUtils.isNotBlank(circularManagementReceiveVo.getAttachmentPath())) {
                String[] attachmentPaths = circularManagementReceiveVo.getAttachmentPath().split(",");
                circularManagementReceiveVo.setAttachmentNum(String.valueOf(attachmentPaths.length));
            } else {
                circularManagementReceiveVo.setAttachmentNum("0");
            }

            if (StringUtils.isNotBlank(circularManagementReceiveVo.getReceiveAttachmentPath())) {
                String[] receiveAttachmentPaths = circularManagementReceiveVo.getReceiveAttachmentPath()
                        .split(",");
                circularManagementReceiveVo
                        .setReceiveAttachmentNum(String.valueOf(receiveAttachmentPaths.length));
            } else {
                circularManagementReceiveVo.setReceiveAttachmentNum("0");
            }

            receiveList.add(circularManagementReceiveVo);
        }
        receiveList.get(0).setReceiveNum(receiveNum);
        receiveList.get(0).setWaitReceiveNum(waitReceiveNum);
        receiveList.get(0).setReturnedNum(returnedNum);
        return receiveList;
    }

    /**
     * 取得通知通函接收人id集合
     *
     * @param receiveInfo
     * @return
     */
    @Override
    public List<String> getReceiveStaffIdList(CircularManagementReceive receiveInfo) {
        // 船舶
        if ("1".equals(receiveInfo.getVesselDeptType())) {
            List<CommonStaff> VesselStaff = staffService.selectList(new EntityWrapper<CommonStaff>()
                    .eq(CommonStaff.QueryFields.VESSEL_ID, receiveInfo.getVesselDeptId()));
            if (CollectionUtils.isNotEmpty(VesselStaff)) {
                return VesselStaff.stream().map(CommonStaff::getStaffId).collect(Collectors.toList());
            }
        }
        // 部门
        else {
            List<CommonRole> roleList = commonRoleService.findDeptRoleList(Arrays.asList(receiveInfo.getVesselDeptId()));
            if (CollectionUtils.isNotEmpty(roleList)) {
                List<CommonStaffRole> staffRoleList = staffRoleService.selectList(new EntityWrapper<CommonStaffRole>()
                        .in(CommonStaffRole.QueryFields.ROLE_ID, roleList.stream().map(CommonRole::getRoleId).collect(Collectors.toList()))
                        .eq(CommonStaffRole.QueryFields.ROLE_MAJOR, "1"));
                if (CollectionUtils.isNotEmpty(staffRoleList)) {
                    return staffRoleList.stream().map(CommonStaffRole::getStaffId).collect(Collectors.toList());
                }
            }
        }
        return null;
    }

    @Override
    public List<CommonVessel> getVesselList(CircularManagementInfoSearchCommand example) {
        List<CommonVessel> commonVesselList = vesselService.getVesselList(AuthSecurityUtils.getCurrentUserInfo().getCompId(), example.getSearchKeyword(), example.getOrder());
        return commonVesselList;
    }

    @Override
    public List<DeptInfoView> getDeptList(CircularManagementInfoSearchCommand example) {
        List<DeptInfoView> deptList = commonDepartmentService.getDeptList(example.getSearchKeyword(), example.getOrder(), AuthSecurityUtils.getCurrentUserInfo().getTenantId());
        return deptList;
    }

    /**
     * 创建通知通函任务
     *
     * @param receiveList 接收集合
     */
    private void createCircularManagementTask(List<CircularManagementReceive> receiveList, NoticeTaskInfo task) {
        if (CollectionUtils.isEmpty(receiveList)) {
            return;
        }
        task.setCompId(AuthSecurityUtils.getCurrentUserInfo().getCompId());
        List<String> staffIds = new ArrayList<>();

        // 取得所有船端接收人id
        receiveList.forEach(e -> {
            staffIds.clear();
            if ("1".equals(e.getVesselDeptType())) {
                List<String> ids = getReceiveStaffIdList(e);
                if (CollectionUtils.isNotEmpty(ids)) {
                    staffIds.addAll(ids);
                }
            }
            if (CollectionUtils.isNotEmpty(staffIds)) {
                task.setBusinessId(e.getId());
                // 给职员插任务
                task.setAcceptType(BaseNotice.AcceptStatus.STAFF);
//                // 创建所有接收任务
//                staffTodoTaskService.create(compId, staffIds, task);
                //创建任务通知
                taskService.createNoticeTask(staffIds, null, task);
            }
        });

        // 岸基部门因为可能多公司，单独插
        // 插任务用的主公司id，所以还是用一样的公司id 2020年3月25日09:23:12
        receiveList.forEach(e -> {
            if (!"1".equals(e.getVesselDeptType())) {
                List<String> ids = getReceiveStaffIdList(e);
                if (CollectionUtils.isNotEmpty(ids)) {
                    task.setBusinessId(e.getId());
                    // 给职务插任务
                    // 因为存在兼职其他部门职务的问题，防止出现多条任务，所以岸基的职务也指定到职员
                    task.setAcceptType(BaseNotice.AcceptStatus.STAFF);
                    // 创建所有接收任务
//                    staffTodoTaskService.create(compId, ids, task);
                    //创建任务通知
                    taskService.createNoticeTask(ids, null, task);
                }
            }
        });
    }

    /**
     * 下载
     *
     * @param path
     * @param response
     * @author 穆永春
     */
    private void download(String path, HttpServletResponse response, Workbook wb) {

        try {

            // path是指欲下载的文件的路径。
            File file = new File(path);
            // 取得文件名。
            String fileName = file.getName();
            // 给文件名编码
            fileName = new String(fileName.getBytes("GBK"), "ISO-8859-1");

            response.setContentType("application/vnd.ms-excel");
            response.addHeader("Content-Disposition", "attachment;filename=" + fileName);

            // 定义byte输出流
            ByteArrayOutputStream out = new ByteArrayOutputStream();

            // 写导出文件
            wb.write(out);

            // 取得模板文件中的数据
            byte[] result = out.toByteArray();

            // 设置输出数据类型
            response.setContentType("application/vnd.ms-excel");
            // 设置输出数据长度
            response.setContentLength(result.length);

            // 设置文件名称
            response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
            // 将文件流输出到画面
            response.getOutputStream().write(result);

            out.flush();
            out.close();

        } catch (IOException ex) {
            log.debug(ex.getMessage());
        }

    }
}
