package com.bcxin.ins.coninsweb.order.controller.api.build;

import com.alibaba.fastjson.JSON;
import com.bcxin.ins.third.build.yangguang.YGGCService;
import com.bcxin.ins.third.build.yangguang.yggc.Result;
import com.bcxin.ins.third.build.yangguang.yggc.YGGC;
import com.bcxin.ins.service.order.PolicyService;
import com.bcxin.ins.service.product.ProductService;
import com.bcxin.ins.rest.UserSupportUtil;
import com.bcxin.ins.core.base.web.BaseController;
import com.bcxin.ins.core.entity.R;
import com.bcxin.ins.spring.annotation.LoginRequired;
import com.bcxin.ins.spring.annotation.OperationLog;
import com.bcxin.ins.util.*;
import com.bcxin.ins.util.enums.OfficeType;
import com.bcxin.ins.vo.*;
import com.bcxin.ins.vo.ConstProp;
import com.bcxin.mybatisplus.toolkit.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.Date;

/**
 * 负责前台建筑类投保流程的业务逻辑处理
 *
 * @author zxf
 */
@Controller
@RequestMapping("/insurance/build")
public class Build_Policy_Controller extends BaseController {


    @Autowired
    private ProductService productService;
    @Autowired
    private PolicyService policyService;
    @Autowired
    private YGGCService yGGCService;

    /**
     * 新跳到投保界面方法
     *
     * @param request
     * @param product_id
     * @param model
     * @return
     */
    @OperationLog(source = OperationLog.SOURCETYPE.FRONT,title ="【视图】产品-访问投保页")
    @LoginRequired(methodParamKey={"1#product_id"}, redirectUrl = "insurance/build/policyInit/{product_id}")
    @RequestMapping("/policyInit/{product_id}")
    public ModelAndView policyInit(HttpServletRequest request, @PathVariable Long product_id, ModelMap model) throws Exception {
        ModelAndView view = new ModelAndView();
        view.addObject(ConstProp.RECOMMEND_CODE, UserSupportUtil.getRecommendCode());
        orderAllotInit(product_id, view);
        setTokenByApi(view);
        return view;
    }

    private void orderAllotInit(Long product_id, ModelAndView view) {
        ProductVo pd = productService.getProduct(product_id);
        OrderFormVo dto = new OrderFormVo();
        dto.setProduct_oid(pd.getOid());
        dto.setProduct_code(pd.getProduct_code());
        dto.setGross_premium(pd.getPremium_min());
        view.addObject(ConstProp.PD,pd);
        view.addObject(ConstProp.DTO,dto);
        if ((StringUtils.isEmpty(pd.getProduct_code()) ? false : ConstProp.BZX_TB_GCTB.equals(pd.getProduct_code()))
                ||(StringUtils.isEmpty(pd.getProduct_code()) ? false : ConstProp.BZX_YG_GCTB.equals(pd.getProduct_code()))
                ||(StringUtils.isEmpty(pd.getProduct_code()) ? false : ConstProp.BZX_DB_GCTB.equals(pd.getProduct_code()))) {//太平洋投标
            view.setViewName("/coninsweb/insurance/build/policy/enterBasicInfo_bd");
            view.addObject("otList", OfficeType.listT(pd.getProduct_code().contains("DB")?"DB":"OT"));
            initEnumList(view);
        } else if (StringUtils.isEmpty(pd.getProduct_code()) ? false : ConstProp.BZX_GCLY.equals(pd.getProduct_code())) {//履约
            view.setViewName("/coninsweb/insurance/build/policy/enterBasicInfo_ly_1");
            initEnumList(view);
        }
    }

