注册流程笔记

这篇博客详细记录了用户注册过程,从接入层的ajax事件开始,经过RxdaiInvokeServlet、AuthService.registerByPhoneForOneshop,到service层的业务逻辑处理,包括NoTX.call、RegisterLogicProvider和AbstractRegisterLogic.register方法。注册过程中涉及UserPersistHelper进行用户持久化操作,以及邀请信息处理、用户认证激活等步骤。最后,成功注册后通过LoginSupport.loginForRegister自动登录用户中心。
摘要由CSDN通过智能技术生成

接入层

简单时序图表示下

Created with Raphaël 2.1.0 RxdaiInvokeServlet RxdaiInvokeServlet AuthService AuthService KeystoneService KeystoneService api.AuthService api.AuthService NoTX NoTX holder holder doInvoke LoginSupport.loginForRegister registerByPhoneForOneshop ApiResult<RegisterResp> getService(api.AuthService.class).register(map) ApiResult<RegisterResp> register ApiResult call ApiResult RegisterResp

1-1 ajax事件

auth.do?method=registerByPhoneForOneshop

在web.xml中找到RxdaiInvokeServlet,

        //1. new holder
        HttpInvokeHolder invokeHolder = new HttpInvokeHolder(subtime, httpRequest, httpResponse) ;

        //2. do invoke
        doInvoke(methodName, invokeHolder) ;

//      logger.info("response status={}", httpResponse.getStatus()) ;
        if(httpResponse.getStatus()==200){
        }

1-2 RxdaiInvokeServlet.doInvoke

            //1. found service holder
            ServiceHolder serviceHolder = InvokeManager.foundServiceHolder(serviceName) ;
            if(serviceHolder==null) throw new InvokeNotFoundException("unfound service=["+serviceName+"] @ "+invokerName) ;

            //2. found method holder
            methodHolder = serviceHolder.getMethodHolder(methodName) ;
            if(methodHolder==null) throw new InvokeNotFoundException("unfound method=["+methodName+"] from service=["+serviceName+"] @ "+invokerName) ;

            ServiceApiStat.stat(serviceName, methodName);
            //check state.
            checkState(methodHolder, invokeHolder) ;

            if(!invokeHolder.isOk()) return ;

            //3. extract invoke args
            invokeArgs = HttpInvokeHelper.extractInvokeParameters(methodHolder.getArgsNames(), methodHolder.getArgsMarkers(), invokeHolder.getHttpRequest()) ;

            //4. register
            InvokeManager.registerInvokeHolder(invokeHolder) ;

            //5. do invoke.
            methodHolder.getMethod().invoke(serviceHolder.getService(), invokeArgs) ;

1-3 查看对应方法AuthService.registerByPhoneForOneshop

目的是通过远程调用获取RegisterResp (registerDispatch(req, phone);),

注:推荐人id :UCode

 //新版一站式理财注册的功能
 @Override
 public User registerByPhoneForOneshop(String md5Pwd, String phone, String phoneCode, String smsRandom, String channel,String inviteUsername,String inviteUCode) {
  try {
   // 验证码校验
   SMSCodeSupport.checkSMSCode2(SMSCodeType.SMS_REGISTER, phoneCode, smsRandom, InvokeChannel.PC);
   //SMSmanages.getSMSInstance().checkValidCode(phoneCode, SMSmanages.SMS_REGISTER, smsRandom);
   phone = CommonUtils.emptyIfNull(phone);

   if (!ParameterCheckUtils.checkPhone(phone)) {
    throw MessageException.newMessageException("手机号码格式错误");
   }

   int invUserid=getInviteUserid(inviteUCode);

   RegisterReq req = new RegisterReq();
   {
    req.setPhone(phone);
    req.setPassword(md5Pwd);
    req.setRegisterType(RegisterReq.REGISTER_TYPE_ONESHOP_PHONE);
    req.setChannel(channel);
    req.setInviteUserName(inviteUsername);
    req.setInviteUserid(invUserid);
   }
   RegisterResp resp = registerDispatch(req, phone);

   User user = resp.getUser();
   String ip = HttpInvokeHelper.getRequestIP();
   LoginSupport.loginForRegister(phone, md5Pwd, ip);
   return user;
  } catch (Exception e) {
   DBClient.getDBClient().rollback();
   throw CommonUtils.convertRuntimeException(e);
  }
 }

