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.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Strings;
import com.muchinfo.mtp.proto.*;
import com.muchinfo.mtp3century.service.ICommonService;
import com.muchinfo.mtp3century.service.ISendMsgService;
import com.muchinfo.mtp3century.service.ITaaccountService;
import com.muchinfo.mtp3century.utils.AjaxResult;
import com.muchinfo.mtp3century.utils.RedisServiceUtil;
import com.muchinfo.mtp3common.enumtype.*;
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.bankaccountsign.AccountSignQueryParam;
import com.muchinfo.mtp3pojos.vo.bankaccountsign.AccountSignQueryResult;
import com.muchinfo.mtp3pojos.vo.investor.*;
import com.muchinfo.mtp3pojos.vo.taaccount.*;
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 com.muchinfo.mtp.proto.AccountRedis.AccRiskInfo;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;


/**
 * <p>
 * 资金账户表 - 导历史 服务实现类
 * </p>
 *
 * @author XKF
 * @since 2024-04-16
 */
@Service
public class TaaccountServiceImpl extends ServiceImpl<ITaaccountMapper, Taaccount> implements ITaaccountService {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());
    @Resource
    private ISystemmanagerMapper iSystemmanagerMapper;
    @Resource
    private SystemmanagerServiceImpl systemmanagerService;
    @Resource
    private ICommonService iCommonService;
    @Resource
    private ITaaccountMapper iTaaccountMapper;
    @Resource
    private IUseraccountMapper iUseraccountMapper;
    @Resource
    private IEnumdicitemMapper iEnumdicitemMapper;
    @Resource
    private RedisServiceUtil redisServiceUtil;
    @Resource
    private IBankAccountsignMapper iBankAccountsignMapper;
    @Resource
    private ILoginaccountMapper iLoginaccountMapper;
    @Resource
    private ILogintaaccountMapper iLogintaaccountMapper;
    @Resource
    private ITaaccountmarketMapper iTaaccountmarketMapper;
    @Resource
    private IArearoleMapper iArearoleMapper;
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Resource
    private ISystemmanagerlogMapper iSystemmanagerlogMapper;
    @Resource
    private ISendMsgService iSendMsgService;
    @Resource
    private IUserinfoMapper iUserinfoMapper;
    @Resource
    private IUserauthinfoMapper iUserauthinfoMapper;
    @Resource
    private IDraftUseraccountNewMapper iDraftUseraccountNewMapper;
    @Resource
    private IDraftUserinfoMapper iDraftUserinfoMapper;
    @Resource
    private IMarketMapper iMarketMapper;
    @Resource
    private IMsExtendroleMapper iMsExtendroleMapper;

    @Override
    public PageResult<TaAccountQueryResult> queryUserMsg(HttpServletRequest request, TaAccountQueryParam taAccountQueryParam) {
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        Arearole ar = iArearoleMapper.selectOne(new QueryWrapper<Arearole>()
                .eq("userid", systemmanager.getAreauserid())
                .eq("roletype", 6));
        taAccountQueryParam.setUserId(systemmanager.getAreauserid());
        IPage<TaAccountQueryResult> page = new Page<>(taAccountQueryParam.getPageNum(), taAccountQueryParam.getPageSize());
        IPage<TaAccountQueryResult> queryResultIPage = iTaaccountMapper.queryTaAccountPage(page, taAccountQueryParam);
        queryResultIPage.getRecords().forEach(a -> {
            if (Objects.nonNull(ar)) {
                a.setSelfsupport(1);
            }
        });
        PageResult<TaAccountQueryResult> pageResult = new PageResult<>();
        pageResult.setCode(Constants.Success_Code_Design);
        pageResult.setMessage(AjaxResult.dealMsg(MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language")));
        pageResult.setPages(queryResultIPage.getPages());
        pageResult.setCurrent(queryResultIPage.getCurrent());
        pageResult.setTotal(queryResultIPage.getTotal());
        pageResult.setPageSize(queryResultIPage.getSize());
        pageResult.setData(queryResultIPage.getRecords());
        return pageResult;
    }

    @Override
    public AjaxResult<TaAccountQueryResultDetail> queryDetail(HttpServletRequest request, Long accountId) {
        TaAccountQueryResultDetail taAccountQueryResult = new TaAccountQueryResultDetail();
        //获取授权交易账户
        List<Long> loginIds = new ArrayList<>();
        Taaccount taaccount = iTaaccountMapper.selectOne(new QueryWrapper<Taaccount>().eq("ACCOUNTID", accountId));
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        if (systemmanager.getReletype() != 1 && !iCommonService.checkIsAreaSon2(systemmanager.getAreauserid(), taaccount.getUserid())) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM003.getCode(), request.getHeader("Accept-Language"));
        }
        //获取风险率
        getRiskFromRedis(taaccount);
        //taAccount赋值
        setAccountMessage(taAccountQueryResult, taaccount);
        //银行信息
        if (taaccount.getIsmain() == 1) {
            AccountSignQueryParam accountSignQueryParam = AccountSignQueryParam.builder().accountCode(taAccountQueryResult.getAccountId()).build();
            List<AccountSignQueryResult> bankAccountsignList = iBankAccountsignMapper.selectByParam(accountSignQueryParam);
            taAccountQueryResult.setBankAccountsignList(bankAccountsignList);
        }
        //获取当前登录账户资金权限
        List<Logintaaccount> logintaaccounts = iLogintaaccountMapper.selectList(new QueryWrapper<Logintaaccount>().eq("ACCOUNTID", taAccountQueryResult.getAccountId()));
        if (CollectionUtils.isNotEmpty(logintaaccounts)) {
            loginIds.addAll(logintaaccounts.stream().map(Logintaaccount::getLoginid).collect(Collectors.toList()));
        }
        //授权交易账号
        List<Long> defaultLogin = iLoginaccountMapper.getLoginNotExistsLt(taAccountQueryResult.getUserId());
        loginIds.addAll(defaultLogin);
        taAccountQueryResult.setLoginIds(loginIds);
        //获取市场权限
        List<TaAccountMarketVo> voList = iTaaccountmarketMapper.selectByAccountId(taAccountQueryResult.getAccountId());
        taAccountQueryResult.setDType(voList);
        //是否展示市场控件
        Arearole ar = iArearoleMapper.selectOne(new QueryWrapper<Arearole>()
                .eq("userid", systemmanager.getAreauserid())
                .eq("roletype", 6));
        if (Objects.nonNull(ar)) {
            taAccountQueryResult.setIsSelf(1);
        }
        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"), taAccountQueryResult);
    }

    @Override
    public AjaxResult updatePwd(HttpServletRequest request, TaAccountPwd vo) {
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        //校验
        if (!iCommonService.checkTaAccountReport(systemmanager, vo.getAccountId())) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM003.getCode(), request.getHeader("Accept-Language"));
        }
        if (StringUtils.isBlank(vo.getOldPwd())) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.PWD_ERROR_CODE_001.getCode(), request.getHeader("Accept-Language"));
        }
        if (StringUtils.isBlank(vo.getNewPwd())) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.PWD_ERROR_CODE_002.getCode(), request.getHeader("Accept-Language"));
        }
        if (StringUtils.isBlank(vo.getConfirmPassword())) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.PWD_ERROR_CODE_003.getCode(), request.getHeader("Accept-Language"));
        }
        if (!vo.getNewPwd().equals(vo.getConfirmPassword())) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.PWD_ERROR_CODE_004.getCode(), request.getHeader("Accept-Language"));
        }
        Taaccount ta = iTaaccountMapper.selectOne(new QueryWrapper<Taaccount>().eq("ACCOUNTID", vo.getAccountId()));
        if (!vo.getOldPwd().equals(ta.getPassword())) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.PWD_ERROR_CODE_005.getCode(), request.getHeader("Accept-Language"));
        }
        ta.setPassword(vo.getNewPwd());
        iTaaccountMapper.update(ta, new QueryWrapper<Taaccount>().eq("ACCOUNTID", ta.getAccountid()));
        //记录日志
        systemmanagerService.writeOperateLog(SysConstants.OPERATION_TAA,
                "修改资金账户id=" + vo.getAccountId() + "的密码", systemmanager, null, null, null);
        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"));
    }

    @Override
    public PageResult<TaAccountAmountStreamResult> queryAmountStream(HttpServletRequest request, TaAccountAmountStreamParam param) {
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        PageResult<TaAccountAmountStreamResult> result = new PageResult<>();
        if (StringUtils.isBlank(param.getAccountId())) {
            result.setCode(Constants.Error_Code_Design);
            result.setMessage(AjaxResult.dealMsg(MessageType.QUERY_ERROR_CODE_007.getCode(), request.getHeader("Accept-Language")));
            return result;
        }
        if (param.getLogType() == 2) {
            if (Strings.isNullOrEmpty(param.getStartTime())) {
                result.setCode(Constants.Error_Code_Design);
                result.setMessage(AjaxResult.dealMsg(MessageType.QUERY_ERROR_CODE_002.getCode(), request.getHeader("Accept-Language")));
                return result;
            }
            if (Strings.isNullOrEmpty(param.getEndTime())) {
                result.setCode(Constants.Error_Code_Design);
                result.setMessage(AjaxResult.dealMsg(MessageType.QUERY_ERROR_CODE_003.getCode(), request.getHeader("Accept-Language")));
                return result;
            }
        }
        if (systemmanager.getReletype() != 1) {
            if (param.getUserId() == null) {
                param.setUserId(systemmanager.getAreauserid());
            }
        }
        //获取分页数据
        IPage<TaAccountAmountStreamResult> page = new Page<>(param.getPageNum(), param.getPageSize());
        IPage<TaAccountAmountStreamResult> listStream = iTaaccountMapper.selectAmountStream(page, param);
        PageResult<TaAccountAmountStreamResult> pageResult = new PageResult<>();
        pageResult.setCode(Constants.Success_Code_Design);
        pageResult.setMessage(AjaxResult.dealMsg(MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language")));
        pageResult.setPages(listStream.getPages());
        pageResult.setCurrent(listStream.getCurrent());
        pageResult.setTotal(listStream.getTotal());
        pageResult.setPageSize(listStream.getSize());
        pageResult.setData(listStream.getRecords());
        return pageResult;
    }

    @Override
    public AjaxResult queryAmountStreamExport(TaAccountAmountStreamParam param, HttpServletRequest request) {
        try {
            String fileName = "资金流水查询_" + DateTimeUtils.getDateTime("yyyyMMdd");
            Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
            //如果不是平台管理员
            if (systemmanager.getReletype() != 1) {
                if (param.getUserId() == null) {
                    param.setUserId(systemmanager.getAreauserid());
                }
            }
            List<TaAccountAmountStreamResult> results = iTaaccountMapper.selectAmountStream(param);

            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, DealerQueryResult.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 inOrOutAmount(TaAccountInOrOutAmountParam param, HttpServletRequest request) {
        //权限校验
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        Taaccount ta = iTaaccountMapper.selectOne(new QueryWrapper<Taaccount>().eq("ACCOUNTID", param.getAccountcode()));
        if (systemmanager.getAreauserid().compareTo(ta.getUserid()) != 0) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM003.getCode(), request.getHeader("Accept-Language"));
        }
        if (param.getMoney() == null || param.getMoney().compareTo(BigDecimal.ZERO) <= 0) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.AMOUNT_ERROR_CODE_001.getCode(), request.getHeader("Accept-Language"));
        }
        //出入金
        Long uuid = SerialNumberUtils.getNewSerialNumber(SerialNumberUtils.prefix_bank);
        BankAccountsign sign = iBankAccountsignMapper.selectOne(new QueryWrapper<BankAccountsign>()
                .eq("ACCOUNTCODE", param.getAccountcode()).eq("CUSBANKID", param.getCusbankid()));

        Calculator ca1 = new Calculator(uuid);
        SerialNumberUtils.lockMap.put(uuid, ca1);

        //  发送消息
        if (param.getType() == 1) {
            BankMI1.t2bBankWithdrawReq.Builder builder = BankMI1.t2bBankWithdrawReq.newBuilder();
            long time = System.currentTimeMillis();

            Common.MessageHead.Builder hd = Common.MessageHead.newBuilder();
            hd.setFunCode(FunCodeConstants.FunCode_Trade_t2bBankWithdrawReq);
            hd.setClientTime(time);
            builder.setHeader(hd);
            String manageid = redisServiceUtil.getCacheMapValue(Constants.REDIS_HEADER_SYSPARAM, "001");

            builder.setExchId(manageid);
            builder.setExtOperatorID(uuid);
            builder.setAccountCode(sign.getAccountcode());
            builder.setCusBankID(sign.getCusbankid());
            builder.setCurrency(sign.getCurrency());
            builder.setAccountType(sign.getAccounttype());
            builder.setOpenCardBankId(StringUtils.isBlank(sign.getBankid()) ? "" : sign.getBankid());
            builder.setBankAccoutNum(StringUtils.isBlank(sign.getBankaccountno()) ? "" : sign.getBankaccountno());
            builder.setBankAccoutName(StringUtils.isBlank(sign.getBankaccountname()) ? "" : sign.getBankaccountname());
            builder.setAmount(param.getMoney().multiply(new BigDecimal(-1)).doubleValue());
            builder.setAppDateTime(String.valueOf(time));
            builder.setBranchBankName(StringUtils.isBlank(sign.getBranchbankname()) ? "" : sign.getBranchbankname());
            builder.setExtendInfo(JsonUtils.object2Json(param.getExtendInfo()));
            builder.setOldTaPWD(EncryptionUtils.encryptSHA(param.getAccpwd()));
            builder.setRemark(StringUtils.isBlank(param.getRemark()) ? "" : param.getRemark());
            byte[] body = ProtoHelper.getNTAS(builder.build().toByteArray(), FunCodeConstants.FunCode_Trade_t2bBankWithdrawReq);
            rabbitTemplate.send(SysConstants.RabbitBankNtfKey, new Message(body, new MessageProperties()));
        } else {
            BankMI1.t2bBankDepositReq.Builder builder = BankMI1.t2bBankDepositReq.newBuilder();
            long time = System.currentTimeMillis();

            Common.MessageHead.Builder hd = Common.MessageHead.newBuilder();
            hd.setFunCode(FunCodeConstants.FunCode_Trade_t2bBankDepositReq);
            hd.setClientTime(time);

            builder.setHeader(hd);
            String manageid = redisServiceUtil.getCacheMapValue(Constants.REDIS_HEADER_SYSPARAM, "001");

            builder.setExchId(manageid);
            builder.setExtOperatorID(uuid);
            builder.setAccountCode(sign.getAccountcode());
            builder.setCusBankID(sign.getCusbankid());
            builder.setCurrency(sign.getCurrency());
            builder.setBankChildAccount(StringUtils.isBlank(sign.getBankchildaccount()) ? "" : sign.getBankchildaccount());
            builder.setOpenCardBankId(StringUtils.isBlank(sign.getBankid()) ? "" : sign.getBankid());
            builder.setBankAccoutNum(sign.getBankaccountno());
            builder.setBankAccoutName(sign.getBankaccountname());
            builder.setAmount(param.getMoney().doubleValue());
            builder.setExtendInfo(JsonUtils.object2Json(param.getExtendInfo()));
            builder.setOldTaPWD(EncryptionUtils.encryptSHA(param.getAccpwd()));
            builder.setRemark(StringUtils.isBlank(param.getRemark()) ? "" : param.getRemark());

            byte[] body = ProtoHelper.getNTAS(builder.build().toByteArray(),
                    FunCodeConstants.FunCode_Trade_t2bBankDepositReq);
            rabbitTemplate.send(SysConstants.RabbitBankNtfKey, new Message(body, new MessageProperties()));
        }

        synchronized (ca1) {
            try {
                ca1.wait(5000);
                Object rsp = ca1.obj;
                if (rsp != null) {
                    switch (param.getType()) {
                        case 1: {
                            BankMI1.t2bBankWithdrawRsp rsp_ = (BankMI1.t2bBankWithdrawRsp) rsp;
                            if (rsp_.getStatus() == 0) {
                                return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM008.getCode(), request.getHeader("Accept-Language"), rsp_.getNetAddr());
                            } else if (rsp_.getStatus() == 6007) {
                                return AjaxResult.success(rsp_.getStatus(), ProtoErrorCodes.resultMsg(rsp_.getStatus()), "", rsp_.getNetAddr());
                            } else {
                                return AjaxResult.error(Constants.Error_Code_Design, ProtoErrorCodes.resultMsg(rsp_.getStatus()) + ";" + rsp_.getCenterErrMsg(), "", rsp_.getNetAddr());
                            }
                        }
                        case 2: {
                            BankMI1.t2bBankDepositRsp rsp_ = (BankMI1.t2bBankDepositRsp) rsp;
                            if (rsp_.getStatus() == 0) {
                                return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM009.getCode(), request.getHeader("Accept-Language"), rsp_.getNetAddr());
                            } else if (rsp_.getStatus() == 6007) {
                                return AjaxResult.success(rsp_.getStatus(), ProtoErrorCodes.resultMsg(rsp_.getStatus()), "", rsp_.getNetAddr());
                            } else {
                                return AjaxResult.error(Constants.Error_Code_Design, ProtoErrorCodes.resultMsg(rsp_.getStatus()) + ";" + rsp_.getCenterErrMsg(), "", rsp_.getNetAddr());
                            }
                        }
                        default:
                            break;
                    }
                } else {
                    return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM005.getCode(), request.getHeader("Accept-Language"));
                }
            } catch (Exception e) {
                log.error("mq接收出入金返回信息失败，失败信息：" + e);
            } finally {
                SerialNumberUtils.lockMap.remove(uuid);
            }
        }
        return null;
    }

    @Override
    public AjaxResult updateTaAccount(TaAccountUpdateParam param, HttpServletRequest request) {
        //权限校验
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        Taaccount ta = iTaaccountMapper.selectOne(new QueryWrapper<Taaccount>().eq("ACCOUNTID", param.getAccountId()));
        if (systemmanager.getReletype() != 1) {
            if (!iCommonService.checkIsAreaSon2(systemmanager.getAreauserid(), ta.getUserid())) {
                return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM003.getCode(), request.getHeader("Accept-Language"));
            }
        }
        if (ta.getIsmain() == 0 && param.getRelateduserid() != null &&
                param.getRelateduserid().compareTo(ta.getUserid()) == 0) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.INVESTOR_ERROR_CODE_012.getCode(), request.getHeader("Accept-Language"));
        }
        //原来的状态
        Integer oldtradestatus = ta.getTradestatus();
        if (param.getRelateduserid() != null) {
            ta.setRelateduserid(param.getRelateduserid());
        }
        ta.setRelatedaccountstatus(param.getRelatedaccountstatus());
        iTaaccountMapper.update(ta, new QueryWrapper<Taaccount>().eq("accountid", ta.getAccountid()));

        List<Logintaaccount> logintaaccounts = iLogintaaccountMapper.selectList(new QueryWrapper<Logintaaccount>().eq("accountid", param.getAccountId()));
        List<Long> list = logintaaccounts.stream().map(Logintaaccount::getAccountid).collect(Collectors.toList());

        Set<Long> set = new HashSet<>();
        Set<Long> set_msg = new HashSet<>();
        if (!list.isEmpty()) {
            set.addAll(list);
        }
        //处理当前登录账户资金权限
        if (CollectionUtils.isNotEmpty(param.getLoginIds())) {
            iLogintaaccountMapper.delete(new QueryWrapper<Logintaaccount>().eq("ACCOUNTID", param.getAccountId()));
            for (Long id : param.getLoginIds()) {
                Logintaaccount lt = new Logintaaccount();
                lt.setAccountid(param.getAccountId());
                lt.setLoginid(id);
                lt.setModifytime(new Date());
                lt.setModifierid(systemmanager.getAutoid());
                iLogintaaccountMapper.insert(lt);

                if (!set.contains(id)) {
                    set_msg.add(id);
                } else {
                    set.remove(id);
                }
            }
        }
        set_msg.addAll(set);
        ta.setSet_msg(set_msg);

        //处理市场权限
        if (systemmanager.getAreauserid().compareTo(ta.getUserid()) == 0) {
            iTaaccountmarketMapper.delete(new QueryWrapper<Taaccountmarket>().eq("ACCOUNTID", param.getAccountId()));
            if (CollectionUtils.isNotEmpty(param.getDType())) {
                for (TaAccountMarketVo td : param.getDType()) {
                    //处理关联市场信息
                    Taaccountmarket lt = dealMarketMsg(td, ta, systemmanager);
                    iTaaccountmarketMapper.insert(lt);
                }
            }
        }
        //记录操作日志
        writeOperateLog(param, ta, systemmanager);

        try {
            //发送登录服务消息
            if (ta.getSet_msg() != null && !ta.getSet_msg().isEmpty()) {
                iSendMsgService.sendLoginMsg(ta.getSet_msg(), 4, 0);
            }

            //发送用户变更通知
            if (Objects.equals(oldtradestatus, SysEnums.TradeStatusEnum.CANCELED.getType())) {
                iSendMsgService.sendUserChangeMsg(ta.getAccountid(), ta.getUserid(),
                        SysEnums.UserOperateTypeEnum.ADD.getType(),
                        SysEnums.NotifyModeEnum.UNICAST.getType());
            } else {
                iSendMsgService.sendUserChangeMsg(ta.getAccountid(), ta.getUserid(),
                        SysEnums.UserOperateTypeEnum.UPDATE.getType(),
                        SysEnums.NotifyModeEnum.UNICAST.getType());
            }
        } catch (Exception e) {
            log.error("资金账户-->修改 发送用户信息修改失败,code=" + FunCodeConstants.FunCode_Trade_UserChangeNtf + "，请检查!，失败原因：" + e);
        }
        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"));
    }

    @Override
    public PageResult<Taaccount> showAccount(Long userid, String accountid, Integer pageNo, Integer pageSize, HttpServletRequest request) {
        QueryWrapper<Taaccount> queryWrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(accountid)) {
            queryWrapper.eq("accountid", accountid);
        }
        if (userid != null) {
            queryWrapper.and(w -> w.eq("userid", userid).eq("ismain", 1)
                    .or()
                    .eq("userid", userid).eq("relateduserid", 1));
        }
        //返回列表
        PageResult<Taaccount> pageResult = new PageResult<>();
        if (pageNo == null) {
            List<Taaccount> taaccountList = iTaaccountMapper.selectList(queryWrapper);
            pageResult.setCode(Constants.Success_Code_Design);
            pageResult.setMessage(AjaxResult.dealMsg(MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language")));
            pageResult.setData(taaccountList);
        } else {
            IPage<Taaccount> page = new Page<>(pageNo, pageSize);
            IPage<Taaccount> taaccountIPage = iTaaccountMapper.selectPage(page, queryWrapper);
            //获取风险率
            taaccountIPage.getRecords().forEach(a -> {
                getRiskFromRedis(a);
                a.setAccountname(iUseraccountMapper.selectOrganName(a.getUserid()));
            });
            pageResult.setCode(Constants.Success_Code_Design);
            pageResult.setMessage(AjaxResult.dealMsg(MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language")));
            pageResult.setPages(taaccountIPage.getPages());
            pageResult.setCurrent(taaccountIPage.getCurrent());
            pageResult.setTotal(taaccountIPage.getTotal());
            pageResult.setPageSize(taaccountIPage.getSize());
            pageResult.setData(taaccountIPage.getRecords());
        }
        return pageResult;
    }

    @Override
    public AjaxResult edit(InvestorTaAccountUpdateParam updateParam, HttpServletRequest request) {
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        Taaccount old = iTaaccountMapper.selectOne(new QueryWrapper<Taaccount>().eq("accountid", updateParam.getAccountid()));
        if (systemmanager.getReletype() != 1) {
            if (!iCommonService.checkIsAreaSon2(systemmanager.getAreauserid(), old.getUserid())) {
                return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM003.getCode(), request.getHeader("Accept-Language"));
            }
        }
        //原来的状态
        Integer oldtradestatus = old.getTradestatus();
        if (updateParam.getOutthreshold() != null) {
            old.setOutthreshold(updateParam.getOutthreshold());
        }
        if (updateParam.getTradestatus() != null) {
            old.setTradestatus(updateParam.getTradestatus());
            old.setChangetime(new Date());
        }
        iTaaccountMapper.update(old, new QueryWrapper<Taaccount>().eq("accountid", old.getAccountid()));

        List<Logintaaccount> logintaaccounts = iLogintaaccountMapper.selectList(new QueryWrapper<Logintaaccount>().eq("accountid", updateParam.getAccountid()));
        Set<Long> set_msg = logintaaccounts.stream().map(Logintaaccount::getAccountid).collect(Collectors.toSet());
        old.setSet_msg(set_msg);

        Systemmanagerlog syslog = new Systemmanagerlog();
        syslog.setUserid(systemmanager.getAutoid());
        syslog.setReletype(systemmanager.getReletype());
        syslog.setLogincode(systemmanager.getLogincode());
        syslog.setUsername(systemmanager.getUsername());
        syslog.setParentuserid(systemmanager.getAreauserid());
        syslog.setOperatetime(new Date());
        syslog.setIp(systemmanager.getLoginip());
        syslog.setResourcecode(SysConstants.OPERATION_TAA);
        syslog.setContent("修改资金账户{\"accountid\":" + old.getAccountid() + "}成功");
        syslog.setOldvalue("{\"accountid\":" + old.getAccountid() + ",\"userid\":" + old.getUserid() + "}");

        syslog.setNewvalue("{\"accountid\":" + old.getAccountid() + ","
                + "\"userid\":" + old.getUserid() + ","
                + "\"tradestatus\":" + updateParam.getTradestatus() + ","
                + "\"relatedaccountstatus\":" + old.getRelatedaccountstatus() + ","
                + "\"outthreshold\":" + old.getOutthreshold() + "\"}");

        try {
            //发送登录服务消息
            if (old.getSet_msg() != null && !old.getSet_msg().isEmpty()) {
                iSendMsgService.sendLoginMsg(old.getSet_msg(), 4, 0);
            }

            //发送用户变更通知
            if (Objects.equals(oldtradestatus, SysEnums.TradeStatusEnum.CANCELED.getType())) {
                iSendMsgService.sendUserChangeMsg(old.getAccountid(), old.getUserid(),
                        SysEnums.UserOperateTypeEnum.ADD.getType(),
                        SysEnums.NotifyModeEnum.UNICAST.getType());
            } else {
                iSendMsgService.sendUserChangeMsg(old.getAccountid(), old.getUserid(),
                        SysEnums.UserOperateTypeEnum.UPDATE.getType(),
                        SysEnums.NotifyModeEnum.UNICAST.getType());
            }
        } catch (Exception e) {
            log.error("资金账户-->修改 发送用户信息修改失败,code=" + FunCodeConstants.FunCode_Trade_UserChangeNtf + "，请检查!，失败原因：" + e);
        }
        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"));
    }

    @Override
    public AjaxResult logOff(Long areaid, HttpServletRequest request) {
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        if (!iCommonService.checkUserAccountRole(systemmanager, areaid)) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM003.getCode(), request.getHeader("Accept-Language"));
        }
        Taaccount ta = iTaaccountMapper.selectOne(new QueryWrapper<Taaccount>().eq("userid", areaid));
        if (Objects.isNull(ta)) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.INVESTOR_ERROR_CODE_001.getCode(), request.getHeader("Accept-Language"));
        }
        Useraccount ua = iUseraccountMapper.selectOne(new QueryWrapper<Useraccount>().eq("userid", areaid));
        if (ua.getUsertype() != 5) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.INVESTOR_ERROR_CODE_002.getCode(), request.getHeader("Accept-Language"));
        }
        //判断资金账户签约信息
        List<BankAccountsign> sign = iBankAccountsignMapper.selectList(new QueryWrapper<BankAccountsign>().eq("accountcode", ta.getAccountid()));
        if (CollectionUtils.isNotEmpty(sign) && sign.get(0).getSignstatus() != 1 && sign.get(0).getSignstatus() != 7) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.INVESTOR_ERROR_CODE_003.getCode(), request.getHeader("Accept-Language"));
        }
        //判断是否是干净账户
        if (ta.getTradestatus() != 7) {
            Long accountuuid = SerialNumberUtils.getNewSerialNumber(SerialNumberUtils.prefix_account);
            AkernelMI1.AccountFundInfoReq.Builder accountbuilder = AkernelMI1.AccountFundInfoReq.newBuilder();
            Common.MessageHead.Builder accounthd = Common.MessageHead.newBuilder();
            accounthd.setAccountID(ta.getAccountid());
            accounthd.setClientTime(System.currentTimeMillis());
            accounthd.setResponseTopic(SysConstants.RabbitMoneyReqKey);
            accounthd.setFunCode(FunCodeConstants.FunCode_Trade_AccountFundInfoReq);
            accountbuilder.setOrderId(accountuuid);
            accountbuilder.setAccountId(ta.getAccountid());
            accountbuilder.setQueryBitMask(4);
            byte[] accountbody = ProtoHelper.getNTAS(accountbuilder.build().toByteArray(),
                    FunCodeConstants.FunCode_Trade_AccountFundInfoReq);
            //卡住
            Calculator calculator = new Calculator(accountuuid);
            SerialNumberUtils.lockMap.put(accountuuid, calculator);
            rabbitTemplate.send(SysConstants.RabbitMoneyReqKey, new Message(accountbody, new MessageProperties()));

            synchronized (calculator) {
                try {
                    calculator.wait(6000);
                    Object o = calculator.obj;
                    if (o != null) {
                        AkernelMI1.AccountFundInfoRsp accountrsp = (AkernelMI1.AccountFundInfoRsp) o;
                        if (accountrsp.getRetCode() == 0) {
                            if (accountrsp.getIsCleanAccount() == 1) {
                                //干净账户
                            } else {
                                return AjaxResult.error(Constants.Error_Code_Design, MessageType.INVESTOR_ERROR_CODE_004.getCode(), request.getHeader("Accept-Language"));
                            }
                        } else {
                            return AjaxResult.error(Constants.Error_Code_Design, "[" + accountrsp.getRetCode() + "]" + ProtoErrorCodes.resultMsg(accountrsp.getRetCode()), "");
                        }
                    } else {
                        return AjaxResult.error(Constants.Error_Code_Design, MessageType.INVESTOR_ERROR_CODE_005.getCode(), request.getHeader("Accept-Language"));
                    }
                } catch (InterruptedException e) {
                    log.error("mq接收出入金返回信息失败，失败信息：" + e);
                } finally {
                    SerialNumberUtils.lockMap.remove(accountuuid);
                }
            }
        }

        Map<String, Object> result = logoutInvestor(areaid, systemmanager, ta);

        if (result.get("userid") != null && result.get("accountid") != null) {

            iSendMsgService.sendUserChangeMsg(
                    Long.parseLong(result.get("accountid").toString()),
                    Long.parseLong(result.get("userid").toString()),
                    SysEnums.UserOperateTypeEnum.DEL.getType(),
                    SysEnums.AccountOperateTypeEnum.DEL.getType(),
                    SysEnums.NotifyModeEnum.UNICAST.getType());

            List<Long> longList = new ArrayList<>();
            List<Loginaccount> list = iLoginaccountMapper.selectList(new QueryWrapper<Loginaccount>().eq("userid", Long.parseLong(result.get("userid").toString())));
            for (Loginaccount tmp : list) {
                longList.add(tmp.getLoginid());
            }
            if (CollectionUtils.isNotEmpty(longList)) {
                Set<Long> longSet = new HashSet<>(longList);
                iSendMsgService.sendLoginMsg(longSet, SysEnums.UserOperateTypeEnum.DEL.getType(), SysEnums.NotifyModeEnum.UNICAST.getType());
            }

            // 发送用户注销消息给中心\银行接口
            List<Taaccount> tas = iTaaccountMapper.selectList(new QueryWrapper<Taaccount>()
                    .eq("userid", Long.parseLong(result.get("userid").toString()))
                    .eq("ismain", 1));
            iSendMsgService.sendM2BUnregistCustomerInfo(tas);
        }
        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult recover(Long areaid, HttpServletRequest request) {
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        if (!iCommonService.checkUserAccountRole(systemmanager, areaid)) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM003.getCode(), request.getHeader("Accept-Language"));
        }
        return refUserAccount(areaid, systemmanager, request);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult rebackChange(Long areaid, HttpServletRequest request) {
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        if (!iCommonService.checkUserAccountRole(systemmanager, areaid)) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM003.getCode(), request.getHeader("Accept-Language"));
        }
        DraftUseraccountNew dua = iDraftUseraccountNewMapper.selectOne(new QueryWrapper<DraftUseraccountNew>().eq("USERID", areaid));
        Useraccount oldVo = JsonUtils.json2Object(dua.getOldcontent(), Useraccount.class);
        iDraftUseraccountNewMapper.deleteById(dua);
        iDraftUserinfoMapper.delete(new QueryWrapper<DraftUserinfo>().eq("USERID", areaid));

        Useraccount organ = iUseraccountMapper.selectOne(new QueryWrapper<Useraccount>().eq("userid", areaid));
        //错误 #58783
        organ.setModifystatus(1);
        // #6607 【交易中心-管理端】将实名认证的申请直接撤回会导致实名状态一直为审核中
        organ.setHasauth((oldVo == null || oldVo.getHasauth() == null) ? 0 : oldVo.getHasauth());
        iUseraccountMapper.update(organ, new QueryWrapper<Useraccount>().eq("userid", organ.getUserid()));

        if (organ.getUsertype() == 3 || organ.getUsertype() == 4) {
            if (systemmanager.getReletype() == 1) {
                systemmanagerService.writeOperateLog(SysConstants.PART_CODE_ORGZ, "撤回id=" + organ.getUserid(), systemmanager, null, null, null);
            } else {
                systemmanagerService.writeOperateLog(SysConstants.PART_CODE_ORGZ_ZJG, "撤回id=" + organ.getUserid(), systemmanager, null, null, null);
            }
        } else if (organ.getUsertype() == 5) {
            systemmanagerService.writeOperateLog(SysConstants.PART_INVESTOR_MANAGE, "撤回id=" + organ.getUserid(), systemmanager, null, null, null);
        }

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

    @Override
    public AjaxResult<TaAccountInitResultDetail> updateTaAccountInit(HttpServletRequest request, Long accountId,String orgztypes) {
        TaAccountInitResultDetail initResultDetail = new TaAccountInitResultDetail();
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        Taaccount taaccount = iTaaccountMapper.selectOne(new QueryWrapper<Taaccount>().eq("ACCOUNTID", accountId));
        //是否显示期权市场

        String sp1 = iCommonService.getSysparmById(SysConstants.SYSPAMA_CODE_ACCOUNT_MARKET);
        if (systemmanager.getReletype() != 1 && !iCommonService.checkIsAreaSon2(systemmanager.getAreauserid(), taaccount.getUserid())) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM003.getCode(), request.getHeader("Accept-Language"));
        }

        String[] roletyes = orgztypes.split(",");
        for (String role : roletyes) {
            if (Integer.parseInt(role) == SysEnums.OrganRole.selfsupport.getCode()) {
                //如果有自营会员角色
                initResultDetail.setSelfFlag(1);
                break;
            }
        }

        String sp = iCommonService.getSysparmById(SysConstants.SYSPARAM_SETTING_SHOW_RU);
        if (sp != null) {
            initResultDetail.setIsshowrelationuser(sp);
        } else {
            initResultDetail.setIsshowrelationuser("1");
        }
        //自营市场
        List<Integer> roletype = new ArrayList<Integer>();
        roletype.add(SysEnums.OrganRole.selfsupport.getCode());
        int isqq = 0;
        if (StringUtils.isNotBlank(sp1) && !"1".equals(sp1)) {
            isqq = 1;
        }
        List<Market> Markets = iMarketMapper.getMarketsNameByUseridAndrole(systemmanager.getAreauserid(),roletype,isqq);
        initResultDetail.setMarkets(Markets);
        //登录账户
        QueryWrapper<Loginaccount> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("loginid");
        queryWrapper.eq("userid", systemmanager.getAreauserid()) // 替换 userId 为实际的参数值
                .eq("loginstatus", 1);
        queryWrapper.exists("SELECT * FROM logintaaccount l WHERE l.loginid = loginaccount.loginid");
        List<BigDecimal> loginIds = iLoginaccountMapper.selectObjs(queryWrapper);
        initResultDetail.setLoginaccount(loginIds);
        List<Long> defaultLogin = iLoginaccountMapper.getLoginNotExistsLt(systemmanager.getAreauserid());
        initResultDetail.setDefaultloginaccount(defaultLogin);

        //获取市场权限
        Map<Long, TaAccountMarketVo> lmap = new HashMap<>();
        List<TaAccountMarketVo> dty = iTaaccountmarketMapper.selectByAccountId(taaccount.getAccountid());
        for (TaAccountMarketVo taAccountMarketVo : dty) {
            taAccountMarketVo.setChecked(1);
            lmap.put(taAccountMarketVo.getMarketId(), taAccountMarketVo);
        }
        for (Market market : Markets) {
            if (!lmap.containsKey(market.getMarketid())) {
                TaAccountMarketVo te = new TaAccountMarketVo();
                te.setChecked(0);
                te.setMarketId(market.getMarketid());
                te.setMarketName(market.getMarketname());
                te.setSpotRightType(market.getSpotrighttype());
                te.setDType(market.getBuyspotrighttype());
                te.setTradeMode(market.getTrademode());
                te.setTradeProperty(market.getTradeproperty());
                lmap.put(market.getMarketid(), te);
            } else {
                lmap.get(market.getMarketid()).setFSpotRightType(market.getSpotrighttype());
                lmap.get(market.getMarketid()).setFdType(market.getBuyspotrighttype());
                lmap.get(market.getMarketid()).setTradeMode(market.getTrademode());
                lmap.get(market.getMarketid()).setTradeProperty(market.getTradeproperty());
            }
        }
        initResultDetail.setClildmarkets(lmap);

        StringBuffer oldLogin = new StringBuffer();
        //获取当前登录账户资金权限
        List<Logintaaccount> logintaaccounts = iLogintaaccountMapper.selectList(new QueryWrapper<Logintaaccount>().eq("ACCOUNTID", taaccount.getAccountid()));
        logintaaccounts.forEach(p -> oldLogin.append(p).append(";"));

        if (taaccount.getRelateduserid() != null) {
            Useraccount ua = iUseraccountMapper.selectOne(new QueryWrapper<Useraccount>().eq("userid",taaccount.getRelateduserid()));
            initResultDetail.setRelatedU(ua);
        }
        if (taaccount.getUserid().compareTo(systemmanager.getAreauserid()) != 0) {
            initResultDetail.setCannotEdit( 1);
        }
        initResultDetail.setOldLogin(oldLogin.toString());
        initResultDetail.setTaa(taaccount);

        MsExtendrole entity = iMsExtendroleMapper.selectOne(new QueryWrapper<MsExtendrole>()
                .eq("roletypeid", 5L)
                .eq("areauserid", taaccount.getUserid()));
        if (entity != null) {
            initResultDetail.setCannotEdit(1);
        }

        //交易类型
        Map<String, Object> map = redisServiceUtil.getCacheMap(Constants.REDIS_HEADER_DICT + "marketbstype");
        Map<Integer, String> map_ = new TreeMap<>();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            map_.put(Integer.valueOf(entry.getKey()), entry.getValue().toString());
        }
        initResultDetail.setMarketbstype(map_);

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

    private AjaxResult refUserAccount(Long areaid, Systemmanager systemmanager, HttpServletRequest request) {
        Useraccount org = iUseraccountMapper.selectOne(new QueryWrapper<Useraccount>().eq("userid", areaid)); //areaid就是userid
        Userinfo ui = iUserinfoMapper.selectOne(new QueryWrapper<Userinfo>().eq("userid", areaid));
        List<Userinfo> uiList = iUserinfoMapper.selectList(new QueryWrapper<Userinfo>()
                .eq("userstatus", 1)
                .ne("userid", ui.getUserid())
                .and(a -> a.eq(StringUtils.isNotBlank(ui.getCardnum()), "cardnum", ui.getCardnum())
                        .or()
                        .eq(StringUtils.isNotBlank(ui.getMobile()), "mobile", ui.getMobile()))
        );
        if (CollectionUtils.isNotEmpty(uiList)) {
            for (Userinfo userinfo : uiList) {
                if (userinfo.getCardnum().equals(ui.getCardnum())) {
                    return AjaxResult.error(Constants.Error_Code_Design, MessageType.ORGAN_ERROR_CODE_006.getCode(), request.getHeader("Accept-Language"));
                }
                //5 投资者
                if (org.getUsertype() == 5 && userinfo.getMobile().equals(ui.getMobile())) {
                    return AjaxResult.error(Constants.Error_Code_Design, MessageType.ORGAN_ERROR_CODE_007.getCode(), request.getHeader("Accept-Language"));
                }
            }
        }
        if (org.getParentuserid() != 0) {
            Useraccount p = iUseraccountMapper.selectOne(new QueryWrapper<Useraccount>().eq("userid", org.getParentuserid()));
            if (p.getAccountstatus() != 4) {
                return AjaxResult.error(Constants.Error_Code_Design, MessageType.ORGAN_ERROR_CODE_008.getCode(), request.getHeader("Accept-Language"));
            }
        }
        if (org.getUsertype() == 5) {
            //所属会员是否有经纪角色
            Arearole ar = iArearoleMapper.selectOne(new QueryWrapper<Arearole>()
                    .eq("roletype", 7)
                    .eq("userid", org.getMemberuserid()));
            if (Objects.isNull(ar)) {
                return AjaxResult.error(Constants.Error_Code_Design, MessageType.ORGAN_ERROR_CODE_009.getCode(), request.getHeader("Accept-Language"));
            }
        }

        AjaxResult ajaxResult = checkOrgan(org, request);
        if (ajaxResult != null) {
            return ajaxResult;
        }

        org.setAccountstatus(4);
        org.setModifierid(systemmanager.getAutoid());
        org.setModifytime(new Date());
        iUseraccountMapper.update(org, new QueryWrapper<Useraccount>().eq("userid", org.getUserid()));

        ui.setUserstatus(1);
        iUserinfoMapper.update(ui, new QueryWrapper<Userinfo>().eq("userid", ui.getUserid()));

        //管理员账户
        Systemmanager admin = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>()
                .eq("areauserid", areaid)
                .eq("isdefault", 1)
        );
        if (admin != null) {
            admin.setManagerstatus(1);
            iSystemmanagerMapper.updateById(admin);
        }

        //写入日志
        if (org.getUsertype() == 2)
            systemmanagerService.writeOperateLog(SysConstants.PART_CODE_ORGZ, "恢复机构id=" + org.getUserid(), systemmanager, null, null, null);
        else if (org.getUsertype() == 3 || org.getUsertype() == 4) {
            String name = "";
            if (org.getUsertype() == 3)
                name = "子机构";
            if (org.getUsertype() == 4)
                name = "经纪人";
            if (systemmanager.getReletype() == 1)
                systemmanagerService.writeOperateLog(SysConstants.PART_CODE_ORGZ, "恢复" + name + "id=" + org.getUserid(), systemmanager, null, null, null);
            else
                systemmanagerService.writeOperateLog(SysConstants.PART_CODE_ORGZ_ZJG, "恢复" + name + "id=" + org.getUserid(), systemmanager, null, null, null);
        } else if (org.getUsertype() == 5) {
            systemmanagerService.writeOperateLog(SysConstants.PART_INVESTOR_MANAGE, "恢复投资者id=" + org.getUserid(), systemmanager, null, null, null);
        }

        List<Taaccount> tas = iTaaccountMapper.selectList(new QueryWrapper<Taaccount>()
                .eq("userid", org.getUserid())
                .eq("ismain", 1));
        Userinfo userinfo = iUserinfoMapper.selectOne(new QueryWrapper<Userinfo>().eq("userid", areaid));

        for (Taaccount ta : tas) {
            iSendMsgService.sendCustomerInfo(userinfo, ta.getAccountid(), "2", 3);
        }
        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"));
    }

    private AjaxResult checkOrgan(Useraccount ua, HttpServletRequest request) {
        if (ua.getUsertype() == 2) {
            return null;
        }
        List<Long> ids = new ArrayList<>();
        if (ua.getMemberuserid() != null) {
            ids.add(ua.getMemberuserid());
        }
        if (ua.getParentuserid() != null) {
            ids.add(ua.getParentuserid());
        }
        if (ua.getBroker() != null) {
            ids.add(ua.getBroker());
        }
        List<Useraccount> organ = iUseraccountMapper.selectList(new QueryWrapper<Useraccount>().in("userid", ids));

        if (CollectionUtils.isNotEmpty(organ)) {
            for (Useraccount ua_ : organ) {
                if (ua_.getAccountstatus() != 4) {
                    if (ua.getAccountstatus() == 4) {
                        break;
                    }

                    if (ua.getUsertype() == 2) {
                        return AjaxResult.error(Constants.Error_Code_Design, MessageType.ORGAN_ERROR_CODE_023.getCode(), request.getHeader("Accept-Language"));
                    } else if (ua.getUsertype() == 3) {
                        return AjaxResult.error(Constants.Error_Code_Design, MessageType.ORGAN_ERROR_CODE_024.getCode(), request.getHeader("Accept-Language"));
                    } else {
                        return AjaxResult.error(Constants.Error_Code_Design, MessageType.ORGAN_ERROR_CODE_025.getCode(), request.getHeader("Accept-Language"));
                    }
                }
            }
        }
        return null;
    }

    private Map<String, Object> logoutInvestor(Long areaid, Systemmanager systemmanager, Taaccount ta) {
        //返回结果
        Map<String, Object> result = new HashMap<String, Object>();

        //todo 查询积分
        boolean isScore = false;
        /*Map<String, Object> properties = new HashMap<String, Object>();
        properties.put("userId", ta.getUserid());
        List<UserScore> userScoreList = userScoreDao.queryByProerties(properties);
        if(userScoreList != null && userScoreList.size() > 0){
            for(UserScore tmp : userScoreList){
                if(tmp.getCurScore() > 0L){
                    isScore = true;
                    break;
                }
            }
        }*/

        if (!isScore) {
            //todo 不存在积分
            /*if(temp != null){
                temp.setHandlestatus(SysEnums.AccountOffStatusEnum.PASS.getType());
                temp.setApplystatus(SysEnums.AccountOffApplyEnum.FINISH.getType());
                temp.setAuditid(user.getAutoid());
                temp.setAudittime(new Date());
                userCancelApplyDao.update(temp);
            }*/
            //更新账户状态
            Useraccount ua = updateAccountStatus(Long.parseLong(String.valueOf(ta.getUserid())), systemmanager.getAutoid(), ta);
            //发短信
            sendSMS(ua.getAccountname(), ua.getUserid(), 14);
            result.put("userid", ta.getUserid());
            result.put("accountid", ta.getAccountid());
        } else {
            //todo 发送积分清理
           /* Long uuid = SerialNumberUtils.getNewSerialNumber(SerialNumberUtils.prefix_score);
            ScoreMI1.ClearScoreReq.Builder builder = ScoreMI1.ClearScoreReq.newBuilder();
            Common.MessageHead.Builder hd = Common.MessageHead.newBuilder();
            hd.setUUID(uuid.toString());
            hd.setFunCode(FunCodeConstants.FunCode_Trade_ClearScoreReq);
            hd.setResponseTopic(SysConstants.RabbitScoreRsp);
            hd.setUserID(Integer.parseInt(ta.getUserid().toString()));
            hd.setAccountID(ta.getAccountid().longValue());
            builder.setHeader(hd);
            builder.setClientSerialID(uuid.longValue());
            builder.setUserID(Integer.parseInt(ta.getUserid().toString()));
            builder.setResponseTopic(SysConstants.RabbitScoreRsp);
            Calculator ca = new Calculator(uuid);
            SerialNumberUtils.lockMap.put(uuid, ca);
            byte[] body = ProtoHelper.getNTAS(builder.build().toByteArray(), FunCodeConstants.FunCode_Trade_ClearScoreReq);
            amqpTemplate.send(SysConstants.RabbitScoreReq, new Message(body, new MessageProperties()));
            log.debug("积分清理请求");
            log.debug(builder.toString());

            synchronized(ca){
                try {
                    ca.wait(10000);
                    Object obj = ca.obj;
                    if(obj != null){
                        ScoreMI1.ClearScoreRsp rsp = (ScoreMI1.ClearScoreRsp)obj;
                        if(rsp.getRetCode() == ErrorCode.Err_Ok){
                            if(temp != null){
                                temp.setHandlestatus(SysEnums.AccountOffStatusEnum.PASS.getType());
                                temp.setApplystatus(SysEnums.AccountOffApplyEnum.FINISH.getType());
                                temp.setAuditid(user.getAutoid());
                                temp.setAudittime(new Date());
                                userCancelApplyDao.update(temp);
                            }
                            //更新账户状态
                            UserAccount ua = updateAccountStatus(Long.parseLong(String.valueOf(rsp.getUserID())), user.getAutoid());
                            result.put("userid", ta.getUserid());
                            result.put("accountid", ta.getAccountid());
                            //发短信
                            sendSMS(ua.getAccountname(), ua.getUserid(), 14);
                            result.put("code", ErrorCode.Err_Ok);
                            if(temp != null)
                                result.put("msg", "审核成功.");
                            else
                                result.put("msg", "注销成功.");
                        }else {
                            result.put("code", rsp.getRetCode());
                            result.put("msg", ProtoErrorCodes.resultMsg(rsp.getRetCode()));
                        }
                    }else {
                        result.put("code", "500");
                        result.put("msg", "请求超时,请稍后查询或重试");
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }finally {
                    SerialNumberUtils.lockMap.remove(uuid);
                }
            }*/
        }

        // 添加操作日志
        systemmanagerService.writeOperateLog(SysConstants.PART_INVESTOR_MANAGE, "交易商销户id=" + areaid, systemmanager, null, null, null);
        return result;
    }

    /**
     * 更新账户状态
     *
     * @param userid
     * @param canceluserid 销户修改人
     * @return
     */
    private Useraccount updateAccountStatus(Long userid, Long canceluserid, Taaccount ta) {

        Useraccount ua = iUseraccountMapper.selectOne(new QueryWrapper<Useraccount>().eq("userid", userid));
        ua.setAccountstatus(SysEnums.AccountStatusEnum.CANCELED.getType()); //注销状态
        ua.setCanceltime(new Date());
        ua.setCanceluserid(canceluserid);
        iUseraccountMapper.update(ua, new QueryWrapper<Useraccount>().eq("userid", ua.getUserid()));

        Loginaccount loginaccount = iLoginaccountMapper.selectOne(new QueryWrapper<Loginaccount>().eq("userid", userid));
        //注销状态
        loginaccount.setLoginstatus(3);
        //最后修改人
        loginaccount.setModifierid(canceluserid);
        loginaccount.setModifytime(new Date());
        iLoginaccountMapper.update(loginaccount, new QueryWrapper<Loginaccount>().eq("loginid", loginaccount.getLoginid()));

        //最终确认直接删除三方账户
        iUserauthinfoMapper.delete(new QueryWrapper<Userauthinfo>().eq("userid", userid));

        //注销状态
        ta.setTradestatus(SysEnums.TradeStatusEnum.CANCELED.getType());
        ta.setTradestatuschangetime(new Date());
        iTaaccountMapper.update(ta, new QueryWrapper<Taaccount>().eq("accountid", ta.getAccountid()));

        Userinfo info = iUserinfoMapper.selectOne(new QueryWrapper<Userinfo>().eq("userid", userid));
        info.setUserstatus(2);
        iUserinfoMapper.update(info, new QueryWrapper<Userinfo>().eq("userid", info.getUserid()));

        return ua;
    }

    private void sendSMS(String accountname, Long userid, int templateid) {
        Userinfo info = iUserinfoMapper.selectOne(new QueryWrapper<Userinfo>().eq("userid", userid));
        if (info == null || info.getMobile() == null)
            return;
        ShortMessageMtp1.ShortMsgSendReq.Builder builder = ShortMessageMtp1.ShortMsgSendReq.newBuilder();
        builder.setMsgType(2);
        builder.setTemplateID(templateid);
        builder.setPriority(2);
        builder.setScheduledTime("");
        builder.addRecvPhone(EncryptionUtils.decryptForAES(info.getMobile()));
        builder.addParamValues(accountname);

        Common.MessageHead.Builder headBuil = Common.MessageHead.newBuilder();
        headBuil.setFunCode(FunCodeConstants.FunCode_Trade_ShortMsgSendReq);
        builder.setHeader(headBuil.build());
        byte[] body = ProtoHelper.getNTAS(builder.build().toByteArray(), FunCodeConstants.FunCode_Trade_ShortMsgSendReq);
        MessageProperties msgProperties = new MessageProperties();
        msgProperties.setHeader("messageType", "protoBuf");
        rabbitTemplate.send(SysConstants.RabbitShortMessage, new Message(body, msgProperties));
    }

    private void writeOperateLog(TaAccountUpdateParam vo, Taaccount ta, Systemmanager user) {
        try {
            Systemmanagerlog syslog = new Systemmanagerlog();
            syslog.setUserid(user.getAutoid());
            syslog.setReletype(user.getReletype());
            syslog.setLogincode(user.getLogincode());
            syslog.setUsername(user.getUsername());
            syslog.setParentuserid(user.getAreauserid());
            syslog.setOperatetime(new Date());
            syslog.setIp(user.getLoginip());
            syslog.setResourcecode(SysConstants.OPERATION_TAA);
            syslog.setResourcename("资金账号管理");
            syslog.setContent("修改资金账户{\"accountid\":" + ta.getAccountid() + "}成功");
            syslog.setOldvalue("{\"accountid\":" + ta.getAccountid() + ",\"userid\":" + ta.getUserid() + "}");
            String marketids = "";
            if (vo.getDType() != null) {
                for (int i = 0; i < vo.getDType().size(); i++) {
                    if (i == vo.getDType().size() - 1)
                        marketids += vo.getDType().get(i);
                    else
                        marketids += vo.getDType().get(i) + ",";
                }
            }

            String loginids = "";
            if (vo.getLoginIds() != null) {
                for (int i = 0; i < vo.getLoginIds().size(); i++) {
                    if (i == vo.getLoginIds().size() - 1)
                        loginids += vo.getLoginIds().get(i);
                    else
                        loginids += vo.getLoginIds().get(i) + ",";
                }
            }

            syslog.setRemark("{\"arearolemarket\":\"" + marketids + "\","
                    + "\"tradeloginid\":\"" + loginids + "\"}");

            syslog.setNewvalue("{\"accountid\":" + ta.getAccountid() + ","
                    + "\"userid\":" + ta.getUserid() + ","
                    + "\"tradestatus\":" + ta.getTradestatus() + ","
                    + "\"relateduserid\":" + ta.getRelateduserid() + ","
                    + "\"relatedaccountstatus\":" + ta.getRelatedaccountstatus() + ","
                    + "\"outthreshold\":" + ta.getOutthreshold() + ","
                    + "\"marketids\":\"" + marketids + "\","
                    + "\"loginidright\":\"" + loginids + "\"}");
            iSystemmanagerlogMapper.insert(syslog);
        } catch (Exception ex) {
            logger.error("记录操作日志失败" + ex.getMessage());
        }
    }

    private Taaccountmarket dealMarketMsg(TaAccountMarketVo td, Taaccount ta, Systemmanager systemmanager) {
        Taaccountmarket lt = new Taaccountmarket();
        lt.setAccountid(ta.getAccountid());
        lt.setMarketid(td.getMarketId());
        lt.setModifytime(new Date());
        lt.setModifierid(systemmanager.getAutoid());
        if (td.getMarketId() == 79201) {
            lt.setBuyspotrighttype(2);
        } else if (td.getMarketId() == 78201) {
            lt.setSpotrighttype(2);
        } else {
            lt.setSpotrighttype(td.getSpotRightType());
            lt.setBuyspotrighttype(td.getDType());
        }
        return lt;
    }

    private void getRiskFromRedis(Taaccount record) {
        try {
            String floatplFlag = iCommonService.getSystemParam(Constants.REDIS_HEADER_SYSPARAM, "113");
            String creditFlag = iCommonService.getSystemParam(Constants.REDIS_HEADER_SYSPARAM, "946");
            String closeplFlag = iCommonService.getSystemParam(Constants.REDIS_HEADER_SYSPARAM, "112");
            String inamountFlag = iCommonService.getSystemParam(Constants.REDIS_HEADER_SYSPARAM, "111");

            byte[] valuebts = redisServiceUtil.getBytes("risk:" + record.getAccountid());
            AccountRedis.AccRiskInfo accRiskInfo = null;
            if (valuebts != null) {
                accRiskInfo = AccountRedis.AccRiskInfo.newBuilder().mergeFrom(valuebts).build();
                logger.info("risk:" + record.getAccountid() + "--------------accRiskInfo:" + accRiskInfo);

                record.setCur_risk_rate(BigDecimal.valueOf(accRiskInfo.getCURRISKRATE()).multiply(BigDecimal.valueOf(100d)).setScale(2, RoundingMode.DOWN));
                record.setFloatpl(BigDecimal.valueOf(accRiskInfo.getTOTALFLOATPL()));
            } else {
                // Redis无记录，风险率、浮动盈亏设置为0
                record.setCur_risk_rate(BigDecimal.ZERO);
                record.setFloatpl(BigDecimal.ZERO);
            }

            // 更新可用
            setAvaliableAmount(record, floatplFlag);

            // 更新可出
            setAvaliableOutAmount(record, floatplFlag, creditFlag, closeplFlag, inamountFlag);

            // 更新当前净值= 期末余额+浮动盈亏(收益权)
            record.setFloatnetvalue(record.getCurrentbalance().add(record.getFloatpl()));

            //获取子账户信息
            List<Taaccount> taaccounts = iTaaccountMapper.selectList(new QueryWrapper<Taaccount>().eq("parentaccountid", record.getAccountid()));
            if (CollectionUtils.isNotEmpty(taaccounts)) {
                for (int j = 0; j < taaccounts.size(); j++) {
                    String accountid_ = taaccounts.get(j).getAccountid().toString();
                    byte[] valuebtsChild = redisServiceUtil.getBytes("risk:" + accountid_);
                    if (valuebtsChild != null) {
                        AccRiskInfo accRiskInfo1 = AccRiskInfo.newBuilder().mergeFrom(AccRiskInfo.parseFrom(valuebtsChild)).build();
                        taaccounts.get(j).setCur_risk_rate(BigDecimal.valueOf(accRiskInfo1.getCURRISKRATE()).multiply(BigDecimal.valueOf(100d)).setScale(2, RoundingMode.DOWN));
                    }
                }
            }
        } catch (Exception e) {
            logger.error("设置风险率失败，请检查！");
        }
    }

    private void setAvaliableOutAmount(Taaccount vo, String floatplFlag, String creditFlag, String closeplFlag, String inamountFlag) {
        //根据系统参数计算s1(946	是否可设置收益权市场的交易授信 0:不显示 1:显示 默认0)
        //946 = 0：
        //s1=期末余额-交易占用-交易冻结-手续费冻结-出金冻结-其它冻结-授信金额-其它授信金额+浮动盈亏-[平仓盈利(正值)](当日平仓盈利不可出112)-[浮动盈利(正值)](当日浮动盈利不可出113)
        //946 = 1:
        //s1=期末余额-交易占用-交易冻结-手续费冻结-出金冻结-其它冻结-授信金额-其它授信金额+浮动盈亏-[平仓盈利(正值)](当日平仓盈利不可出112)-[浮动盈利(正值)](当日浮动盈利不可出113)
        //s2=期初余额+子账号期初余额汇总+当日出金(负值)-出金冻结+[当日入金](当日入金可出111)
        //可出资金=min(s1,s2)
        BigDecimal s1 = BigDecimal.ZERO;
        if ("1".equals(creditFlag)) {
            s1 = vo.getCurrentbalance().subtract(vo.getUsedmargin())
                    .subtract(vo.getFreezemargin()).subtract(vo.getOtherfreezemargin()).subtract(vo.getFreezecharge())
                    .subtract(vo.getOutamountfreeze()).subtract(vo.getOthercredit()).add(vo.getFloatpl());

        } else {
            s1 = vo.getCurrentbalance().subtract(vo.getUsedmargin())
                    .subtract(vo.getFreezemargin()).subtract(vo.getOtherfreezemargin()).subtract(vo.getFreezecharge())
                    .subtract(vo.getOutamountfreeze()).subtract(vo.getMortgagecredit()).subtract(vo.getOthercredit())
                    .add(vo.getFloatpl());
        }

        if ("0".equals(closeplFlag) && vo.getClosepl().compareTo(BigDecimal.ZERO) > 0) {
            s1 = s1.subtract(vo.getClosepl());
        }
        if ("0".equals(floatplFlag) && vo.getFloatpl().compareTo(BigDecimal.ZERO) > 0) {
            s1 = s1.subtract(vo.getFloatpl());
        }
        BigDecimal s2 = vo.getBalance();
        if (vo.getOutamount().compareTo(BigDecimal.ZERO) < 0) {
            s2 = s2.add(vo.getOutamount());
        }
        s2.subtract(vo.getOutamountfreeze());
        if ("1".equals(inamountFlag)) {
            s2 = s2.add(vo.getInamount());
        }

        if ("0".equals(closeplFlag)) {
            vo.setAvaiableoutmoney(s1.compareTo(s2) > 0 ? s2 : s1);
        } else {
            vo.setAvaiableoutmoney(s1);
        }

        // 减去账户出金阀值
        if (vo.getOutthreshold() != null) {
            if (vo.getOutthreshold().compareTo(vo.getAvaiableoutmoney()) > -1) {
                vo.setAvaiableoutmoney(BigDecimal.ZERO);
            } else {
                vo.setAvaiableoutmoney(vo.getAvaiableoutmoney().subtract(vo.getOutthreshold()));
            }
        }

        // 可出小于0，显示时强制值为0
        if (BigDecimal.ZERO.compareTo(vo.getAvaiableoutmoney()) > -1) {
            vo.setAvaiableoutmoney(BigDecimal.ZERO);
        }
    }

    private void setAvaliableAmount(Taaccount vo, String floatplFlag) {
        //可用资金：
        //      账户总浮动盈亏为负：
        //      =期末余额+总浮动盈亏（收益权）-占用-冻结-其它冻结-手续费冻结-出金冻结
        //		账户总浮动盈亏为正 且 113 = 0 ：
        //		=期末余额-占用-冻结-其它冻结-手续费冻结-出金冻结
        //		账户总浮动盈亏为正 且 113 = 1 ：
        //		=期末余额+总浮动盈亏（收益权）-占用-冻结-其它冻结-手续费冻结-出金冻结
        //		*系统参数”113“（当日浮动盈利是否可用） 0:不可用 1:可用
        if (vo == null) return;

        if (floatplFlag.equals("1") || vo.getFloatpl().compareTo(new BigDecimal(0)) < 0) {
            vo.setAvaiablemoney(vo.getCurrentbalance().add(vo.getFloatpl()).subtract(vo.getUsedmargin())
                    .subtract(vo.getFreezemargin()).subtract(vo.getOtherfreezemargin()).subtract(vo.getFreezecharge())
                    .subtract(vo.getOutamountfreeze()));
        } else {
            vo.setAvaiablemoney(vo.getCurrentbalance().subtract(vo.getUsedmargin())
                    .subtract(vo.getFreezemargin()).subtract(vo.getOtherfreezemargin()).subtract(vo.getFreezecharge())
                    .subtract(vo.getOutamountfreeze()));
        }
    }

    private void setAccountMessage(TaAccountQueryResultDetail taAccountQueryResult, Taaccount taaccount) {
        taAccountQueryResult.setAccountId(taaccount.getAccountid());
        taAccountQueryResult.setUserId(taaccount.getUserid());
        taAccountQueryResult.setAccountName(iUseraccountMapper.selectOrganName(taaccount.getUserid()));
        taAccountQueryResult.setIsMain(taaccount.getIsmain());
        taAccountQueryResult.setParentAccountId(taaccount.getParentaccountid());
        taAccountQueryResult.setRelatedUserId(taaccount.getRelateduserid());
        taAccountQueryResult.setRelatedAccountStatus(taaccount.getRelatedaccountstatus());
        taAccountQueryResult.setCurrency(taaccount.getCurrencyid());
        taAccountQueryResult.setTaAccountType(taaccount.getTaaccounttype());
        taAccountQueryResult.setChangeFlag(taaccount.getChangeflag());
        taAccountQueryResult.setTradeStatus(taaccount.getTradestatus());
        taAccountQueryResult.setCurrentBalance(taaccount.getCurrentbalance());
        taAccountQueryResult.setPayCharge(taaccount.getPaycharge());
        taAccountQueryResult.setOtherPay(taaccount.getOtherpay());
        taAccountQueryResult.setOtherFreezeMargin(taaccount.getOtherfreezemargin());
        taAccountQueryResult.setFreezeMargin(taaccount.getFreezemargin());
        taAccountQueryResult.setUsedMargin(taaccount.getUsedmargin());
        taAccountQueryResult.setFreezeCharge(taaccount.getFreezecharge());
        taAccountQueryResult.setOutAmountFreeze(taaccount.getOutamountfreeze());
        taAccountQueryResult.setOutThreshold(taaccount.getOutthreshold());
    }


}