    private void orderAllot(Long order_id, ModelAndView view) {
        OrderFormVo dto = policyService.accordingToOrderIDToGetPolicyDto(order_id);
        ProductVo pd = productService.getProduct(Long.parseLong(dto.getProduct_oid()));
        view.addObject(ConstProp.PD, pd);
        view.addObject(ConstProp.DTO, dto);
        if(StringUtils.isEmpty(dto.getProduct_code())){
            return;
        }
        if (ConstProp.BZX_TB_GCTB.equals(dto.getProduct_code())
                ||ConstProp.BZX_YG_GCTB.equals(dto.getProduct_code())
                ||ConstProp.BZX_DB_GCTB.equals(dto.getProduct_code())) {
            
            view.addObject("otList", OfficeType.listT(pd.getProduct_code().contains("DB")?"DB":"OT"));
            SpecialBidVo vo = policyService.accordingToOrderIDToGetSpecialBidVo(order_id);
            view.addObject(ConstProp.PROVINCELIST, RegionUtils.findDistrictByParentCode(ConstProp.DIGIT_ONE, ConstProp.BLANK_CHAR));
            //保单投保地址
            if (StringUtils.isNotEmpty(vo.getProvince())) {
                view.addObject(ConstProp.CITYLIST, RegionUtils.findDistrictByParentCode(ConstProp.DIGIT_TWO, vo.getProvince()));
            }
            if (StringUtils.isNotEmpty(vo.getCity())) {
                view.addObject(ConstProp.AREALIST, RegionUtils.findDistrictByParentCode(ConstProp.DIGIT_THREE, vo.getCity()));
            }
            //投保人地址
            if (StringUtils.isNotEmpty(vo.getRoleSubjectList().get(0).getReg_province())) {
                view.addObject(ConstProp.REG_CITYLIST, RegionUtils.findDistrictByParentCode(ConstProp.DIGIT_TWO, vo.getRoleSubjectList().get(0).getReg_province()));
            }
            if (StringUtils.isNotEmpty(vo.getRoleSubjectList().get(0).getReg_city())) {
                view.addObject(ConstProp.REG_AREALIST, RegionUtils.findDistrictByParentCode(ConstProp.DIGIT_THREE, vo.getRoleSubjectList().get(0).getReg_city()));
            }
            if (StringUtils.isNotEmpty(vo.getMailPolicyVo().getBank_province())) {
                view.addObject(ConstProp.BANKCITYLIST, RegionUtils.findDistrictByParentCode(ConstProp.DIGIT_TWO, vo.getMailPolicyVo().getBank_province()));
            }
            //被保险人地址
            if (StringUtils.isNotEmpty(vo.getRoleSubjectList().get(1).getReg_province())) {
                view.addObject(ConstProp.REG_CITY_1_LIST, RegionUtils.findDistrictByParentCode(ConstProp.DIGIT_TWO, vo.getRoleSubjectList().get(1).getReg_province()));
            }
            if (StringUtils.isNotEmpty(vo.getRoleSubjectList().get(1).getReg_city())) {
                view.addObject(ConstProp.REG_AREA_1_LIST, RegionUtils.findDistrictByParentCode(ConstProp.DIGIT_THREE, vo.getRoleSubjectList().get(1).getReg_city()));
            }
            view.addObject(ConstProp.VO, vo);
            view.setViewName("/coninsweb/insurance/build/policy/enterBasicInfo_bd");
            initEnumList(view);
        }else if ("BZX-GCLY".equals(dto.getProduct_code())) {
            SpecialPerformanceVo_1 vo = policyService.accordingToOrderIDToGetSpecialPerformanceVo_1(order_id);
            view.addObject(ConstProp.PROVINCELIST, RegionUtils.findDistrictByParentCode(ConstProp.DIGIT_ONE, ConstProp.BLANK_CHAR));
            if (StringUtils.isNotEmpty(vo.getProvince())) {
                view.addObject(ConstProp.CITYLIST, RegionUtils.findDistrictByParentCode(ConstProp.DIGIT_TWO, vo.getProvince()));
            }
            if (StringUtils.isNotEmpty(vo.getProvince())) {
                view.addObject(ConstProp.AREALIST, RegionUtils.findDistrictByParentCode(ConstProp.DIGIT_THREE, vo.getCity()));
            }
            view.addObject(ConstProp.VO, vo);
            view.setViewName("/coninsweb/insurance/build/policy/enterBasicInfo_ly_1");
            initEnumList(view);
        }
    }

    private void initEnumList(ModelAndView view) {
        view.addObject(ConstProp.PROVINCELIST, RegionUtils.findDistrictByParentCode(ConstProp.DIGIT_ONE, ConstProp.BLANK_CHAR));
    }

    /**
     * <b>通过订单ID跳转到投保界面 </b>
     *
     * @param request
     * @param order_id
     * @param status
     * @param model
     * @return
     * @author ZXF
     * @date 2016年12月21日 下午1:46:44
     * @注意事项 </b>
     * <b>
     */
    @LoginRequired(methodParamKey={"1#order_id"}, redirectUrl = "insurance/build/policy/{order_id}")
    @RequestMapping("/policy/{order_id}")
    public ModelAndView enterInfo(HttpServletRequest request, @PathVariable Long order_id, SessionStatus status, ModelMap model) {
        ModelAndView view = new ModelAndView();
        try {
            orderAllot(order_id, view);
        } catch (Exception e) {
            e.printStackTrace();
        }
        setTokenByApi(view);
        return view;
    }

