package com.bcxin.ins.service.order.impl;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.aspose.words.*;
import com.bcxin.ins.core.entity.ME;
import com.bcxin.ins.dao.order.InsClaimInformationAPIDao;
import com.bcxin.ins.entity.policy_report.InsCaseInfo;
import com.bcxin.ins.entity.policy_report.InsClaimInformation;
import com.bcxin.ins.rest.UserSupportUtil;
import com.bcxin.ins.service.user.ClientUserService;
import com.bcxin.ins.spring.executor.MyAsyncExecutor;
import com.bcxin.ins.third.gzzrx.changan.GZZRX_CARequestService;
import com.bcxin.ins.third.gzzrx.pingancai.GZZRX_PACRequestService;
import com.bcxin.ins.enums.TransTypeEnum;
import com.bcxin.ins.dao.order.InsCommonReportAPIDao;
import com.bcxin.ins.core.entity.SysUser;
import com.bcxin.ins.entity.policy_report.InsCommonReport;
import com.bcxin.ins.entity.policy_report.InsPaymentInfo;
import com.bcxin.ins.service.order.*;
import com.bcxin.ins.third.gzzrx.taibao.GZZRX_TBRequestService;
import com.bcxin.ins.third.gzzrx.taibao.util.TransType;
import com.bcxin.ins.util.*;
import com.bcxin.ins.vo.*;
import com.bcxin.ins.vo.ConstProp;
import com.bcxin.ins.vo.report_pac.*;
import com.bcxin.mybatisplus.plugins.Page;
import com.bcxin.mybatisplus.service.impl.ServiceImpl;
import com.bcxin.mybatisplus.toolkit.StringUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.lang.RandomStringUtils;
import org.dom4j.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.io.*;
import java.math.BigDecimal;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.*;
import java.util.List;


/**
 * <b>雇主责任险雇员特殊字段业务处理 </b>
 * 
 * @author zxf
 * @date 2017年1月5日 上午10:28:33
 * @注意事项 </b>
 * <b>
 */
@Service
@Transactional
public class InsCommonReportAPIServiceImpl extends ServiceImpl<InsCommonReportAPIDao, InsCommonReport> implements InsCommonReportAPIService {

	private static Logger log =  LoggerFactory.getLogger(InsCommonReportAPIServiceImpl.class);

	@Autowired
	private InsCommonReportAPIDao dao;

	@Autowired
	private InsPaymentInfoAPIService insPaymentInfoAPIService;
	@Autowired
	private InsClaimInformationAPIService insClaimInformationAPIService;
	@Autowired
	private InsCaseScheduleAPIService insCaseScheduleAPIService;
	@Autowired
	private InsCaseInfoAPIService insCaseInfoAPIService;
	@Autowired
	private GZZRX_PACRequestService gZZRX_PACRequestService;
	@Autowired
	private GZZRX_CARequestService gZZRX_CARequestService;
	@Autowired
	private GZZRX_TBRequestService gZZRX_TBRequestService;
	@Autowired
	private InsInsuranceSlipAPIService insInsuranceSlipAPIService;
	@Autowired
	private InsRoleInpolicyAPIService insRoleInpolicyAPIService;
	@Autowired
	private ComTaskResidualAPIService comTaskResidualAPIService;
	@Autowired
	private PolicyService policyService;
	@Autowired
	private ClientUserService userService;

	@Autowired
	private MyAsyncExecutor myAsyncExecutor;

	/**
	 * <b> 报案信息初始化 </b>
	 * @author ZXF
	 * @create 2019/11/27 0027 14:13
	 * @version
	 * @注意事项 </b>
	 */
	private InsCommonReport initInsCommonReport(Long user_id,Long order_id) {
		InsCommonReport insCommonReport = new InsCommonReport();
		InsPaymentInfo insPaymentInfo = insPaymentInfoAPIService.initInsPaymentInfo(user_id);
		insCommonReport.setIns_payment_info_id(insPaymentInfo.getIns_payment_info_id());
		insCommonReport.setCreate_time(new Date());
		insCommonReport.setCreate_by(new SysUser(user_id));
		insCommonReport.setRegister_user_id(user_id);
		insCommonReport.setIns_insurance_slip_id(order_id);
		dao.insert(insCommonReport);
		return insCommonReport;
	}