1-4 之后registerDispatch远程调用

//新版注册远程调用
private static RegisterResp registerDispatch(RegisterReq req, String lock) {
        synchronized (lock.intern()) {
            HttpServletRequest request = HttpInvokeHelper.getHttpServletRequest();
            String addip = HttpInvokeHelper.getRequestIP() ;
            String cpsLable = CookieHelper.getCookie(Constant.ADS_FOLLOW_KEY, request);// 从cookie中获取广告追踪
            {
                req.setCpsLable(cpsLable);
                req.setIp(addip);
                req.setEntryChannel(InvokeChannel.PC.name());
            }
            Map<String, String> map;
            try {
                map = BeanUtils.describe(req);
            } catch (Exception e) {
                throw CommonUtils.convertRuntimeException(e);
            }
            ApiResult<RegisterResp> ar = KeystoneServiceFactory.getService(com.touna.user.api.AuthService.class).register(map);
            if (!ar.isOK()) {
                throw MessageException.newMessageException(ar.getMessage());
            } else if (ar.getResult().getUser() != null && ar.getResult().getUser().getUserid() > 0) {// 注册成功,且已经生成了user记录清掉相关cookie
                CookieHelper.clearCookie(Constant.ADS_FOLLOW_KEY, request, HttpInvokeHelper.getHttpServletResponse());
                CookieHelper.clearCookie(Constant.CHARGE_CARD_KEY, request, HttpInvokeHelper.getHttpServletResponse());
            }
            return ar.getResult();
        }
    }

1-5 具体的还是交给Keystone,调用AuthService.register返回ApiResult

如果成功清掉cookie,不浪费cookie空间,好习惯

KeystoneServiceFactory.getService(com.touna.user.api.AuthService.class).register(map);

1-6 如果成功,之后跳转自动登录到用户中心(LoginSupport.loginForRegister(phone, md5Pwd, ip);)。

//注册时进行登录
public static void loginForRegister(String loginName, String loginPwd, String ip) {
        Map<String, Object> holder = new HashMap<>(4, 1.0f) ;
        login(loginName, loginPwd, ip, holder) ;
        LoginTocken tocken = CommonUtils.get(holder, LoginTocken.LOGIN_TOCKEN_TAG) ;
        HttpInvokeHelper.setInvokeResult(tocken);
    }

service层

服务层时序示意图

Created with Raphaël 2.1.0 NoTX NoTX holder holder holder holder RegisterLogicProvider RegisterLogicProvider AbstractRegisterLogic AbstractRegisterLogic UserPersistHelper UserPersistHelper call RegisterResp call register returnUser check doregister 持久化操作

com.*.user.api(对应server是user-server)包下AuthServiceImpl.register

AuthServiceImpl

public ApiResult<RegisterResp> register(Map<String, String> map)
  {
    final RegisterReq req = (RegisterReq)Bean2MapUtils.populate(map, RegisterReq.class);
    return NoTX.call(new TxCallable()
    {
      public RegisterResp call(DBClient dbClient) throws Exception {
        RegisterResp resp = RegisterLogicProvider.getLogic(req).register(dbClient, req);
        if ((resp.getUser() != null) && (resp.getUser().getUserid() > 0L))
        {
          if (StringUtil.isNotEmpty(resp.getUser().getPhone())) {
            UserAreaWriter.getInstance().write(resp.getUser());
          }

          UserLogHelper.logRegister(resp.getUser().getUserid(), req.getRegisterType(), req.toString(), req.getIp());
        }
        return resp;
      }
    });
  }

