package com.muchinfo.mtp3century.service.impl;

import com.alibaba.fastjson2.JSONObject;
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.muchinfo.mtp.proto.Common;
import com.muchinfo.mtp.proto.NotifyMI1;
import com.muchinfo.mtp.proto.PublicMI1;
import com.muchinfo.mtp3century.exception.GlobalException;
import com.muchinfo.mtp3century.service.ICommonService;
import com.muchinfo.mtp3century.service.IOrganSonService;
import com.muchinfo.mtp3century.service.ISendMsgService;
import com.muchinfo.mtp3century.utils.RedisServiceUtil;
import com.muchinfo.mtp3century.utils.SequenceIDGeneratorUtils;
import com.muchinfo.mtp3common.enumtype.*;
import com.muchinfo.mtp3common.utils.CommonUtil;
import com.muchinfo.mtp3common.utils.EncryptionUtils;
import com.muchinfo.mtp3common.utils.JsonUtils;
import com.muchinfo.mtp3common.utils.SensitiveEncryptUtil;
import com.muchinfo.mtp3century.utils.AjaxResult;
import com.muchinfo.mtp3common.vo.PageResult;
import com.muchinfo.mtp3common.vo.ProtoHelper;
import com.muchinfo.mtp3interface.mapper.*;
import com.muchinfo.mtp3pojos.entity.*;
import com.muchinfo.mtp3pojos.vo.common.OrganSelectResult;
import com.muchinfo.mtp3pojos.vo.investor.DetailAfterResult;
import com.muchinfo.mtp3pojos.vo.investor.DetailBeforeResult;
import com.muchinfo.mtp3pojos.vo.investor.UserAccountDetailVo;
import com.muchinfo.mtp3pojos.vo.investor.UserinfoDetailVo;
import com.muchinfo.mtp3pojos.vo.organ.UserAccountReqParam;
import com.muchinfo.mtp3pojos.vo.organ.UserAccountRspResult;
import com.muchinfo.mtp3pojos.vo.organ.son.*;
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.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Service
public class OrganSonServiceService implements IOrganSonService {

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Resource
    private ISystemmanagerMapper iSystemmanagerMapper;
    @Resource
    private ICommonService iCommonService;
    @Resource
    private IUseraccountMapper iUseraccountMapper;
    @Resource
    private IUserinfoMapper iUserinfoMapper;
    @Resource
    private IUserauthinfoMapper iUserauthinfoMapper;
    @Resource
    private ISendMsgService iSendMsgService;
    @Resource
    private IDivisionMapper iDivisionMapper;
    @Resource
    private IMarketrunMapper iMarketrunMapper;
    @Resource
    private SystemmanagerServiceImpl systemmanagerService;
    @Resource
    private IWskhOpenaccountconfigMapper iWskhOpenaccountconfigMapper;
    @Resource
    private IDraftUseraccountNewMapper iDraftUseraccountNewMapper;
    @Resource
    private IArearoleMapper iArearoleMapper;
    @Resource
    private IDraftUserinfoMapper iDraftUserinfoMapper;
    @Resource
    private ITaaccountMapper iTaaccountMapper;
    @Resource
    private ITradepositionMapper iTradepositionMapper;
    @Resource
    private ILoginaccountMapper iLoginaccountMapper;
    @Resource
    private RabbitTemplate rabbitTemplate;
    @Resource
    private IEnumdicitemMapper iEnumdicitemMapper;
    @Resource
    private IBankSystemconfigMapper iBankSystemconfigMapper;
    @Resource
    private SequenceIDGeneratorUtils idGeneratorUtils;
    @Resource
    private RedisServiceUtil redisServiceUtil;
    @Resource
    private IUserreckonaccountMapper iUserreckonaccountMapper;
    @Resource
    private IWskhBlacklistMapper iWskhBlacklistMapper;
    @Resource
    private IRoleuserMapper iRoleuserMapper;
    @Resource
    private IQuoterMapper iQuoterMapper;
    @Resource
    private IInvestortransferMapper iInvestortransferMapper;
    @Resource
    private ISubareagroupdetailMapper iSubareagroupdetailMapper;

    @Override
    public PageResult<UserAccountRspResult> querySon(UserAccountReqParam param, HttpServletRequest request) {
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        if (systemmanager.getReletype() == 3) {
            if (param.getParentuserid() == null) {
                param.setParentuserid(param.getMemberuserid());
            }
            //父级和所属会员两个条件同时查，查不出来子机构，所以把所属会员条件去掉
            param.setMemberuserid(null);
        }
        if (systemmanager.getReletype() == 1) {
            param.setMemberuserid(null);
        }
        IPage<UserAccountRspResult> page = new Page<>(param.getPageNum(), param.getPageSize());
        IPage<UserAccountRspResult> userAccountVos = iUseraccountMapper.querySonOrganPage(page, param);
        PageResult<UserAccountRspResult> pageResult = new PageResult<>();
        pageResult.setCode(Constants.Success_Code_Design);
        pageResult.setMessage(AjaxResult.dealMsg(MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language")));
        pageResult.setPages(userAccountVos.getPages());
        pageResult.setCurrent(userAccountVos.getCurrent());
        pageResult.setTotal(userAccountVos.getTotal());
        pageResult.setPageSize(userAccountVos.getSize());
        pageResult.setData(userAccountVos.getRecords());
        return pageResult;
    }

    @Override
    public AjaxResult<UserAccountRspResult> getAreaAndAllChilds(HttpServletRequest request, Long userid) {
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        if (systemmanager.getReletype() != 1) {
            userid = systemmanager.getAreauserid();
        }
        List<UserAccountRspResult> result = iUseraccountMapper.getAreaAndAllChilds(userid);
        for (UserAccountRspResult userAccountVo : result) {
            //最大层级数
            Object maxLev = iCommonService.getSystemParam(Constants.REDIS_HEADER_SYSPARAM, "069");
            if (maxLev == null || StringUtils.isBlank(maxLev.toString())) {
                maxLev = 4;
            }
            userAccountVo.setMaxLevel(Math.min(7, Integer.parseInt(maxLev.toString())));
            userAccountVo.setParentid(systemmanager.getAreauserid());

            Useraccount ua = iUseraccountMapper.selectOne(new QueryWrapper<Useraccount>().eq("userid", systemmanager.getAreauserid()));
            Integer level = iUseraccountMapper.querySonOrganLevel(ua.getUserid(), ua.getMemberuserid());
            userAccountVo.setSubarealevel(level);
            userAccountVo.setCuruserid(ua.getUserid());

            // 是否可跨级添加子机构
            Object canCrossAdd = redisServiceUtil.getCacheMapValue(Constants.REDIS_HEADER_SYSPARAM, "1000");
            if (canCrossAdd == null || StringUtils.isBlank(canCrossAdd.toString())) {
                canCrossAdd = 1;
            }
            userAccountVo.setCancrossadd(Integer.valueOf(canCrossAdd.toString()));

            Userinfo userinfo = iUserinfoMapper.selectOne(new QueryWrapper<Userinfo>().eq("userid", userAccountVo.getUserid()));
            userAccountVo.setUserinfotype(userinfo.getUserinfotype());
            userAccountVo.setContactname(userinfo.getContactname());
            if (userinfo.getDistrictid() != null) {
                userAccountVo.setPathname(iDivisionMapper.selectAreaPathName(userinfo.getCountryid()) + iDivisionMapper.selectAreaPathName(userinfo.getDistrictid()) + userinfo.getAddress());
            }
        }
        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"), result);
    }

    @Override
    public AjaxResult<OrganSonDetailResult> viewson(Long areaid, Integer modifystatus, HttpServletRequest request) {
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        new Thread(new Runnable() {
            @Override
            public void run() {
                systemmanagerService.saveMGLog(systemmanager, SysConstants.PART_CODE_ORGZ, areaid);
            }
        }).start();

        OrganSonDetailResult result = new OrganSonDetailResult();
        Useraccount useraccount = iUseraccountMapper.selectOne(new QueryWrapper<Useraccount>().eq("userid", areaid));
        String sp1 = iCommonService.getSysparmById(SysConstants.SYSPARAM_SETTING_SON_AUDIT);

        //管理员账户
        Systemmanager admin = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>()
                .eq("areauserid", areaid)
                .eq("isdefault", 1));
        result.setUserid(admin.getAutoid());
        result.setUsername(admin.getUsername());
        result.setUserstatus(admin.getManagerstatus());
        result.setLogincode(admin.getLogincode());

        //整理返回数据
        if (modifystatus != null && modifystatus >= 2 && useraccount.getAccountstatus() == 4
                && "1".equals(sp1)) {
            result.setOldResult(getUserAccountDetail(areaid, result));
            result.setNewResult(getModifyInvestorDetail(areaid));
            return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"), result);
        } else {
            result.setOldResult(getUserAccountDetail(areaid, result));
            return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"), result);
        }
    }

    @Override
    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"));
        }

