16 changed files with 519 additions and 14 deletions
@ -1,4 +1,7 @@
@@ -1,4 +1,7 @@
|
||||
# 程序自身数据源配置 |
||||
spring.datasource.url=jdbc:mysql://10.100.0.108:3306/idle_game?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true |
||||
spring.datasource.username=root |
||||
spring.datasource.password=mBMjp2v74c7MzhC/5RGeXF1V3E+AcRFs1f5OH6PDHi3nWaM3njaaoewswq8Sl7/AY631t0sONVDG672pX4mFpZx/8xex8BJP3uX1wUu9NGpTCSHskb5cD6KZMNV4jNsfoqxFRyJq8yk86djPsCfR4ch0sPnLH+LCg9XY1DAw8szh93QnKDkiImq2JLkaIwG3R3t8dNWv1wVoMR6vVecPsEUyPJu5vsrvJhjP3uAL7jZYJVGZG6bkrpV3R6I6mja0QnTdF41NCL5Ex0TINSi7GKnrALjZ0qWcT9fe2bTUCKq50+CtVEAQnEz2ZJpYUaBZXJbHh4OrUyqjAmA5s7IelQ== |
||||
spring.datasource.password=123456 |
||||
|
||||
login.token.timeout=10080 |
||||
login.token.domain= |
@ -0,0 +1,46 @@
@@ -0,0 +1,46 @@
|
||||
package vip.xumy.idle.server.conf; |
||||
|
||||
import java.nio.charset.Charset; |
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
import org.springframework.context.annotation.Bean; |
||||
import org.springframework.context.annotation.Configuration; |
||||
import org.springframework.http.MediaType; |
||||
import org.springframework.http.converter.HttpMessageConverter; |
||||
|
||||
import com.alibaba.fastjson.serializer.SerializerFeature; |
||||
import com.alibaba.fastjson.support.config.FastJsonConfig; |
||||
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; |
||||
|
||||
/** Ownership belongs to the company |
||||
* |
||||
* @author:mengyxu |
||||
* @date:2025年5月19日 |
||||
*/ |
||||
|
||||
@Configuration |
||||
public class Configer { |
||||
|
||||
@Bean |
||||
public HttpMessageConverter<?> configureMessageConverters() { |
||||
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); |
||||
FastJsonConfig config = new FastJsonConfig(); |
||||
config.setSerializerFeatures( |
||||
SerializerFeature.WriteMapNullValue, |
||||
SerializerFeature.WriteNullStringAsEmpty, |
||||
SerializerFeature.WriteNullNumberAsZero, |
||||
SerializerFeature.WriteNullListAsEmpty, |
||||
SerializerFeature.WriteNullBooleanAsFalse, |
||||
SerializerFeature.DisableCircularReferenceDetect |
||||
); |
||||
|
||||
converter.setFastJsonConfig(config); |
||||
converter.setDefaultCharset(Charset.forName("UTF-8")); |
||||
List<MediaType> mediaTypeList = new ArrayList<>(); |
||||
mediaTypeList.add(MediaType.APPLICATION_JSON); |
||||
converter.setSupportedMediaTypes(mediaTypeList); |
||||
return converter; |
||||
} |
||||
|
||||
} |
@ -0,0 +1,49 @@
@@ -0,0 +1,49 @@
|
||||
package vip.xumy.idle.server.ctrl; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.web.bind.annotation.GetMapping; |
||||
import org.springframework.web.bind.annotation.PostMapping; |
||||
import org.springframework.web.bind.annotation.RequestBody; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.bind.annotation.RestController; |
||||
|
||||
import vip.xumy.core.pojo.com.BaseResponse; |
||||
import vip.xumy.idle.server.pojo.Archive; |
||||
import vip.xumy.idle.server.service.ArchiveService; |
||||
import vip.xumy.idle.server.util.LoginUtil; |
||||
|
||||
/** |
||||
* Ownership belongs to the company |
||||
* |
||||
* @author:mengyxu |
||||
* @date:2025年5月19日 |
||||
*/ |
||||
|
||||
@RestController |
||||
@RequestMapping("archive") |
||||
public class ArchiveController { |
||||
@Autowired |
||||
private ArchiveService archiveService; |
||||
|
||||
@PostMapping |
||||
public BaseResponse saveArchive(@RequestBody Archive archive) { |
||||
String userId = LoginUtil.getUserId(); |
||||
if (userId == null) { |
||||
return new BaseResponse(true, "请先登录"); |
||||
} |
||||
archive.setUsername(userId); |
||||
archiveService.saveOrUpdate(archive); |
||||
return new BaseResponse(true, "存档保存成功"); |
||||
} |
||||
|
||||
@GetMapping |
||||
public BaseResponse getArchive(String version) { |
||||
String userId = LoginUtil.getUserId(); |
||||
Archive archive = archiveService.getByKey(userId, version); |
||||
if (archive == null) { |
||||
return new BaseResponse(false, "未查询到你的存档"); |
||||
} |
||||
return new BaseResponse(true, archive.getArchive()); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,18 @@
@@ -0,0 +1,18 @@
|
||||
package vip.xumy.idle.server.mapper; |
||||
|
||||
import org.apache.ibatis.annotations.Mapper; |
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; |
||||
|
||||
import vip.xumy.idle.server.pojo.Archive; |
||||
|
||||
/** Ownership belongs to the company |
||||
* |
||||
* @author:mengyxu |
||||
* @date:2025年5月19日 |
||||
*/ |
||||
|
||||
@Mapper |
||||
public interface IArchiveMapper extends BaseMapper<Archive> { |
||||
|
||||
} |
@ -0,0 +1,26 @@
@@ -0,0 +1,26 @@
|
||||
package vip.xumy.idle.server.pojo; |
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableName; |
||||
|
||||
import lombok.Getter; |
||||
import lombok.Setter; |
||||
|
||||
/** |
||||
* Ownership belongs to the company |
||||
* |
||||
* @author:mengyxu |
||||
* @date:2025年5月19日 |
||||
*/ |
||||
|
||||
@Setter |
||||
@Getter |
||||
@TableName("archive") |
||||
public class Archive { |
||||
|
||||
private String username; |
||||
private String version; |
||||
private int lv; |
||||
private long coins; |
||||
private String archive; |
||||
|
||||
} |
@ -0,0 +1,38 @@
@@ -0,0 +1,38 @@
|
||||
package vip.xumy.idle.server.service; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.stereotype.Service; |
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; |
||||
|
||||
import vip.xumy.idle.server.mapper.IArchiveMapper; |
||||
import vip.xumy.idle.server.pojo.Archive; |
||||
|
||||
/** Ownership belongs to the company |
||||
* |
||||
* @author:mengyxu |
||||
* @date:2025年5月19日 |
||||
*/ |
||||
|
||||
@Service |
||||
public class ArchiveService { |
||||
@Autowired |
||||
private IArchiveMapper archiveMapper; |
||||
|
||||
public void saveOrUpdate(Archive archive) { |
||||
Archive exit = getByKey(archive.getUsername(), archive.getVersion()); |
||||
if(exit == null) { |
||||
archiveMapper.insert(archive); |
||||
}else { |
||||
archiveMapper.updateById(archive); |
||||
} |
||||
} |
||||
|
||||
public Archive getByKey(String username, String version) { |
||||
QueryWrapper<Archive> wrapper = new QueryWrapper<>(); |
||||
wrapper.eq("username", username); |
||||
wrapper.eq("version", version); |
||||
return archiveMapper.selectOne(wrapper); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,51 @@
@@ -0,0 +1,51 @@
|
||||
package vip.xumy.idle.server.service; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.stereotype.Service; |
||||
|
||||
import vip.xumy.core.utils.DateUtil; |
||||
import vip.xumy.core.utils.StringUtil; |
||||
import vip.xumy.idle.server.mapper.IUserMapper; |
||||
import vip.xumy.idle.server.pojo.User; |
||||
|
||||
/** |
||||
* Ownership belongs to the company |
||||
* |
||||
* @author:mengyxu |
||||
* @date:2025年5月19日 |
||||
*/ |
||||
|
||||
@Service |
||||
public class UserService { |
||||
@Autowired |
||||
private IUserMapper userMapper; |
||||
|
||||
public User login(User param) { |
||||
String username = param.getUsername(); |
||||
String password = param.getPassword(); |
||||
if (StringUtil.isEmpty(username, password)) { |
||||
return null; |
||||
} |
||||
User user = getById(username); |
||||
if (user != null) { |
||||
if (password.equals(user.getPassword())) { |
||||
userMapper.login(username); |
||||
return user; |
||||
} else { |
||||
return null; |
||||
} |
||||
} else { |
||||
String time = DateUtil.format(); |
||||
param.setState("0"); |
||||
param.setRegisterTime(time); |
||||
param.setLastLogin(time); |
||||
userMapper.insert(param); |
||||
return param; |
||||
} |
||||
} |
||||
|
||||
public User getById(String username) { |
||||
return userMapper.selectById(username); |
||||
} |
||||
|
||||
} |
@ -0,0 +1,205 @@
@@ -0,0 +1,205 @@
|
||||
package vip.xumy.idle.server.util; |
||||
|
||||
import javax.servlet.http.Cookie; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired; |
||||
import org.springframework.beans.factory.annotation.Value; |
||||
import org.springframework.stereotype.Component; |
||||
|
||||
import vip.xumy.core.golbal.GlobalBuffer; |
||||
import vip.xumy.core.pojo.com.Cache; |
||||
import vip.xumy.core.utils.StringUtil; |
||||
import vip.xumy.idle.server.pojo.User; |
||||
|
||||
/** |
||||
* Ownership belongs to the company |
||||
* |
||||
* @author:mengyxu |
||||
* @date:2024年3月5日 |
||||
*/ |
||||
|
||||
//@Log4j2
|
||||
@Component |
||||
public class LoginUtil { |
||||
public static final String TIKEN_KEY_PREFIX = "token-"; |
||||
public static final String LOGIN_COOKIE_NAME = "token"; |
||||
|
||||
@Value("${login.token.timeout}") |
||||
public void setTimeout(Integer timeout) { |
||||
LoginUtil.timeout = timeout; |
||||
} |
||||
|
||||
private static Integer timeout; |
||||
|
||||
@Value("${login.token.domain}") |
||||
public void setDomain(String domain) { |
||||
LoginUtil.domain = domain; |
||||
} |
||||
|
||||
private static String domain; |
||||
|
||||
private static HttpServletRequest request; |
||||
|
||||
@Autowired |
||||
public void setRequest(HttpServletRequest request) { |
||||
LoginUtil.request = request; |
||||
} |
||||
|
||||
private static HttpServletResponse response; |
||||
|
||||
@Autowired |
||||
public void setResponse(HttpServletResponse response) { |
||||
LoginUtil.response = response; |
||||
} |
||||
|
||||
private static String getTokenKey(String userId) { |
||||
return TIKEN_KEY_PREFIX + userId; |
||||
} |
||||
|
||||
public static boolean isLogin(String userId) { |
||||
Cache cache = GlobalBuffer.getCache(getTokenKey(userId)); |
||||
return !Cache.isEmpty(cache); |
||||
} |
||||
|
||||
public static void remveLoginInfo(String userId) { |
||||
String tokenKey = LoginUtil.getTokenKey(userId); |
||||
Cache token = GlobalBuffer.getCache(tokenKey); |
||||
if (!Cache.isEmpty(token)) { |
||||
String value = token.getValue(); |
||||
GlobalBuffer.removeCache(value.substring(0, 10)); |
||||
GlobalBuffer.removeCache(tokenKey); |
||||
} |
||||
} |
||||
|
||||
public static void saveLoginInfo(User user) { |
||||
// 删除旧的token信息
|
||||
String userId = user.getUsername(); |
||||
Cache exitToken = GlobalBuffer.getCache(LoginUtil.getTokenKey(userId)); |
||||
if (!Cache.isEmpty(exitToken)) { |
||||
String value = exitToken.getValue(); |
||||
GlobalBuffer.removeCache(value.substring(0, 10)); |
||||
} |
||||
|
||||
// 计算新的token
|
||||
String ip = getIpAddr(); |
||||
String seq = GlobalBuffer.getSeq(); |
||||
String token = seq + StringUtil.md5(user.getUsername() + ip + System.currentTimeMillis(), false); |
||||
|
||||
// 保存用户token
|
||||
GlobalBuffer.addCache(LoginUtil.getTokenKey(userId), new Cache(token, timeout * 60)); |
||||
// 保存token的用户信息
|
||||
GlobalBuffer.addCache(seq, new Cache(user, timeout * 60)); |
||||
|
||||
LoginUtil.addToken(token, response); |
||||
|
||||
} |
||||
|
||||
private static void addToken(String token, HttpServletResponse response) { |
||||
Cookie cookie = new Cookie(LOGIN_COOKIE_NAME, token); |
||||
if (!StringUtil.isEmpty(domain)) { |
||||
cookie.setDomain(domain); |
||||
} |
||||
cookie.setPath("/"); |
||||
response.addCookie(cookie); |
||||
} |
||||
|
||||
public static User getUserInfo(String token, boolean refresh) { |
||||
if (StringUtil.isEmpty(token)) { |
||||
token = getToken(); |
||||
} |
||||
User empty = new User(); |
||||
if (StringUtil.isEmpty(token) || token.length() != 42) { |
||||
return empty; |
||||
} |
||||
Cache userCache = GlobalBuffer.getCache(token.substring(0, 10)); |
||||
if (Cache.isEmpty(userCache)) { |
||||
return empty; |
||||
} |
||||
User user = userCache.getValue(); |
||||
String userId = user.getUsername(); |
||||
Cache exitToken = GlobalBuffer.getCache(LoginUtil.getTokenKey(userId)); |
||||
if (Cache.isEmpty(exitToken)) { |
||||
return empty; |
||||
} |
||||
if (StringUtil.equals(token, exitToken.getValue())) { |
||||
if (refresh) { |
||||
userCache.refresh(); |
||||
exitToken.refresh(); |
||||
} |
||||
return user; |
||||
} |
||||
return empty; |
||||
} |
||||
|
||||
public static String getUserId() { |
||||
return getUserInfo(null, false).getUsername(); |
||||
} |
||||
|
||||
public static String getUserIdAndRefresh() { |
||||
return getUserInfo(null, true).getUsername(); |
||||
} |
||||
|
||||
public static User getUserInfo() { |
||||
return getUserInfo(null, false); |
||||
} |
||||
|
||||
public static void loginOut() { |
||||
String token = LoginUtil.getToken(); |
||||
if (!StringUtil.isEmpty(token)) { |
||||
String seq = token.substring(0, 10); |
||||
Cache userCache = GlobalBuffer.getCache(seq); |
||||
if (!Cache.isEmpty(userCache)) { |
||||
User user = userCache.getValue(); |
||||
String userId = user.getUsername(); |
||||
GlobalBuffer.removeCache(getTokenKey(userId)); |
||||
} |
||||
GlobalBuffer.removeCache(seq); |
||||
} |
||||
} |
||||
|
||||
public static String getToken() { |
||||
Cookie[] cookies = request.getCookies(); |
||||
if (cookies == null) { |
||||
return null; |
||||
} |
||||
for (Cookie cookie : cookies) { |
||||
if (LOGIN_COOKIE_NAME.equals(cookie.getName())) { |
||||
return cookie.getValue(); |
||||
} |
||||
} |
||||
return null; |
||||
} |
||||
|
||||
/** |
||||
* 获取访问者IP |
||||
* |
||||
* 在一般情况下使用Request.getRemoteAddr()即可,但是经过nginx等反向代理软件后,这个方法会失效。 |
||||
* |
||||
* 本方法先从Header中获取X-Real-IP,如果不存在再从X-Forwarded-For获得第一个IP(用,分割), 如果还不存在则调用Request |
||||
* .getRemoteAddr()。 |
||||
* |
||||
* @param request |
||||
* @return |
||||
*/ |
||||
public static String getIpAddr() { |
||||
String ip = request.getHeader("X-Real-IP"); |
||||
if (!StringUtil.isEmpty(ip) && !"unknown".equalsIgnoreCase(ip)) { |
||||
return ip; |
||||
} |
||||
ip = request.getHeader("X-Forwarded-For"); |
||||
if (!StringUtil.isEmpty(ip) && !"unknown".equalsIgnoreCase(ip)) { |
||||
// 多次反向代理后会有多个IP值,第一个为真实IP。
|
||||
int index = ip.indexOf(','); |
||||
if (index != -1) { |
||||
return ip.substring(0, index); |
||||
} else { |
||||
return ip; |
||||
} |
||||
} else { |
||||
return request.getRemoteAddr(); |
||||
} |
||||
} |
||||
|
||||
} |
@ -0,0 +1,15 @@
@@ -0,0 +1,15 @@
|
||||
export const post = (url, data) => { |
||||
const options = { |
||||
method: 'POST', |
||||
body: JSON.stringify(data), |
||||
headers: { |
||||
'Content-Type': 'application/json', |
||||
}, |
||||
}; |
||||
return new Promise((reslove, reject) => { |
||||
fetch(url, options) |
||||
.then((response) => response.json()) |
||||
.then((data) => console.log(data)) |
||||
.catch((error) => console.error('Error:', error)); |
||||
}); |
||||
}; |
@ -0,0 +1,11 @@
@@ -0,0 +1,11 @@
|
||||
import { post } from './base'; |
||||
|
||||
let commit; |
||||
|
||||
export const setCommit = (data) => { |
||||
commit = data; |
||||
}; |
||||
|
||||
export const login = (param) => { |
||||
post('api/public/login', param); |
||||
}; |
Loading…
Reference in new issue