    /**
     * <b>履约投保单向下3页操作到确认投保界面 </b>
     *
     * @param reqeust 页码投保单数据
     * @return
     * @throws Exception
     * @author ZXF
     * @date 2016年12月28日 下午4:20:11
     * @注意事项 </b>
     * <b>
     */
    @LoginRequired(methodParamKey={"0#order_id", "1#page"}, redirectUrl = "insurance/build/policy/pg_policy/{order_id}/{page}")
    @RequestMapping("/policy/pg_policy/{order_id}/{page}")
    public ModelAndView pg_policy(@PathVariable Long order_id, @PathVariable int page, HttpServletRequest reqeust) throws Exception {
        ModelAndView view = new ModelAndView();
        if (page <= 0) {
            return view;
        }
        OrderFormVo dto = null;
        try {
            dto = policyService.accordingToOrderIDToGetPolicyDto(order_id);
        } catch (Exception e) {
            e.printStackTrace();
        }
        view.addObject(ConstProp.DTO, dto);
        if (page == 1) {
            view.setViewName("/coninsweb/insurance/build/policy/enterBasicInfo_ly_1");
            //第一页内容存储
            SpecialPerformanceVo_1 vo = policyService.accordingToOrderIDToGetSpecialPerformanceVo_1(order_id);

            view.addObject(ConstProp.PROVINCELIST, RegionUtils.findDistrictByParentCode(ConstProp.DIGIT_ONE, ConstProp.BLANK_CHAR));
            if (StringUtils.isNotEmpty(vo.getProvince())) {
                view.addObject(ConstProp.CITYLIST, RegionUtils.findDistrictByParentCode(ConstProp.DIGIT_TWO, vo.getProvince()));
            }
            if (StringUtils.isNotEmpty(vo.getProvince())) {
                view.addObject(ConstProp.AREALIST, RegionUtils.findDistrictByParentCode(ConstProp.DIGIT_THREE, vo.getCity()));
            }
            view.addObject(ConstProp.VO, vo);
        } else if (page == 2) {
            view.setViewName("/coninsweb/insurance/build/policy/enterBasicInfo_ly_2");
            //第二页内容存储
            SpecialPerformanceVo_2 vo = policyService.accordingToOrderIDToGetSpecialPerformanceVo_2(order_id);
            view.addObject(ConstProp.PROVINCELIST, RegionUtils.findDistrictByParentCode(ConstProp.DIGIT_ONE, ConstProp.BLANK_CHAR));
            if (StringUtils.isNotEmpty(vo.getMailPolicyVo().getBank_province())) {
                view.addObject(ConstProp.BANKCITYLIST, RegionUtils.findDistrictByParentCode(ConstProp.DIGIT_TWO, vo.getMailPolicyVo().getBank_province()));
            }
            //投保人地址
            if (vo.getRoleSubjectList().size() <= 0) {
                view.addObject(ConstProp.VO, vo);
                return view;
            }
            if (StringUtils.isNotEmpty(vo.getRoleSubjectList().get(0).getReg_province())) {
                view.addObject(ConstProp.REG_CITYLIST, RegionUtils.findDistrictByParentCode(ConstProp.DIGIT_TWO, vo.getRoleSubjectList().get(0).getReg_province()));
            }
            if (StringUtils.isNotEmpty(vo.getRoleSubjectList().get(0).getReg_city())) {
                view.addObject(ConstProp.REG_AREALIST, RegionUtils.findDistrictByParentCode(ConstProp.DIGIT_THREE, vo.getRoleSubjectList().get(0).getReg_city()));
            }
            //被保险人地址
            if (StringUtils.isNotEmpty(vo.getRoleSubjectList().get(1).getReg_province())) {
                view.addObject(ConstProp.REG_CITY_1_LIST, RegionUtils.findDistrictByParentCode(ConstProp.DIGIT_TWO, vo.getRoleSubjectList().get(1).getReg_province()));
            }
            if (StringUtils.isNotEmpty(vo.getRoleSubjectList().get(1).getReg_city())) {
                view.addObject(ConstProp.REG_AREA_1_LIST, RegionUtils.findDistrictByParentCode(ConstProp.DIGIT_THREE, vo.getRoleSubjectList().get(1).getReg_city()));
            }
            view.addObject(ConstProp.VO, vo);
        } else if (page == 3) {
            view.setViewName("/coninsweb/insurance/build/policy/enterBasicInfo_ly_3");
            //第三页内容存储
            SpecialPerformanceVo_3 vo = policyService.accordingToOrderIDToGetSpecialPerformanceVo_3(order_id);
            view.addObject(ConstProp.VO, vo);
        }
        setTokenByApi(view);
        return view;
    }

