package com.muchinfo.mtp3century.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Strings;
import com.muchinfo.mtp.proto.AkernelMI1;
import com.muchinfo.mtp.proto.Common;
import com.muchinfo.mtp.proto.TkernelMI2;
import com.muchinfo.mtp3century.service.ICommonService;
import com.muchinfo.mtp3century.service.ISettlementService;
import com.muchinfo.mtp3century.utils.AjaxResult;
import com.muchinfo.mtp3common.enumtype.Constants;
import com.muchinfo.mtp3common.enumtype.FunCodeConstants;
import com.muchinfo.mtp3common.enumtype.MessageType;
import com.muchinfo.mtp3common.enumtype.SysConstants;
import com.muchinfo.mtp3common.utils.*;
import com.muchinfo.mtp3common.vo.*;
import com.muchinfo.mtp3interface.mapper.*;
import com.muchinfo.mtp3pojos.entity.*;
import com.muchinfo.mtp3pojos.vo.ProtoErrorCodes;
import com.muchinfo.mtp3pojos.vo.settlement.*;
import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFDataFormat;
import org.apache.poi.hssf.usermodel.HSSFDateUtil;
import org.apache.poi.ss.usermodel.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;

@Service
public class SettlementServiceImpl implements ISettlementService {

    private final Logger log = LoggerFactory.getLogger(this.getClass());
    @Resource
    private ISystemmanagerMapper iSystemmanagerMapper;
    @Resource
    private ICommonService iCommonService;
    @Resource
    private IReckonDaydividecountMapper iReckonDaydividecountMapper;
    @Resource
    private IBankAccountsignMapper iBankAccountsignMapper;
    @Resource
    private IUseraccountMapper iUseraccountMapper;
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Resource
    private ILoginaccountMapper iLoginaccountMapper;
    @Resource
    private IGoodsMapper iGoodsMapper;