	/**
	 * <b> 为文件激活fileId（平安专用） </b>
	 * @param ossPath 通过oss方式上传得到的文件访问地址
	 * @author ZXF
	 * @create 2020/05/09 0009 17:05
	 * @version
	 * @注意事项 </b>
	 */
	private InsClaimInformationVo activateFileId(String ossPath){
		String fileId = UUID.randomUUID().toString();
		try {
			String key = ossPath.split(".com/")[1];
			String[] arr = key.split(ConstProp.SLASH);
			String fileName = arr[arr.length-1];
			InputStream is = OSSFileUtil.getInputStreamByUrl(ossPath);
			if(gZZRX_PACRequestService.isUploadPA(is,fileId,fileName)){
				InsClaimInformationVo vo = new InsClaimInformationVo();
				vo.setFile_key(fileId);
				vo.setFile_name(fileName);
				vo.setFile_path(ossPath);
				vo.setShort_group_code("006004");
				return vo;
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * <b> saas图片地址上传平安ibos平台激活fileId </b>
	 * @author ZXF
	 * @create 2020/06/29 0029 16:22
	 * @version
	 * @注意事项 </b>
	 */
	private String saasActivateFileId(String hwPath,String sign){
		if(StringUtils.isEmpty(hwPath)){
			return "";
		}
		InputStream is = null;
		try {
			String fileId = sign + "-" + UUID.randomUUID().toString();
			URL url = new URL(hwPath);
			HttpURLConnection conn = (HttpURLConnection)url.openConnection();
			conn.setRequestMethod("GET");
			conn.setConnectTimeout(5 * 1000);
			is = conn.getInputStream();//通过输入流获取图片数据
			String fileName = hwPath.contains("%2F")?hwPath.split("%2F")[2]:hwPath.split("/")[5];
			if(gZZRX_PACRequestService.isUploadPA(is,fileId,fileName)){
				return fileId;
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (is != null) {
				try {
					is.close();
				} catch (IOException e1) {
					e1.printStackTrace();
				}
			}
		}
		return "";
	}

	/**
	 * <b> saas图片地址上传平安ibos平台激活fileId </b>
	 * @author ZXF
	 * @create 2020/06/29 0029 16:22
	 * @version
	 * @注意事项 </b>
	 */
	@Override
	public String getFileIdByPath(String path, String sign) {
		return saasActivateFileId(path,sign);
	}

	/**
	 * <b> SAAS App保存理赔信息 </b>
	 * @author ZXF
	 * @create 2019/11/19 0019 14:55
	 * @version
	 * @注意事项 </b>
	 */
	@Override
	public ResultDto saveInsCommonReportByApp(InsCommonReportVo vo,Long user_id) {
		if(StringUtils.isEmpty(vo.getPolicy_no())){
			return new ResultDto("保单号不能为空！", ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
		}
		if(StringUtils.isNotEmpty(vo.getIns_insurance_slip_id())){
			return saveInsCommonReport(vo,user_id);
		}
		OrderFormVo order = insInsuranceSlipAPIService.findPolicyByExternalAndRoleName(vo.getPolicy_no(), "");
		if(order == null){
			return new ResultDto("保单不存在！", ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
		}
		if(!ConstProp.DIGIT_ZERO.equals(vo.getStatus())) {
			Date inc = DateUtil.parseDate(order.getInception_date());
			Date acc = DateUtil.convertString2Date(vo.getAccident_date());
			if((acc.getTime()-inc.getTime())<0){
				return new ResultDto("出险时间不能在生效日期之前！", ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
			}
		}
		vo.setIns_insurance_slip_id(order.getOid());
		return saveInsCommonReport(vo,user_id);
	}

	/**
	 * <b> 保存理赔信息 </b>
	 * @author ZXF
	 * @create 2019/11/19 0019 14:55
	 * @version
	 * @注意事项 </b>
	 */
	@Override
	public ResultDto saveInsCommonReport(InsCommonReportVo vo,Long user_id) {
		try{

			vo.setRegister_user_id(String.valueOf(user_id));

			//接口返回成功就将赋值
			Map<String, Object> map = submitReportResult(vo);
			if(map.get("ResultDto") != null){
				return (ResultDto)map.get("ResultDto");
			}
			//接口返回成功就将赋值
			String[] resultArr = (String[])map.get("resultArr");

			InsCommonReport insCommonReport;
			if(StringUtils.isEmpty(vo.getIns_common_report_id())){
				insCommonReport = initInsCommonReport(user_id,Long.parseLong(vo.getIns_insurance_slip_id()));
			}else{
				insCommonReport = dao.selectById(Long.parseLong(vo.getIns_common_report_id()));
			}
			MyConverUtil.map2PO(MyConverUtil.PO2Map(vo), insCommonReport);
			insCommonReport.setIs_sync("0");
			dao.updateById(insCommonReport);
			vo.setRegister_user_id(String.valueOf(user_id));
			//附件
			insClaimInformationAPIService.accordingToTheInsCommonReportVoSetUpInsClaimInformation(vo,insCommonReport.getIns_common_report_id());
			//支付信息
			insPaymentInfoAPIService.saveInsPaymentInfo(vo.getInsPaymentInfoVo(),insCommonReport.getIns_payment_info_id());
			if(resultArr == null){
				return new ResultDto("报案信息已成功暂存!", ConstProp.CODE_SUCCESS, String.valueOf(insCommonReport.getIns_common_report_id()), ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
			}
			//如果不是0暂存
			vo.setIns_common_report_id(String.valueOf(insCommonReport.getIns_common_report_id()));
			vo.setUpdate_by(String.valueOf(user_id));
			vo.setUpdate_time(DateUtil.getCurrentDateTime());
			vo.setReport_no(resultArr[1]);
			vo.setChannel_code(resultArr[2]);
			vo.setReport_date(resultArr[3]);
			vo.setStatus(ConstProp.DIGIT_ONE);//审核中（已报案）
			dao.updateReportNo(vo);
			//变更附件状态
			insClaimInformationAPIService.updateStatusByReportId(insCommonReport.getIns_common_report_id());
			//如果是来自saas-app的才生成索赔申请书
			if(StringUtils.isNotEmpty(vo.getSignature_path())&&StringUtils.isNotEmpty(vo.getSaas_com_id())&&StringUtils.isNotEmpty(vo.getSaas_idcardno())){
				//生成索赔申请书附件同时推给平安ibos平台
				draftWord(insCommonReport.getIns_common_report_id());
			}
			String msg = "报案成功!";
			if(StringUtils.isEmpty(resultArr[1])){
				msg = "您的理赔申请已提交，保险公司理赔人员会第一时间与您取得联系，告知您准备理赔材料，请耐心等待！";
			}
			return new ResultDto(msg, ConstProp.CODE_SUCCESS, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
		}catch (Exception e){
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			e.printStackTrace();
			return new ResultDto("附件补传异常："+e.getMessage(), ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
		}
	}

	/**
	 * <b> 申请理赔提交不暂存就做校验并传给第三方接口 </b>
	 * @author ZXF
	 * @create 2020/09/15 0015 11:31
	 * @version
	 * @注意事项 </b>
	 */
	private Map<String,Object> submitReportResult(InsCommonReportVo vo) throws Exception {
		Map<String,Object> map = Maps.newHashMap();
		map.put("ResultDto",null);
		map.put("resultArr",null);
		//如果不是0暂存
		if(ConstProp.DIGIT_ZERO.equals(vo.getStatus())) {
			return map;
		}
		String productCode = insInsuranceSlipAPIService.getProductCode(Long.parseLong(vo.getIns_insurance_slip_id()));
		//如果是平安财就走接口
		if(StringUtils.isEmpty(productCode)){
			map.put("resultArr",new String[]{"200","","",DateUtil.getCurrentDateTime()});
			return map;
		}
		if(productCode.contains(ConstProp.GZZRX_CA)){
			vo.setReport_date(DateUtil.getCurrentDateTime());
			String result = gZZRX_CARequestService.requestReportCA(vo, TransTypeEnum.BASL.getValue());
			result += "##"+vo.getReport_date();
			String[] strs = result.split(ConstProp.POUND_SIGN);
			if (ConstProp.CODE_FAILURE.equals(strs[0])) {
				map.put("ResultDto",new ResultDto(strs[1], ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR));
			}else{
				map.put("resultArr",strs);
			}
		}else if(productCode.contains(ConstProp.GZZRX_TB)){
			vo.setReport_date(DateUtil.getCurrentDateTime());
			String result = gZZRX_TBRequestService.requestReport(Long.parseLong(vo.getIns_insurance_slip_id()),vo,"", TransType.TB_BA.getValue());
			result += "##"+vo.getReport_date();
			String[] strs = result.split(ConstProp.POUND_SIGN);
			if (ConstProp.CODE_FAILURE.equals(strs[0])) {
				map.put("ResultDto",new ResultDto(strs[1], ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR));
			}else{
				map.put("resultArr",strs);
			}
		}else if(productCode.contains(ConstProp.GZZRX_PAC)){
			List<InsClaimInformationVo> clist = vo.getClaimInformationVoList();
			if(clist == null){
				map.put("ResultDto",new ResultDto("无报案资料上传信息！", ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR));
				return map;
			}
			//报案时自动添加已有的公司营业执照
			String ossPath = insRoleInpolicyAPIService.getOrgUrlByOrderID(Long.parseLong(vo.getIns_insurance_slip_id()));
			InsClaimInformationVo icifVo = activateFileId(ossPath);
			if(icifVo!=null){
				clist.add(icifVo);
				vo.setClaimInformationVoList(clist);
			}

			String result = gZZRX_PACRequestService.submitReportPAC(vo, TransTypeEnum.BASL.getValue());
			String[] strs = result.split(ConstProp.POUND_SIGN);
			if (ConstProp.CODE_FAILURE.equals(strs[0])) {
				map.put("ResultDto",new ResultDto(strs[1], ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR));
			}else{
				map.put("resultArr",strs);
			}
		}
		return map;
	}

	@Override
	public void getCACaseById(InsCommonReportVo vo, Long report_id){
		try {
			String result = gZZRX_CARequestService.requestXXReportCA("",vo.getReport_no(),1, TransTypeEnum.AJCX.getValue());
			String[] strs = result.split(ConstProp.POUND_SIGN);
			if(!ConstProp.CODE_SUCCESS.equals(strs[0])) {
				return;
			}
			List<Map> list = JSONArray.parseArray(strs[1],Map.class);
			if(list.size() < 1){
				return;
			}
			Map<String,String> map = list.get(0);
			//保存报案成功案件信息
			setCACaseInfo(map, vo, report_id);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	//保存报案成功案件信息
	private void setCACaseInfo(Map<String, String> caseInfo, InsCommonReportVo vo, Long report_id){
		List<InsCaseInfoVo> caseInfoList = Lists.newArrayList();
		InsCaseInfoVo insCaseInfoVo = new InsCaseInfoVo();
		String caseStatus = caseInfo.get("CaseStatusCode");
		insCaseInfoVo.setCase_status(caseStatus);//案件状态（1：已报案;2：已理算;3：已结案;4：重开赔案）
		insCaseInfoVo.setCase_status_1(caseInfo.get("CaseStatusName"));//案件状态【“查勘中”、“定责中”、“定损中”、“核赔前置中”、“理算中”、“审核中”、“支付退回中”、“待归档”、“已归档”】
		caseInfoList.add(insCaseInfoVo);
		vo.setCaseInfoVoList(caseInfoList);
		dao.updateStatus("3".equals(caseStatus)?"2":"1",DateUtil.getCurrentDate(), report_id);//修改状态,状态：已结案
		insCaseInfoAPIService.delectAllInsCaseInfo(report_id);
		insCaseInfoAPIService.accordingToTheInsCommonReportVoSetUpInsCaseInfo(vo,report_id);
	}

	@Override
	public void getTBCaseById(InsCommonReportVo vo, Long report_id){
		try {
			//200#报案号#状态#赔付金额#结案时间#理赔说明
			String result = gZZRX_TBRequestService.requestReportTB(Long.parseLong(vo.getIns_insurance_slip_id()),vo,"", TransType.EPIC_AJCX.getValue());
			String[] strs = result.split(ConstProp.POUND_SIGN);
			if(!ConstProp.CODE_SUCCESS.equals(strs[0])) {
				return;
			}
			Map<String,String> map = Maps.newHashMap();
			map.put("registerno",strs[1]);
			map.put("status",strs[2]);
			map.put("payamount",strs[3]);
			map.put("closeDate",strs[4]);
			map.put("explanation",strs[5]);
			//保存报案成功案件信息
			setTBCaseInfo(map, vo, report_id);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	//保存报案成功案件信息
	private void setTBCaseInfo(Map<String, String> caseInfo, InsCommonReportVo vo, Long report_id){
		List<InsCaseInfoVo> caseInfoList = Lists.newArrayList();
		InsCaseInfoVo insCaseInfoVo = new InsCaseInfoVo();
		String caseStatus = caseInfo.get("status");//0-已结案 1-已报案  2-已理算  6-已归档）
		String cStatus = "1".equals(caseStatus)?"1":"2".equals(caseStatus)?"0":"3".equals(caseStatus)?"0":"4".equals(caseStatus)?"6":"0";
		insCaseInfoVo.setCase_status(cStatus);//案件状态（1：已报案;2：已理算;3：已结案;4：重开赔案）
		String cStatus1 = "1".equals(caseStatus)?"处理中":"2".equals(caseStatus)?"注销":"3".equals(caseStatus)?"结案待支付":"4".equals(caseStatus)?"结案已支付":"";
		insCaseInfoVo.setCase_status_1(cStatus1);//案件状态【“查勘中”、“定责中”、“定损中”、“核赔前置中”、“理算中”、“审核中”、“支付退回中”、“待归档”、“已归档”】
		insCaseInfoVo.setEnd_case_date(caseInfo.get("closeDate"));
		insCaseInfoVo.setEnd_case_amount_sum(caseInfo.get("payamount"));
		insCaseInfoVo.setWithdraw_reason(caseInfo.get("payamount"));
		String audit_status = "";
		if(StringUtils.isNotEmpty(caseInfo.get("payamount"))&&Double.parseDouble(caseInfo.get("payamount"))>0&&"4".equals(caseStatus)){
			audit_status = "1";
		}else if(StringUtils.isNotEmpty(caseInfo.get("payamount"))&&Double.parseDouble(caseInfo.get("payamount"))<1&&"4".equals(caseStatus)){
			audit_status = "0";
			insCaseInfoVo.setReject_notice_date(caseInfo.get("closeDate"));
		}
		insCaseInfoVo.setAudit_status(audit_status);
		caseInfoList.add(insCaseInfoVo);
		vo.setCaseInfoVoList(caseInfoList);
		//0.暂存、待提交；1.审核中；2.已结案；9.删除。
		dao.updateStatus("3".equals(caseStatus)?"2":"4".equals(caseStatus)?"2":"2".equals(caseStatus)?"2":"1",DateUtil.getCurrentDate(), report_id);//修改状态,状态：已结案
		insCaseInfoAPIService.delectAllInsCaseInfo(report_id);
		insCaseInfoAPIService.accordingToTheInsCommonReportVoSetUpInsCaseInfo(vo,report_id);
	}

	/**
	 * <b> 理赔审批信息查询(请求平安接口) </b>
	 * 当报案传统为已归档
	 * @author ZXF
	 * @create 2019/11/27 0027 14:14
	 * @version
	 * @注意事项 </b>
	 */
	@Override
	public void getCaseById(InsCommonReportVo vo, Long report_id){
		try {
			String result = gZZRX_PACRequestService.requestReportPAC(report_id, TransTypeEnum.AJCX.getValue());
			String[] strs = result.split(ConstProp.POUND_SIGN);
			if(!ConstProp.CODE_SUCCESS.equals(strs[0])) {
				return;
			}
			Map map  = JSON.parseObject(strs[1],Map.class);
			if(map == null){
				return;
			}
			List<Map> caseInfoList = JSONArray.parseArray(map.get("caseInfoList").toString(),Map.class);
			if(caseInfoList.size()>0){
				Map<String, String> caseInfo = caseInfoList.get(0);
				//保存赔款到账时间
				setPaymentItem(caseInfo, vo, report_id);
				//保存案件进展与计划信息
				setCaseSchedule(caseInfo, vo, report_id);
				//保存报案成功案件信息
				setCaseInfo(caseInfo, vo, report_id);
			}
			List<Map> details = JSONArray.parseArray(map.get("details").toString(),Map.class);
			if(details.size()>0){
				Map<String,String> detail = details.get(0);
				if(detail != null){
					//保存报案基本信息
					setDetail(detail, vo, report_id);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	//保存赔款到账时间
	private void setPaymentItem(Map<String, String> caseInfo, InsCommonReportVo vo, Long report_id){
		String pays = String.valueOf(caseInfo.get("paymentItemList"));
		if(StringUtils.isEmpty(pays)){
			return;
		}
		List<Map> paymentItemList = JSONArray.parseArray(pays,Map.class);
		if(paymentItemList.size()>0){
			Map<String,String> paymentItem = paymentItemList.get(0);
			String payDate = paymentItem.get("payDate");
			if(StringUtils.isNotEmpty(payDate)){
				vo.getInsPaymentInfoVo().setPay_date(payDate);
				insPaymentInfoAPIService.savePayDate(payDate,report_id);
			}
		}
	}

	//保存案件进展与计划信息
	private void setCaseSchedule(Map<String, String> caseInfo, InsCommonReportVo vo, Long report_id){
		String caseSchedules = String.valueOf(caseInfo.get("caseScheduleList"));
		if(StringUtils.isEmpty(caseSchedules)){
			return;
		}
		List<Map> caseScheduleList = JSONArray.parseArray(caseSchedules,Map.class);
		if(caseScheduleList.size()<=0){
			return;
		}
		List<InsCaseScheduleVo> caseScheduleVoList = Lists.newArrayList();
		InsCaseScheduleVo csVo;
		for (Map<String,String> map:caseScheduleList) {
			csVo = new InsCaseScheduleVo();
			csVo.setClean_date(map.get("cleanDate"));
			csVo.setDuty_reason_name(map.get("dutyReasonName"));
			csVo.setDuty_reason_remark(map.get("dutyReasonRemark"));
			csVo.setReason_code_1(map.get("reasonCode1"));
			csVo.setReason_code_2(map.get("reasonCode2"));
			csVo.setReason_code_3(map.get("reasonCode3"));
			csVo.setClean_schedule(map.get("cleanSchedule"));
			csVo.setClean_schedule_remark(map.get("cleanScheduleRemark"));
			csVo.setInput_date(map.get("inputDate"));
			caseScheduleVoList.add(csVo);
		}
		if(caseScheduleVoList.size()>0){
			vo.setCaseScheduleVoList(caseScheduleVoList);
			insCaseScheduleAPIService.delectInsCaseScheduleByOid(report_id);
			insCaseScheduleAPIService.accordingToTheInsCommonReportVoSetUpInsCaseSchedule(vo,report_id);
		}
	}

	//保存报案成功案件信息
	private void setCaseInfo(Map<String, String> caseInfo, InsCommonReportVo vo, Long report_id){
		List<InsCaseInfoVo> caseInfoList = Lists.newArrayList();
		InsCaseInfoVo insCaseInfoVo = new InsCaseInfoVo();
		insCaseInfoVo.setCase_no(caseInfo.get("caseNo"));
		insCaseInfoVo.setAudit_status(caseInfo.get("auditStatus"));//是否理赔状态【1理赔，0不理赔】
		String caseStatus = caseInfo.get("caseStatus");
		insCaseInfoVo.setCase_status(caseStatus);//案件状态（0-已结案 1-已报案  2-已理算  6-已归档）
		insCaseInfoVo.setCase_status_1(caseInfo.get("caseStatus1"));//案件状态【“查勘中”、“定责中”、“定损中”、“核赔前置中”、“理算中”、“审核中”、“支付退回中”、“待归档”、“已归档”】
		insCaseInfoVo.setCase_status_2(caseInfo.get("caseStatus2"));//案件状态【审核中、案件已完结、赔款已到账】
		insCaseInfoVo.setCase_times(caseInfo.get("caseTimes"));
		insCaseInfoVo.setClaim_name(caseInfo.get("claimName"));
		insCaseInfoVo.setClaim_no(caseInfo.get("claimNo"));
		insCaseInfoVo.setClaim_phone(caseInfo.get("claimPhone"));
		insCaseInfoVo.setEnd_case_amount_sum(caseInfo.get("endCaseAmountSum"));
		insCaseInfoVo.setIndemnity_conclusion(caseInfo.get("indemnityConclusion"));
		insCaseInfoVo.setEnd_case_date(caseInfo.get("endCaseDate"));
		insCaseInfoVo.setOrder_no(caseInfo.get("orderNo"));
		insCaseInfoVo.setWithdraw_reason(caseInfo.get("withdrawReason"));
		caseInfoList.add(insCaseInfoVo);
		vo.setCaseInfoVoList(caseInfoList);
		dao.updateStatus("0".equals(caseStatus)?"2":"1",caseInfo.get("endCaseDate"), report_id);//修改状态,状态：已结案
		insCaseInfoAPIService.delectAllInsCaseInfo(report_id);
		insCaseInfoAPIService.accordingToTheInsCommonReportVoSetUpInsCaseInfo(vo,report_id);
	}

	//保存报案基本信息
	private void setDetail(Map<String, String> detail, InsCommonReportVo vo, Long report_id){
		vo.setCheck_loss_sum(detail.get("checkLossSum"));
		vo.setAudit_status(detail.get("auditStatus"));
		vo.setClaim_no(detail.get("claimNo"));
		vo.setSuggestion_text(detail.get("suggestionText"));
		dao.updateResult(vo);
	}

	/**
	 * <b> 根据id查询报案结果 </b>
	 * @author ZXF
	 * @create 2019/11/19 0019 14:41
	 * @version
	 * @注意事项 </b>
	 */
	@Override
	public InsCommonReportVo getInsCommonReportVoById(Long oid){
		return dao.getInsCommonReportVoById(oid);
	}

	/**
	 * <b> 报案详情，sign：0表示可能会去平安拉数据更新详情，1表示只查自己库里的数据 </b>
	 * @author ZXF
	 * @create 2019/12/06 0006 14:08
	 * @version
	 * @注意事项 </b>
	 */
	@Override
	public InsCommonReportVo getInsCommonReportVoInfoById(Long oid,int sign){
		InsCommonReportVo insCommonReportVo = getInsCommonReportVoById(oid);
		if(insCommonReportVo == null){
			return insCommonReportVo;
		}
		OrderFormVo order = policyService.accordingToOrderIDToGetPolicyDto(Long.parseLong(insCommonReportVo.getIns_insurance_slip_id()));
		InsPaymentInfoVo insPaymentInfoVo = insPaymentInfoAPIService.getInsPaymentInfoVo(Long.parseLong(insCommonReportVo.getIns_payment_info_id()));
		insCommonReportVo.setInsPaymentInfoVo(insPaymentInfoVo);
		insClaimInformationAPIService.getInsCommonReportVoByReportID(insCommonReportVo,oid);
		if(sign == 0){
			if(ConstProp.DIGIT_ONE.equals(insCommonReportVo.getStatus())){//审核中去平安取
				String productCode = insInsuranceSlipAPIService.getProductCode(Long.parseLong(insCommonReportVo.getIns_insurance_slip_id()));
				if(productCode.contains(ConstProp.GZZRX_CA)){
//					getCACaseById(insCommonReportVo,oid);
				}else if(productCode.contains(ConstProp.GZZRX_TB)){
					getTBCaseById(insCommonReportVo,oid);
				}else if(productCode.contains(ConstProp.GZZRX_PAC)){
					getCaseById(insCommonReportVo,oid);
				}
			}else if(ConstProp.DIGIT_TWO.equals(insCommonReportVo.getStatus())){//审核归档就去自己库取
				insCaseInfoAPIService.getInsCommonReportVoByReportID(insCommonReportVo,oid);
				insCaseScheduleAPIService.getInsCommonReportVoByReportID(insCommonReportVo,oid);
			}
		}else{
			insCaseInfoAPIService.getInsCommonReportVoByReportID(insCommonReportVo,oid);
			insCaseScheduleAPIService.getInsCommonReportVoByReportID(insCommonReportVo,oid);
		}
		String accident_address = RegionUtils.getRegionNameByALLCode(insCommonReportVo.getAccident_province_code()
				,insCommonReportVo.getAccident_city_code()
				,insCommonReportVo.getAccident_county_code())+insCommonReportVo.getAccident_place();
		insCommonReportVo.setAccident_address(accident_address);
		String sg = order==null?ConstProp.BLANK_CHAR:order.getProduct_code().contains(ConstProp.GZZRX_CA)?"CA":ConstProp.BLANK_CHAR;
		ReportCodeVo rcvo = new ReportCodeVo(sg);
		if("CA".equals(sg)){
			insCommonReportVo.setAccident_cause_level(rcvo.getCxyyName(insCommonReportVo.getAccident_cause_level_1()));
		}else{
			if("0".equals(insCommonReportVo.getIs_sync())){
				insCommonReportVo.setAccident_cause_level(rcvo.getCxyyName(insCommonReportVo.getAccident_cause_level_1())+"："+rcvo.getCxyyName(insCommonReportVo.getAccident_cause_level_2()));
			}else{
				insCommonReportVo.setAccident_cause_level(rcvo.getCxyyName(insCommonReportVo.getAccident_cause_level_2()));
			}
		}
		insCommonReportVo.setInjured_detail_content(setInj(insCommonReportVo.getInjured_detail()
				,insCommonReportVo.getOutpatient_list()
				,insCommonReportVo.getMaim_list()
				,insCommonReportVo.getDemise_list()));
		return insCommonReportVo;
	}

	//组装人伤相关信息
	private String setInj(String injured_detail, String outpatient_list, String maim_list, String demise_list){
		String content = ConstProp.BLANK_CHAR;
		if(StringUtils.isEmpty(injured_detail)){
			return content;
		}
		String[] injs = injured_detail.split(",");
		for (String str : injs) {
			if(str.equals("01")){
				content += "门诊："+outpatient_list+"；";
			}else if(str.equals("02")){
				content += "住院、伤残："+maim_list+"；";
			}else if(str.equals("03")){
				content += "死亡："+demise_list+"；";
			}
		}
		return content;
	}

	/**
	 * <b> 附件补传 </b>
	 * @author ZXF
	 * @create 2019/11/29 0029 13:45
	 * @version
	 * @注意事项 </b>
	 */
	@Override
	public ResultDto saveUploadFile(InsCommonReportVo vo){
		try {
			Long report_id = Long.parseLong(vo.getIns_common_report_id());
			insClaimInformationAPIService.accordingToTheInsCommonReportVoSetUpInsClaimInformation(vo,report_id);
			String productCode = dao.getProductCodeByReportId(report_id);
			if(StringUtils.isNotEmpty(productCode)&& productCode.contains(ConstProp.GZZRX_CA)){
				InsCommonReportVo icvo = getInsCommonReportVoInfoById(report_id,1);
				String result = gZZRX_CARequestService.requestReportCA(icvo, TransTypeEnum.CLSC.getValue());
				String[] strs = result.split(ConstProp.POUND_SIGN);
				//附件补传成功
				if(ConstProp.CODE_SUCCESS.equals(strs[0])) {
					//变更附件状态
					insClaimInformationAPIService.updateStatusByReportId(report_id);
					return new ResultDto("附件影像保存成功", ConstProp.CODE_SUCCESS, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
				}else{
					List<String> ids = Lists.newArrayList();
					//筛选上传接口成功的附件id
					for(InsClaimInformationVo icfvo : icvo.getClaimInformationVoList()){
						if(ConstProp.DIGIT_ZERO.equals(icfvo.getStatus())){
							int len = icfvo.getIns_claim_information_id().length();
							String sign = icfvo.getIns_claim_information_id().substring(len-3,len);
							String index = icfvo.getShort_group_code()+sign;
							if(!strs[1].contains(index)){
								ids.add(icfvo.getIns_claim_information_id());
							}
						}
					}
					//变更附件状态
					insClaimInformationAPIService.updateStatusByIds(ids);
					return new ResultDto(strs[2], ConstProp.CODE_SUCCESS, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
				}
			}else if(StringUtils.isNotEmpty(productCode)&& productCode.contains(ConstProp.GZZRX_PAC)){
				String result = gZZRX_PACRequestService.requestReportPAC(report_id, TransTypeEnum.CLSC.getValue());
				String[] strs = result.split(ConstProp.POUND_SIGN);
				//附件补传成功
				if(ConstProp.CODE_SUCCESS.equals(strs[0])) {
					//变更附件状态
					insClaimInformationAPIService.updateStatusByReportId(report_id);
					return new ResultDto(strs[1], ConstProp.CODE_SUCCESS, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
				}else{
					TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
					return new ResultDto(strs[1], ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
				}
			}else if(StringUtils.isNotEmpty(productCode)&& productCode.contains(ConstProp.GZZRX_TB)){
				String result = gZZRX_TBRequestService.requestReportTB(Long.parseLong(vo.getIns_insurance_slip_id()),vo,"", TransType.EPIC_YXSC.getValue());
				String[] strs = result.split(ConstProp.POUND_SIGN);
				//附件补传成功
				if(ConstProp.CODE_SUCCESS.equals(strs[0])) {
					//变更附件状态
					insClaimInformationAPIService.updateStatusByReportId(report_id);
					return new ResultDto(strs[1], ConstProp.CODE_SUCCESS, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
				}else{
					TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
					return new ResultDto(strs[1], ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
				}
			}else {
				return new ResultDto("附件影像保存成功", ConstProp.CODE_SUCCESS, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
			}
		} catch (Exception e) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			return new ResultDto("附件补传异常："+e.getMessage(), ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
		}
	}

	/**
	 * 根据id删除报案申请数据
	 * @param oid 雇员id
	 * @return
	 */
	@Override
	public boolean delectInsCommonReportByOid(Long oid){
		try {
			dao.updateStatusById(oid);
			return true;
		}catch (Exception e){
			return false;
		}
	}

	/**
	 * <b> 根据订单id 查询报案列表</b>
	 * @author ZXF
	 * @create 2019/11/19 0019 14:37
	 * @version
	 * @注意事项 </b>
	 */
	@Override
	public List<InsCommonReportVo> selectInsCommonReportVoListByOrderID(String keyword, String status, String startDate, String endDate,Long user_id, DwzPage page){
		Page<InsCommonReportVo> pageHelper = new Page(page.getPageNum(), page.getNumPerPage());
		List<InsCommonReportVo> voList = dao.selectInsCommonReportVoListByOrderID(pageHelper,keyword, status, startDate, endDate, user_id);
		page.setTotalCount(new Long(pageHelper.getTotal()).intValue());
		return voList;
	}

	/**
	 * <b> 根据被标记的身份证号查询理赔记录 </b>
	 * @author ZXF
	 * @create 2020/06/19 0019 14:17
	 * @version
	 * @注意事项 </b>
	 */
	@Override
	public List<Map<String,String>> selectReportListByIdCardNo(String status, String saasIdCardNo){
		return dao.selectReportListByIdCardNo(status, saasIdCardNo);
	}

	@Override
	public String sendApi(String oid) throws Exception{
		String result = gZZRX_PACRequestService.requestReportPAC(Long.parseLong(oid),"16");
		return result;
	}

	/**
	 * <b> 根据保单号查询线下做理赔的保安信息列 </b>
	 * 注：用户登录后触发该方法，避免一次性查系统内数据导致数据随时间越来越大，通过区分用户可以分流数据量
	 * @author ZXF
	 * @create 2020/04/27 0027 11:17
	 * @version
	 * @注意事项 </b>
	 */
	@Override
	public void findXXReportDetails(){
		ClientUserVo userdetail = UserSupportUtil.getSessionUser();
		if(userdetail==null){
			return;
		}
		Long userId = Long.parseLong(userdetail.getOid());
		List<String> policyNosPAC = insInsuranceSlipAPIService.findPolicyNosByPACGZZRX(userId);
		List<String> policyNosCA = insInsuranceSlipAPIService.findPolicyNosByCAGZZRX(userId);
		if(policyNosPAC.size()>0){
			int count = 0;
			List<String> list = Lists.newArrayList();
			for(String policyNo : policyNosPAC){
				list.add(policyNo);
				if(count == 49){
					loadAndSetXXReport(userId, String.join(",", list));
					count = 0;
					list = Lists.newArrayList();
				}
				count ++;
			}
			if(list.size()>0){
				loadAndSetXXReport(userId, String.join(",", list));
			}
		}
		if(policyNosCA.size()>0){
			int count = 0;
			List<String> list = Lists.newArrayList();
			for(String policyNo : policyNosCA){
				list.add(policyNo);
				if(count == 49){
					loadAndSetCAXXReport(userId, list);
					count = 0;
					list = Lists.newArrayList();
				}
				count ++;
			}
			if(list.size()>0){
				loadAndSetCAXXReport(userId, list);
			}
		}
	}

	private void loadAndSetCAXXReport(Long userId, List<String> policyNos) {
		myAsyncExecutor.execute(()->{
			List<Map> arrMap = Lists.newArrayList();
			try {
				for(String policyNo:policyNos){
					int total = 0;
					int totalPageNum = 1;
					for(int i=1;i<=totalPageNum;i++){
						String result = gZZRX_CARequestService.requestXXReportCA(policyNo,"",i, TransTypeEnum.AJCX.getValue());
						String[] arr = result.split(ConstProp.POUND_SIGN);
						if(!ConstProp.CODE_SUCCESS.equals(arr[0])){
							break;
						}
						Map<String,String> map = JSON.parseObject(arr[1], Map.class);
						if(i == 1){
							totalPageNum = Integer.parseInt(map.get("TotalPage"));
							total = Integer.parseInt(map.get("TotalCount"));
							//要跑的数据多(>100)符合以下限制(白天用户操作时间段)，将业务数据寄存任务表放到晚上跑，避开高峰期
							if(total>100&&DateUtil.getHours()>8&&DateUtil.getHours()<23){
								comTaskResidualAPIService.saveComTaskResidual2("task_loadAndSetCAXXReport","请求接口获取报案数据","com.bcxin.ins.service.order.InsCommonReportAPIService",2,"Long,String",String.valueOf(userId)+","+policyNo);
								break;
							}
						}
						if(total>0){
							arrMap.addAll(JSONArray.parseArray(map.get("ReportInfo"), Map.class));
						}
					}
				}
				List<InsCommonReport> icrList = Lists.newArrayList();
				List<InsPaymentInfo> ipiList = Lists.newArrayList();
				List<InsCaseInfo> iciList = Lists.newArrayList();
				for(Map map : arrMap){
					setCAXXReport(map, userId,icrList,ipiList,iciList);
				}
				if(icrList.size()>0){
					updateBatchById(icrList);
					insPaymentInfoAPIService.updateBatchById(ipiList);
					insCaseInfoAPIService.updateBatchById(iciList);
				}
			} catch(Exception e) {
				e.printStackTrace();
			}
		});
	}

	/**
	 * <b> 请求接口获取报案数据，保存到数据库 </b>
	 * @author ZXF
	 * @create 2020/04/27 0027 14:55
	 * @version
	 * @注意事项 </b>
	 */
	private void loadAndSetXXReport(Long userId, String policyNos) {
		myAsyncExecutor.execute(()->{
			try {
				List<Map> arrMap = Lists.newArrayList();
				int total = 0;
				int pageSize = 100;
				int pageNum = 1;
				for(int i=0;i<10;i++){
					String result = gZZRX_PACRequestService.requestXXReportPAC(policyNos,pageSize,pageNum,"18");
					String[] arr = result.split(ConstProp.POUND_SIGN);
					if(!ConstProp.CODE_SUCCESS.equals(arr[0])){
						break;
					}
					if(pageNum == 1){
						total = Integer.parseInt(arr[1]);
						//要跑的数据多(>100)符合以下限制(白天用户操作时间段)，将业务数据寄存任务表放到晚上跑，避开高峰期
						if(total>100&&DateUtil.getHours()>8&&DateUtil.getHours()<23){
							comTaskResidualAPIService.saveComTaskResidual2("task_loadAndSetXXReport","请求接口获取报案数据","com.bcxin.ins.service.order.InsCommonReportAPIService",2,"Long,String",String.valueOf(userId)+","+policyNos.replace(",","#"));
							break;
						}
					}
					if(total>0){
						String data = arr[3];
						arrMap.addAll(JSONArray.parseArray(data, Map.class));
					}
					if((total-pageSize)<0){
						break;
					}
					total = total-pageSize;
					pageNum = pageNum + 1;
				}
				List<InsCommonReport> icrList = Lists.newArrayList();
				List<InsPaymentInfo> ipiList = Lists.newArrayList();
				List<InsCaseInfo> iciList = Lists.newArrayList();
				for(Map map : arrMap){
					setXXReport(map, userId,icrList,ipiList,iciList);
				}
				if(icrList.size()>0){
					updateBatchById(icrList);
					insPaymentInfoAPIService.updateBatchById(ipiList);
					insCaseInfoAPIService.updateBatchById(iciList);
				}
			} catch(Exception e) {
				e.printStackTrace();
			}
		});
	}

	/**
	 * <b> 请求接口获取报案数据，保存到数据库(定时任务处理用) </b>
	 * @param userId 用户id
	 * @param policyNos 保单号列（多个"#"号隔开，业务方法里再转成","）
	 * @author ZXF
	 * @create 2020/04/27 0027 14:55
	 * @version
	 * @注意事项 </b>
	 */
	@Override
	public boolean task_loadAndSetXXReport(Long userId, String policyNos) {
			try {
				if(userId==null||StringUtils.isEmpty(policyNos)){
					return true;
				}
				policyNos = policyNos.replace("#",",");
				List<Map> arrMap = Lists.newArrayList();
				int total = 0;
				int pageSize = 100;
				int pageNum = 1;
				for(int i=0;i<10;i++){
					String result = gZZRX_PACRequestService.requestXXReportPAC(policyNos,pageSize,pageNum,"18");
					String[] arr = result.split(ConstProp.POUND_SIGN);
					if(!ConstProp.CODE_SUCCESS.equals(arr[0])){
						break;
					}
					if(pageNum == 1){
						total = Integer.parseInt(arr[1]);
					}
					if(total>0){
						String data = arr[3];
						arrMap.addAll(JSONArray.parseArray(data, Map.class));
					}
					if((total-pageSize)<0){
						break;
					}
					total = total-pageSize;
					pageNum = pageNum + 1;
				}
				List<InsCommonReport> icrList = Lists.newArrayList();
				List<InsPaymentInfo> ipiList = Lists.newArrayList();
				List<InsCaseInfo> iciList = Lists.newArrayList();
				for(Map map : arrMap){
					setXXReport(map, userId,icrList,ipiList,iciList);
				}
				if(icrList.size()>0){
					updateBatchById(icrList);
					insPaymentInfoAPIService.updateBatchById(ipiList);
					insCaseInfoAPIService.updateBatchById(iciList);
				}
				return true;
			} catch(Exception e) {
				e.printStackTrace();
			}
		return false;
	}

	/**
	 * <b> 长安请求接口获取报案数据，保存到数据库(定时任务处理用) </b>
	 * @param userId 用户id
	 * @param policyNos 保单号列（多个"#"号隔开）
	 * @author ZXF
	 * @create 2020/04/27 0027 14:55
	 * @version
	 * @注意事项 </b>
	 */
	@Override
	public boolean task_loadAndSetCAXXReport(Long userId, String policyNos) {
		List<Map> arrMap = Lists.newArrayList();
		try {
			if(userId==null||StringUtils.isEmpty(policyNos)){
				return true;
			}
			String[] policyNoArr = policyNos.split("#");
			for(String policyNo:policyNoArr){
				int total = 0;
				int totalPageNum = 1;
				for(int i=1;i<=totalPageNum;i++){
					String result = gZZRX_CARequestService.requestXXReportCA(policyNo,"",i, TransTypeEnum.AJCX.getValue());
					String[] arr = result.split(ConstProp.POUND_SIGN);
					if(!ConstProp.CODE_SUCCESS.equals(arr[0])){
						break;
					}
					Map<String,String> map = JSON.parseObject(arr[1], Map.class);
					if(i == 1){
						totalPageNum = Integer.parseInt(map.get("TotalPage"));
						total = Integer.parseInt(map.get("TotalCount"));
					}
					if(total>0){
						arrMap.addAll(JSONArray.parseArray(map.get("ReportInfo"), Map.class));
					}
				}
			}
			List<InsCommonReport> icrList = Lists.newArrayList();
			List<InsPaymentInfo> ipiList = Lists.newArrayList();
			List<InsCaseInfo> iciList = Lists.newArrayList();
			for(Map map : arrMap){
				setCAXXReport(map, userId,icrList,ipiList,iciList);
			}
			if(icrList.size()>0){
				updateBatchById(icrList);
			}
			if(ipiList.size()>0){
				insPaymentInfoAPIService.updateBatchById(ipiList);
			}
			if(iciList.size()>0){
				insCaseInfoAPIService.updateBatchById(iciList);
			}
			return true;
		} catch(Exception e) {
			e.printStackTrace();
		}
		return false;
	}

	private void setXXReport(Map map, Long userId, List<InsCommonReport> icrList, List<InsPaymentInfo> ipiList, List<InsCaseInfo> iciList) throws Exception {
		Long order_id = insInsuranceSlipAPIService.getIdByPolicyNo(String.valueOf(map.get("policyNo")));
		//保存报案信息
		List<InsCommonReport> list = dao.selectByMap(new ME().put("report_no", String.valueOf(map.get("reportNo"))).getM());
		InsCommonReport insCommonReport;
		if(list.size()>0){
			insCommonReport = list.get(0);
			//如果已结案就不做更新
			if(insCommonReport.getStatus() == 2){
				return;
			}
			insCommonReport.setUpdate_time(new Date());
		}else{
			insCommonReport = initInsCommonReport(userId, order_id);
			insCommonReport.setIs_sync("1");
		}
		//组装的在保人员信息
		List<String> zzList = dao.getZBRYByOrderId(order_id);
		String zz = "";
		if(zzList.size()>0){
			zz = org.apache.commons.lang.StringUtils.join(zzList.toArray(), ",");
		}
		//是线下报案的才去设置报案人姓名
		if("1".equals(insCommonReport.getIs_sync())){
			insCommonReport.setReporter_name(map.get("reporterName")==null?"":String.valueOf(map.get("reporterName")));
			insCommonReport.setReport_no(map.get("reportNo")==null?"":String.valueOf(map.get("reportNo")));
			insCommonReport.setPolicy_no(map.get("policyNo")==null?"":String.valueOf(map.get("policyNo")));
			insCommonReport.setReporter_tel(map.get("reporterCallNo")==null?"":String.valueOf(map.get("reporterCallNo")));
			insCommonReport.setReport_date(map.get("reportDate")==null?null:DateUtil.convertStringToDate(String.valueOf(map.get("reportDate"))));
			insCommonReport.setAccident_date(map.get("accidentDate")==null?null:DateUtil.convertStringToDate(String.valueOf(map.get("accidentDate"))));
			insCommonReport.setAccident_place(map.get("accidentPlace")==null?"":String.valueOf(map.get("accidentPlace")));
			insCommonReport.setAccident_process(map.get("accidentDetail")==null?"":String.valueOf(map.get("accidentDetail")));
			insCommonReport.setAccident_cause_level_2(map.get("accidentCause")==null?"":String.valueOf(map.get("accidentCause")));
			insCommonReport.setEnd_case_date(map.get("endCaseDate")==null?null:DateUtil.convertStringToDate(String.valueOf(map.get("endCaseDate"))));
			insCommonReport.setCheck_loss_sum(map.get("payAmount")==null? BigDecimal.ZERO:new BigDecimal(String.valueOf(map.get("payAmount"))));
			insCommonReport.setAudit_status("1");
			String treatment = map.get("treatment")==null?"":String.valueOf(map.get("treatment"));
			String personName = map.get("personName")==null?"":String.valueOf(map.get("personName"));
			String certificateNo = map.get("certificateNo")==null?"":String.valueOf(map.get("certificateNo"));
			insCommonReport.setInjured_detail(treatment);
			String outPatient = setList(insCommonReport.getOutpatient_list(),treatment,personName,certificateNo,"01",zz);
			if(StringUtils.isNotEmpty(outPatient)){
				insCommonReport.setOutpatient_list(outPatient);
			}
			String maim = setList(insCommonReport.getMaim_list(),treatment,personName,certificateNo,"02",zz);
			if(StringUtils.isNotEmpty(maim)){
				insCommonReport.setMaim_list(maim);
			}
			String demise = setList(insCommonReport.getDemise_list(),treatment,personName,certificateNo,"03",zz);
			if(StringUtils.isNotEmpty(demise)){
				insCommonReport.setDemise_list(demise);
			}
		}
		insCommonReport.setStatus("3".equals(String.valueOf(map.get("caseStatus")))?2:1);
		icrList.add(insCommonReport);
		//保存支付信息
		InsPaymentInfo insPaymentInfo = insPaymentInfoAPIService.selectById(insCommonReport.getIns_payment_info_id());
		if("1".equals(insCommonReport.getIs_sync())){
			insPaymentInfo.setClient_name(map.get("clientName")==null?"":String.valueOf(map.get("clientName")));
			insPaymentInfo.setClient_bank_account(map.get("clientBankAccount")==null?"":String.valueOf(map.get("clientBankAccount")));
			insPaymentInfo.setClient_bank_name(map.get("clientBankName")==null?"":String.valueOf(map.get("clientBankName")));
		}
		insPaymentInfo.setPay_date(map.get("payDate")==null?null:DateUtil.convertStringToDate(String.valueOf(map.get("payDate"))));
		insPaymentInfo.setUpdate_time(new Date());
		ipiList.add(insPaymentInfo);
		//报案成功案件信息
//		insCaseInfoAPIService.deleteByMap(new ME().put("ins_common_report_id", String.valueOf(insCommonReport.getIns_common_report_id())).getM());
		InsCaseInfo insCaseInfo;
		List<InsCaseInfo> ciList = insCaseInfoAPIService.selectByMap(new ME().put("ins_common_report_id", String.valueOf(insCommonReport.getIns_common_report_id())).getM());
		if(ciList.size()>0){
			insCaseInfo =ciList.get(0);
		}else{
			insCaseInfo = insCaseInfoAPIService.initInsCaseInfo(userId, insCommonReport.getIns_common_report_id());
		}
		insCaseInfo.setIns_common_report_id(insCommonReport.getIns_common_report_id());
		insCaseInfo.setCase_no(map.get("caseNo")==null?"":String.valueOf(map.get("caseNo")));
		insCaseInfo.setAudit_status(map.get("rejectNoticeDate")==null?"1":"0");//是否理赔状态【1理赔，0不理赔】
		String caseStatus = "3".equals(String.valueOf(map.get("caseStatus")))?"0":String.valueOf(map.get("caseStatus"));
		insCaseInfo.setCase_status(caseStatus);//案件状态（0-已结案 1-已报案  2-已理算  6-已归档）
		insCaseInfo.setCase_times(map.get("caseTimes")==null?null:Integer.parseInt(String.valueOf(map.get("caseTimes"))));
		insCaseInfo.setClaim_name(map.get("claimName")==null?"":String.valueOf(map.get("claimName")));
		insCaseInfo.setEnd_case_amount_sum(map.get("payAmount")==null?"":String.valueOf(map.get("payAmount")));
		String ic = String.valueOf(map.get("indemnityConclusion"));
		String indemnity_conclusion = "1".equals(ic)?"正常赔付"
				:"2".equals(ic)?"零结"
				:"3".equals(ic)?"拒赔"
				:"4".equals(ic)?"立案注销"
				:"5".equals(ic)?"报案注销"
				:"";
		insCaseInfo.setIndemnity_conclusion(indemnity_conclusion);
		insCaseInfo.setReject_notice_date(map.get("rejectNoticeDate")==null?null:DateUtil.convertStringToDate(String.valueOf(map.get("rejectNoticeDate"))));
		insCaseInfo.setEnd_case_date(map.get("endCaseDate")==null?null:DateUtil.convertStringToDate(String.valueOf(map.get("endCaseDate"))));
		insCaseInfo.setWithdraw_reason(map.get("withdrawReason")==null?"":String.valueOf(map.get("withdrawReason")));
		String rejectNoticeUrl = map.get("rejectNoticeUrl")==null?"":String.valueOf(map.get("rejectNoticeUrl"));
		if(StringUtils.isEmpty(insCaseInfo.getReject_notice_url())&&StringUtils.isNotEmpty(rejectNoticeUrl)){
			//如果拒赔通知书地址存在，就转存为本地文件
			String path = FileHelp.saveFile(rejectNoticeUrl);
			if(StringUtils.isNotEmpty(path)){
				rejectNoticeUrl = GlobalResources.WEB_URL + path;
			}
			insCaseInfo.setReject_notice_url(rejectNoticeUrl);
		}
		iciList.add(insCaseInfo);
	}

	private void setCAXXReport(Map map, Long userId, List<InsCommonReport> icrList, List<InsPaymentInfo> ipiList, List<InsCaseInfo> iciList) throws Exception {
		Long order_id = insInsuranceSlipAPIService.getIdByPolicyNo(String.valueOf(map.get("PolicyNo")));
		//保存报案信息
		List<InsCommonReport> list = dao.selectByMap(new ME().put("report_no", String.valueOf(map.get("RegistNo"))).getM());
		InsCommonReport insCommonReport;
		if(list.size()>0){
			insCommonReport = list.get(0);
			//如果已结案就不做更新
			if(insCommonReport.getStatus() == 2){
				return;
			}
			insCommonReport.setUpdate_time(new Date());
		}else{
			insCommonReport = initInsCommonReport(userId, order_id);
			insCommonReport.setIs_sync("1");
		}
		if(StringUtils.isEmpty(insCommonReport.getReport_no())){
			insCommonReport.setReport_no(map.get("RegistNo")==null?"":String.valueOf(map.get("RegistNo")));
		}
		//是线下报案的才去设置报案人姓名
		if("1".equals(insCommonReport.getIs_sync())){
			insCommonReport.setReporter_name(map.get("ReportName")==null?"":String.valueOf(map.get("ReportName")));
			insCommonReport.setPolicy_no(map.get("PolicyNo")==null?"":String.valueOf(map.get("PolicyNo")));
			insCommonReport.setReporter_tel(map.get("PhoneNumber")==null?"":String.valueOf(map.get("PhoneNumber")));
			insCommonReport.setReport_date(map.get("ReportTime")==null?null:DateUtil.convertStringToDate(String.valueOf(map.get("ReportTime"))));
			insCommonReport.setAccident_date(map.get("DamageTime")==null?null:DateUtil.convertStringToDate(String.valueOf(map.get("DamageTime"))));
			insCommonReport.setAccident_place(map.get("DamageAddress")==null?"":String.valueOf(map.get("DamageAddress")));
			insCommonReport.setAccident_process(map.get("context")==null?"":String.valueOf(map.get("context")));
			insCommonReport.setAccident_cause_level_1(map.get("DamageCode")==null?"":String.valueOf(map.get("DamageCode")));
			insCommonReport.setCheck_loss_sum(BigDecimal.ZERO);
			insCommonReport.setAudit_status("1");
			if(StringUtils.isNotEmpty(String.valueOf(map.get("rs")))){
				String[] rsArr = String.valueOf(map.get("rs")).split(";");
				String outpatient_list = "";
				String demise_list = "";
				for(String rs : rsArr){
					String[] r = rs.split("|");
					if("1".equals(r[1])){
						outpatient_list = outpatient_list+r[0]+",";
					}
					if("2".equals(r[1])){
						demise_list = demise_list+r[0]+",";
					}
				}
				String treatment = (StringUtils.isNotEmpty(outpatient_list)?"01,":"")+(StringUtils.isNotEmpty(demise_list)?"03":"");
				insCommonReport.setInjured_detail(treatment);
				if(StringUtils.isNotEmpty(outpatient_list)){
					insCommonReport.setOutpatient_list(outpatient_list);
				}
				if(StringUtils.isNotEmpty(demise_list)){
					insCommonReport.setDemise_list(demise_list);
				}
			}

			if(StringUtils.isNotEmpty(String.valueOf(map.get("pm")))){
				String[] pmArr = String.valueOf(map.get("pm")).split(";");
				String[] pmInfo = pmArr[0].split("|");
				//保存支付信息
				InsPaymentInfo insPaymentInfo = insPaymentInfoAPIService.selectById(insCommonReport.getIns_payment_info_id());
				insPaymentInfo.setClient_name(pmInfo[0]);
				insPaymentInfo.setClient_certificate_no(pmInfo[1]);
				insPaymentInfo.setClient_certificate_type("1".equals(pmInfo[6])?"0":"2");
				insPaymentInfo.setClient_bank_account(pmInfo[3]);
				insPaymentInfo.setClient_bank_name(pmInfo[2]);
				insPaymentInfo.setUpdate_time(new Date());
				insPaymentInfo.setProvince_code(pmInfo[4]);
				insPaymentInfo.setRegion_code(pmInfo[5]);
				insPaymentInfo.setBank_account_attribute("1".equals(pmInfo[6])?"1":"0");
				ipiList.add(insPaymentInfo);
			}
		}
		insCommonReport.setStatus("3".equals(String.valueOf(map.get("CaseStatusCode")))?2:1);
		icrList.add(insCommonReport);
		//报案成功案件信息
//		insCaseInfoAPIService.deleteByMap(new ME().put("ins_common_report_id", String.valueOf(insCommonReport.getIns_common_report_id())).getM());
		InsCaseInfo insCaseInfo;
		List<InsCaseInfo> ciList = insCaseInfoAPIService.selectByMap(new ME().put("ins_common_report_id", String.valueOf(insCommonReport.getIns_common_report_id())).getM());
		if(ciList.size()>0){
			insCaseInfo =ciList.get(0);
		}else{
			insCaseInfo = insCaseInfoAPIService.initInsCaseInfo(userId, insCommonReport.getIns_common_report_id());
		}
		insCaseInfo.setCase_status(String.valueOf(map.get("CaseStatusCode")));//案件状态（1：已报案;2：已理算;3：已结案;4：重开赔案）
		insCaseInfo.setCase_status_1(String.valueOf(map.get("CaseStatusName")));
		iciList.add(insCaseInfo);
	}

	private static String setList(String oldName,String treatment, String personName, String certificateNo, String type, String zz){
		List<String> list = Lists.newArrayList();
		if(StringUtils.isEmpty(treatment)){
			return list.size()>0?String.join(",",list):"";
		}
		String[] treatments = treatment.split(",");
		String[] personNames = StringUtils.isNotEmpty(personName)?personName.split(","):null;
		String[] certificateNos = StringUtils.isNotEmpty(certificateNo)?certificateNo.split(","):null;
		for(int i=0;i<treatments.length;i++){
			if(!type.equals(treatments[i])){
				continue;
			}
			if(personNames==null||personNames.length<=i){
				continue;
			}
			String name = personNames[i];
			if(certificateNos==null||certificateNos.length<=i){
				list.add(name);
				continue;
			}
			//组装成能跟数据库查询出来的字符串匹配的格式
			name = name+"("+certificateNos[i]+")";
			String cts = name.substring(0,1)+"("+certificateNos[i]+");";
			if(StringUtils.isNotEmpty(zz)){
				if(zz.contains(cts)){
					//能匹配上说明在保
					try{
						String zzR = zz.replace(cts,"&&");
						name = zzR.split(cts)[1].split(",")[0];
					}catch (Exception e){}
				}else{
					//匹配不上说明已经减员，就保留原来设置过的人伤信息
					if(StringUtils.isNotEmpty(oldName)&&oldName.contains("(")&&oldName.contains(")")){
						name = oldName;
					}
				}
			}
			list.add(name);
		}
		return list.size()>0?String.join(",",list):"";
	}

	/**
	 * <b> 通过aspose，生成doc初稿，索赔申请书 </b>
	 * @author ZXF
	 * @create 2020/06/08 0008 11:14
	 * @version
	 * @注意事项 </b>
	 */
	@Override
	public String draftWord(Long reportId){
		InsCommonReportVo vo = getInsCommonReportVoById(reportId);
		OrderFormVo orderVo = policyService.accordingToOrderIDToGetPolicyDto(Long.parseLong(vo.getIns_insurance_slip_id()));
		String path = draft(vo,orderVo);
		if(StringUtils.isEmpty(path)){
			return path;
		}
		path =  GlobalResources.DONOW_PATH+path;
		String fileName = path.split("report/")[1];
		String fileId = UUID.randomUUID().toString();
		String sysPath = GlobalResources.COM_IMG_RE+path.split("path=")[1];
		doc2pdf(sysPath);
		try(InputStream is = new FileInputStream(sysPath)) {
			if(gZZRX_PACRequestService.isUploadPA(is,fileId,fileName)){
				InsClaimInformation ic = new InsClaimInformation();
				ic.setFile_key(fileId);
				ic.setFile_name(fileName);
				ic.setFile_path(path);
				ic.setStatus(1);
				ic.setShort_group_code("001000");
				ic.setIns_common_report_id(reportId);
				ic.setCreate_time(new Date());
				insClaimInformationAPIService.insert(ic);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return path;
	}

	/**
	 * <b> 通过aspose，生成doc初稿 </b>
	 * @author ZXF
	 * @create 2020/06/08 0008 11:14
	 * @version
	 * @注意事项 </b>
	 */
	@Override
	public String draft(InsCommonReportVo vo, OrderFormVo orderVo){
		FileOutputStream fileOS = null;
		InputStream license = null;
		FileInputStream word = null;
		try {
			license = new PathMatchingResourcePatternResolver().getResource("/aspose/license.xml").getInputStream();
			License aposeLic = new License();
			aposeLic.setLicense(license);
			String classpath = this.getClass().getResource("/").getPath().replaceFirst("/", "");
			String webappRoot = classpath.replaceAll("WEB-INF/classes/", "");
			String filePath = "/"+webappRoot+"/static/coninsweb/public-resources/files/索赔申请书示例APP.doc";
			word = new FileInputStream(new File(filePath.replace("%20"," ")));
			Document docAll = new Document(word);
			DocumentBuilder builder = new DocumentBuilder(docAll);
			Map<String,String> map = Maps.newHashMap();
			map.put("comName",orderVo.getApplicant_name());
			map.put("productName",orderVo.getProduct_name());
			map.put("policyNo",orderVo.getExternal_reference());
			map.put("reportNo",vo.getReport_no());
			map.put("reportName",vo.getReporter_name());
			map.put("reportTel",vo.getReporter_tel());
			map.put("accidentDate",vo.getAccident_date());
			map.put("accidentPlace",vo.getAccident_place());
			map.put("accidentProcess",vo.getAccident_process());
			map.put("insName",vo.getSignature_path());
			map.put("year",DateUtil.getCurrentDate().split(ConstProp.MINUS)[0]);
			map.put("month",DateUtil.getCurrentDate().split(ConstProp.MINUS)[1]);
			map.put("day",DateUtil.getCurrentDate().split(ConstProp.MINUS)[2]);
			if (map != null && !map.isEmpty()) {
				Set set = map.keySet();
				Iterator it = set.iterator();
				while (it.hasNext()) {
					//获取模板中的域名
					String next = String.valueOf(it.next());
					//通过域名获取想要在该域名处替换的数据
					String s = String.valueOf(map.get(next));
					//向域中添加图片
					if(next.equals("insName")){
						builder.moveToMergeField(next);
						URL url = new URL(vo.getSignature_path());
						HttpURLConnection conn = (HttpURLConnection)url.openConnection();
						conn.setRequestMethod("GET");
						conn.setConnectTimeout(5 * 1000);
						//通过输入流获取图片数据
						license = conn.getInputStream();
						//设置图片位置、宽高,
						builder.insertImage(license,0,65,0,11, 42, 25,3);
					}
					//普通文本的数据替换
					if (builder.moveToMergeField(next)) {
						builder.write(String.valueOf(s));
					}

				}
			}

			docAll.getMailMerge().setFieldMergingCallback(new HandleMergeField());
			docAll.getMailMerge().deleteFields();
			String savePath = "/report/";
			String files = (new Date()).getTime() + RandomStringUtils.random(5, new char[]{'a','b','c','d','e','f'}) +".doc";
			String result = savePath + files;
			String path = GlobalResources.COM_IMG_RE+savePath+files;
			//写入doc文件
			fileOS = new FileOutputStream(new File(path));
			docAll.save(fileOS, SaveFormat.DOCX);
			return "/getResource?path="+result;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (fileOS != null) {
					fileOS.close();
				}
				if (license != null) {
					license.close();
				}
				if (word != null) {
					word.close();
				}
			} catch (IOException e){
				e.printStackTrace();
			}
		}
		return "";
	}

	public static void doc2pdf(String docRead) {
		String pdfPath = docRead.replace(".doc",".png");
		String folderPath = "/usr/share/fonts/";
		try(InputStream license = new PathMatchingResourcePatternResolver().getResource("/aspose/license.xml").getInputStream();
			FileOutputStream fileOS = new FileOutputStream(new File(pdfPath))) {
			License aposeLic = new License();
			aposeLic.setLicense(license);
			Document doc = new Document(docRead);
			//加载服务器字体库
			List<FontSourceBase> fontSources = Lists.newArrayList(FontSettings.getFontsSources());
			FolderFontSource folderFontSource = new FolderFontSource(folderPath,true);
			fontSources.add(folderFontSource);
			FontSourceBase[] updatedFontSources = new FontSourceBase[fontSources.size()];
			for (int i = 0; i < fontSources.size(); i++) {
				updatedFontSources[i] = fontSources.get(i);
			}
			FontSettings.setFontsSources(updatedFontSources);
			//word转png
			ImageSaveOptions iso = new ImageSaveOptions(SaveFormat.PNG);
			iso.setResolution(200);
			doc.save(fileOS, iso);
//			doc.save(fileOS, SaveFormat.PDF);
		}catch (Exception e){
			e.printStackTrace();
		}
	}

	private static class HandleMergeField implements IFieldMergingCallback {
		private DocumentBuilder mBuilder;

		@Override
		public void fieldMerging(FieldMergingArgs e) throws Exception {
		}
		@Override
		public void imageFieldMerging(ImageFieldMergingArgs e) throws Exception {
			if (mBuilder == null) {
				mBuilder = new DocumentBuilder(e.getDocument());
			}
			if (e.getFieldValue() instanceof List) {
				mBuilder.moveToMergeField(e.getFieldName());
				for (Object o : (List) e.getFieldValue()) {
					if (o instanceof byte[]) {
						mBuilder.insertImage((byte[]) o);
						mBuilder.insertHtml("<br/>");
					} else if (o instanceof String) {
						mBuilder.insertImage((String) o,60,35);
            			/* 去掉换行，解决 系统生成的报告会自动增加段前段后间距，与模版不一致 的问题*/
						//mBuilder.insertHtml("<br/>");
					} else if (o instanceof InputStream) {
						mBuilder.insertImage((InputStream) o,60,35);
						mBuilder.insertHtml("<br/>");
					}
				}
			}
		}
	}
}