    /**
     * <b>投标/履约保险投保界面跳转到确认页面中间的业务 </b>
     *
     * @param order_id
     * @param reqeust
     * @return
     * @throws Exception
     * @author ZXF
     * @date 2016年12月28日 下午4:21:44
     * @注意事项 </b>
     * <b>
     */
    @LoginRequired(methodParamKey={"0#order_id"}, redirectUrl = "insurance/build/policy/confirmPage/{order_id}")
    @RequestMapping("/policy/confirmPage/{order_id}")
    public ModelAndView confirmPage(@PathVariable Long order_id, HttpServletRequest reqeust) throws Exception {
        ModelAndView view = new ModelAndView();
        OrderFormVo dto = policyService.accordingToOrderIDToGetPolicyDto(order_id);
        view.addObject(ConstProp.DTO, dto);
        if(StringUtils.isEmpty(dto.getProduct_code())){
            return view;
        }
        if (ConstProp.BZX_TB_GCTB.equals(dto.getProduct_code())
                ||ConstProp.BZX_YG_GCTB.equals(dto.getProduct_code())
                ||ConstProp.BZX_DB_GCTB.equals(dto.getProduct_code())) {
            view.setViewName("/coninsweb/insurance/build/policy/policyConfirm_bd");
            SpecialBidVo vo = policyService.accordingToOrderIDToGetSpecialBidVo(order_id);
            view.addObject("otList", OfficeType.listT(dto.getProduct_code().contains("DB")?"DB":"OT"));
            view.addObject(ConstProp.VO, vo);
            view.addObject(ConstProp.REG_POLICY, RegionUtils.getRegionNameByALLCode(vo.getProvince(), vo.getCity(), vo.getArea_code()));
            view.addObject(ConstProp.REG_ROLE, RegionUtils.getRegionNameByALLCode(vo.getRoleSubjectList().get(0).getReg_province(), vo.getRoleSubjectList().get(0).getReg_city(), vo.getRoleSubjectList().get(0).getReg_district()));
            view.addObject(ConstProp.REG_ROLE_1, RegionUtils.getRegionNameByALLCode(vo.getRoleSubjectList().get(1).getReg_province(), vo.getRoleSubjectList().get(1).getReg_city(), vo.getRoleSubjectList().get(1).getReg_district()));
        } else if (ConstProp.BZX_GCLY.equals(dto.getProduct_code())) {
            view.setViewName("/coninsweb/insurance/build/policy/policyConfirm_ly");
            SpecialPerformanceVo_1 vo1 = policyService.accordingToOrderIDToGetSpecialPerformanceVo_1(order_id);
            SpecialPerformanceVo_2 vo2 = policyService.accordingToOrderIDToGetSpecialPerformanceVo_2(order_id);
            SpecialPerformanceVo_3 vo3 = policyService.accordingToOrderIDToGetSpecialPerformanceVo_3(order_id);
            view.addObject(ConstProp.VO1, vo1);
            view.addObject(ConstProp.VO2, vo2);
            view.addObject(ConstProp.VO3, vo3);
            view.addObject(ConstProp.REG_POLICY, RegionUtils.getRegionNameByALLCode(vo1.getProvince(), vo1.getCity(), vo1.getArea_code()));
            view.addObject(ConstProp.REG_ROLE, RegionUtils.getRegionNameByALLCode(vo2.getRoleSubjectList().get(0).getReg_province(), vo2.getRoleSubjectList().get(0).getReg_city(), vo2.getRoleSubjectList().get(0).getReg_district()));
        }
        setTokenByApi(view);
        return view;
    }

    /**
     * <b>企业短期第一页投保单客户填一半暂存，方法 </b>
     *
     * @param reqeust
     * @param response
     * @param model
     * @return
     * @throws Exception
     * @author ZXF
     * @date 2016年12月21日 下午1:47:55
     * @注意事项 </b>
     * <b>
     */
    @OperationLog(source = OperationLog.SOURCETYPE.FRONT_ORDER,title ="【请求】产品-订单投保")
    @RequestMapping("/policy/pendingSpecialPerformance_1VoPolicy")
    @ResponseBody
    public ResultDto pendingSpecialPerformance_1VoPolicy(SpecialPerformanceVo_1 vo, HttpServletRequest reqeust, HttpServletResponse response, ModelMap model) throws Exception {
        String recommendCode = reqeust.getParameter(ConstProp.RECOMMEND_CODE);
        return policyService.pendingSpecialPerformance_1VoPolicy(vo, recommendCode);
    }

    /**
     * <b>企业短期第二页投保单客户填一半暂存，方法 </b>
     *
     * @param reqeust
     * @param response
     * @param model
     * @return
     * @throws Exception
     * @author ZXF
     * @date 2016年12月21日 下午1:47:55
     * @注意事项 </b>
     * <b>
     */
    @RequestMapping("/policy/pendingSpecialPerformance_2VoPolicy")
    @ResponseBody
    public ResultDto pendingSpecialPerformance_2VoPolicy(SpecialPerformanceVo_2 vo, HttpServletRequest reqeust, HttpServletResponse response, ModelMap model) throws Exception {
        return policyService.pendingSpecialPerformance_2VoPolicy(vo);
    }

    /**
     * <b>企业短期第三页投保单客户填一半暂存，方法 </b>
     *
     * @param reqeust
     * @param response
     * @param model
     * @return
     * @throws Exception
     * @author ZXF
     * @date 2016年12月21日 下午1:47:55
     * @注意事项 </b>
     * <b>
     */
    @RequestMapping("/policy/pendingSpecialPerformance_3VoPolicy")
    @ResponseBody
    public ResultDto pendingSpecialPerformance_3VoPolicy(SpecialPerformanceVo_3 vo, HttpServletRequest reqeust, HttpServletResponse response, ModelMap model) throws Exception {
        return policyService.pendingSpecialPerformance_3VoPolicy(vo);
    }

    /**
     * <b>小微投保单客户填一半暂存，方法 </b>
     *
     * @param reqeust
     * @param response
     * @param model
     * @return
     * @throws Exception
     * @author ZXF
     * @date 2016年12月21日 下午1:47:55
     * @注意事项 </b>
     * <b>
     */
    @OperationLog(source = OperationLog.SOURCETYPE.FRONT_ORDER,title ="【请求】产品-订单投保")
    @RequestMapping("/policy/pendingSpecialBidPolicy")
    @ResponseBody
    public ResultDto pendingSpecialBidPolicy(SpecialBidVo vo, HttpServletRequest reqeust, HttpServletResponse response, ModelMap model) throws Exception {
        String recommendCode = reqeust.getParameter(ConstProp.RECOMMEND_CODE);
        return policyService.pendingSpecialBidPolicy(vo, recommendCode);
    }