2-1 代码简化,目的是返回ApiResult

    final RegisterReq req = (RegisterReq)Bean2MapUtils.populate(map, RegisterReq.class);
    return NoTX.call(new TxCallable() resp);

2-1-1 NoTX.call方法如下

public static <T> ApiResult<T> call(TxCallable<T> handler)
  {
    ApiResult result = new ApiResult();
    DBClient dbClient = DBClientFactory.getDefaultDBClient();
    try {
      Object t = handler.call(dbClient);
      result.setResult(t);
    } catch (MessageException e) {
      return result.error(e.getMessage());
    } catch (Throwable e) {
      logger.info("NoTx call() with:", e);
      throw CommonUtils.convertRuntimeException(e);
    }

    return result.ok();
  }

2-1-2 重点还是handler.call。

TxCallable里也没有实现,只是接口,handler.call这里写法没见过,回调? handler.call在AuthServiceImpl.register里;

public RegisterResp call(DBClient dbClient) throws Exception {
        RegisterResp resp = RegisterLogicProvider.getLogic(req).register(dbClient, req);
        if ((resp.getUser() != null) && (resp.getUser().getUserid() > 0L))
        {
          if (StringUtil.isNotEmpty(resp.getUser().getPhone())) {
            UserAreaWriter.getInstance().write(resp.getUser());
          }

          UserLogHelper.logRegister(resp.getUser().getUserid(), req.getRegisterType(), req.toString(), req.getIp());
        }
        return resp;
      }

RegisterLogic依次用到如下几个类

2-1-2-1 RegisterLogicProvider
RegisterLogicProvider.getLogic(req).register(dbClient, req);

先看看RegisterLogicProvider类中的getLogic方法,是从req中取出注册类型,这里是手机注册,

public class RegisterLogicProvider {
    public static IRegisterLogic getLogic(RegisterReq req) {
        IRegisterLogic logic = map.get(req.getRegisterType());
        if (logic == null) {
            throw CommonUtils.illegalStateException("Can not found suitable register logic for register type=" + req.getRegisterType());
        }
        return logic;
    }
}
2-1-2-1-2 看看IRegisterLogic,

是抽象接口,没有register的实现,继续找发现AbstractRegisterLogic里实现了register,负责对RegisterResp 的处理,其他具体regiserLogic继承AbstractRegisterLogic

regiserLogic类的关系

Created with Raphaël 2.1.0 holder holder RegisterLogicProvider RegisterLogicProvider IRegisterLogic IRegisterLogic AbstractRegisterLogic AbstractRegisterLogic OneshopEmailRegisterLogic OneshopEmailRegisterLogic call register implements extend

继续看AbstractRegisterLogic类

public abstract class AbstractRegisterLogic
  implements IRegisterLogic{
  protected Logger logger = LoggerFactory.getLogger(getClass());

  public RegisterResp register(DBClient dbClient, RegisterReq req)
  {
    this.logger.debug("Begin register user! RegisterReq={}", req);

    Date now = SystemTime.getNow();

    User u = returnUser(dbClient, now, req);

    UserCheckField[] fields = getCheckFields(req);

    UserCheckHelper.checkParameter(fields, u);

    checkUserMore(u);

    UserCheckHelper.checkDuplicate(dbClient, fields, u);

    RegisterResp resp = doRegister(dbClient, req, u, now);

    this.logger.debug("End register user! RegisterResp={}", resp.getUser());

    return resp;
  }

  private User returnUser(DBClient dbClient, Date now, RegisterReq req)
  {
   //见后文
  }

  protected void checkUserMore(User u)
  {
  }

  protected void assemble(DBClient dbClient, RegisterReq req, User user)
  {
    //见后文
  }

  protected RegisterResp doRegister(DBClient dbClient, RegisterReq req, User u, Date now)
  {
    //见后文
  }
}
2-1-2-1-2-1 关于AbstractRegisterLogic.register方法,简化下代码分几步处理的
//1 先得到user对象
User u = returnUser(dbClient, now, req);
//2 检查user对象
UserCheckHelper.*(dbClient, fields, u);
//3 进行注册得到RegisterResp 对象
RegisterResp resp = doRegister(dbClient, req, u, now);

