基于SpringBoot的AI游戏对战平台
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

138 lines
5.7 KiB

package com.kob.backend.service.impl.user.account.acwing;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.kob.backend.mapper.UserMapper;
import com.kob.backend.pojo.User;
import com.kob.backend.service.impl.user.account.acwing.utils.HttpClientUtil;
import com.kob.backend.service.user.account.acwing.WebService;
import com.kob.backend.utils.JwtUtil;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.time.Duration;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;
@Service
public class WebServiceImpl implements WebService {
private static final String appId = "3357";
private static final String appSecret = "f343ff7eeaa649d2a257bffac0a9323a";
private static final String redirectUri = "https://kob.bnblogs.cc/user/account/acwing/web/receive_code/";
private static final String applyAccessTokenUrl = "https://www.acwing.com/third_party/api/oauth2/access_token/";
private static final String getUserInfoUrl = "https://www.acwing.com/third_party/api/meta/identity/getinfo/";
private static final Random random = new Random();
@Autowired
private UserMapper userMapper;
@Autowired
private RedisTemplate<String,String> redisTemplate;
@Override
public JSONObject applyCode() {
JSONObject resp = new JSONObject();
String encodeUrl="";
try {
encodeUrl = URLEncoder.encode(redirectUri,"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
resp.put("result","failed");
return resp;
}
StringBuilder state = new StringBuilder();
for (int i = 0; i < 10; i++) {
state.append((char)(random.nextInt(10) + '0')); // 十位随机数字字符串
}
resp.put("result","success");
redisTemplate.opsForValue().set(state.toString(),"true"); // 将state值存入redis
redisTemplate.expire(state.toString(), Duration.ofMinutes(10)); // 设置过期时间为10分钟
String applyCodeUrl = "https://www.acwing.com/third_party/api/oauth2/web/authorize/?appid=" + appId
+ "&redirect_uri=" + encodeUrl
+ "&scope=userinfo"
+ "&state=" + state;
resp.put("apply_code_url",applyCodeUrl);
return resp;
}
@Override
public JSONObject receiveCode(String code, String state) {
JSONObject resp = new JSONObject();
resp.put("result","failed");
if (code == null || state == null) return resp; // 传入的code和state为空
if (Boolean.FALSE.equals(redisTemplate.hasKey(state))) return resp; // redis中没有该state
redisTemplate.delete(state); // 删除该state,只使用一次
// 获取accessToken
List<NameValuePair> nameValuePairs = new LinkedList<>();
nameValuePairs.add(new BasicNameValuePair("appid",appId));
nameValuePairs.add(new BasicNameValuePair("secret",appSecret));
nameValuePairs.add(new BasicNameValuePair("code",code));
String getString = HttpClientUtil.get(applyAccessTokenUrl,nameValuePairs); // 请求结果存入一个字符串
if (getString == null) return resp;
JSONObject getResp = JSONObject.parseObject(getString);
String accessToken = getResp.getString("access_token");
String openId = getResp.getString("openid");
if (accessToken == null || openId == null) return resp;
QueryWrapper<User> qw = new QueryWrapper<>();
qw.eq("openid",openId);
List<User> users = userMapper.selectList(qw); // 查询满足openid的用户是否存在
if (!users.isEmpty()) {
User user = users.get(0);
String jwt = JwtUtil.createJWT(user.getId().toString());
resp.put("result","success");
resp.put("jwt_token",jwt);
return resp;
}
// 如果不存在说明该用户没有登录过,需要根据上面的accessToken和openid向Acwing请求用户信息
nameValuePairs = new LinkedList<>();
nameValuePairs.add(new BasicNameValuePair("access_token",accessToken));
nameValuePairs.add(new BasicNameValuePair("openid",openId));
getString = HttpClientUtil.get(getUserInfoUrl,nameValuePairs); // 将请求结果存入字符串
if (getString == null) return resp;
getResp = JSONObject.parseObject(getString);
// 获得用户的用户名和头像
String username = getResp.getString("username");
String photo = getResp.getString("photo");
if (username == null || photo == null) return resp;
// 避免新出现的用户重名
for (int i = 0; i < 100; i++) { // 随机在后面添加以为数字
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("username",username);
// 没有重名,直接退出
if (userMapper.selectList(queryWrapper).isEmpty()) break;
username += (char)(random.nextInt(10) + '0');
if (i == 99) return resp; // 小概率事件,太逆天,直接返回
}
// 根据获得的信息建立一个用户
User user = new User(null,username,null,photo,null,openId);
userMapper.insert(user);
String jwt = JwtUtil.createJWT(user.getId().toString());
resp.put("result","success");
resp.put("jwt_token",jwt);
return resp;
}
}