        iDraftUseraccountNewMapper.delete(new QueryWrapper<DraftUseraccountNew>().eq("userid", areaid));
        iDraftUserinfoMapper.delete(new QueryWrapper<DraftUserinfo>().eq("USERID", areaid));

        Useraccount organ = iUseraccountMapper.selectOne(new QueryWrapper<Useraccount>().eq("userid", areaid));
        //错误 #58783
        organ.setModifystatus(1);
        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 delete(Long areaid, HttpServletRequest request) {
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        Useraccount org = iUseraccountMapper.selectOne(new QueryWrapper<Useraccount>().eq("userid", areaid));
        //校验
        if (org.getUsertype() != 5) {
            List<Arearole> list2 = iArearoleMapper.selectList(new QueryWrapper<Arearole>().eq("userid", areaid));
            if (CollectionUtils.isNotEmpty(list2)) {
                return AjaxResult.error(Constants.Error_Code_Design, MessageType.ORGAN_ERROR_CODE_001.getCode(), request.getHeader("Accept-Language"));
            }

            List<Useraccount> list = iUseraccountMapper.selectList(new QueryWrapper<Useraccount>()
                    .eq("parentuserid", areaid)
                    .eq("accountstatus", 4)
                    .in("usertype", 3, 4)
            );
            if (CollectionUtils.isNotEmpty(list)) {
                return AjaxResult.error(Constants.Error_Code_Design, MessageType.ORGAN_ERROR_CODE_002.getCode(), request.getHeader("Accept-Language"));
            }
            if (org.getUsertype() == 4) {
                list = iUseraccountMapper.selectList(new QueryWrapper<Useraccount>()
                        .eq("usertype", 5)
                        .eq("broker", areaid)
                        .eq("accountstatus", 4));
                if (CollectionUtils.isNotEmpty(list)) {
                    return AjaxResult.error(Constants.Error_Code_Design, MessageType.ORGAN_ERROR_CODE_003.getCode(), request.getHeader("Accept-Language"));
                }
            } else {
                list = iUseraccountMapper.selectList(new QueryWrapper<Useraccount>()
                        .eq("parentuserid", areaid)
                        .eq("accountstatus", 4)
                        .eq("usertype", 5));
                if (CollectionUtils.isNotEmpty(list)) {
                    return AjaxResult.error(Constants.Error_Code_Design, MessageType.ORGAN_ERROR_CODE_003.getCode(), request.getHeader("Accept-Language"));
                }
            }
        } else {
            List<Taaccount> taList = iTaaccountMapper.selectList(new QueryWrapper<Taaccount>()
                    .eq("userid", areaid)
                    .gt("currentbalance", 0)
            );
            if (CollectionUtils.isNotEmpty(taList)) {
                return AjaxResult.error(Constants.Error_Code_Design, MessageType.ORGAN_ERROR_CODE_004.getCode(), request.getHeader("Accept-Language"));
            }
            List<Tradeposition> tpList = iTradepositionMapper.queryAmount(areaid);
            if (CollectionUtils.isNotEmpty(tpList)) {
                return AjaxResult.error(Constants.Error_Code_Design, MessageType.ORGAN_ERROR_CODE_005.getCode(), request.getHeader("Accept-Language"));
            }
        }

        log.info("收到用户注销请求：" + areaid.toString());
        org.setAccountstatus(6);
        org.setModifierid(systemmanager.getAutoid());
        org.setModifytime(new Date());
        org.setCanceltime(new Date());
        iUseraccountMapper.update(org, new QueryWrapper<Useraccount>().eq("userid", org.getUserid()));

        Userinfo ui = iUserinfoMapper.selectOne(new QueryWrapper<Userinfo>().eq("userid", areaid));
        ui.setUserstatus(2);
        iUserinfoMapper.update(ui, new QueryWrapper<Userinfo>().eq("userid", ui.getUserid()));
        //注销 所有账户
        List<Systemmanager> admin = iSystemmanagerMapper.selectList(new QueryWrapper<Systemmanager>().eq("areauserid", areaid));
        if (admin != null && !admin.isEmpty()) {
            admin.forEach(p -> {
                p.setManagerstatus(2);//停用
                iSystemmanagerMapper.updateById(p);
            });
        }
        //删除登录关联关系
        iUserauthinfoMapper.delete(new QueryWrapper<Userauthinfo>().eq("userid", areaid));
        //写入日志
        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);

        log.info("用户注销更新完成：" + areaid.toString());
        List<Loginaccount> las = iLoginaccountMapper.selectList(new QueryWrapper<Loginaccount>()
                .eq("userid", org.getUserid())
                .eq("loginstatus", 1));

        if (CollectionUtils.isNotEmpty(las)) {
            Loginaccount la = new Loginaccount();
            la.setUserid(org.getUserid());
            la.setLoginstatus(3);//无效
            iLoginaccountMapper.update(la, new QueryWrapper<Loginaccount>().eq("loginid", la.getLoginid()));

            NotifyMI1.LoginAccChangeNtf.Builder builder = NotifyMI1.LoginAccChangeNtf.newBuilder();
            Common.MessageHead.Builder hd = Common.MessageHead.newBuilder();
            PublicMI1.NotifyHead.Builder nhd = PublicMI1.NotifyHead.newBuilder();
            nhd.setNtfMode(0);
            hd.setFunCode(FunCodeConstants.FunCode_Trade_LoginAccChangeNtf);
            hd.setClientTime(System.currentTimeMillis());
            builder.setNtfHeader(nhd);
            builder.setHeader(hd);
            las.forEach(p -> {
                NotifyMI1.LoginAccChange.Builder lab = NotifyMI1.LoginAccChange.newBuilder();
                lab.setChangeType(SysEnums.AccountOperateTypeEnum.DEL.getType());
                lab.setLoginId(p.getLoginid());
                builder.addLoginAccChange(lab);
            });
            byte[] body = ProtoHelper.getNTAS(builder.build().toByteArray(),
                    FunCodeConstants.FunCode_Trade_LoginAccChangeNtf);
            rabbitTemplate.send(SysConstants.RabbitNtfKey,
                    new Message(body, new MessageProperties()));

            log.info("用户注销发送登录账户变更通知：" + areaid.toString());
        }

        // 发送用户注销消息给中心\银行接口
        List<Taaccount> tas = iTaaccountMapper.selectList(new QueryWrapper<Taaccount>()
                .eq("userid", org.getUserid())
                .eq("ismain", 1));
        iSendMsgService.sendM2BUnregistCustomerInfo(tas);

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