    @RequestMapping("/policy/json")
    @ResponseBody
    public ModelAndView testJson(HttpServletRequest reqeust, HttpServletResponse response) {
        ModelAndView view = new ModelAndView("/coninsweb/insurance/build/transaction/testJson");
        setTokenByApi(view);
        return view;
    }


    /**
     * <b>修改订单状态</b>
     *
     * @return
     * @throws Exception
     * @author ZXF
     * @date 2016年12月21日 下午1:47:55
     * @注意事项 </b>
     * <b>
     */
    @LoginRequired
    @RequestMapping("/policy/updateOrderFormStatus")
    @ResponseBody
    public ResultDto updateOrderFormStatus(HttpServletRequest reqeust) throws Exception {

        String order_id = reqeust.getParameter(ConstProp.ORDER_ID);
        String status = reqeust.getParameter("status");
        OrderFormVo dto = policyService.accordingToOrderIDToGetPolicyDto(Long.valueOf(order_id));
        String url = null;
        if (StringUtils.isNotEmpty(dto.getProduct_code()) && "BZX-YG-GCTB".equals(dto.getProduct_code())) {
            try {
                SpecialBidVo specialBidVo = policyService.accordingToOrderIDToGetSpecialBidVo(Long.valueOf(order_id));
                Result result = yGGCService.underwritingHttpSend(JSON.toJSONString(YGGC.getDemo(dto, specialBidVo)), "1");
                String errorCode = result.getTbResultList().get(0).getErrorCode();
                String policyNo = result.getTbResultList().get(0).getPolicyNo();
                String premiumP = specialBidVo.getPremium();
                if (!"SUCCESS00000".equals(errorCode)) {
                    String operateMessage = result.getTbResultList().get(0).getOperateMessage();
                    return new ResultDto("审核失败：" + operateMessage, ConstProp.CODE_FAILURE, order_id, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
                }
                R r = yGGCService.payUrlZFB(policyNo, premiumP);
                if (r.getSuccess()) {
                    PolicyTransactionVo pvo = new PolicyTransactionVo();
                    pvo.setPolicy_id(dto.getOid());
                    pvo.setPolicy_serial_number(policyNo);//设置投保单号
                    policyService.saveTransaction(pvo);
                    url = r.getMsg();
                }
            } catch (Exception e) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                e.printStackTrace();
            }
        }else if (StringUtils.isNotEmpty(dto.getProduct_code()) && ConstProp.BZX_DB_GCTB.equals(dto.getProduct_code())) {
            String result = policyService.HTTP_DB_BUILD_HB(order_id);
            if(ConstProp.CODE_FAILURE.equals(result.split(ConstProp.POUND_SIGN)[0])){
                return new ResultDto(result.split(ConstProp.POUND_SIGN)[1], ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
            }
        }
        if (StringUtils.isEmpty(order_id) || StringUtils.isEmpty(status)) {
            return new ResultDto("数据丢失，请刷新页面后重试！", ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
        }
        OrderFormVo vo = new OrderFormVo();
        vo.setOid(String.valueOf(order_id));
        vo.setPolicy_status(status);
        String orderID = policyService.updateOrderFormStatus(vo);
        if (StringUtils.isNotEmpty(orderID)) {
            return new ResultDto("订单录入成功。", ConstProp.CODE_SUCCESS, orderID, ConstProp.BLANK_CHAR, url);
        } else {
            return new ResultDto("数据丢失，请刷新页面后重试！", ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
        }
    }

    /**
     * <b>业务逻辑处理，保存保单信息
     * 页面流转：点击保单保存，跳转支付页面 </b>
     *
     * @return
     * @author ZXF
     * @date 2016年12月21日 下午1:46:17
     * @注意事项 </b>
     * <b>
     */
    @LoginRequired(methodParamKey={"0#oid"}, redirectUrl = "insurance/build/policy/policyPayment/{oid}")
    @RequestMapping("/policy/policyPayment/{oid}")
    @Transactional
    public ModelAndView savePolicy(@PathVariable long oid) {
        OrderFormVo vo = policyService.accordingToOrderIDToGetPolicyDto(oid);
        ModelAndView view = null;
        if (vo.getPolicy_status().equals(DictConst.ORDER_STATUS_DSH)) {//待核保
            view = new ModelAndView("/coninsweb/insurance/build/transaction/waitOffer");
        } else if (vo.getPolicy_status().equals(DictConst.ORDER_STATUS_YCB)) {//承保通过
            view = new ModelAndView("/coninsweb/insurance/build/transaction/finishPay");
            view.addObject("code", ConstProp.CODE_SUCCESS);
            view.addObject("msg", "支付成功！");
        } else if (vo.getPolicy_status().equals(DictConst.ORDER_STATUS_YJB)) {//拒保
            view = new ModelAndView("/coninsweb/insurance/build/transaction/declinature");
        } else if (vo.getPolicy_status().equals(DictConst.ORDER_STATUS_DZF)) {//待支付
            if (StringUtils.isEmpty(vo.getProduct_code()) ? false : ConstProp.BZX_TB_GCTB.equals(vo.getProduct_code())) {
                view = new ModelAndView("/coninsweb/insurance/build/transaction/policyPayment");
            } else if (StringUtils.isEmpty(vo.getProduct_code()) ? false : ConstProp.BZX_YG_GCTB.equals(vo.getProduct_code())) {
                view = new ModelAndView("/coninsweb/insurance/build/transaction/policyPaymentYG");
                GCTB_YG_Payment(oid, vo, view);
            }else if (StringUtils.isEmpty(vo.getProduct_code()) ? false : "BZX-DB-GCTB".equals(vo.getProduct_code())) {
                view = new ModelAndView("/coninsweb/insurance/build/transaction/policyPaymentDB");
            } else if (StringUtils.isEmpty(vo.getProduct_code()) ? false : "BZX-GCLY".equals(vo.getProduct_code())) {
                //TODO 最低保险费,保费缴纳方式 值未确定
                AdviceNoteVo anVo = policyService.accordingToOrderIDToGetAdviceNoteVo(oid);
                String path_sign = policyService.accordingToOrderIDGainPathSign(oid);
                view = new ModelAndView("/coninsweb/insurance/transaction/paymentNotice");
                view.addObject(ConstProp.ANVO, anVo);
                view.addObject(ConstProp.PATH_SIGN, path_sign);
            }
        } else if (vo.getPolicy_status().equals(DictConst.ORDER_STATUS_DCB)) {//待承保
            view = new ModelAndView("/coninsweb/insurance/build/transaction/finishPay_ly");
        }
        view.addObject(ConstProp.DTO, vo);
        view.addObject(ConstProp.NOWTIME, new Date());
        setTokenByApi(view);
        return view;
    }

    /**
     * <b> 阳光工程投保产品支付业务 </b>
     * @author ZXF
     * @create 2020/09/27 0027 17:44
     * @version
     * @注意事项 </b>
     */
    private void GCTB_YG_Payment(@PathVariable long oid, OrderFormVo vo, ModelAndView view) {
        String url = null;
        boolean isSuccess = true;
        try {
            SpecialBidVo specialBidVo = policyService.accordingToOrderIDToGetSpecialBidVo(Long.valueOf(oid));
            Result result = yGGCService.underwritingHttpSend(JSON.toJSONString(YGGC.getDemo(vo, specialBidVo)), "1");
            String errorCode = result.getTbResultList().get(0).getErrorCode();
            String policyNo = result.getTbResultList().get(0).getPolicyNo();
            String premiumP = specialBidVo.getPremium();
            if ("SUCCESS00000".equals(errorCode)) {
                R r = yGGCService.payUrlZFB(policyNo, premiumP);
                if (r.getSuccess()) {
                    PolicyTransactionVo pvo = new PolicyTransactionVo();
                    pvo.setPolicy_id(vo.getOid());
                    pvo.setPolicy_serial_number(policyNo);//设置投保单号
                    policyService.saveTransaction(pvo);
                    url = r.getMsg();
                }
            } else {
                String operateMessage = result.getTbResultList().get(0).getOperateMessage();
                isSuccess = false;
                url = "/insurance/build/policy/updateOrderFormStatus";
                view.addObject("wrongMessage", operateMessage);
            }

            view.addObject("oid", oid);
            view.addObject("isSuccess", isSuccess);
            view.addObject("url", url);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * <b>业务逻辑处理，查看保单
     * 页面流转：跳转下载保单页面 </b>
     *
     * @return
     * @author ZXF
     * @date 2016年12月21日 下午1:46:17
     * @注意事项 </b>
     * <b>
     */
    @RequestMapping("/policy/downloadInsurancePolicy/{oid}")
    public @ResponseBody ResultDto downloadInsurancePolicy(@PathVariable long oid) {
        String downloadUrl = policyService.HTTP_YG_BUILD_DZBD(String.valueOf(oid));
        if(StringUtils.isNotEmpty(downloadUrl)){
            return new ResultDto("电子保单下载地址获取成功", ConstProp.CODE_SUCCESS, "请求ID:" + oid, ConstProp.BLANK_CHAR, downloadUrl);
        }
        return new ResultDto("保单下载请求失败", ConstProp.CODE_FAILURE, "请求ID:" + oid, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
    }

    @RequestMapping("/policy/requestPlanEndTime")
    @ResponseBody
    public ResultDto requestPlanEndTime(HttpServletRequest request) throws Exception {
        String bidtime = request.getParameter("bidtime");
        String bidPeriod = request.getParameter("bidPeriod");
        String productCode = request.getParameter("productCode");
        if (StringUtils.isEmpty(productCode)||StringUtils.isEmpty(bidtime)||StringUtils.isEmpty(bidPeriod)) {
            return new ResultDto("", "301", ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
        }
        //2.计算投标日期+投标有效期+28天后的日期
        int bpd = Integer.parseInt(bidPeriod) + 28;
        Date planTimeLast = DateUtil.convertStringToDate(DateUtil.dateAdd(3,bidtime,Integer.parseInt(bidPeriod)));//不加28天
        Date planTimeNow = DateUtil.convertStringToDate(DateUtil.dateAdd(3,bidtime,bpd));//加28天
        if(productCode.contains("BZX-TB")){//太保规则
            //1.计算一年后的时间
            Date planTime = DateUtil.convertStringToDate(DateUtil.dateAdd(1,bidtime,1));
            //3.比较planTimeLast的日期是否大于planTime，是就超出一年期限
            if (DateUtil.calculateTwoDateDvalue(planTime,planTimeLast)<0) {
                return new ResultDto("保险期间大于一年，请重新设置投标有效期！", ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
            }
            if (DateUtil.calculateTwoDateDvalue(planTime,planTimeNow)<0) {//如果按+28天的日期来比较超出1年的限制就直接按一年算
                planTimeNow = DateUtil.convertStringToDate(DateUtil.dateAdd(3,DateUtil.dateAdd(1,bidtime,1),-1));
            }
        }else if(productCode.contains("BZX-YG")){//阳光规则
            //1.计算一年后的时间
//                Date planTime = DateUtil.convertStringToDate(DateUtil.dateAdd(3,DateUtil.dateAdd(1,bidtime,1),-1));
            Date planTime = DateUtil.convertStringToDate(DateUtil.dateAdd(1,bidtime,1));
            //3.比较planTimeLast的日期是否大于planTime，是就超出一年期限
            if (DateUtil.calculateTwoDateDvalue(planTime,planTimeLast)<0) {
                return new ResultDto("保险期间大于一年，请重新设置投标有效期！", ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
            }
            if (DateUtil.calculateTwoDateDvalue(planTime,planTimeNow)<0) {//如果按+28天的日期来比较超出1年的限制就直接按一年算
                planTimeNow = DateUtil.convertStringToDate(DateUtil.dateAdd(3,DateUtil.dateAdd(1,bidtime,1),-1));
            }
        }else if(productCode.contains("BZX-DB")){//都邦规则
            //1.计算三个月后的时间
            Date planTime = DateUtil.convertStringToDate(DateUtil.dateAdd(2,bidtime,3));
            //3.比较planTimeLast的日期是否大于planTime，是就超出三个月期限
            if (DateUtil.calculateTwoDateDvalue(planTime,planTimeLast)<0) {
                return new ResultDto("保险期间不能大于三个月，请重新设置投标有效期！", ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
            }
            if (DateUtil.calculateTwoDateDvalue(planTime,planTimeNow)<0) {//如果按+28天的日期来比较超出1年的限制就直接按一年算
                planTimeNow = planTime;
            }
        }
        if (planTimeNow != null) {
            String plannedEnd = DateUtil.convertDateToString(planTimeNow, DateUtil.FORMAT2);
            return new ResultDto(plannedEnd, ConstProp.CODE_SUCCESS, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
        } else {
            return new ResultDto("获取失效日期失败", ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
        }
    }

    /**
     * <b> 工程投标各保险公司计算保费 </b>
     * @author ZXF
     * @create 2018/04/10 0010 14:13
     * @version
     * @注意事项 </b>
     */
    @RequestMapping("/policy/computePremium")
    @ResponseBody
    public ResultDto computePremium(HttpServletRequest request){
        String insuredAmount = request.getParameter("insuredAmount");//保险金额
        String productCode = request.getParameter("productCode");//产品编码
        String provinceCode = request.getParameter("provinceCode");//省编码
        String cityCode = request.getParameter("cityCode");//市编码
        String aptitudeLevel = request.getParameter("aptitudeLevel");//资质等级
        String officeType = request.getParameter("officeType");//工程类型
        if(StringUtils.isEmpty(insuredAmount)
                ||StringUtils.isEmpty(productCode)
                ||StringUtils.isEmpty(provinceCode)
                ||StringUtils.isEmpty(cityCode)){
            return new ResultDto(ConstProp.BLANK_CHAR, ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
        }
        BigDecimal premium = BigDecimal.ZERO;
        if("350200".equals(cityCode)){
            //如果是厦门市直接用方案二计算保费
            premium = numPremium(insuredAmount, aptitudeLevel, officeType);
        }else {
            if(productCode.contains("BZX-DB")){
                premium = numPremium(insuredAmount, aptitudeLevel, officeType);
            }else if(productCode.contains("BZX-TB")){
                if("350000".equals(provinceCode)) {
                    //如果是福建省除厦门市外用方案一计算保费
                    premium = numPremiumOt(insuredAmount);
                }else{
                    return new ResultDto(ConstProp.BLANK_CHAR, ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
                }
            }else{
                return new ResultDto(ConstProp.BLANK_CHAR, ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
            }
        }
        if(!(premium.compareTo(BigDecimal.ZERO)<0)){
            return new ResultDto(String.valueOf(premium.setScale(2,BigDecimal.ROUND_HALF_UP)), ConstProp.CODE_SUCCESS, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
        }else{
            return new ResultDto(ConstProp.BLANK_CHAR, ConstProp.CODE_FAILURE, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR, ConstProp.BLANK_CHAR);
        }
    }

    //保费计算方案一（太保福建地区除厦门市外）
    private BigDecimal numPremiumOt(String insuredAmount){
        BigDecimal ia = BigDecimal.valueOf(Double.parseDouble(insuredAmount));
        BigDecimal premium = BigDecimal.ZERO;
        if(!(ia.compareTo(BigDecimal.ZERO)<0)&&!((BigDecimal.valueOf(Double.parseDouble("100000"))).compareTo(ia)<0)){//0-100000
            premium = BigDecimal.valueOf(Double.parseDouble("150"));
        }else if(!(ia.compareTo(BigDecimal.valueOf(Double.parseDouble("100000")))<0)&&!((BigDecimal.valueOf(Double.parseDouble("800000"))).compareTo(ia)<0)){//100000-800000
            premium = ia.multiply(BigDecimal.valueOf(Double.parseDouble("0.0015")));
        }
        return premium;
    }

    //保费计算方案二（阳光，太保厦门地区用，都邦全国用）
    private BigDecimal numPremium(String insuredAmount, String aptitudeLevel, String officeType){
        BigDecimal ia = BigDecimal.valueOf(Double.parseDouble(insuredAmount));
        BigDecimal premium = BigDecimal.ZERO;
        if(!(ia.compareTo(BigDecimal.ZERO)<0)&&!((BigDecimal.valueOf(Double.parseDouble("100000"))).compareTo(ia)<0)){//0-100000
            premium = BigDecimal.valueOf(Double.parseDouble("300"));
        }else if(!(ia.compareTo(BigDecimal.valueOf(Double.parseDouble("100000")))<0)&&!((BigDecimal.valueOf(Double.parseDouble("200000"))).compareTo(ia)<0)){//100000-200000
            premium = BigDecimal.valueOf(Double.parseDouble("350"));
        }else if(!(ia.compareTo(BigDecimal.valueOf(Double.parseDouble("200000")))<0)&&!((BigDecimal.valueOf(Double.parseDouble("300000"))).compareTo(ia)<0)){//200000-300000
            premium = BigDecimal.valueOf(Double.parseDouble("400"));
        }else if(!(ia.compareTo(BigDecimal.valueOf(Double.parseDouble("300000")))<0)&&!((BigDecimal.valueOf(Double.parseDouble("400000"))).compareTo(ia)<0)){//300000-400000
            premium = BigDecimal.valueOf(Double.parseDouble("450"));
        }else if(!(ia.compareTo(BigDecimal.valueOf(Double.parseDouble("400000")))<0)&&!((BigDecimal.valueOf(Double.parseDouble("500000"))).compareTo(ia)<0)){//400000-500000
            premium = BigDecimal.valueOf(Double.parseDouble("500"));
        }else if(!(ia.compareTo(BigDecimal.valueOf(Double.parseDouble("500000")))<0)&&!((BigDecimal.valueOf(Double.parseDouble("600000"))).compareTo(ia)<0)){//500000-600000
            premium = BigDecimal.valueOf(Double.parseDouble("550"));
        }else if(!(ia.compareTo(BigDecimal.valueOf(Double.parseDouble("600000")))<0)&&!((BigDecimal.valueOf(Double.parseDouble("700000"))).compareTo(ia)<0)){//600000-700000
            premium = BigDecimal.valueOf(Double.parseDouble("600"));
        }else if(!(ia.compareTo(BigDecimal.valueOf(Double.parseDouble("700000")))<0)&&!((BigDecimal.valueOf(Double.parseDouble("800000"))).compareTo(ia)<0)){//700000-800000
            premium = BigDecimal.valueOf(Double.parseDouble("650"));
        }
        return premium.multiply(alNum(aptitudeLevel)).multiply(otNum(officeType));
    }

    //企业资质系数
    private BigDecimal alNum(String aptitudeLevel){
        if(ConstProp.DIGIT_ONE.equals(aptitudeLevel)) {
            return BigDecimal.valueOf(Double.parseDouble("0.7"));
        }
        if(ConstProp.DIGIT_TWO.equals(aptitudeLevel)) {
            return BigDecimal.valueOf(Double.parseDouble("0.95"));
        }
        if(ConstProp.DIGIT_THREE.equals(aptitudeLevel)) {
            return BigDecimal.valueOf(Double.parseDouble("1"));
        }
        if(ConstProp.DIGIT_FOUR.equals(aptitudeLevel)) {
            return BigDecimal.valueOf(Double.parseDouble("1.3"));
        }
        if(ConstProp.DIGIT_FIVE.equals(aptitudeLevel)) {
            return BigDecimal.valueOf(Double.parseDouble("1.5"));
        }
        return BigDecimal.valueOf(Double.parseDouble("1"));
    }

    //工程类型系数
    private BigDecimal otNum(String officeType){
        if("7".equals(officeType)||"0001".equals(officeType)) {
            return BigDecimal.valueOf(Double.parseDouble("0.7"));
        }
        return BigDecimal.valueOf(Double.parseDouble("1"));
    }
}
