| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 |
- package com.ytpm.handle;
- import cn.hutool.core.util.IdUtil;
- import cn.hutool.core.util.RandomUtil;
- import cn.hutool.core.util.StrUtil;
- import com.ytpm.agent.enums.UserStatusEnum;
- import com.ytpm.app.enums.LoginType;
- import com.ytpm.app.model.YtDyzLoginRecord;
- import com.ytpm.app.model.YtDyzUser;
- import com.ytpm.app.param.LoginParam;
- import com.ytpm.app.view.WxDefaultConfig;
- import com.ytpm.general.RepMessage;
- import com.ytpm.general.Result;
- import com.ytpm.util.IPUtil;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.util.CollectionUtils;
- import javax.servlet.http.HttpServletRequest;
- import java.util.Date;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Objects;
- /**
- * <p>登陆模板</p>
- * 兼容多登陆模式及风控校验
- * <p>需重写方法:<br>
- * 1.登陆参数校验 validateParams
- * 2.根据设备及渠道ID查询用户 queryUserByDeviceAndDitch
- * 3.获取登陆默认配置 getLoginConfig
- * 4.根据登陆参数获取系统用户 queryDyzUserByParam
- * 5.用户新注册逻辑 registryUser
- * 6.已注册用户处理逻辑 deadWithUserCrud
- * 7.登陆记录保存 saveLoginRecord
- * 8.远程调用风控 remoteCheckLoginRisk
- * 9.远程调用风控 remoteCheckRegRisk
- * </p>
- *
- * <p>回调方法:<br>
- * 1.用户注册时回调 beforeRegistryUser<br>
- * 2.用户登陆时回调 beforeDeadWithUserCrud
- * </p>
- *
- * <p>可选重写方法:<br>
- * 1.第三方登陆调用处理及参数传递 setThirdPartyLoginInfo <br>
- * 2.登陆成功后调用风控服务校验 ytRiskValidate
- * 3.登陆用户信息配置额外信息 setExtInfo
- * </p>
- *
- * @author lih
- * @date 2025/9/4
- */
- @Slf4j
- public abstract class AbstractLoginService {
- @Value("${risk.config.banned.tips}")
- private String tips;
- @Value("${spring.application.name:}")
- private String applicationName;
- protected abstract LoginType getLoginType();
- /**
- * 登陆逻辑处理
- * @param loginParam 登陆参数
- * @param request request
- * @return YtDyzUser
- */
- public final YtDyzUser loginHandle(LoginParam loginParam, HttpServletRequest request) {
- loginParam.setLoginIp(IPUtil.getClientIp(request));
- // 获取默认配置
- WxDefaultConfig defaultConfig = getLoginConfig(loginParam.getAppType());
- if (Objects.isNull(defaultConfig)) {
- throw new CommonException(StrUtil.format("{}登录失败,未找到相应配置!", getLoginType().getTypeName()));
- }
- loginParam.setAppId(defaultConfig.getPlatformAppId());
- // 参数校验
- validateParams(loginParam, request);
- // 获取第三方登陆信息 如微信授权码、微信登陆后授权信息
- Map<String, Object> paramMap = setThirdPartyLoginInfo(loginParam, defaultConfig, request);
- YtDyzUser ytDyzUser;
- if (getLoginType() == LoginType.VISITOR) {
- // 游客模式
- paramMap.put("defaultConfig", defaultConfig);
- ytDyzUser = visitorLoginHandle(loginParam, paramMap);
- } else {
- ytDyzUser = clientLoginHandle(loginParam, paramMap);
- }
- // 配置额外信息
- setExtInfo(ytDyzUser, paramMap);
- // 添加用户登录记录
- addLoginRecord(loginParam,ytDyzUser);
- // 调用风控服务校验默认风控配置
- ytRiskValidate(ytDyzUser, paramMap);
- // 游客登陆 校验通过 更新用户状态为正常
- if (getLoginType() == LoginType.VISITOR) {
- updateUserStatus(ytDyzUser, UserStatusEnum.NORMAL, null);
- }
- return ytDyzUser;
- }
- protected abstract void updateUserStatus(YtDyzUser ytDyzUser, UserStatusEnum statusEnum, String reason);
- /**
- * 登陆参数校验
- */
- protected abstract void validateParams(LoginParam loginParam, HttpServletRequest request);
- /**
- * 微信端/IOS端登陆
- */
- private YtDyzUser clientLoginHandle(LoginParam loginParam, Map<String, Object> paramMap) {
- YtDyzUser ytDyzUser;
- List<YtDyzUser> ytDyzUsers = queryDyzUserByParam(loginParam, paramMap);
- if (CollectionUtils.isEmpty(ytDyzUsers)) {
- beforeRegistryUser(loginParam, paramMap);
- ytDyzUser = new YtDyzUser();
- registryUser(loginParam, ytDyzUser, paramMap);
- } else {
- ytDyzUser = ytDyzUsers.get(0);
- beforeDeadWithUserCrud(loginParam, ytDyzUser, paramMap);
- deadWithUserCrud(loginParam, ytDyzUser, paramMap);
- }
- ytDyzUser.setLoginType(LoginType.WX);
- return ytDyzUser;
- }
- /**
- * 游客模式登录
- */
- private YtDyzUser visitorLoginHandle(LoginParam loginParam, Map<String, Object> paramMap) {
- // 唯一性判断
- YtDyzUser ytDyzUser = queryUserByDeviceAndDitch(loginParam.getDeviceId(), loginParam.getDitchId());
- if(ytDyzUser == null) {
- log.warn(StrUtil.format("visitor register[ deviceId:{}, ditchId: {}]",
- loginParam.getDeviceId(), loginParam.getDitchId()));
- beforeRegistryUser(loginParam, paramMap);
- ytDyzUser = new YtDyzUser();
- registryUser(loginParam, ytDyzUser, paramMap);
- } else {
- log.warn(StrUtil.format("visitor login[ deviceId:{}, ditchId: {}]",
- loginParam.getDeviceId(), loginParam.getDitchId()));
- //当前渠道已有用户,校验用户是否处于风控中 & 更新用户信息
- beforeDeadWithUserCrud(loginParam, ytDyzUser, paramMap);
- //如果当前登录是本日第一次登录则登录天数+1
- //202550916 游客登陆不记录登陆信息
- deadWithUserCrud(loginParam, ytDyzUser, paramMap);
- }
- // 保存游客广告信息
- WxDefaultConfig defaultConfig = (WxDefaultConfig) paramMap.get("defaultConfig");
- saveVisitorAdRecord(ytDyzUser, loginParam, defaultConfig);
- ytDyzUser.setLoginType(LoginType.VISITOR);
- return ytDyzUser;
- }
- // 游客登陆时保存传递记录
- protected void saveVisitorAdRecord(YtDyzUser ytDyzUser, LoginParam loginParam, WxDefaultConfig defaultConfig) {
- }
- /**
- * 根据设备及渠道ID查询用户
- */
- protected abstract YtDyzUser queryUserByDeviceAndDitch(String deviceId, Long ditchId);
- /**
- * 第三方登陆调用处理及参数传递
- */
- protected Map<String, Object> setThirdPartyLoginInfo(LoginParam loginParam, WxDefaultConfig defaultConfig,
- HttpServletRequest request) {
- Map<String, Object> map = new HashMap<>();
- return map;
- }
- /**
- * 获取登陆默认配置
- */
- protected abstract WxDefaultConfig getLoginConfig(Integer appType);
- /**
- * 根据登陆配置信息 查询系统用户记录
- * @param loginParam 登陆参数
- * @param thirdPartyLoginInfo 第三方登陆西悉尼
- */
- protected abstract List<YtDyzUser> queryDyzUserByParam(LoginParam loginParam, Map<String, Object> thirdPartyLoginInfo);
- // 注册用户处理器回调
- protected void beforeRegistryUser(LoginParam loginParam, Map<String, Object> paramMap){
- }
- // 用户注册逻辑
- protected abstract YtDyzUser registryUser(LoginParam loginParam,YtDyzUser user, Map<String, Object> paramMap);
- // 已注册用户处理前回调
- protected void beforeDeadWithUserCrud(LoginParam loginParam, YtDyzUser ytDyzUser, Map<String, Object> paramMap){
- //当前渠道已有用户,校验用户是否处于风控中 & 更新用户信息
- if(ytDyzUser != null && !ytDyzUser.getUserStatus().equals(UserStatusEnum.NORMAL.getCode())
- && !ytDyzUser.getUserStatus().equals(UserStatusEnum.VISITOR_LOCK.getCode())){
- throw new CommonException(getTipsMsg());
- }
- }
- private String getTipsMsg(){
- String[] split = tips.split(",");
- return split[RandomUtil.randomInt(split.length)];
- }
- // 已注册用户处理逻辑
- protected abstract void deadWithUserCrud(LoginParam loginParam, YtDyzUser old, Map<String, Object> paramMap);
- private void addLoginRecord(LoginParam param, YtDyzUser old) {
- YtDyzLoginRecord loginRecord = new YtDyzLoginRecord();
- loginRecord.setRecordId(IdUtil.fastSimpleUUID());
- loginRecord.setUserId(old.getUserId());
- loginRecord.setLoginTime(new Date());
- loginRecord.setDeviceBrand(param.getBrand());
- loginRecord.setDeviceModel(param.getModel());
- loginRecord.setLoginIp(param.getLoginIp());
- loginRecord.setOperator(param.getIpOperator());
- loginRecord.setIpAddr(param.getIpLocation());
- loginRecord.setPhoneJson(param.getPhoneJson());
- loginRecord.setLoginType(old.getLoginType().toString());
- saveLoginRecord(loginRecord);
- }
- /**
- * 保存登陆记录实现
- */
- protected abstract void saveLoginRecord(YtDyzLoginRecord loginRecord);
- /**
- * 调用风控服务校验默认风控配置
- */
- protected void ytRiskValidate(YtDyzUser ytDyzUser, Map<String, Object> paramMap) {
- Result<?> result = remoteCheckLoginRisk(ytDyzUser);
- if (result == null) {
- throw new CommonException("feign invoke Fail!");
- }
- if (result.getCode() != 200) {
- String errorMessage = result.getMessage();
- if (ytDyzUser.getLoginType() == LoginType.VISITOR && RepMessage.RISK_VISITOR_LOWER_VALUE.equals(errorMessage)) {
- WxDefaultConfig defaultConfig = (WxDefaultConfig) paramMap.get("defaultConfig");
- throw new CommonException(StrUtil.emptyToDefault(defaultConfig.getLowValueTip(), errorMessage));
- }
- throw new CommonException(errorMessage);
- }
- }
- /**
- * 配置相关信息
- *
- * @param ytDyzUser
- * @param paramMap
- */
- protected void setExtInfo(YtDyzUser ytDyzUser, Map<String, Object> paramMap) {
- ytDyzUser.setServiceName(applicationName);
- }
- /**
- * 远程调用校验用户风控,需设置风控编码[riskCode],并重写该方法
- * @param ytDyzUser 当前用户
- */
- protected abstract Result<?> remoteCheckLoginRisk(YtDyzUser ytDyzUser);
- /**
- * 远程调用校验注册用户
- * @param user 参数
- */
- protected abstract Result<?> remoteCheckRegRisk(YtDyzUser user);
- }
|