看下AbstractRegisterLogic.returnUser,返回值为user

private User returnUser(DBClient dbClient, Date now, RegisterReq req)
  {
    User user = new User();

    user.setChannel(req.getChannel());

    user.setPassword(req.getPassword());

    assemble(dbClient, req, user);

    Pair pair = InviteHelper.getInviteInfo(dbClient, req);
    if (((Integer)pair.getFirst()).intValue() == 0) {
      pair = InviteHelper.getInviteInfoWithPreReg(dbClient, req.getPhone());
    }
    user.setInviteUserid(((Integer)pair.getFirst()).intValue());
    req.setInviteUserName((String)pair.getSecond());

    if (user.getChannel() == null) {
      user.setChannel("");
    }
    String time = TimeUtils.stringOfUnixtimestamp(now);
    String ip = req.getIp();
    user.setTypeid(2);
    user.setCreditRating(3);
    user.setAddtime(time);
    user.setAddip(ip);
    user.setUptime(time);
    user.setUpip(ip);
    user.setLasttime(time);
    user.setLastip(ip);
    user.setQq(req.getQq() == null ? "" : req.getQq());
    return user;
  }

调用了AbstractRegisterLogic.assemble(dbClient, req, user);这里未用到dbClient

protected void assemble(DBClient dbClient, RegisterReq req, User user)
  {
    for (UserCheckField field : getCheckFields(req))
      UserFieldProcessorProvider.getProcessor(field).setValueToUser(req, user);
  }

其中UserFieldProcessorProvider:用户字段校验器提供类 ,看下UserFieldProcessorProvider.getProcessor方法。

public static UserFieldProcessor getProcessor(UserCheckField field) {
        UserFieldProcessor processor = map.get(field);
        if (processor == null) {
            throw CommonUtils.illegalStateException("Can not found suitable user field processor for field type=" + field);
        }
        return processor;
    }

UserFieldProcessor:用户字段类,抽象接口中有setValueToUser方法,实现往下找

public abstract interface UserFieldProcessor
{
  //其他方法略,见文末
  public abstract void setValueToUser(RegisterReq paramRegisterReq, User paramUser);
}

参考loginType的设计,AbstractUserFieldProcessor实现抽象接口,其他具体用户字段如PhoneProcessor 再继承AbstractUserFieldProcessor并分别重写setValueToUser,代码举例如下。

public abstract class AbstractUserFieldProcessor
  implements UserFieldProcessor

public class PhoneProcessor extends AbstractUserFieldProcessor(){
  public void setValueToUser(RegisterReq req, User u)
  {
    u.setPhone(req.getPhone());
    u.setPhoneStatus(1);
  }
}

UserField类的关系

Created with Raphaël 2.1.0 UserFieldProcessorProvider UserFieldProcessorProvider UserFieldProcessor UserFieldProcessor AbstractUserFieldProcessor AbstractUserFieldProcessor PhoneProcessor PhoneProcessor getProcess UserFieldProcessor impl extend

assemble操作是把req中的参数填充到user中,继续

Pair pair = InviteHelper.getInviteInfo(dbClient, req);

其中InviteHelper:注册时,邀请信息处理帮助类,这里操作是对有邀请码的用户,我这里没有邀请码,具体InviteHelper.getInviteInfo的code见文末。