    @Override
    public PageResult<SecondProfitSharResult> sharedayquery(String tradedate, Integer areatype, Integer pageNum, Integer pageSize, HttpServletRequest request) {
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        Long parentuserid = null;
        if (systemmanager.getReletype() != 1) {
            parentuserid = systemmanager.getAreauserid();
        }
        IPage<SecondProfitSharResult> page = new Page<>(pageNum, pageSize);
        IPage<SecondProfitSharResult> resultIPage = iReckonDaydividecountMapper.queryShareDayList(page, parentuserid, areatype, tradedate);
        PageResult<SecondProfitSharResult> result = new PageResult<>();
        result.setCode(Constants.Success_Code_Design);
        result.setMessage(AjaxResult.dealMsg(MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language")));
        result.setPages(resultIPage.getPages());
        result.setCurrent(resultIPage.getCurrent());
        result.setTotal(resultIPage.getTotal());
        result.setPageSize(resultIPage.getSize());
        result.setData(resultIPage.getRecords());
        return result;
    }

    @Override
    public PageResult<SecondProfitSharDetailResult> view(SecondProfitSharDetailParam param, HttpServletRequest request) {
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        if (systemmanager.getReletype() != 1) {
            param.setParentuserid(systemmanager.getAreauserid());
        }
        IPage<SecondProfitSharDetailResult> page = new Page<>(param.getPageNum(), param.getPageSize());
        IPage<SecondProfitSharDetailResult> resultIPage = iReckonDaydividecountMapper.queryOrgShareDayList(page, param);
        PageResult<SecondProfitSharDetailResult> result = new PageResult<>();
        result.setCode(Constants.Success_Code_Design);
        result.setMessage(AjaxResult.dealMsg(MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language")));
        result.setPages(resultIPage.getPages());
        result.setCurrent(resultIPage.getCurrent());
        result.setTotal(resultIPage.getTotal());
        result.setPageSize(resultIPage.getSize());
        result.setData(resultIPage.getRecords());
        return result;
    }

    @Override
    public AjaxResult export(String tradedate, HttpServletRequest request) {
        try {
            String fileName = "分润付款确认信息_" + DateTimeUtils.getDateTime("yyyyMMdd");
            List<SecondProfitSharResult> results = iReckonDaydividecountMapper.queryShareDayList(null, null, tradedate);

            if (CollectionUtils.isEmpty(results)) {
                return AjaxResult.error(Constants.Error_Code_Design, MessageType.QUERY_ERROR_CODE_005.getCode(), request.getHeader("Accept-Language"));
            }
            ExportResult exportResult = ExportUtil.write(fileName, SecondProfitSharResult.class, results);
            return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"), exportResult);
        } catch (Exception e) {
            log.error("分润付款确认信息导出失败，失败原因：" + e);
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.QUERY_ERROR_CODE_006.getCode(), request.getHeader("Accept-Language"));
        }
    }

    @Override
    public AjaxResult<ReckonDaydividecount> detail(String tradedate, Integer areatype, Long areaid, HttpServletRequest request) {
        ReckonDaydividecount reckonDaydividecount = iReckonDaydividecountMapper.selectOne(new QueryWrapper<ReckonDaydividecount>()
                .eq("tradedate", tradedate)
                .eq("areatype", areatype)
                .eq("areaid", areaid));
        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"), reckonDaydividecount);
    }

    @Override
    public AjaxResult batchPay(String areaids, Integer tradedate, HttpServletRequest request) {
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        String[] areaArr = areaids.split(",");
        Map<String, Object> map;
        int success = 0;
        int fail = 0;
        for (int i = 0; i < areaArr.length; i++) {
            try {
                String[] area = areaArr[i].split("-");
                Long areaid = Long.parseLong(area[0]);
                Integer areatype = Integer.valueOf(area[1]);

                ReckonDaydividecount reckonDaydividecount = iReckonDaydividecountMapper.selectOne(new QueryWrapper<ReckonDaydividecount>()
                        .eq("tradedate", tradedate)
                        .eq("areatype", areatype)
                        .eq("areaid", areaid));
                if (reckonDaydividecount.getPaystatus() != 1) {
                    return AjaxResult.error(Constants.Error_Code_Design, MessageType.SETTLEMENT_MESSAGE_002.getCode(), request.getHeader("Accept-Language"));
                }

                map = confirmPay(reckonDaydividecount, systemmanager);
                if (map.isEmpty() || ((Integer) map.get("code")) != 0) {
                    fail++;
                } else {
                    success++;
                }
            } catch (Exception e) {
                e.printStackTrace();
                fail++;
            }
        }
        Object[] param = {success, fail};

        return AjaxResult.success(Constants.Success_Code_Design, MessageType.SETTLEMENT_MESSAGE_001.getCode(), param, request.getHeader("Accept-Language"));
    }

    @Override
    public PageResult<PositionTransferQueryResult> positiontransferquery(PositionTransferQueryParam param, HttpServletRequest request) {
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        if (!SysConstants.SYS_TYPE_MANAGE.equals(systemmanager.getReletype())) {
            // 会员查询自己转出的记录
            param.setOutuserid(systemmanager.getAreauserid());
        }
        IPage<PositionTransferQueryResult> page = new Page<>(param.getPageNum(), param.getPageSize());
        IPage<PositionTransferQueryResult> resultIPage = iReckonDaydividecountMapper.queryPositionTransfer(page, param);
        PageResult<PositionTransferQueryResult> result = new PageResult<>();
        result.setCode(Constants.Success_Code_Design);
        result.setMessage(AjaxResult.dealMsg(MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language")));
        result.setPages(resultIPage.getPages());
        result.setCurrent(resultIPage.getCurrent());
        result.setTotal(resultIPage.getTotal());
        result.setPageSize(resultIPage.getSize());
        result.setData(resultIPage.getRecords());
        return result;
    }

    @Override
    public AjaxResult<PositionTransferQueryResult> positiontransferdetail(String applyid, HttpServletRequest request) {
        PositionTransferQueryParam param = new PositionTransferQueryParam();
        param.setApplyid(applyid);
        List<PositionTransferQueryResult> resultIPage = iReckonDaydividecountMapper.queryPositionTransfer(param);

        if (StringUtils.isNotBlank(resultIPage.get(0).getRetremark())) {
            String p_[] = resultIPage.get(0).getRetremark().split(":");
            if (p_.length > 1 && null != p_[1] && StringUtils.isNotBlank(p_[1])) {
                resultIPage.get(0).setRetremark(p_[0] + ":" + ProtoErrorCodes.resultMsg(Integer.valueOf(p_[1])));
            }
        }
        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"), resultIPage.get(0));
    }

    @Override
    public AjaxResult<PositionTransferImport> batchimport(MultipartHttpServletRequest request) {
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        // 平台 按登录账号转移
        Iterator<String> fileNames = request.getFileNames();
        if (fileNames.hasNext()) {
            String fileName = fileNames.next();
            MultipartFile file = request.getFile(fileName);
            InputStream is = null;
            try {
                is = file.getInputStream();
                List<PositionTransferImport> returnList = new ArrayList<>();
                Set<Long> loginList = new HashSet<>();
                Set<String> goodsList = new HashSet<>();

                Workbook wb = WorkbookFactory.create(is);
                Sheet sheet = wb.getSheetAt(0);
                int lastr = sheet.getLastRowNum();

                if (lastr == 0) {
                    return AjaxResult.error(Constants.Error_Code_Design, MessageType.QUERY_ERROR_CODE_010.getCode(), request.getHeader("Accept-Language"));
                }
                for (int i = 1; i <= lastr; i++) {
                    Row row = sheet.getRow(i);
                    Cell c_outloginid;
                    Cell c_inloginid;
                    Cell c_goodscode;
                    Cell c_buyorsell;
                    Cell c_transferprice;
                    Cell c_qty;
                    Cell c_freezedays;
                    String outloginid = null;

                    if (systemmanager.getReletype() == 1) {
                        c_outloginid = row.getCell(0);
                        c_inloginid = row.getCell(1);
                        c_goodscode = row.getCell(2);
                        c_buyorsell = row.getCell(3);
                        c_transferprice = row.getCell(4);
                        c_qty = row.getCell(5);
                        c_freezedays = row.getCell(6);
                        outloginid = Strings.isNullOrEmpty(c_outloginid.toString().trim()) ? "0" : getCellValue2(c_outloginid);
                        if (StringUtils.isEmpty(outloginid) || outloginid.equals("0")) {
                            // 转出方为空时，忽略此行
                            continue;
                        }
                        loginList.add(Long.valueOf(outloginid));
                    } else {
                        c_inloginid = row.getCell(0);
                        c_goodscode = row.getCell(1);
                        c_buyorsell = row.getCell(2);
                        c_transferprice = row.getCell(3);
                        c_qty = row.getCell(4);
                        c_freezedays = row.getCell(5);
                    }


                    String inloginid = Strings.isNullOrEmpty(c_inloginid.toString().trim()) ? "0" : getCellValue2(c_inloginid);
                    if (StringUtils.isEmpty(inloginid) || inloginid.equals("0")) {
                        // 转入方为空时，忽略此行
                        continue;
                    }

                    String goodscode = c_goodscode == null ? "0" : getCellValue2(c_goodscode);
                    String buyorsell = c_buyorsell == null ? "0" : getCellValue(c_buyorsell);
                    String transferprice = c_transferprice == null ? "0" : getCellValue(c_transferprice);
                    String qty = c_qty == null ? "0" : getCellValue2(c_qty);
                    String freezedays = c_freezedays == null ? "0" : getCellValue2(c_freezedays);

                    PositionTransferImport anImport = PositionTransferImport.builder()
                            .outloginid(outloginid)
                            .inloginid(inloginid)
                            .goodscode(goodscode)
                            .buyorsell(buyorsell)
                            .transferprice(transferprice)
                            .qty(qty)
                            .freezedays(freezedays).build();
                    anImport.setOutloginid(outloginid);
                    returnList.add(anImport);

                    //数据校验
                    loginList.add(Long.valueOf(inloginid));
                    goodsList.add(goodscode);
                }

                if (loginList.isEmpty()) {
                    return AjaxResult.error(Constants.Error_Code_Design, MessageType.QUERY_ERROR_CODE_010.getCode(), request.getHeader("Accept-Language"));
                }

                checkImport(returnList, loginList, goodsList, systemmanager);
                return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"), returnList);
            } catch (Exception e) {
                log.error("导出文件失败，失败原因：" + e.getMessage());
            } finally {
                try {
                    is.close();
                } catch (IOException ignored) {
                }
            }
        }
        return null;
    }

    @Override
    public AjaxResult saveimport(List<PositionTransferImport> param, HttpServletRequest request) {

        if(CollectionUtils.isNotEmpty(param)) {
            //调用16201 服务“持仓过户申请”接口
            Long uuid = SerialNumberUtils.getNewSerialNumber(SerialNumberUtils.prefix_positiontransfer);
            Calculator ca = new Calculator(uuid, FunCodeConstants.FuncCode_HolderTransferApplyReq);
            SerialNumberUtils.lockMap.put(uuid, ca);

            TkernelMI2.HolderTransferApplyReq.Builder builder = TkernelMI2.HolderTransferApplyReq.newBuilder();

            Common.MessageHead.Builder hd = Common.MessageHead.newBuilder();
            hd.setUUID(String.valueOf(uuid));
            hd.setFunCode(FunCodeConstants.FuncCode_HolderTransferApplyReq);
            hd.setMarketID(16201);
            builder.setHeader(hd);

            for (PositionTransferImport anImport : param) {
                // 平台导入时转出方登录号不为空，自营会员转出时转出方用户ID不为空
                if (anImport != null && (anImport.getOutuserid() != null || anImport.getOutloginid() != null)) {
                    Integer outUserID = null;
                    if (anImport.getOutuserid() == null){
                        Loginaccount  outLogin = iLoginaccountMapper.selectOne(new QueryWrapper<Loginaccount>().eq("loginid",anImport.getOutloginid()));
                        if (outLogin != null){
                            outUserID = outLogin.getUserid().intValue();
                        }
                    }else{
                        outUserID = anImport.getOutuserid().intValue();
                    }
                    if(outUserID == null){
                        continue;
                    }

                    Loginaccount inLogin = iLoginaccountMapper.selectOne(new QueryWrapper<Loginaccount>().eq("loginid",anImport.getInloginid()));
                    if (inLogin == null){
                        continue;
                    }

                    if (anImport.getGoodsid() == null){
                        continue;
                    }

                    TkernelMI2.HolderTransferDetail.Builder detail = TkernelMI2.HolderTransferDetail.newBuilder();
                    detail.setOutUserID(outUserID);
                    detail.setInUserID(inLogin.getUserid().intValue());
                    detail.setGoodsID(anImport.getGoodsid().intValue());
                    detail.setBuyOrSell(Integer.parseInt(anImport.getBuyorsell()));
                    detail.setQty(Long.parseLong(anImport.getQty()));
                    detail.setTransferPrice(Double.parseDouble(anImport.getTransferprice()));
                    detail.setFreezeDays(Integer.parseInt(anImport.getFreezedays()));
                    detail.setTransferType(1);

                    builder.addHolderTransferDetails(detail);
                }
            }

            builder.setClientSerialNo(String.valueOf(uuid));
            builder.setClientType(1); // PC管理端

            byte[] body = ProtoHelper.getNTAS(builder.build().toByteArray(), FunCodeConstants.FuncCode_HolderTransferApplyReq);

            rabbitTemplate.send(SysConstants.RabbitOrderReq, new Message(body, new MessageProperties()));

            synchronized (ca) {
                try {
                    ca.wait(10000);
                    Object rsp = ca.obj;
                    if (rsp != null) {
                        TkernelMI2.HolderTransferApplyRsp rsp_ = (TkernelMI2.HolderTransferApplyRsp) rsp;
                        if (rsp_.getRetCode() == 0) {
                            return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM020.getCode(), request.getHeader("Accept-Language"));
                        } else {
                            return AjaxResult.error(Constants.Error_Code_Design, ProtoErrorCodes.resultMsg(rsp_.getRetCode()), "");
                        }
                    } else {
                        return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM006.getCode(), request.getHeader("Accept-Language"));
                    }
                } catch (InterruptedException e) {
                    log.error("收取锁定交易账号通知失败，失败原因：" + e.getMessage());
                } finally {
                    SerialNumberUtils.lockMap.remove(uuid);
                }
            }
        }

        return null;
    }

    private void checkImport(List<PositionTransferImport> returnList, Set<Long> loginList, Set<String> goodList, Systemmanager user) {
        // 登录账号校验
        List<Loginaccount> loginlist = iLoginaccountMapper.selectList(new QueryWrapper<Loginaccount>()
                .in("loginid", loginList));

        String ologinid = null;
        if (user.getReletype() != 1) {
            // 获取转出方登录账号
            Loginaccount outLoginAccount = iLoginaccountMapper.selectOne(new QueryWrapper<Loginaccount>().eq("userid", user.getAreauserid()));
            ologinid = outLoginAccount == null ? "" : outLoginAccount.getLoginid().toString();
        }

        Map<Long, Loginaccount> loginMap = new HashMap<>();
        for (Loginaccount loginaccount : loginlist) {
            loginMap.put(loginaccount.getLoginid(), loginaccount);
        }

        // 商品校验
        List<Goods> goodsList = iGoodsMapper.selectList(new QueryWrapper<Goods>()
                .in("goodscode", goodList));
        Map<String, Goods> hasgood = new HashMap<>();
        for (Goods goods : goodsList) {
            hasgood.put(goods.getGoodscode(), goods);
        }

        List<String> bs = Arrays.asList("卖", "买");

        Pattern pt = Pattern.compile("^\\d+(\\.\\d+)?$");

        for (PositionTransferImport anImport : returnList) {
            if (!isNumeric(anImport.getOutloginid())) {
                anImport.setCresult("转出登录账号错误");
                continue;
            }
            if (!isNumeric(anImport.getInloginid())) {
                anImport.setCresult("转入登录账号错误");
                continue;
            }
            if (!pt.matcher(anImport.getTransferprice()).matches()) {
                anImport.setCresult("转让价格错误");
                continue;
            }
            if (!pt.matcher(anImport.getQty()).matches()) {
                anImport.setCresult("转让数量错误");
                continue;
            }

            if (!pt.matcher(anImport.getFreezedays()).matches()) {
                anImport.setCresult("冻结天数错误");
                continue;
            }

            if (!bs.contains(anImport.getBuyorsell())) {
                anImport.setCresult("买卖方向错误");
                continue;
            }

            if (user.getReletype() != 1) {
                if (anImport.getInloginid().equals(ologinid)) {
                    anImport.setCresult("转出转入账号不能相同");
                    continue;
                }
            } else {
                if (anImport.getOutloginid().equals(anImport.getInloginid())) {
                    anImport.setCresult("转出转入账号不能相同");
                    continue;
                }
            }

            if (!loginMap.containsKey(Long.valueOf(anImport.getOutloginid()))) {
                anImport.setCresult("转出登录账号不存在");
                continue;
            }

            if (!loginMap.containsKey(Long.valueOf(anImport.getInloginid()))) {
                anImport.setCresult("转入登录账号不存在");
                continue;
            }

            if (!hasgood.containsKey(anImport.getGoodscode())) {
                anImport.setCresult("商品不存在");
                anImport.setGoodsname(anImport.getGoodscode());
            } else {
                anImport.setGoodsname(hasgood.get(anImport.getGoodscode()).getGoodsname() + "/" + anImport.getGoodscode());
                anImport.setGoodsid(hasgood.get(anImport.getGoodscode()).getGoodsid());
            }
        }
    }

    private Map<String, Object> confirmPay(ReckonDaydividecount rd, Systemmanager systemmanager) {
        Map<String, Object> result = new HashMap<>();
        Object l = iCommonService.getSystemParam(Constants.REDIS_HEADER_SYSPARAM, "074");
        String f = l == null ? "0" : l.toString();
        if ("1".equals(f)) {
            // 复审
            rd.setPaystatus(4);
            iReckonDaydividecountMapper.update(rd, new QueryWrapper<ReckonDaydividecount>()
                    .eq("tradedate", rd.getTradedate())
                    .eq("areatype", rd.getAreatype())
                    .eq("areaid", rd.getAreaid()));
            result.put("code", 0);
            return result;
        }
        return confirmPayTo(rd, systemmanager);
    }

    private Map<String, Object> confirmPayTo(ReckonDaydividecount osdp, Systemmanager user) {
        //判断是否签约
        Map<String, Object> result = new HashMap<>();
        List<BankAccountsign> sign = iBankAccountsignMapper.selectList(new QueryWrapper<BankAccountsign>()
                .eq("accountcode", osdp.getAreaaccountid())
                .eq("signstatus", 4));
        if (sign == null || sign.isEmpty()) {
            result.clear();
            result.put("code", 500);
            result.put("msg", "账户未签约");
            return result;
        }

        //分润付款状态变为待支付
        osdp.setPaystatus(2);
        osdp.setPayerid(user.getAutoid());
        osdp.setPaytime(new Date());
        iReckonDaydividecountMapper.update(new QueryWrapper<ReckonDaydividecount>()
                .eq("tradedate", osdp.getTradedate())
                .eq("areatype", osdp.getAreatype())
                .eq("areaid", osdp.getAreaid()));

        if (user.getAreauserid() == 0 || user.getAreauserid() == 1) {
            //平台
            // 发消息给账户服务处理
            AkernelMI1.AccountCommandReq.Builder builder1 = AkernelMI1.AccountCommandReq.newBuilder();
            builder1.setBusinessCode(102);//业务编号
            builder1.setUserId(osdp.getAreaid());  //用户
            builder1.setAccountId(osdp.getAreaaccountid()); //资金账户

            // 用主键拼接，币种都一样的，不管币种。 tradedate=8 + areaid=8 + areatype=2
            String relatedorderid1 = osdp.getTradedate() + osdp.getAreaid() + osdp.getAreatype();
            // 不会超过2位
            builder1.setRelatedOrderId(Long.valueOf(relatedorderid1));//服务需要这个去重消息
            //子指令
            AkernelMI1.SubCommand.Builder sub1 = AkernelMI1.SubCommand.newBuilder();
            sub1.setCommandCode(FunCodeConstants.FunCode_Trade_FundOperationCmd);    //子指令功能码
            AkernelMI1.FundOperationCmd.Builder fun1 = AkernelMI1.FundOperationCmd.newBuilder();           //资金操作
            fun1.setAccountId(osdp.getAreaaccountid());
            fun1.setChangeAmount(osdp.getDivideamount().doubleValue());            //金额符号要根据操作类型判断
            fun1.setOperateType(405);        //操作类型
            log.debug("subcommand:{}", fun1.build().toString());
            sub1.setCommandStrings(fun1.build().toByteString());
            builder1.addSubCommands(sub1);    //加入子指令

            //消息头
            Long uuid1 = SerialNumberUtils.getNewSerialNumberByFuncode(
                    FunCodeConstants.FunCode_Trade_AccountCommandRsp);
            Calculator ca1 = new Calculator(uuid1);
            SerialNumberUtils.lockMap.put(uuid1, ca1);

            Common.MessageHead.Builder hd1 = Common.MessageHead.newBuilder();
            hd1.setAccountID(osdp.getAreaaccountid());
            hd1.setUUID(uuid1.toString());
            hd1.setFunCode(FunCodeConstants.FunCode_Trade_AccountCommandReq);
            builder1.setHeader(hd1);

            byte[] body1 = ProtoHelper.getNTAS(builder1.build().toByteArray(),
                    FunCodeConstants.FunCode_Trade_AccountCommandReq);
            log.debug("add money:{}", builder1.build().toString());
            rabbitTemplate.send(SysConstants.RabbitMoneyReqKey, new Message(body1, new MessageProperties()));

            //等待消息分润付款状态变为已支付
            synchronized (ca1) {
                try {
                    ca1.wait(10000);
                    Object rsp1 = ca1.obj;
                    if (rsp1 != null) {
                        AkernelMI1.AccountCommandRsp rsp_1 = (AkernelMI1.AccountCommandRsp) rsp1;
                        if (rsp_1.getRetCode() == 0) {
                            osdp.setPaystatus(3);
                            osdp.setPayerid(user.getAutoid());
                            osdp.setPaytime(new Date());
                            iReckonDaydividecountMapper.update(new QueryWrapper<ReckonDaydividecount>()
                                    .eq("tradedate", osdp.getTradedate())
                                    .eq("areatype", osdp.getAreatype())
                                    .eq("areaid", osdp.getAreaid()));
                            result.put("code", 0);
                            result.put("msg", "操作成功");
                        } else {
                            result.put("code", 500);
                            result.put("msg", "操作失败");
                        }
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    SerialNumberUtils.lockMap.remove(uuid1);
                }
            }
            return result;
        }

        // 发消息给账户服务处理
        // 用主键拼接，币种都一样的，不管币种。 tradedate=8 + areaid=8 + areatype=2
        String relatedorderid = 1 + osdp.getTradedate() + osdp.getAreaid() + osdp.getAreatype();
        Useraccount ua = iUseraccountMapper.selectOne(new QueryWrapper<Useraccount>().eq("userid", user.getAreauserid()));
        AkernelMI1.AccountCommandReq.Builder builder = AkernelMI1.AccountCommandReq.newBuilder();
        builder.setBusinessCode(102);//业务编号
        builder.setUserId(user.getAreauserid());  //用户
        builder.setAccountId(osdp.getAreaaccountid()); //资金账户
        // 不会超过2位
        builder.setRelatedOrderId(Long.valueOf(relatedorderid));//服务需要这个去重消息
        //子指令
        AkernelMI1.SubCommand.Builder sub = AkernelMI1.SubCommand.newBuilder();
        sub.setCommandCode(FunCodeConstants.FunCode_Trade_FundOperationCmd);    //子指令功能码
        AkernelMI1.FundOperationCmd.Builder fun = AkernelMI1.FundOperationCmd.newBuilder();           //资金操作
        fun.setAccountId(ua.getReckonaccountid());
        fun.setChangeAmount(osdp.getDivideamount().doubleValue() * -1);            //金额符号要根据操作类型判断
        fun.setOperateType(405);        //操作类型
        log.debug("subcommand:{}", fun.build().toString());
        sub.setCommandStrings(fun.build().toByteString());
        builder.addSubCommands(sub);    //加入子指令

        //消息头
        Long uuid = SerialNumberUtils.getNewSerialNumberByFuncode(FunCodeConstants.FunCode_Trade_AccountCommandRsp);
        Calculator ca = new Calculator(uuid);
        SerialNumberUtils.lockMap.put(uuid, ca);

        Common.MessageHead.Builder hd = Common.MessageHead.newBuilder();
        hd.setAccountID(osdp.getAreaaccountid());
        hd.setUUID(uuid.toString());
        hd.setFunCode(FunCodeConstants.FunCode_Trade_AccountCommandReq);
        builder.setHeader(hd);

        byte[] body = ProtoHelper.getNTAS(builder.build().toByteArray(),
                FunCodeConstants.FunCode_Trade_AccountCommandReq);
        log.debug("减 money:{}", builder.build().toString());
        rabbitTemplate.send(SysConstants.RabbitMoneyReqKey, new Message(body, new MessageProperties()));

        //等待消息分润付款状态变为已支付
        synchronized (ca) {
            try {
                ca.wait(10000);
                Object rsp = ca.obj;
                if (rsp != null) {
                    AkernelMI1.AccountCommandRsp rsp_ = (AkernelMI1.AccountCommandRsp) rsp;
                    if (rsp_.getRetCode() == 0) {

                        // 发消息给账户服务处理
                        AkernelMI1.AccountCommandReq.Builder builder1 = AkernelMI1.AccountCommandReq.newBuilder();
                        builder1.setBusinessCode(102);//业务编号
                        builder1.setUserId(osdp.getAreaid());  //用户
                        builder1.setAccountId(osdp.getAreaaccountid()); //资金账户

                        // 用主键拼接，币种都一样的，不管币种。 tradedate=8 + areaid=8 + areatype=2
                        String relatedorderid1 = osdp.getTradedate() + osdp.getAreaid() + osdp.getAreatype();
                        // 不会超过2位
                        builder1.setRelatedOrderId(Long.valueOf(relatedorderid1));//服务需要这个去重消息
                        //子指令
                        AkernelMI1.SubCommand.Builder sub1 = AkernelMI1.SubCommand.newBuilder();
                        sub1.setCommandCode(FunCodeConstants.FunCode_Trade_FundOperationCmd);    //子指令功能码
                        AkernelMI1.FundOperationCmd.Builder fun1 = AkernelMI1.FundOperationCmd.newBuilder();           //资金操作
                        fun1.setAccountId(osdp.getAreaaccountid());
                        fun1.setChangeAmount(osdp.getDivideamount().doubleValue());            //金额符号要根据操作类型判断
                        fun1.setOperateType(405);        //操作类型
                        log.debug("subcommand:{}", fun1.build().toString());
                        sub1.setCommandStrings(fun1.build().toByteString());
                        builder1.addSubCommands(sub1);    //加入子指令

                        //消息头
                        Long uuid1 = SerialNumberUtils.getNewSerialNumberByFuncode(
                                FunCodeConstants.FunCode_Trade_AccountCommandRsp);
                        Calculator ca1 = new Calculator(uuid1);
                        SerialNumberUtils.lockMap.put(uuid1, ca1);

                        Common.MessageHead.Builder hd1 = Common.MessageHead.newBuilder();
                        hd1.setAccountID(osdp.getAreaaccountid());
                        hd1.setUUID(uuid1.toString());
                        hd1.setFunCode(FunCodeConstants.FunCode_Trade_AccountCommandReq);
                        builder1.setHeader(hd1);

                        byte[] body1 = ProtoHelper.getNTAS(builder1.build().toByteArray(),
                                FunCodeConstants.FunCode_Trade_AccountCommandReq);
                        log.debug("add money:{}", builder1.build().toString());
                        rabbitTemplate.send(SysConstants.RabbitMoneyReqKey, new Message(body1, new MessageProperties()));

                        //等待消息分润付款状态变为已支付
                        synchronized (ca1) {
                            try {
                                ca1.wait(10000);
                                Object rsp1 = ca1.obj;
                                if (rsp1 != null) {
                                    AkernelMI1.AccountCommandRsp rsp_1 = (AkernelMI1.AccountCommandRsp) rsp1;
                                    if (rsp_1.getRetCode() == 0) {
                                        osdp.setPaystatus(3);
                                        osdp.setPayerid(user.getAutoid());
                                        osdp.setPaytime(new Date());
                                        iReckonDaydividecountMapper.update(new QueryWrapper<ReckonDaydividecount>()
                                                .eq("tradedate", osdp.getTradedate())
                                                .eq("areatype", osdp.getAreatype())
                                                .eq("areaid", osdp.getAreaid()));
                                        result.put("code", 0);
                                        result.put("msg", "操作成功");
                                    } else {
                                        result.put("code", 500);
                                        result.put("msg", "操作失败");
                                    }
                                }
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            } finally {
                                SerialNumberUtils.lockMap.remove(uuid1);
                            }
                        }
                    } else {
                        result.put("code", 500);
                        result.put("msg", "操作失败");
                    }
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                SerialNumberUtils.lockMap.remove(uuid);
            }
        }
        return result;
    }

    private String getCellValue2(Cell cell) {
        int cellType = cell.getCellType();
        switch (cellType) {
            case HSSFCell.CELL_TYPE_STRING:
                return cell.getStringCellValue();
            case HSSFCell.CELL_TYPE_NUMERIC:
                DecimalFormat df = new DecimalFormat("0");
                return df.format(cell.getNumericCellValue());
            default:
                return cell.toString();
        }
    }

    protected String getCellValue(Cell cell) {
        NumberFormat formater = NumberFormat.getInstance();
        formater.setGroupingUsed(false);
        formater.setMaximumFractionDigits(6);
        String cellValue = "";
        if (cell == null) {
            return cellValue;
        }
        switch (cell.getCellType()) {
            case HSSFCell.CELL_TYPE_NUMERIC:

                if (HSSFDateUtil.isCellDateFormatted(cell)) {
                    SimpleDateFormat sdf = null;
                    if (cell.getCellStyle().getDataFormat() == HSSFDataFormat.getBuiltinFormat("h:mm:ss")) {
                        sdf = new SimpleDateFormat("HH:mm:ss");
                    } else {// 日期
                        sdf = new SimpleDateFormat("yyyy-MM-dd");

                    }
                    Date date = cell.getDateCellValue();
                    cellValue = sdf.format(date);

                } else {
                    cellValue = formater.format(cell.getNumericCellValue());
        		/* if("-".equals(cellValue.trim())){
               	  System.out.println(cellValue);
                 }*/
                }
                break;
            case HSSFCell.CELL_TYPE_STRING:

                cellValue = cell.getStringCellValue();
                if ("-".equals(cellValue.trim())) {
                    cellValue = "";
                }
                break;
            case HSSFCell.CELL_TYPE_BLANK:
                cellValue = cell.getStringCellValue();
                break;
            case HSSFCell.CELL_TYPE_BOOLEAN:
                cellValue = Boolean.valueOf(cell.getBooleanCellValue()).toString();
                break;
            case HSSFCell.CELL_TYPE_ERROR:
                cellValue = String.valueOf(cell.getErrorCellValue());
                break;
            default:
                cellValue = "";
        }
        return cellValue.trim();
    }

    public boolean isNumeric(String str) {
        if (str == null) {
            return false;
        }
        int sz = str.length();
        for (int i = 0; i < sz; i++) {
            if (!Character.isDigit(str.charAt(i))) {
                return false;
            }
        }
        return true;
    }
}
