|
|
|
@ -2,29 +2,38 @@ package com.bnyer.img.service.impl; |
|
|
|
|
|
|
|
import com.alibaba.fastjson.JSONObject; |
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; |
|
|
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; |
|
|
|
import com.bnyer.common.core.exception.ServiceException; |
|
|
|
import com.bnyer.common.core.utils.Sm4Util; |
|
|
|
import com.bnyer.common.core.utils.StringUtils; |
|
|
|
import com.bnyer.common.core.utils.uuid.IdUtils; |
|
|
|
import com.bnyer.common.redis.service.RedisService; |
|
|
|
import com.bnyer.img.config.TiktokConfig; |
|
|
|
import com.bnyer.img.constants.RedisKeyConstant; |
|
|
|
import com.bnyer.img.constants.TiktokConstant; |
|
|
|
import com.bnyer.img.domain.TiktokImg; |
|
|
|
import com.bnyer.img.domain.TiktokUser; |
|
|
|
import com.bnyer.img.dto.TiktokBindPhoneDto; |
|
|
|
import com.bnyer.img.dto.TiktokCreaterDto; |
|
|
|
import com.bnyer.img.dto.TiktokLoginDto; |
|
|
|
import com.bnyer.img.dto.TiktokUserPageDto; |
|
|
|
import com.bnyer.img.feign.TiktokFeign; |
|
|
|
import com.bnyer.img.mapper.TiktokImgMapper; |
|
|
|
import com.bnyer.img.mapper.TiktokUserMapper; |
|
|
|
import com.bnyer.img.service.TiktokUserService; |
|
|
|
import com.bnyer.img.vo.TiktokSessionInfoVo; |
|
|
|
import com.bnyer.img.vo.TiktokUserInfoVo; |
|
|
|
import com.bnyer.img.vo.TiktokUserPhoneInfoVo; |
|
|
|
import com.bnyer.img.vo.TiktokUserVo; |
|
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
|
import org.springframework.stereotype.Service; |
|
|
|
|
|
|
|
import javax.annotation.Resource; |
|
|
|
import java.util.HashMap; |
|
|
|
import java.util.List; |
|
|
|
import java.util.Map; |
|
|
|
import javax.crypto.Cipher; |
|
|
|
import javax.crypto.spec.IvParameterSpec; |
|
|
|
import javax.crypto.spec.SecretKeySpec; |
|
|
|
import java.util.*; |
|
|
|
import java.util.concurrent.TimeUnit; |
|
|
|
|
|
|
|
@Service |
|
|
|
@ -46,16 +55,67 @@ public class TiktokUserServiceImpl implements TiktokUserService { |
|
|
|
@Autowired |
|
|
|
private TiktokFeign tiktokFeign; |
|
|
|
|
|
|
|
@Override |
|
|
|
public int insert(TiktokUser tiktokUser) { |
|
|
|
return 0; |
|
|
|
/** |
|
|
|
* 检查搜索码是否重复 |
|
|
|
* @param scanCode 搜索码 |
|
|
|
* @return - |
|
|
|
*/ |
|
|
|
private boolean checkScanCode(String scanCode){ |
|
|
|
LambdaQueryWrapper<TiktokUser> wrapper = new LambdaQueryWrapper<>(); |
|
|
|
wrapper.eq(TiktokUser::getScanCode, scanCode); |
|
|
|
List<TiktokUser> tiktokUsers = tiktokUserMapper.selectList(wrapper); |
|
|
|
if(tiktokUsers.size() > 0){ |
|
|
|
return true; |
|
|
|
}else{ |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 检查用户是否绑定过手机号 |
|
|
|
* @param phone 手机号 |
|
|
|
* @return - |
|
|
|
*/ |
|
|
|
private boolean checkPhone(String phone){ |
|
|
|
LambdaQueryWrapper<TiktokUser> wrapper = new LambdaQueryWrapper<>(); |
|
|
|
wrapper.eq(TiktokUser::getPhone, phone); |
|
|
|
List<TiktokUser> tiktokUsers = tiktokUserMapper.selectList(wrapper); |
|
|
|
if(tiktokUsers.size() > 0){ |
|
|
|
return true; |
|
|
|
}else{ |
|
|
|
return false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public int update(TiktokUser tiktokUser) { |
|
|
|
return 0; |
|
|
|
public int insertCreator(TiktokCreaterDto dto) { |
|
|
|
//检查手机号是否存在
|
|
|
|
boolean b1 = checkPhone(Sm4Util.sm4Encryption(dto.getPhone())); |
|
|
|
if(!b1){ |
|
|
|
throw new ServiceException("用户尚未绑定手机号,请手动绑定!"); |
|
|
|
} |
|
|
|
//检查搜索码是否重复
|
|
|
|
boolean b = this.checkScanCode(dto.getScanCode()); |
|
|
|
if(b){ |
|
|
|
throw new ServiceException("搜索码重复,请重新编辑!"); |
|
|
|
} |
|
|
|
TiktokUser user = new TiktokUser(); |
|
|
|
user.setIntro(dto.getIntro()); |
|
|
|
user.setScanCode(dto.getScanCode()); |
|
|
|
user.setInviteCode(dto.getInviteCode()); |
|
|
|
user.setTiktokNumber(dto.getTiktokNum()); |
|
|
|
LambdaUpdateWrapper<TiktokUser> updateWrapper = new LambdaUpdateWrapper<>(); |
|
|
|
updateWrapper.eq(TiktokUser::getPhone, Sm4Util.sm4Encryption(dto.getPhone())); |
|
|
|
int update = tiktokUserMapper.update(user, updateWrapper); |
|
|
|
log.info("用户【{}】成为艺术家成功!",dto.getPhone()); |
|
|
|
return update; |
|
|
|
} |
|
|
|
|
|
|
|
// @Override
|
|
|
|
// public int update(TiktokUser tiktokUser) {
|
|
|
|
// return 0;
|
|
|
|
// }
|
|
|
|
|
|
|
|
@Override |
|
|
|
public int delete(List<Long> ids) { |
|
|
|
int delete = tiktokUserMapper.deleteBatchIds(ids); |
|
|
|
@ -72,7 +132,7 @@ public class TiktokUserServiceImpl implements TiktokUserService { |
|
|
|
public List<TiktokUser> queryPage(TiktokUserPageDto dto) { |
|
|
|
LambdaQueryWrapper<TiktokUser> wrapper = new LambdaQueryWrapper<>(); |
|
|
|
wrapper.like(StringUtils.isNotNull(dto.getUsername()), TiktokUser::getUsername, dto.getUsername()); |
|
|
|
wrapper.eq(StringUtils.isNotNull(dto.getPhone()),TiktokUser::getPhone, dto.getPhone()); |
|
|
|
wrapper.eq(StringUtils.isNotNull(dto.getPhone()),TiktokUser::getPhone, Sm4Util.sm4Encryption(dto.getPhone())); |
|
|
|
wrapper.eq(StringUtils.isNotNull(dto.getTiktokNumber()), TiktokUser::getTiktokNumber, dto.getTiktokNumber()); |
|
|
|
wrapper.eq(StringUtils.isNotNull(dto.getScanCode()), TiktokUser::getScanCode, dto.getScanCode()); |
|
|
|
wrapper.eq(StringUtils.isNotNull(dto.getInviteCode()), TiktokUser::getInviteCode, dto.getInviteCode()); |
|
|
|
@ -98,8 +158,12 @@ public class TiktokUserServiceImpl implements TiktokUserService { |
|
|
|
return tiktokUserVo; |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public TiktokSessionInfoVo getSessionInfo(String code) { |
|
|
|
/** |
|
|
|
* 获取用户openId及sessionKey |
|
|
|
* @param code 登录凭证code |
|
|
|
* @return - |
|
|
|
*/ |
|
|
|
private TiktokSessionInfoVo getSessionInfo(String code) { |
|
|
|
Map<String, String> params = new HashMap(8); |
|
|
|
params.put("appid", tiktokConfig.getAppId()); |
|
|
|
params.put("secret", tiktokConfig.getSecret()); |
|
|
|
@ -118,4 +182,132 @@ public class TiktokUserServiceImpl implements TiktokUserService { |
|
|
|
result.setUnionId(data.getString("unionid")); |
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 获取用户敏感信息 |
|
|
|
* @param sessionKey - |
|
|
|
* @param encryptedData 敏感数据 |
|
|
|
* @param iv 加密向量 |
|
|
|
* @return - |
|
|
|
*/ |
|
|
|
private TiktokUserInfoVo getUserInfo(String sessionKey,String encryptedData,String iv){ |
|
|
|
Base64.Decoder decoder = Base64.getDecoder(); |
|
|
|
byte[] sessionKeyBytes = decoder.decode(sessionKey); |
|
|
|
byte[] ivBytes = decoder.decode(iv); |
|
|
|
byte[] encryptedBytes = decoder.decode(encryptedData); |
|
|
|
|
|
|
|
Cipher cipher = null; |
|
|
|
try { |
|
|
|
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); |
|
|
|
SecretKeySpec skeySpec = new SecretKeySpec(sessionKeyBytes, "AES"); |
|
|
|
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes); |
|
|
|
cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec); |
|
|
|
byte[] ret = cipher.doFinal(encryptedBytes); |
|
|
|
if (null != ret && ret.length > 0) { |
|
|
|
String result = new String(ret, "UTF-8"); |
|
|
|
return JSONObject.parseObject(result,TiktokUserInfoVo.class); |
|
|
|
} |
|
|
|
} catch (Exception e) { |
|
|
|
e.printStackTrace(); |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
|
|
|
|
/** |
|
|
|
* 保存用户 |
|
|
|
* @param openId 抖音id |
|
|
|
* @param sessionKey - |
|
|
|
* @param encryptedData 敏感信息数据 |
|
|
|
* @param iv 加密向量 |
|
|
|
* @return - |
|
|
|
*/ |
|
|
|
private TiktokUser saveUserInfo(String openId,String sessionKey,String encryptedData,String iv){ |
|
|
|
//获取敏感信息
|
|
|
|
TiktokUserInfoVo userInfo = this.getUserInfo(sessionKey, encryptedData, iv); |
|
|
|
TiktokUser user = new TiktokUser(); |
|
|
|
user.setUsername(userInfo.getNickName()); |
|
|
|
user.setImg(userInfo.getAvatarUrl()); |
|
|
|
user.setTiktokCode(Sm4Util.sm4Encryption(openId)); |
|
|
|
user.setIsHot("0"); |
|
|
|
user.setIsShow("1"); |
|
|
|
user.setCreateTime(new Date()); |
|
|
|
user.setUpdateTime(new Date()); |
|
|
|
tiktokUserMapper.insert(user); |
|
|
|
log.info("抖音用户【{}】创建成功!",user.getId()); |
|
|
|
return user; |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public Map<String, Object> login(TiktokLoginDto dto) { |
|
|
|
TiktokSessionInfoVo sessionInfo = this.getSessionInfo(dto.getCode()); |
|
|
|
//检查数据库中是否存在该openId,存在则直接设置会话状态登录;不存在则新增
|
|
|
|
LambdaQueryWrapper<TiktokUser> wrapper = new LambdaQueryWrapper<>(); |
|
|
|
wrapper.eq(sessionInfo.getOpenId() != null,TiktokUser::getTiktokCode,dto.getCode()); |
|
|
|
TiktokUser tiktokUser = tiktokUserMapper.selectOne(wrapper); |
|
|
|
if(tiktokUser == null){ |
|
|
|
//新用户,新增
|
|
|
|
tiktokUser = this.saveUserInfo(sessionInfo.getOpenId(), sessionInfo.getSessionKey(), dto.getEncryptedData(), dto.getIv()); |
|
|
|
} |
|
|
|
//设置会话状态
|
|
|
|
String redisKey = RedisKeyConstant.TIKTOK_USER_LOGIN_KEY+sessionInfo.getOpenId(); |
|
|
|
//存在该登录态则删除刷新
|
|
|
|
if(redisService.hasKey(redisKey)){ |
|
|
|
redisService.deleteObject(redisKey); |
|
|
|
} |
|
|
|
StringBuffer sb = new StringBuffer(); |
|
|
|
String randomId = IdUtils.fastSimpleUUID(); |
|
|
|
sb.append(randomId).append("#").append(sessionInfo.getOpenId()); |
|
|
|
//设置登录会话
|
|
|
|
redisService.setCacheObject(redisKey,sb.toString(),30L, TimeUnit.DAYS); |
|
|
|
Map<String, Object> map = new HashMap<>(2); |
|
|
|
map.put("token", sb.toString()); |
|
|
|
map.put("userInfo",tiktokUser); |
|
|
|
return map; |
|
|
|
} |
|
|
|
|
|
|
|
@Override |
|
|
|
public void bindPhone(TiktokBindPhoneDto dto) { |
|
|
|
TiktokUserPhoneInfoVo phoneInfo = this.getPhone(dto.getSessionKey(), dto.getEncryptedData(), dto.getIv()); |
|
|
|
if(phoneInfo != null){ |
|
|
|
TiktokUser user = new TiktokUser(); |
|
|
|
user.setId(dto.getUserId()); |
|
|
|
user.setPhone(Sm4Util.sm4Encryption(phoneInfo.getPhoneNumber())); |
|
|
|
tiktokUserMapper.updateById(user); |
|
|
|
log.info("获取用户【{}】手机号成功!",dto.getUserId()); |
|
|
|
}else{ |
|
|
|
log.error("获取用户【{}】手机号失败!",dto.getUserId()); |
|
|
|
throw new ServiceException("用户手机号绑定失败!"); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
* 获取用户手机号 |
|
|
|
* @param sessionKey - |
|
|
|
* @param encryptedData 敏感信息 |
|
|
|
* @param iv 加密向量 |
|
|
|
* @return - |
|
|
|
*/ |
|
|
|
private TiktokUserPhoneInfoVo getPhone(String sessionKey, String encryptedData, String iv) { |
|
|
|
Base64.Decoder decoder = Base64.getDecoder(); |
|
|
|
byte[] sessionKeyBytes = decoder.decode(sessionKey); |
|
|
|
byte[] ivBytes = decoder.decode(iv); |
|
|
|
byte[] encryptedBytes = decoder.decode(encryptedData); |
|
|
|
|
|
|
|
Cipher cipher = null; |
|
|
|
try { |
|
|
|
cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); |
|
|
|
SecretKeySpec skeySpec = new SecretKeySpec(sessionKeyBytes, "AES"); |
|
|
|
IvParameterSpec ivSpec = new IvParameterSpec(ivBytes); |
|
|
|
cipher.init(Cipher.DECRYPT_MODE, skeySpec, ivSpec); |
|
|
|
byte[] ret = cipher.doFinal(encryptedBytes); |
|
|
|
if (null != ret && ret.length > 0) { |
|
|
|
String result = new String(ret, "UTF-8"); |
|
|
|
return JSONObject.parseObject(result,TiktokUserPhoneInfoVo.class); |
|
|
|
} |
|
|
|
} catch (Exception e) { |
|
|
|
e.printStackTrace(); |
|
|
|
} |
|
|
|
return null; |
|
|
|
} |
|
|
|
} |
|
|
|
|