2-1-2-3-1-2 检查用户,略
2-1-2-3-1-3 注册AbstractRegisterLogic.doRegister,
 protected RegisterResp doRegister(DBClient dbClient, RegisterReq req, User u, Date now)
  {
    int uid = UserPersistHelper.persistUser(dbClient, u);

    UserPersistHelper.persistUserExtend(dbClient, uid, u.getInviteUserid(), req.getInviteUserName(), req.getEntryChannel());

    UserPersistHelper.persistAccount(dbClient, uid);

    UserPersistHelper.persistNewbie(dbClient, uid);

    AuthActive active = UserPersistHelper.dealEmailAuth(dbClient, u, now);

    UserPersistHelper.dealAdsFollow(dbClient, u, req.getCpsLable());

    UserPersistHelper.activeChargeCard(dbClient, uid, req.getChargeCard());

    SinglesDayUtils.registerSuccess(dbClient, u, req.getIp());

    return new RegisterResp(u, active, now);
  }

关于UserPersistHelper:用户持久化帮助类
方法简述如下,例UserPersistHelper.persistUser,其他持久化操作间文末。

//持久化用户记录 见dw_user表
public static int persistUser(DBClient dbClient, User u) {
        //存在尚未认证的邮箱
        boolean ignorePersitEmail = existUnauthorizedEmail(u);

        //持久化前,把用户的邮箱信息置空
        String email = u.getEmail();
        if (ignorePersitEmail) {
            u.setEmail(null);
        }

        //持久化
        int uid = (int) dbClient.insertObject(u);
        u.setUserid(uid);

        //持久化后,把用户的邮箱信息加上
        if (ignorePersitEmail) {
            u.setEmail(email);
        }

        return uid;
    }

上述是注册用户的持久化操作,继续看

AuthActive active = UserPersistHelper.dealEmailAuth(dbClient, u, now);

AuthActive 是认证激活类,判断邮箱是否需要激活,更新持久化。
继续UserPersistHelper.dealAdsFollow(dbClient, u, req.getCpsLable());删除广告
UserPersistHelper.activeChargeCard(dbClient, uid, req.getChargeCard());激活充值卡,活动结束后屏蔽掉。

马上要注册成功了!SinglesDayUtils.registerSuccess(dbClient, u, req.getIp());
关于SinglesDayUtils:各种优惠和奖励在这个里面操作。节日过后就删除。这种做法耦合较高,目前做法是直接更新接口,少改user-server包。
registerSuccess方法会做一些过滤,最后添加未过期的活动给用户。

public static void registerSuccess(DBClient dbClient, User user, String ip) {
        if (user != null) {
            long addtime = Long.parseLong(user.getAddtime());
            // 活动期间,手机注册用户,送1万体验金
            boolean organBlacklist = GrayManager.isGray(Constants.GRAY_KEY_ORGANIZATION_BLACKLIST, user.getUserid());//资金机构黑名单
            if (isInactiviyTime(addtime) && user.getPhoneStatus() == User.USER_AUDIT_STATUS_NOW && !organBlacklist) {
                if (filterUserByUtmSource(dbClient, user.getUserid(), addtime)) {
                    logger.info("filterUserByUtmSource uid={}, addtime={}", new Object[]{user.getUserid(), addtime});
                    return;
                }
                addVirtualCash(dbClient, user.getUserid(), 9, 10000, addtime, ip);
            }
        }
    }

addVirtualCash:查询那些活动适用,写入数据库。

2-1-2-2 TxCallable.call UserAreaWriter
 UserAreaWriter 没有write方法,继续找其父类AutoWriter,可以看到write是将resp.getUser()插入队列未,这里用队列是为了提高速度(用户体验):把不需要立即执行的动作放到消息队列,优先完成其他操作,在高并发模式下可以提高速度
private final Queue<T> queue = new ConcurrentLinkedQueue();
public abstract class AutoWriter<T>
{
  public void write(T t) {
    logger.info("Queue offer: " + t.toString());
    this.queue.offer(t);
  }
}
2-1-2-3 UserLogHelper
 UserLogHelper是记录日志操作类,logRegister方法是记录注册操作日志,不做代码展示。