    @Override
    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"));
        }
        Useraccount org = iUseraccountMapper.selectOne(new QueryWrapper<Useraccount>().eq("userid", areaid));
        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("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 (ar == null) {
                return AjaxResult.error(Constants.Error_Code_Design, MessageType.ORGAN_ERROR_CODE_009.getCode(), request.getHeader("Accept-Language"));
            }
        }
        // todo allocated != null && allocated == 1
        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);

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

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult addsonorgan(OrganAddSonOrganParam param, HttpServletRequest request) {
        // #6597 管理端】不管是后台注册还是客户端注册，身份证号填写的那一栏，如果涉及到输入字母X，需要固定只能输入大写字母
        if (param != null && StringUtils.isNotBlank(param.getCardnum())) {
            param.setCardnum(param.getCardnum().toUpperCase());
        }

        //校验唯一性
        List<Useraccount> c2 = iUseraccountMapper.selectList(new QueryWrapper<Useraccount>().eq("userid", createUserid(param.getParentuserid(), param.getUserid())));
        if (CollectionUtils.isNotEmpty(c2)) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.ORGAN_ERROR_CODE_010.getCode(), request.getHeader("Accept-Language"));
        }
        // 机构开户证件号码是否唯一
        String areacardflag = iCommonService.getSystemParam(Constants.REDIS_HEADER_SYSPARAM, Constants.SYSPARAM_CARD_NO);
        //验证证件号码是否存在
        Boolean checkFlag1 = iCommonService.checkOranCardNumOrMobile(3, 1, null, EncryptionUtils.encryptByAES(param.getCardnum().trim()));
        if (areacardflag != null && areacardflag.equals("1") && checkFlag1) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.ORGAN_ERROR_CODE_011.getCode(), request.getHeader("Accept-Language"));
        }
        List<WskhBlacklist> wskhBlacklists = iWskhBlacklistMapper.selectList(new QueryWrapper<WskhBlacklist>()
                .eq("CARDTYPE", param.getCardtypeid())
                .eq("CARDNUM", EncryptionUtils.encryptByAES(param.getCardnum().trim())));
        if (!CollectionUtils.isEmpty(wskhBlacklists)) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.ORGAN_ERROR_CODE_012.getCode(), request.getHeader("Accept-Language"));
        }
        if (param.getUserinfotype() == 2) {
            //机构类型为企业需 名称唯一
            List<Userinfo> c3 = iUserinfoMapper.selectList(new QueryWrapper<Userinfo>()
                    .eq("customername", param.getCustomername().trim())
                    .eq("userinfotype", 2));
            if (CollectionUtils.isNotEmpty(c3)) {
                return AjaxResult.error(Constants.Error_Code_Design, MessageType.ORGAN_ERROR_CODE_013.getCode(), request.getHeader("Accept-Language"));
            }
        }
        List<Systemmanager> list = iSystemmanagerMapper.selectList(new QueryWrapper<Systemmanager>().eq("logincode", param.getLogincode().trim()));
        if (CollectionUtils.isNotEmpty(list)) {
            return AjaxResult.error(Constants.Error_Code_Design, MessageType.ORGAN_ERROR_CODE_014.getCode(), request.getHeader("Accept-Language"));
        }
        try {
            Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
            if (param.getUsertype() == 3) {
                addSonOrgan(param, systemmanager);
            } else {
                // todo 新增经纪人
                // userAccountSercive.addBroker(param, rsp.getUser());
            }
        } catch (Exception e) {
            log.info("新增失败，失败原因：" + e);
            throw new GlobalException(Constants.Error_Code_Design, MessageType.ORGAN_ERROR_CODE_015.getCode(), request.getHeader("Accept-Language"));
        }
        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult editsonorgan(OrganAddSonOrganParam param, HttpServletRequest request) {
        // #6597 管理端】不管是后台注册还是客户端注册，身份证号填写的那一栏，如果涉及到输入字母X，需要固定只能输入大写字母
        if (param != null && StringUtils.isNotBlank(param.getCardnum())) {
            param.setCardnum(param.getCardnum().toUpperCase());
        }

        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        Useraccount organ = iUseraccountMapper.selectOne(new QueryWrapper<Useraccount>().eq("userid", param.getUserid()));

        DraftUseraccountNew dua = new DraftUseraccountNew();
        BeanUtils.copyProperties(organ, dua);

        //校验
        String card = param.getCardnum();
        if (StringUtils.isNotBlank(card)) {
            card = EncryptionUtils.encryptByAES(card);
            List<Userinfo> uiList = iUserinfoMapper.selectList(new QueryWrapper<Userinfo>()
                    .eq("usertype", 5)
                    .eq("cardnum", card)
                    .eq("userid", param.getUserid()));
            if (CollectionUtils.isNotEmpty(uiList)) {
                String sysparm = iCommonService.getSysparmById(Constants.SYSPARAM_CARD_NOTWO);
                if (sysparm == null || "1".equals(sysparm)) {
                    return AjaxResult.error(Constants.Error_Code_Design, MessageType.ORGAN_ERROR_CODE_011.getCode(), request.getHeader("Accept-Language"));
                }
            }
        }
        String mobile = param.getMobile();
        if (StringUtils.isNotBlank(mobile)) {
            mobile = EncryptionUtils.encryptByAES(param.getMobile());
            List<Userinfo> uiList = iUserinfoMapper.selectList(new QueryWrapper<Userinfo>()
                    .eq("usertype", 5)
                    .eq("mobile", mobile)
                    .eq("userid", param.getUserid()));
            if (CollectionUtils.isNotEmpty(uiList)) {
                return AjaxResult.error(Constants.Error_Code_Design, MessageType.ORGAN_ERROR_CODE_016.getCode(), request.getHeader("Accept-Language"));
            }
        }

        dua.setAccountname(param.getAccountname());
        dua.setModifierid(systemmanager.getAutoid());
        dua.setModifytime(new Date());
        dua.setModifystatus(param.getModifystatus());
        if (param.getParentuserid() != null) {
            dua.setParentuserid(param.getParentuserid());
        }
        //todo 子机构新增未引入 更新是否实名、newContent字段 -- dyp
        //dua.setHasauth(param.getHasauth());
        dua.setNewcontent(JsonUtils.object2Json(dua));
        dua.setOldcontent(JsonUtils.object2Json(organ));
        iDraftUseraccountNewMapper.insert(dua);

        organ.setModifystatus(param.getModifystatus());
        organ.setModifierid(systemmanager.getAutoid());
        organ.setModifytime(new Date());
        iUseraccountMapper.update(organ, new QueryWrapper<Useraccount>().eq("userid", organ.getUserid()));


        Userinfo ui = iUserinfoMapper.selectOne(new QueryWrapper<Userinfo>().eq("userid", param.getUserid()));
        DraftUserinfo dui = new DraftUserinfo();
        BeanUtils.copyProperties(ui, dui);
        dui.setAddress(param.getAddress());
        dui.setBiznature(param.getBiznature());
        dui.setCardbackphotourl(param.getCardbackphotourl());
        dui.setCardfrontphotourl(param.getCardfrontphotourl());
        dui.setCardnum(param.getCardnum());
        dui.setCardtypeid(param.getCardtypeid());
        dui.setCityid(param.getCityid());
        dui.setCompany(param.getCompany());
        if (StringUtils.isBlank(param.getCustomername())) {
            //取useraccount里的accountname
            dui.setCustomername(param.getAccountname());
        } else {
            dui.setCustomername(param.getCustomername());
        }
        dui.setDistrictid(param.getDistrictid());
        dui.setCountryid(param.getCountryid());
        dui.setEmail(param.getEmail());
        dui.setMobile(param.getMobile());
        dui.setModifierid(systemmanager.getAutoid());
        dui.setModifiertime(new Date());
        dui.setContactname(param.getContactname());
        dui.setPostalcode(param.getPostalcode());
        dui.setProvinceid(param.getProvinceid());
        dui.setQq(param.getQq());
        dui.setRemark(param.getRemark());
        dui.setSex(param.getSex());
        dui.setTelphone(param.getTelphone());
        dui.setWechat(param.getWechat());
        dui.setLegalpersonname(param.getLegalpersonname());
        dui.setLegalcardbackphotourl(param.getLegalcardbackphotourl());
        dui.setLegalcardfrontphotourl(param.getLegalcardfrontphotourl());
        dui.setAttachment1(param.getAttachment1());
        dui.setAttachment2(param.getAttachment2());
        dui = (DraftUserinfo) SensitiveEncryptUtil.sensitiveEncrypt(dui, null);
        iDraftUserinfoMapper.insert(dui);

        //资金账户配置变更  配置业务
        /*if (param.getConfig() != null && param.getConfig().getAccountid() != null) {
            //子账户为  投资者机构所有  关联给投资者使用，，

            //此处变更时，记为投资者变更  ，变更表userid填入投资者的userid
            DraftTaAccountConfig config = new DraftTaAccountConfig();
            config.setAccountid(param.getConfig().getAccountid());
            config.setUserid(organ.getUserid());
            config.setNewcontent(JSonHelp.object2Json(param.getConfig()));
            commonDao.merge(config);
        }*/
        JSONObject jsonObj = JSONObject.parseObject(JSONObject.toJSONString(dua));
        JSONObject jsonObjUi = JSONObject.parseObject(JSONObject.toJSONString(dui));
        if (organ.getUsertype() == 3 || organ.getUsertype() == 4) {
            if (systemmanager.getReletype() == 1) {
                if (organ.getUsertype() == 3)
                    systemmanagerService.writeOperateLog(SysConstants.PART_CODE_ORGZ_ZJG, "修改子机构id=" + organ.getUserid() + "并提交审核", systemmanager, null, jsonObjUi.toString(), jsonObj.toString());
                else
                    systemmanagerService.writeOperateLog(SysConstants.PART_CODE_ORGZ, "修改经纪人id=" + organ.getUserid() + "并提交审核", systemmanager, null, jsonObjUi.toString(), jsonObj.toString());
            } else {
                if (organ.getUsertype() == 3)
                    systemmanagerService.writeOperateLog(SysConstants.PART_CODE_ORGZ_ZJG, "修改子机构id=" + organ.getUserid() + "并提交审核", systemmanager, null, jsonObjUi.toString(), jsonObj.toString());
                else
                    systemmanagerService.writeOperateLog(SysConstants.PART_CODE_ORGZ, "修改经纪人id=" + organ.getUserid() + "并提交审核", systemmanager, null, jsonObjUi.toString(), jsonObj.toString());
            }
        } else if (organ.getUsertype() == 5) {
            systemmanagerService.writeOperateLog(SysConstants.PART_INVESTOR_MANAGE, "修改交易商id=" + organ.getUserid() + "并提交审核", systemmanager, null, jsonObjUi.toString(), jsonObj.toString());
        }
        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public AjaxResult edit(OrganAddSonOrganParam param, HttpServletRequest request) {
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        Useraccount organ = iUseraccountMapper.selectOne(new QueryWrapper<Useraccount>().eq("userid", param.getUserid()));

        //当为特许经销商时，因为新增特许经销商的时候，默认加了一个名称一样的报价商，现在修改特许经销商名称时，报价商名称也一起修改
        if (organ.getUsertype() == 2) {
            List<Arearole> ar = iArearoleMapper.selectList(new QueryWrapper<Arearole>()
                    .eq("roletype", 13)
                    .eq("userid", organ.getUserid()));
            if (CollectionUtils.isNotEmpty(ar)) {
                Quoter qt = iQuoterMapper.selectOne(new QueryWrapper<Quoter>()
                        .eq("areauserid", organ.getUserid())
                        .eq("quotername", organ.getAccountname()));
                if (Objects.nonNull(qt)) {
                    qt.setQuotername(param.getAccountname()); //修改为修改后的机构名称
                    qt.setModifytime(new Date());
                    qt.setModifierid(systemmanager.getAutoid());
                    iQuoterMapper.updateById(qt);
                }
            }
        }
        if (param.getAccountstatus() != null && param.getAccountstatus().equals(2)) {
            organ.setAccountstatus(param.getAccountstatus());
        }
        organ.setAccountname(param.getAccountname());
        organ.setModifierid(systemmanager.getAutoid());
        organ.setModifytime(new Date());
        if (param.getRefereeuserid() != null) {
            organ.setRefereeuserid(param.getRefereeuserid());
        }
        iUseraccountMapper.update(organ, new QueryWrapper<Useraccount>().eq("userid", organ.getUserid()));

        String sysparm = iCommonService.getSysparmById(Constants.SYSPARAM_CARD_NOTWO);

        Userinfo ui = iUserinfoMapper.selectOne(new QueryWrapper<Userinfo>().eq("userid", param.getUserid()));
        if (ui.getCardnum() != null && !ui.getCardnum().equals(EncryptionUtils.encryptByAES(param.getCardnum()))) {
            String card = param.getCardnum();
            if (StringUtils.isNotBlank(card)) {
                card = EncryptionUtils.encryptByAES(param.getCardnum());
                List<Userinfo> uiList = iUserinfoMapper.selectList(new QueryWrapper<Userinfo>()
                        .eq("cardnum", card)
                        .eq("userid", param.getUserid()));
                if (CollectionUtils.isNotEmpty(uiList)) {
                    if ((sysparm == null) || ("1".equals(sysparm))) {
                        return AjaxResult.error(Constants.Error_Code_Design, MessageType.ORGAN_ERROR_CODE_011.getCode(), request.getHeader("Accept-Language"));
                    }
                }
            }
        }
        if (ui.getUserinfotype() == 2 && !ui.getCustomername().equals(param.getCustomername().trim())) {
            //机构类型为企业需 名称唯一
            List<Userinfo> uiList = iUserinfoMapper.selectList(new QueryWrapper<Userinfo>()
                    .eq("customername", param.getCustomername().trim())
                    .eq("userinfotype", 2));
            if (CollectionUtils.isNotEmpty(uiList)) {
                return AjaxResult.error(Constants.Error_Code_Design, MessageType.ORGAN_ERROR_CODE_017.getCode(), request.getHeader("Accept-Language"));
            }
        }
        ui.setAddress(param.getAddress());
        ui.setBiznature(param.getBiznature());
        ui.setCardbackphotourl(param.getCardbackphotourl());
        ui.setCardfrontphotourl(param.getCardfrontphotourl());
        ui.setCardnum(param.getCardnum());
        ui.setCardtypeid(param.getCardtypeid());
        ui.setCityid(param.getCityid());
        ui.setCountryid(param.getCountryid());
        ui.setCompany(param.getCompany());
        ui.setCustomername(param.getCustomername());
        ui.setDistrictid(param.getDistrictid());
        ui.setEmail(param.getEmail());
        ui.setMobile(param.getMobile());
        ui.setModifierid(systemmanager.getAutoid());
        ui.setModifiertime(new Date());
        ui.setContactname(param.getContactname());
        ui.setPostalcode(param.getPostalcode());
        ui.setProvinceid(param.getProvinceid());
        ui.setQq(param.getQq());
        ui.setRemark(param.getRemark());
        ui.setSex(param.getSex());
        ui.setTelphone(param.getTelphone());
        ui.setLegalcardbackphotourl(param.getLegalcardbackphotourl());
        ui.setLegalpersonname(param.getLegalpersonname());
        ui.setLegalcardfrontphotourl(param.getLegalcardfrontphotourl());
        ui.setWechat(param.getWechat());
        ui.setAttachment1(param.getAttachment1());
        ui.setAttachment2(param.getAttachment2());

        ui = (Userinfo) SensitiveEncryptUtil.sensitiveEncrypt(ui, null);
        iUserinfoMapper.update(ui, new QueryWrapper<Userinfo>().eq("userid", ui.getUserid()));

        if (organ.getUsertype().intValue() != 4) {
            Systemmanager admin = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>()
                    .eq("logincode", param.getLogincode()));
            if (admin != null && !admin.getUsername().equals(param.getUsername())) {
                admin.setUsername(param.getUsername());
                iSystemmanagerMapper.updateById(admin);
            }
        }

        if (param.getUsertype() == 2 || param.getUsertype() == 3) {
            try {
                Userinfo current = iUserinfoMapper.selectOne(new QueryWrapper<Userinfo>().eq("userid", param.getUserid()));
                List<Taaccount> list = iTaaccountMapper.selectList(new QueryWrapper<Taaccount>()
                        .eq("userid", current.getUserid())
                        .eq("ismain", 1));
                if (CollectionUtils.isNotEmpty(list)) {
                    list.forEach(p -> {
                        iSendMsgService.sendCustomerInfo(current, p.getAccountid(), "2", 3);
                    });
                }
            } catch (Exception e) {
                log.error("保存子机构修改信息发送消息失败，失败原因：" + Arrays.toString(e.getStackTrace()));
            }
        }

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

    @Override
    public PageResult<UserAccountRspResult> queryaudit(UserAccountReqParam param, HttpServletRequest request) {
        IPage<UserAccountRspResult> page = new Page<>(param.getPageNum(), param.getPageSize());
        IPage<UserAccountRspResult> userAccountVos = iUseraccountMapper.querySonOrganPage(page, param);
        PageResult<UserAccountRspResult> pageResult = new PageResult<>();
        pageResult.setCode(Constants.Success_Code_Design);
        pageResult.setMessage(AjaxResult.dealMsg(MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language")));
        pageResult.setPages(userAccountVos.getPages());
        pageResult.setCurrent(userAccountVos.getCurrent());
        pageResult.setTotal(userAccountVos.getTotal());
        pageResult.setPageSize(userAccountVos.getSize());
        pageResult.setData(userAccountVos.getRecords());
        return pageResult;
    }

    @Override
    public AjaxResult auditorganson(Long userid, Long auditflag, String msg, HttpServletRequest request) {
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        Useraccount entity = iUseraccountMapper.selectOne(new QueryWrapper<Useraccount>().eq("userid", userid));
        Integer accountstatus;
        List<Systemmanager> smList = iSystemmanagerMapper.selectList(new QueryWrapper<Systemmanager>().eq("areauserid", userid));
        if (auditflag != 1) {
            accountstatus = SysEnums.AccountStatusEnum.REFUSED.getType();
            //审核拒绝时，登录账号状态改为停用
            for (Systemmanager sm : smList) {
                sm.setManagerstatus(2);
                iSystemmanagerMapper.update(sm, new QueryWrapper<Systemmanager>().eq("autoid", sm.getAutoid()));
            }

            iDraftUseraccountNewMapper.delete(new QueryWrapper<DraftUseraccountNew>().eq("userid", userid));
            iDraftUserinfoMapper.delete(new QueryWrapper<DraftUserinfo>().eq("USERID", userid));
        } else {
            accountstatus = SysEnums.AccountStatusEnum.NORMAL.getType();
            for (Systemmanager sm : smList) {
                if (sm.getManagerstatus() != 1) {
                    sm.setManagerstatus(1);
                    iSystemmanagerMapper.update(sm, new QueryWrapper<Systemmanager>().eq("autoid", sm.getAutoid()));
                }
            }
        }

        entity.setAccountstatus(accountstatus);
        entity.setModifierid(systemmanager.getAutoid());
        entity.setModifytime(new Date());
        entity.setAudituserid(systemmanager.getAutoid());
        entity.setAuditremark(msg);
        iUseraccountMapper.update(entity, new QueryWrapper<Useraccount>().eq("userid", entity.getUserid()));

        systemmanagerService.writeOperateLog(SysConstants.PART_CODE_ORGZ_ZJG, "审核确认id=" + entity.getUserid(), systemmanager, null, null, null);

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

    @Override
    public PageResult<UserAccountRspResult> queryOrganSonModify(UserAccountReqParam param, HttpServletRequest request) {
        IPage<UserAccountRspResult> page = new Page<>(param.getPageNum(), param.getPageSize());
        IPage<UserAccountRspResult> userAccountVos = iUseraccountMapper.queryOrganSonModify(page, param);
        userAccountVos.getRecords().forEach(a -> {

        });
        PageResult<UserAccountRspResult> pageResult = new PageResult<>();
        pageResult.setCode(Constants.Success_Code_Design);
        pageResult.setMessage(AjaxResult.dealMsg(MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language")));
        pageResult.setPages(userAccountVos.getPages());
        pageResult.setCurrent(userAccountVos.getCurrent());
        pageResult.setTotal(userAccountVos.getTotal());
        pageResult.setPageSize(userAccountVos.getSize());
        pageResult.setData(userAccountVos.getRecords());
        return pageResult;
    }

    @Override
    public PageResult<OrganSonTransferResult> queryOrganSonTransfer(OrganSonTransferParam param, HttpServletRequest request) {
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));
        if (systemmanager.getReletype() != 1) {
            param.setMemberuserid(systemmanager.getAreauserid());
        }
        IPage<OrganSonTransferResult> page = new Page<>(param.getPageNum(), param.getPageSize());
        IPage<OrganSonTransferResult> userAccountVos = iUseraccountMapper.queryOrganSonTransfer(page, param);
        userAccountVos.getRecords().forEach(a -> {
            a.setOutparentusername(iUseraccountMapper.selectOrganName(a.getAreauserid()));
            a.setInuseridname(iUseraccountMapper.selectOrganName(a.getNewareauserid()));
            if (param.getTransferusertype() == 1) {
                a.setOutmemberusername(iUseraccountMapper.selectOrganName(a.getMemberuserid()));
                a.setOutinvestorname(iUseraccountMapper.selectOrganName(a.getInvestoruserid()));
                a.setInmemberusername(iUseraccountMapper.selectOrganName(a.getNewmemberuserid()));
            }
        });

        PageResult<OrganSonTransferResult> pageResult = new PageResult<>();
        pageResult.setCode(Constants.Success_Code_Design);
        pageResult.setMessage(AjaxResult.dealMsg(MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language")));
        pageResult.setPages(userAccountVos.getPages());
        pageResult.setCurrent(userAccountVos.getCurrent());
        pageResult.setTotal(userAccountVos.getTotal());
        pageResult.setPageSize(userAccountVos.getSize());
        pageResult.setData(userAccountVos.getRecords());
        return pageResult;
    }

    @Override
    public AjaxResult executeTransfer(HttpServletRequest request) {
        Marketrun mr = iMarketrunMapper.selectOne(new QueryWrapper<Marketrun>().eq("marketid", 0L));
        if (mr != null && mr.getRunstatus().equals(SysEnums.MarketRunStatus.SYSTEM_RECKON_SUCCESS.getCode())) {
            // 系统日终处理成功时执行，用于自动执行出错时手动执行
            organSonTransferExecute();
            return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"));
        }
        return AjaxResult.error(Constants.Error_Code_Design, MessageType.MESSAGE_ERROR_CODE_SYSTEM018.getCode(), request.getHeader("Accept-Language"));
    }

    @Override
    public AjaxResult backtranfor(Long autoid, HttpServletRequest request) {
        Investortransfer div = iInvestortransferMapper.selectOne(new QueryWrapper<Investortransfer>().eq("autoid", autoid));
        if (div != null && div.getTransferstatus().equals(1)) {
            div.setTransferstatus(4);
            iInvestortransferMapper.updateById(div);
        }
        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"));
    }

    @Override
    public AjaxResult<OrganSelectResult> querySonOrganPageByLevel(Integer subarealevel, String searchcode, HttpServletRequest request) {
        List<OrganSelectResult> results = iUseraccountMapper.querySonOrganPageByLevel(subarealevel, searchcode);
        return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM001.getCode(), request.getHeader("Accept-Language"), results);
    }

    @Override
    public AjaxResult organSonTransferAdd(OrganSonTransferAddParam vo, HttpServletRequest request) {
        // 转移交易商（单个+批量）、转移子机构
        Systemmanager systemmanager = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("LOGINCODE", iCommonService.getUserLoginCode(request)));

        Marketrun mr = iMarketrunMapper.selectOne(new QueryWrapper<Marketrun>().eq("marketid", 0L));
        //申请，不转移
        Investortransfer it = new Investortransfer();
        it.setAreauserid(vo.getOutparentuserid());
        it.setBrokeruserid(vo.getOutborkerid());
        it.setInvestoruserid(vo.getOutinvestor());
        it.setMemberuserid(vo.getOutmemberuserid());
        it.setNewareauserid(vo.getInuserid());
        it.setNewmemberuserid(vo.getInmemberuserid());
        it.setNewbrokeruserid(vo.getInborker());
        it.setOperatorid(systemmanager.getAutoid().toString());
        it.setTransfertype(vo.getDiversiontype());
        it.setCreatetime(new Date());
        it.setTransferstatus(1);
        it.setTransfermode(vo.getTransfermode());

        if (mr != null && mr.getRunstatus() != 26) {
            iInvestortransferMapper.insert(it);
            return AjaxResult.success(Constants.Success_Code_Design, MessageType.MESSAGE_CODE_SYSTEM021.getCode(), request.getHeader("Accept-Language"));
        } else {
            // 执行中
            it.setTransferstatus(5);
            iInvestortransferMapper.insert(it);

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

    private void organSonTransferExecute() {
        log.info("------开始转移--start---------------------------");
        // 1:单个转移(交易商)  2:批量转移(交易商) 3:子机构转移
        List<Investortransfer> list = iInvestortransferMapper.selectList(new QueryWrapper<Investortransfer>().eq("transferstatus", 1));
        for (Investortransfer investortransfer : list) {
            investorTransfer2(investortransfer);
        }
        log.info("------转移---------end--------------------");
    }

    private void investorTransfer2(Investortransfer it) {
        log.info("---转移------------------------{}", it.getAutoid());
        try {
            Systemmanager user = iSystemmanagerMapper.selectOne(new QueryWrapper<Systemmanager>().eq("autoid", it.getOperatorid()));
            // 1:单个转移(交易商)  2:批量转移(交易商) 3:子机构转移
            switch (it.getTransfertype()) {
                case 1:
                case 2:
                    log.info("---转移交易商------------------------{}", it.getAutoid());
                    investorTransfer(it, user);
                    break;
                case 3:
                    log.info("---转移子机构------------------------{}", it.getAutoid());
                    organSonTransfer(it);
                    break;
                default:
                    break;
            }
            it.setUpdatetime(new Date());
            iInvestortransferMapper.updateById(it);
        } catch (Exception e) {
            log.error("当前转移失败，失败id：" + it.getAutoid() + ",失败原因：" + e.getMessage());

            it.setTransferstatus(3);
            it.setRemark(e.getMessage().substring(0, 250));
            it.setUpdatetime(new Date());
            iInvestortransferMapper.updateById(it);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    public void organSonTransfer(Investortransfer it) {
        if (it.getAreauserid().equals(it.getNewareauserid())) {
            it.setTransferstatus(3);
            it.setRemark("转出转入机构相等");
            return;
        }

        Useraccount outUser = iUseraccountMapper.selectOne(new QueryWrapper<Useraccount>().eq("userid", it.getAreauserid()));
        Useraccount inUser = iUseraccountMapper.selectOne(new QueryWrapper<Useraccount>().eq("userid", it.getNewareauserid()));

        // 转移前的Subarealevelpath
        String oldSubPath = outUser.getSubarealevelpath();
        // 整体转移后的 Subarealevelpath
        String newSubPath = inUser.getSubarealevelpath() + outUser.getUserid() + ",";

        // 更新所有下级子机构及交易商的memberuserid、parentuserid、Subarealevelpath
        List<Useraccount> list = iUseraccountMapper.queryUser("," + outUser.getUserid() + ",");

        if (it.getTransfermode() != null && it.getTransfermode().equals(1)) {
            // 转移下级
            for (Useraccount ua : list) {
                if (ua.getUserid().equals(outUser.getUserid())) {
                    // 忽略自己
                    continue;
                }

                if (ua.getParentuserid().equals(outUser.getUserid())) {
                    // 更新当前子机构的直属下级的上级
                    ua.setParentuserid(inUser.getUserid());
                }

                ua.setMemberuserid(inUser.getMemberuserid());
                // levelpath 用转入机构的path替换转出机构的path
                String descPath = ua.getSubarealevelpath().replace(oldSubPath, inUser.getSubarealevelpath());
                ua.setSubarealevelpath(descPath);

                iUseraccountMapper.update(ua, new QueryWrapper<Useraccount>().eq("userid", ua.getUserid()));
            }

            // 转移下级时，删除转出机构分润分组内的下一级子机构
            iUseraccountMapper.deleteSubAreaGroupDetailByUserid(outUser.getUserid());

        } else if (it.getTransfermode() != null && it.getTransfermode().equals(2)) {
            // 整体转移
            for (Useraccount ua : list) {
                ua.setMemberuserid(inUser.getMemberuserid());

                if (ua.getUserid().equals(outUser.getUserid())) {
                    // 转移的当前子机构更新上级为经纪会员
                    ua.setParentuserid(inUser.getUserid());
                    // 更新 Subarealevelpath
                    ua.setSubarealevelpath(newSubPath);
                } else {
                    // 转移的下级子机构及交易商
                    String descPath = ua.getSubarealevelpath().replace(oldSubPath, newSubPath);
                    ua.setSubarealevelpath(descPath);
                }

                iUseraccountMapper.update(ua, new QueryWrapper<Useraccount>().eq("userid", ua.getUserid()));
            }

            // 整体转移时，删除自己所在分润组的记录
            iSubareagroupdetailMapper.delete(new QueryWrapper<Subareagroupdetail>().eq("userid", outUser.getUserid()));
        }
        it.setTransferstatus(2);
        it.setRemark("执行成功");
    }

    @Transactional(rollbackFor = Exception.class)
    public void investorTransfer(Investortransfer it, Systemmanager user) {
        Long in_id = it.getNewareauserid() == null ? it.getNewmemberuserid() : it.getNewareauserid();
        if ((it.getTransfertype() - 1) == 0) {
            // 1:单个转移
            Useraccount investor = iUseraccountMapper.selectOne(new QueryWrapper<Useraccount>().eq("userid", it.getInvestoruserid()));
            if (investor.getParentuserid().equals(in_id)) {
                it.setTransferstatus(3);
                it.setRemark("投资者不能在同一机构下转移");
                return;
            }

            //会员转时也不用，只有所平台转移才需要检验
            //因为所属会员不变更，不影响单据
            if (user.getReletype() != 1 && investor.getMemberuserid().compareTo(user.getAreauserid()) != 0) {
                it.setTransferstatus(3);
                it.setRemark("不能转移非会员下级投资者");
                return;
            } else {
                String chkmsg = checkInvestorTransfor(it.getInvestoruserid());
                if (chkmsg != null) {
                    it.setTransferstatus(3);
                    it.setRemark(chkmsg);
                    return;
                }
            }

            if (investor.getModifystatus() == 3 || investor.getModifystatus() == 4) {
                investor.setModifystatus(1);
                iDraftUseraccountNewMapper.delete(new QueryWrapper<DraftUseraccountNew>().eq("userid", it.getInvestoruserid()));
            }

            Useraccount in = iUseraccountMapper.selectOne(new QueryWrapper<Useraccount>().eq("userid", in_id));
            investor.setParentuserid(in.getUserid());
            investor.setMemberuserid(in.getMemberuserid());
            investor.setBroker(it.getNewbrokeruserid());
            investor.setSubarealevelpath(in.getSubarealevelpath() + investor.getUserid() + ",");
            iUseraccountMapper.update(investor, new QueryWrapper<Useraccount>().eq("userid", in.getUserid()));
        } else if ((it.getTransfertype() - 1) == 1) {
            // 2:批量转移
            Long out_id = it.getAreauserid() == null ? it.getMemberuserid() : it.getAreauserid();

            if (out_id.equals(in_id)) {
                it.setTransferstatus(3);
                it.setRemark("投资者不能在同一机构下转移");
                return;
            }
            List<Useraccount> list = iUseraccountMapper.getInvestorTODiversion(it.getMemberuserid(), it.getAreauserid(), it.getBrokeruserid());
            if (CollectionUtils.isNotEmpty(list)) {
                Useraccount in = iUseraccountMapper.selectOne(new QueryWrapper<Useraccount>().eq("userid", in_id));
                if (user.getReletype() != 1 && in.getMemberuserid().compareTo(user.getAreauserid()) != 0) {
                    it.setTransferstatus(3);
                    it.setRemark("不能转移非本会员下级投资者");
                    return;
                }

                for (Useraccount ua : list) {
                    if (user.getReletype() == 1) {
                        String chkmsg = checkInvestorTransfor(ua.getUserid());
                        if (chkmsg != null) {
                            it.setTransferstatus(3);
                            it.setRemark(chkmsg);
                            return;
                        }
                    }
                    if (ua.getModifystatus() == 3 || ua.getModifystatus() == 4) {
                        ua.setModifystatus(1);
                        iDraftUseraccountNewMapper.delete(new QueryWrapper<DraftUseraccountNew>().eq("userid", it.getInvestoruserid()));
                    }
                    ua.setParentuserid(in.getUserid());
                    ua.setMemberuserid(in.getMemberuserid());
                    ua.setBroker(it.getNewbrokeruserid());
                    ua.setSubarealevelpath(in.getSubarealevelpath() + ua.getUserid() + ",");
                    iUseraccountMapper.update(ua, new QueryWrapper<Useraccount>().eq("userid", ua.getUserid()));
                }
            }
        }
        it.setTransferstatus(2);
        it.setRemark("执行成功");
    }

    private String checkInvestorTransfor(Long userid) {
        //管理端-投资者管理 > 投资者批量转移： 没有做市收益权模式持仓单时，可以进行投资者转移
        List<Taaccount> tas = iTaaccountMapper.selectList(new QueryWrapper<Taaccount>().eq("userid", userid));
        if (tas != null && !tas.isEmpty()) {
            Integer count = iTradepositionMapper.queryPositionByUserid(userid);
            if (count > 0) {
                return "要转移的投资者存在做市收益权持仓单,不能转移";
            }
        }
        return null;
    }

    public void addSonOrgan(OrganAddSonOrganParam param, Systemmanager systemmanager) {
        String lPwd = iCommonService.getSystemParam(Constants.REDIS_HEADER_SYSPARAM, SysConstants.SYSPARAM_CODE_DEFAULT_PWD);
        Useraccount organ = new Useraccount();
        String userid = createUserid(param.getParentuserid(), param.getUserid());
        organ.setUserid(Long.valueOf(userid));
        //资金账户  多币种----
        List<Enumdicitem> li = iEnumdicitemMapper.selectList(new QueryWrapper<Enumdicitem>()
                .eq("enumdiccode", "currency")
                .eq("enumitemstatus", 1));

        BankSystemconfig config = iBankSystemconfigMapper.selectOne(new QueryWrapper<BankSystemconfig>().eq("CONFIGID", SysConstants.BANK_CONFIG_ACTIVATION));
        lPwd = EncryptionUtils.encryptSHA(lPwd);
        List<Taaccount> taaccounts = new ArrayList<>();
        for (Enumdicitem enumdicitem : li) {
            String manageid = redisServiceUtil.getCacheMapValue(Constants.REDIS_HEADER_SYSPARAM, "001");
            Long accountno = Long.valueOf(manageid + CommonUtil.addZero(String.valueOf(idGeneratorUtils.getGeneratorID(Taaccount.class)), 9));
            Taaccount ac = new Taaccount();
            ac.setAccountid(accountno);
            ac.setUserid(organ.getUserid());
            ac.setPassword(lPwd);
            ac.setCurrencyid(enumdicitem.getEnumitemname());
            //资金账号是否需要激活
            if (config != null && config.getValidstatus() == 1 && config.getConfigvalue().equals("1") && ac.getIsmain() == 1) {
                ac.setTradestatus(SysEnums.TradeStatusEnum.TOBEACTIVATE.getType());
            } else {
                ac.setTradestatuschangetime(new Date()); //激活时间
            }
            if (1 == enumdicitem.getEnumitemname()) {
                organ.setReckonaccountid(accountno);
            }
            ac.setRelateduserid(organ.getUserid());
            ac.setRelatedaccountstatus(1);
            taaccounts.add(ac);
            iTaaccountMapper.insert(ac);

            Userreckonaccount ura = new Userreckonaccount();
            ura.setCurrencyid(ac.getCurrencyid());
            ura.setUserid(ac.getUserid());
            ura.setReckonaccountid(ac.getAccountid());
            ura.setUpdatetime(new Date());
            ura.setDefaultaccounttype(1);
            iUserreckonaccountMapper.insert(ura);
        }

        organ.setRefernum(generateReferNum());
        String sysparm = iCommonService.getSysparmById("063");
        Useraccount parent = iUseraccountMapper.selectOne(new QueryWrapper<Useraccount>().eq("userid", param.getParentuserid()));
        organ.setUsertype(3);

        if (sysparm == null) {
            organ.setAccountstatus(4);
        } else if (sysparm.equals("1")) {
            organ.setAccountstatus(2);
        } else {
            organ.setAccountstatus(4);
        }
        organ.setCreatetradedate(iMarketrunMapper.selectOne(new QueryWrapper<Marketrun>().eq("marketid", 0L)).getTradedate());
        organ.setParentuserid(param.getParentuserid());
        organ.setMemberuserid(parent.getMemberuserid());
        organ.setCreatorid(systemmanager.getAutoid());
        organ.setCreatetime(new Date());
        organ.setModifierid(systemmanager.getAutoid());
        organ.setModifytime(new Date());
        organ.setAccountname(param.getAccountname());
        organ.setSubarealevelpath(parent.getSubarealevelpath() + organ.getUserid() + ",");
        iUseraccountMapper.insert(organ);

        Userinfo ui = new Userinfo();
        ui.setCustomername(organ.getAccountname());
        ui.setUsertype(3);
        ui.setUserstatus(1);
        ui.setOpenmode(1);
        ui.setCreatetime(new Date());
        ui.setCreatorid(systemmanager.getAutoid());
        ui.setUserid(organ.getUserid());
        ui.setUserinfotype(param.getUserinfotype());
        ui.setCustomername(param.getCustomername());
        ui.setCompany(param.getCompany());
        ui.setBiznature(param.getBiznature());
        ui.setCardtypeid(param.getCardtypeid());
        ui.setCardnum(param.getCardnum());
        ui.setCardfrontphotourl(param.getCardfrontphotourl());
        ui.setCardbackphotourl(param.getCardbackphotourl());
        ui.setLegalpersonname(param.getLegalpersonname());
        ui.setLegalcardfrontphotourl(param.getLegalcardfrontphotourl());
        ui.setLegalcardbackphotourl(param.getLegalcardbackphotourl());
        ui.setContactname(param.getContactname());
        ui.setSex(param.getSex());
        ui.setMobile(param.getMobile());
        ui.setTelphone(param.getTelphone());
        ui.setProvinceid(param.getProvinceid());
        ui.setCityid(param.getCityid());
        ui.setDistrictid(param.getDistrictid());
        ui.setAddress(param.getAddress());
        ui.setPostalcode(param.getPostalcode());
        ui.setEmail(param.getEmail());
        ui.setQq(EncryptionUtils.encryptByAES(param.getQq()));
        ui.setWechat(param.getWechat());
        ui.setRemark(param.getRemark());
        ui.setAttachment1(param.getAttachment1());
        ui.setAttachment2(param.getAttachment2());
        ui = (Userinfo) SensitiveEncryptUtil.sensitiveEncrypt(ui, null);
        iUserinfoMapper.insert(ui);

        //管理员账户
        Systemmanager us = new Systemmanager();
        us.setLogincode(param.getLogincode());
        us.setAreauserid(organ.getUserid());
        us.setUsername(StringUtils.isNotBlank(param.getUsername()) ? param.getUsername() : organ.getAccountname());
        us.setReletype(3);
        us.setManagerstatus(1);
        us.setLoginfailnum(0);
        us.setLoginstatus(1);
        us.setIsdefault(1);
        us.setUploginid(systemmanager.getAutoid());
        us.setModifytime(new Date());
        us.setPassword(EncryptionUtils.encryptSHA(us.getLogincode() + lPwd));
        us.setPwdexpdate(new Date());
        us.setSystemtype(2);
        us.setManagertype(1);
        iSystemmanagerMapper.insert(us);

        Object l = redisServiceUtil.getCacheMapValue(Constants.REDIS_HEADER_SYSPARAM, "002");
        if (l == null || !"2".equals(l.toString())) {
            Roleuser ur = new Roleuser();
            ur.setRoleid(1L);
            ur.setManagerid(us.getAutoid());
            ur.setRoletype(3);
            iRoleuserMapper.insert(ur);
        }
        //子机构
        if (organ.getUsertype() == 3) {
            Roleuser ur = new Roleuser();
            ur.setRoleid(12L);
            ur.setManagerid(us.getAutoid());
            ur.setRoletype(3);
            iRoleuserMapper.insert(ur);
        }

        Integer reletype = systemmanager.getReletype();
        String menucode = "";
        if (reletype.equals(1))
            menucode = "M00400220000";
        else
            menucode = SysConstants.PART_CODE_ORGZ_ZJG;
        JSONObject jsonObj = JSONObject.parseObject(JSONObject.toJSONString(param));
        if (organ.getUsertype() == 2) {
            systemmanagerService.writeOperateLog(SysConstants.PART_CODE_ORGZ, "新增机构id=" + organ.getUserid(), systemmanager, null, "{}", jsonObj.toString());
        } else if (organ.getUsertype() == 3) {
            systemmanagerService.writeOperateLog(menucode, "新增子机构id=" + organ.getUserid(), systemmanager, null, "{\"userid\":" + organ.getUserid() + "}", jsonObj.toString());
        } else if (organ.getUsertype() == 4) {
            systemmanagerService.writeOperateLog(menucode, "新增经纪人id=" + organ.getUserid(), systemmanager, null, "{\"userid\":" + organ.getUserid() + "}", jsonObj.toString());
        } else if (organ.getUsertype() == 5) {
            systemmanagerService.writeOperateLog(SysConstants.PART_INVESTOR_OPEN, "新增投资者id=" + organ.getUserid(), systemmanager, null, "{\"userid\":" + organ.getUserid() + "}", jsonObj.toString());
        }

        try {
            for (int i = 0; i < taaccounts.size(); i++) {
                iSendMsgService.sendCustomerInfo(ui, taaccounts.get(i).getAccountid(), "1", 3);
                iSendMsgService.sendUserChangeMsg(taaccounts.get(i).getAccountid(), taaccounts.get(i).getUserid(),
                        SysEnums.UserOperateTypeEnum.ADD.getType(),
                        SysEnums.AccountOperateTypeEnum.ADD.getType(),
                        SysEnums.NotifyModeEnum.UNICAST.getType());
            }
        } catch (Exception e) {
            log.error("新增子机构发送消息失败；失败原因：" + Arrays.toString(e.getStackTrace()));
        }
    }

    private DetailAfterResult getModifyInvestorDetail(Long userid) {
        DetailAfterResult detailResult = new DetailAfterResult();
        UserAccountDetailVo userAccountDetailVo = iUseraccountMapper.selectNewDetail(userid);
        detailResult.setUserAccountDetailVo(userAccountDetailVo);
        UserinfoDetailVo userinfoDetailVo = iUserinfoMapper.getUserinfoNewDetail(userid);
        userinfoDetailVo.setPathName(userinfoDetailVo.getCountryName() + userinfoDetailVo.getPathName());
        detailResult.setUserinfoDetailVo(userinfoDetailVo);
        return detailResult;
    }

    private DetailBeforeResult getUserAccountDetail(Long userid, OrganSonDetailResult result) {
        DetailBeforeResult detailResult = new DetailBeforeResult();
        UserAccountDetailVo userAccountDetailVo = iUseraccountMapper.selectDetail(userid);
        detailResult.setUserAccountDetailVo(userAccountDetailVo);
        UserinfoDetailVo userinfoDetailVo = iUserinfoMapper.getUserinfoDetail(userid);
        userinfoDetailVo.setPathName(userinfoDetailVo.getCountryName() + userinfoDetailVo.getPathName());
        detailResult.setUserinfoDetailVo(userinfoDetailVo);
        //开户地址
        if (userAccountDetailVo.getUsertype() != 5) {
            //如果是经纪会员、会员子机构、经纪人，则查询网上开户地址
            WskhOpenaccountconfig config = iWskhOpenaccountconfigMapper.selectOne(new QueryWrapper<WskhOpenaccountconfig>()
                    .eq("configtype", 59));
            if (null != config && null != config.getConfigvalue()) {
                result.setOpenUrl(config.getConfigvalue());
            }
            //移动端开户地址
            WskhOpenaccountconfig config1 = iWskhOpenaccountconfigMapper.selectOne(new QueryWrapper<WskhOpenaccountconfig>()
                    .eq("configtype", 60));
            if (null != config1 && null != config1.getConfigvalue()) {
                result.setMobileUrl(config1.getConfigvalue());
            }
            //微信开户地址
            WskhOpenaccountconfig config2 = iWskhOpenaccountconfigMapper.selectOne(new QueryWrapper<WskhOpenaccountconfig>()
                    .eq("configtype", 65));
            if (null != config2 && null != config2.getConfigvalue()) {
                result.setWeixinUrl(config2.getConfigvalue());
            }
            //三方开户地址
            WskhOpenaccountconfig config3 = iWskhOpenaccountconfigMapper.selectOne(new QueryWrapper<WskhOpenaccountconfig>()
                    .eq("configtype", 66));
            if (null != config3 && null != config3.getConfigvalue()) {
                result.setSanfangUrl(config3.getConfigvalue());
            }
        }
        return detailResult;
    }

    private String createUserid(Long pid, Long userid) {
        String memid = pid.toString().substring(0, 4);
        return memid + CommonUtil.addZero(userid.toString(), 4);
    }

    private String generateReferNum() {
        //系统参数996 为2时，推荐码只有数字；
        String sysparm = iCommonService.getSysparmById("996");
        if (sysparm != null && !sysparm.equals("2")) {
            return CommonUtil.getUuid2();
        }
        return CommonUtil.getUuid();
    }
}