最后LoginSupport.loginForRegister

HttpInvokeHelper.setInvokeResult(tocken);

续-如何判断新注册用户的?
后台暂时没找到,前端对比发现如下请求

Request URL:http://oneshop.touna.cn/account.oneshop.do?method=loadBasicUserInfo&subtime=1461584120258

web.xml中找下account.oneshop.do对应servlet没变,好吧
找到OneshopAccountSupport中有loadBasicUserInfo方法
account.oneshop.do有2次,第一次没有参数,第二次有新手引导的信息,推测是ajax判断。


持久层

3-1 DBClient 只是封装,继续追

public abstract interface DBClient extends MapperClientApi
{
}

3-2 MapperClientApi

public abstract interface MapperClientApi extends BaseClientApiExt
{
  public abstract <T> T findObjectValue(Class<?> paramClass, String paramString1, String paramString2, Object[] paramArrayOfObject);

  public abstract <T> T findObjectFields(Class<?> paramClass, String paramString1, String paramString2, Object[] paramArrayOfObject);

  public abstract <T> T findObject(Class<?> paramClass, String paramString, Object[] paramArrayOfObject);

  public abstract <T> T lockObjectFields(Class<T> paramClass, String paramString1, String paramString2, Object[] paramArrayOfObject);

  public abstract <T> T lockObject(Class<T> paramClass, String paramString, Object[] paramArrayOfObject);

  public abstract <E> List<E> queryObjectField(Class<?> paramClass, String paramString1, String paramString2, Object[] paramArrayOfObject);

  public abstract <T> List<T> queryObjectFields(Class<T> paramClass, String paramString1, String paramString2, Object[] paramArrayOfObject);

  public abstract <T> List<T> queryObject(Class<T> paramClass, String paramString, Object[] paramArrayOfObject);

  public abstract <T> long countObject(Class<T> paramClass, String paramString, Object[] paramArrayOfObject);

  public abstract <T> int updateObjectFields(Class<T> paramClass, String paramString1, String paramString2, Object[] paramArrayOfObject);

  public abstract int updateObjectFields(Object paramObject, String paramString1, String paramString2, Object[] paramArrayOfObject);

  public abstract int updateObject(Object paramObject, String paramString, Object[] paramArrayOfObject);

  public abstract long insertObject(Object paramObject);

  public abstract long insertObjectFields(Object paramObject, String paramString);

  public abstract int deleteObject(Class<?> paramClass, String paramString, Object[] paramArrayOfObject);

  public abstract <T> int[] batchUpdateObjects(String paramString1, String paramString2, List<T> paramList);

  public abstract <T> int[] batchUpdateClasses(Class<T> paramClass, String paramString1, String paramString2, List<Object[]> paramList);

  public abstract <T> int[] batchInsertObjects(List<T> paramList);

  public abstract <T> int[] batchInsertObjectFields(String paramString, List<T> paramList);

  public abstract <T> int insertOnDuplicateKey(Object paramObject, String paramString1, String paramString2, Object[] paramArrayOfObject);

  public abstract <T> int[] batchOnDuplicateKey(String paramString1, String paramString2, List<T> paramList);

  public abstract <T> int[] batchOnDuplicateKeyUpdate(String paramString1, String paramString2, List<T> paramList, List<Object[]> paramList1);
}

未用到的代码块在这里

TxCallable

public abstract interface TxCallable<T>
{
  public abstract T call(DBClient paramDBClient)
    throws Exception;
}

UserAreaWriter

/**
 * 根据手机号获取省市区,并写入user表
 */
public class UserAreaWriter extends AutoWriter<User> {

    private static UserAreaWriter INSTANCE = new UserAreaWriter();

    public static UserAreaWriter getInstance() {
        return INSTANCE;
    }

    public UserAreaWriter() {
        super();
    }

    @Override
    public void doWrite() {
        List<User> users = pollAll();
        if (!users.isEmpty()) {
            for (User user : users) {
                //根据手机号更新省市县信息
                if (user != null && StringUtils.isNotBlank(user.getPhone()) && user.getUserid() > 0) {//手机号不为空
                    try {
                        UserLocaleHelper.updateLocaleInfoByPhone(DBClientAccessor.getTounaClient(), (int) user.getUserid(), user.getPhone());
                    } finally {
                        DBClientFactory.releaseClient();
                    }
                }
            }
        }
    }

UserFieldProcessor

public abstract interface UserFieldProcessor
{
  public abstract void checkParameter(User paramUser);

  public abstract void checkDuplicate(DBClient paramDBClient, User paramUser);

  public abstract void checkParameter(String paramString);

  public abstract void checkDuplicate(DBClient paramDBClient, String paramString);

  public abstract void checkDuplicateExceptUid(DBClient paramDBClient, String paramString, int paramInt);

  public abstract UserCheckField getCheckFiled();

  public abstract String getValueFromUser(User paramUser);

  public abstract void setValueToUser(RegisterReq paramRegisterReq, User paramUser);
}

InviteHelper

public class InviteHelper
{
  private static final Pair<Integer, String> EMPTY = new Pair(Integer.valueOf(0), "");

  //获取当前邀请人的信息
  public static Pair<Integer, String> getInviteInfo(DBClient dbClient, RegisterReq req)
  {
    int uid = req.getInviteUserid();
    if (uid > 0) {
      User u = (User)dbClient.findObjectFields(User.class, "userid,username", "userid=?", new Object[] { Integer.valueOf(uid) });
      if (u != null) {
        return fromInviteUser(u);
      }

    }

    String uname = req.getInviteUserName();
    if (StringUtil.isEmpty(uname)) {
      return EMPTY;
    }

    User u = UserHelper.findUserByUsername(dbClient, uname, "userid");
    if (u != null) {
      return fromInviteUser(u);
    }
    if (ParameterCheckUtils.checkPhone(uname)) {
      u = UserHelper.findUserByPhone(dbClient, uname, "userid");
      if (u != null) {
        return fromInviteUser(u);
      }

    }

    if (ParameterCheckUtils.checkEmail(uname)) {
      u = UserHelper.findUserByEmail(dbClient, uname, "userid");
      if (u != null) {
        return fromInviteUser(u);
      }
    }

    return EMPTY;
  }
}

UserPersistHelper.persistUserExtend

// 持久化UserExtend记录,如果存在邀请人,更新邀请人已邀请的人数统计

public static void persistUserExtend(DBClient dbClient, int uid, int inviteUid, String inviteUname) {
        UserExtend userExtend = new UserExtend();
        userExtend.setUserid(uid);
        if (inviteUid > 0) {
            userExtend.setInviteUserid(inviteUid);
            userExtend.setInviteUserName(inviteUname);
        }
        dbClient.insertObject(userExtend);

        //更新推荐人的总推荐人数(+1)
        if (inviteUid > 0) {
            dbClient.update("update dw_user_extend set total_invite_user = total_invite_user + 1 where user_id =?", inviteUid);
        }
    }

UserPersistHelper.persistAccount

public static void persistAccount(DBClient dbClient, int uid) {
        Account account = new Account();
        account.setUserid(uid);
        dbClient.insertObject(account);
    }

UserPersistHelper.persistNewbie

public static void persistNewbie(DBClient dbClient, int uid) {
        Newbie newbie = new Newbie();
        newbie.setUserid(uid);
        dbClient.insertObject(newbie);
    }

IRegisterLogic

public abstract interface IRegisterLogic
{
  public abstract RegisterResp register(DBClient paramDBClient, RegisterReq paramRegisterReq);

  public abstract UserCheckField[] getCheckFields(RegisterReq paramRegisterReq);

  public abstract int getRegisterType();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值