提交信息
This commit is contained in:
commit
70ef2cf196
|
@ -0,0 +1,58 @@
|
||||||
|
# ignore these folders
|
||||||
|
target/
|
||||||
|
.idea/
|
||||||
|
.settings/
|
||||||
|
.vscode/
|
||||||
|
bin/
|
||||||
|
out/
|
||||||
|
|
||||||
|
# ignore these files
|
||||||
|
.classpath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.idea
|
||||||
|
|
||||||
|
# filter databfile、sln file
|
||||||
|
*.mdb
|
||||||
|
*.ldb
|
||||||
|
*.sln
|
||||||
|
|
||||||
|
# class file
|
||||||
|
*.com
|
||||||
|
*.class
|
||||||
|
*.dll
|
||||||
|
*.exe
|
||||||
|
*.o
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# compression file
|
||||||
|
*.7z
|
||||||
|
*.dmg
|
||||||
|
*.gz
|
||||||
|
*.iso
|
||||||
|
*.jar
|
||||||
|
*.rar
|
||||||
|
*.tar
|
||||||
|
*.zip
|
||||||
|
*.via
|
||||||
|
*.tmp
|
||||||
|
*.err
|
||||||
|
*.log
|
||||||
|
*.iml
|
||||||
|
|
||||||
|
# OS generated files
|
||||||
|
.DS_Store
|
||||||
|
.DS_Store?
|
||||||
|
._*
|
||||||
|
.Spotlight-V100
|
||||||
|
.Trashes
|
||||||
|
Icon?
|
||||||
|
ehthumbs.db
|
||||||
|
Thumbs.db
|
||||||
|
.factorypath
|
||||||
|
.mvn/
|
||||||
|
mvnw.cmd
|
||||||
|
mvnw
|
||||||
|
|
||||||
|
# Files or folders need to be retained
|
||||||
|
# ...
|
|
@ -0,0 +1,15 @@
|
||||||
|
# 使用官方的OpenJDK基础镜像
|
||||||
|
#FROM openjdk:8-jre-slim
|
||||||
|
FROM openjdk:17
|
||||||
|
|
||||||
|
# 在镜像中创建一个目录用于存放我们的应用
|
||||||
|
VOLUME /tmp
|
||||||
|
|
||||||
|
# 将jar包添加到镜像中并更名为app.jar
|
||||||
|
ADD login/target/login.jar app.jar
|
||||||
|
# ADD shapelight-admin/src/main/resources/application.yml /config/application.yml
|
||||||
|
# ADD shapelight-admin/src/main/resources/application-dev.yml /config/application-de
|
||||||
|
|
||||||
|
# 在容器启动时运行jar包
|
||||||
|
# ENTRYPOINT ["java", "-jar", "app.jar", "--spring.config.location=/config/application.yml,/config/application-dev.yml"]
|
||||||
|
ENTRYPOINT ["java", "-jar", "app.jar"]
|
|
@ -0,0 +1,77 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.guwan</groupId>
|
||||||
|
<artifactId>old</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>login</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.xingyuv</groupId>
|
||||||
|
<artifactId>spring-boot-starter-captcha-plus</artifactId>
|
||||||
|
<version>2.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.lionsoul</groupId>
|
||||||
|
<artifactId>ip2region</artifactId>
|
||||||
|
<version>2.7.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-io</groupId>
|
||||||
|
<artifactId>commons-io</artifactId>
|
||||||
|
<version>2.5</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Sa-Token 权限认证,在线文档:https://sa-token.cc -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.dev33</groupId>
|
||||||
|
<artifactId>sa-token-spring-boot3-starter</artifactId>
|
||||||
|
<version>1.39.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.pig4cloud.plugin</groupId>
|
||||||
|
<artifactId>oss-spring-boot-starter</artifactId>
|
||||||
|
<version>3.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.minio</groupId>
|
||||||
|
<artifactId>minio</artifactId>
|
||||||
|
<version>7.0.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<finalName>${project.artifactId}</finalName>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.guwan.Interceptor;
|
||||||
|
|
||||||
|
import com.guwan.service.TokenService;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.servlet.HandlerInterceptor;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class TokenInterceptor implements HandlerInterceptor {
|
||||||
|
|
||||||
|
private final TokenService tokenService;
|
||||||
|
|
||||||
|
// 注入自定义的 Token 处理服务
|
||||||
|
public TokenInterceptor(TokenService tokenService) {
|
||||||
|
this.tokenService = tokenService;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 在控制器方法执行之前调用
|
||||||
|
@Override
|
||||||
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
|
||||||
|
// 从请求头中获取 Token
|
||||||
|
String token = request.getHeader("Authorization");
|
||||||
|
|
||||||
|
if (token != null) {
|
||||||
|
// 验证 Token 的有效性
|
||||||
|
boolean isValid = tokenService.checkToken(token);
|
||||||
|
if (isValid) {
|
||||||
|
// 如果 Token 有效,可能需要更新 Token 并将新的 Token 添加到响应头中
|
||||||
|
/* String newToken = tokenService.refreshToken(token);
|
||||||
|
if (newToken != null) {
|
||||||
|
response.setHeader("Authorization", newToken);
|
||||||
|
}*/
|
||||||
|
return true; // Token 有效,继续处理请求
|
||||||
|
} else {
|
||||||
|
// 如果 Token 无效,返回未授权状态码
|
||||||
|
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||||
|
return false; // 拦截请求
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果没有 Token,返回未授权状态码
|
||||||
|
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||||
|
return false; // 拦截请求
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
package com.guwan;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.SaManager;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class LoginApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(LoginApplication.class, args);
|
||||||
|
System.out.println("启动成功,Sa-Token 配置如下:" + SaManager.getConfig());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
|
||||||
|
|
||||||
|
package com.guwan.common;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回数据
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class R extends HashMap<String, Object> {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
public R() {
|
||||||
|
put("code", 0);
|
||||||
|
put("msg", "success");
|
||||||
|
put("data", new HashMap<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static R error() {
|
||||||
|
// return error(500, "未知异常,请联系管理员");
|
||||||
|
return error(500, "系统开小差了");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static R error(String msg) {
|
||||||
|
return error(500, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static R error(int code, String msg) {
|
||||||
|
R r = new R();
|
||||||
|
r.put("code", code);
|
||||||
|
r.put("msg", msg);
|
||||||
|
r.put("data",new HashMap<>());
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static R ok(String msg) {
|
||||||
|
R r = new R();
|
||||||
|
r.put("msg", msg);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static R ok(Map<String, Object> map) {
|
||||||
|
R r = new R();
|
||||||
|
r.putAll(map);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static R ok() {
|
||||||
|
return new R();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public R put(String key, Object value) {
|
||||||
|
super.put(key, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
package com.guwan.config;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
/*
|
||||||
|
global:
|
||||||
|
http_flag: http
|
||||||
|
file_path:
|
||||||
|
static-locations: /home/shapelight/sl_site
|
||||||
|
static-user_path: userdata
|
||||||
|
#log_file: snail_develop.log
|
||||||
|
#http_flag: http
|
||||||
|
user_path: /home/shapelight/Snail_develop/UserData
|
||||||
|
common_path: /home/shapelight/Snail_develop/Common
|
||||||
|
wx_code_path: /home/shapelight/Snail_develop/WxCode
|
||||||
|
doc_path: /home/shapelight/Snail_develop/Doc
|
||||||
|
apk_path: /home/shapelight/Snail_develop/Apk
|
||||||
|
ten_pic: pic
|
||||||
|
ten_wx: wx
|
||||||
|
ten_xlsx: xlsx
|
||||||
|
ten_song: song
|
||||||
|
ten_logo: logo
|
||||||
|
ten_member_org: member_org
|
||||||
|
ten_member_face: member_face
|
||||||
|
ten_visitor_org: visitor_org
|
||||||
|
ten_visitor_face: visitor_face
|
||||||
|
ten_member_rec_org: member_rec_org
|
||||||
|
ten_member_rec_face: member_rec_face
|
||||||
|
ten_visitor_rec_org: visitor_rec_org
|
||||||
|
ten_visitor_rec_face: visitor_rec_face
|
||||||
|
url:
|
||||||
|
#addr: 192.168.1.50:9902
|
||||||
|
url_img: 192.168.1.50:9903
|
||||||
|
url_out: 192.168.1.50:9903
|
||||||
|
url_license: 39.96.9.232:3389
|
||||||
|
upload_zip:
|
||||||
|
protocal: http://
|
||||||
|
ip: 127.0.0.1
|
||||||
|
port: 8001
|
||||||
|
zippath: /home/shapelight/DataBase/studentOrg
|
||||||
|
small-face-path: /home/shapelight/DataBase/studentFace
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Data
|
||||||
|
public class GlobalValue {
|
||||||
|
|
||||||
|
@Value("${global.minio.endpoint}")
|
||||||
|
private String minioEndpoint;
|
||||||
|
@Value("${global.minio.port}")
|
||||||
|
private String minioPort;
|
||||||
|
@Value("${global.minio.accessKey}")
|
||||||
|
private String minioAccessKey;
|
||||||
|
@Value("${global.minio.secretKey}")
|
||||||
|
private String minioSecretKey;
|
||||||
|
@Value("${global.minio.bucketName}")
|
||||||
|
private String minioBucketName;
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package com.guwan.config;
|
||||||
|
|
||||||
|
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
|
||||||
|
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||||
|
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class JsonRedisTemplate extends RedisTemplate<String, Object>{
|
||||||
|
|
||||||
|
public JsonRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
|
||||||
|
|
||||||
|
// 构造函数注入 RedisConnectionFactory,设置到父类
|
||||||
|
super.setConnectionFactory(redisConnectionFactory);
|
||||||
|
|
||||||
|
// 使用 Jackson 提供的通用 Serializer
|
||||||
|
GenericJackson2JsonRedisSerializer serializer = new GenericJackson2JsonRedisSerializer();
|
||||||
|
serializer.configure(mapper -> {
|
||||||
|
// 如果涉及到对 java.time 类型的序列化,反序列化那么需要注册 JavaTimeModule
|
||||||
|
mapper.registerModule(new JavaTimeModule());
|
||||||
|
});
|
||||||
|
|
||||||
|
// String 类型的 key/value 序列化
|
||||||
|
super.setKeySerializer(StringRedisSerializer.UTF_8);
|
||||||
|
super.setValueSerializer(serializer);
|
||||||
|
|
||||||
|
// Hash 类型的 key/value 序列化
|
||||||
|
super.setHashKeySerializer(StringRedisSerializer.UTF_8);
|
||||||
|
super.setHashValueSerializer(serializer);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
package com.guwan.config;
|
||||||
|
|
||||||
|
import io.minio.MinioClient;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对象存储工具类
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class MinioConfig {
|
||||||
|
@Autowired
|
||||||
|
private GlobalValue globalValue;
|
||||||
|
|
||||||
|
public String getMinioEndpoint() {
|
||||||
|
return globalValue.getMinioEndpoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getBucketName(){
|
||||||
|
return globalValue.getMinioBucketName();
|
||||||
|
}
|
||||||
|
@Bean("minioClient")
|
||||||
|
public MinioClient minioClient(){
|
||||||
|
MinioClient minioClient=null;
|
||||||
|
try {
|
||||||
|
minioClient = new MinioClient(globalValue.getMinioEndpoint(),
|
||||||
|
// globalValue.getMinioPort(),
|
||||||
|
globalValue.getMinioAccessKey(),
|
||||||
|
globalValue.getMinioSecretKey());
|
||||||
|
if (!minioClient.bucketExists(globalValue.getMinioBucketName())) {
|
||||||
|
minioClient.makeBucket(globalValue.getMinioBucketName());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return minioClient;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
package com.guwan.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
|
||||||
|
import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||||
|
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class RedisConfig {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 实例化 RedisTemplate 对象
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public RedisTemplate<String, Object> functionDomainRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
|
||||||
|
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
|
||||||
|
initDomainRedisTemplate(redisTemplate, redisConnectionFactory);
|
||||||
|
return redisTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置数据存入 redis 的序列化方式,并开启事务
|
||||||
|
*
|
||||||
|
* @param redisTemplate
|
||||||
|
* @param factory
|
||||||
|
*/
|
||||||
|
private void initDomainRedisTemplate(RedisTemplate<String, Object> redisTemplate, RedisConnectionFactory factory) {
|
||||||
|
// 如果不配置Serializer,那么存储的时候缺省使用String,如果用User类型存储,那么会提示错误User can't cast to String!
|
||||||
|
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
||||||
|
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
|
||||||
|
redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
|
||||||
|
redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
|
||||||
|
// 开启事务
|
||||||
|
redisTemplate.setEnableTransactionSupport(true);
|
||||||
|
redisTemplate.setConnectionFactory(factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package com.guwan.config;
|
||||||
|
|
||||||
|
import com.guwan.Interceptor.TokenInterceptor;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class WebConfig implements WebMvcConfigurer {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TokenInterceptor tokenInterceptor;
|
||||||
|
@Override
|
||||||
|
public void addInterceptors(InterceptorRegistry registry) {
|
||||||
|
// 添加自定义的 Token 拦截器
|
||||||
|
registry.addInterceptor(tokenInterceptor)
|
||||||
|
.addPathPatterns("/user/**") // 拦截 /User/** 路径
|
||||||
|
.excludePathPatterns("/user/login"); // 不拦截 /User/login 路径
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
package com.guwan.controller.login;
|
||||||
|
|
||||||
|
import com.xingyuv.captcha.model.common.ResponseModel;
|
||||||
|
import com.xingyuv.captcha.model.vo.CaptchaVO;
|
||||||
|
import com.xingyuv.captcha.service.CaptchaService;
|
||||||
|
import com.xingyuv.captcha.util.StringUtils;
|
||||||
|
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 jakarta.annotation.Resource;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/captcha")
|
||||||
|
public class CaptchaController {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CaptchaService captchaService;
|
||||||
|
|
||||||
|
@PostMapping("/get")
|
||||||
|
public ResponseModel get(@RequestBody CaptchaVO data, HttpServletRequest request) {
|
||||||
|
assert request.getRemoteHost() != null;
|
||||||
|
data.setBrowserInfo(getRemoteId(request));
|
||||||
|
return captchaService.get(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@PostMapping("/check")
|
||||||
|
public ResponseModel check(@RequestBody CaptchaVO data, HttpServletRequest request) {
|
||||||
|
data.setBrowserInfo(getRemoteId(request));
|
||||||
|
return captchaService.check(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
//@PostMapping("/verify")
|
||||||
|
public ResponseModel verify(@RequestBody CaptchaVO data, HttpServletRequest request) {
|
||||||
|
return captchaService.verification(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getRemoteId(HttpServletRequest request) {
|
||||||
|
String xfwd = request.getHeader("X-Forwarded-For");
|
||||||
|
String ip = getRemoteIpFromXfwd(xfwd);
|
||||||
|
String ua = request.getHeader("user-agent");
|
||||||
|
if (StringUtils.isNotBlank(ip)) {
|
||||||
|
return ip + ua;
|
||||||
|
}
|
||||||
|
return request.getRemoteAddr() + ua;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getRemoteIpFromXfwd(String xfwd) {
|
||||||
|
if (StringUtils.isNotBlank(xfwd)) {
|
||||||
|
String[] ipList = xfwd.split(",");
|
||||||
|
return StringUtils.trim(ipList[0]);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,31 @@
|
||||||
|
package com.guwan.controller.login;
|
||||||
|
|
||||||
|
import cn.dev33.satoken.stp.StpUtil;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/user/")
|
||||||
|
public class SatokenController {
|
||||||
|
|
||||||
|
// 测试登录,浏览器访问: http://localhost:8081/user/doLogin?username=zhang&password=123456
|
||||||
|
|
||||||
|
// 存到cookie里面
|
||||||
|
|
||||||
|
@RequestMapping("doLogin")
|
||||||
|
public String doLogin(String username, String password) {
|
||||||
|
// 此处仅作模拟示例,真实项目需要从数据库中查询数据进行比对
|
||||||
|
if("zhang".equals(username) && "123456".equals(password)) {
|
||||||
|
StpUtil.login(10001);
|
||||||
|
return "登录成功";
|
||||||
|
}
|
||||||
|
return "登录失败";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询登录状态,浏览器访问: http://localhost:8081/user/isLogin
|
||||||
|
@RequestMapping("isLogin")
|
||||||
|
public String isLogin() {
|
||||||
|
return "当前会话是否登录:" + StpUtil.isLogin();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,93 @@
|
||||||
|
package com.guwan.controller.login;
|
||||||
|
|
||||||
|
import cn.hutool.http.HttpUtil;
|
||||||
|
import cn.hutool.json.JSONObject;
|
||||||
|
import cn.hutool.json.JSONUtil;
|
||||||
|
import com.guwan.controller.login.info.UserRequest;
|
||||||
|
import com.guwan.controller.login.info.WxMaUserInfo;
|
||||||
|
import com.guwan.controller.login.request.ScanResult;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
public class ScanCodeController {
|
||||||
|
|
||||||
|
@Operation(summary = "获取微信登录二维码信息")
|
||||||
|
@RequestMapping("/wxQr")
|
||||||
|
@ResponseBody
|
||||||
|
public void wxQr(String secret) {
|
||||||
|
// 请求易登获取二维码接口
|
||||||
|
String s = HttpUtil.get("https://yd.jylt.cc/api/wxLogin/tempUserId?secret=" + secret);
|
||||||
|
JSONObject jsonObject = JSONUtil.parseObj(s);
|
||||||
|
if (jsonObject.getInt("code") != 0) {
|
||||||
|
System.out.println(jsonObject.getInt("code") + "二维码获取失败");
|
||||||
|
}else {
|
||||||
|
System.out.println(jsonObject.getJSONObject("data"));
|
||||||
|
System.out.println(jsonObject.getJSONObject("data").
|
||||||
|
getStr("qrUrl"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("/callback")
|
||||||
|
public ScanResult handleUserRequest(@RequestBody UserRequest userRequest) {
|
||||||
|
// 从userRequest中提取信息
|
||||||
|
String tempUserId = userRequest.getTempUserId();
|
||||||
|
WxMaUserInfo wxMaUserInfo = userRequest.getWxMaUserInfo();
|
||||||
|
|
||||||
|
// 你可以在这里添加你的业务逻辑,比如保存用户信息到数据库等
|
||||||
|
|
||||||
|
System.out.println(tempUserId);
|
||||||
|
System.out.println(userRequest.getWxMaUserInfo().getNickName());
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {
|
||||||
|
* "code": "0:登录成功;其他:登录失败",
|
||||||
|
* "msg": "响应给用户的提示信息,该信息用于在小程序端进行提示"
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
|
// 以下是一个简单的响应示例
|
||||||
|
return new ScanResult(0, "恭喜" +
|
||||||
|
userRequest.getWxMaUserInfo().getNickName() + "成功登录!!!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//用户必须要修改 易登 的信息
|
||||||
|
//生产二维码之后 会有一个随机id
|
||||||
|
|
||||||
|
//用户 如果想使用扫码登录 必须要注册 易登
|
||||||
|
//而且必须要把 易登 的名字改成和系统一样
|
||||||
|
|
||||||
|
|
||||||
|
public ScanResult demo(@RequestBody UserRequest userRequest) {
|
||||||
|
// 从userRequest中提取信息
|
||||||
|
String tempUserId = userRequest.getTempUserId();
|
||||||
|
WxMaUserInfo wxMaUserInfo = userRequest.getWxMaUserInfo();
|
||||||
|
|
||||||
|
// 你可以在这里添加你的业务逻辑,比如保存用户信息到数据库等
|
||||||
|
System.out.println(tempUserId);
|
||||||
|
System.out.println(wxMaUserInfo.getNickName());
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
"code": "0:登录成功;其他:登录失败",
|
||||||
|
"msg": "响应给用户的提示信息,该信息用于在小程序端进行提示"
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
//TODO: 查询该用户是否注册
|
||||||
|
// 注册之后 走 token 逻辑
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 以下是一个简单的响应示例
|
||||||
|
return new ScanResult(0, "恭喜" +
|
||||||
|
userRequest.getWxMaUserInfo().getNickName() + "成功登录!!!");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
package com.guwan.controller.login;
|
||||||
|
|
||||||
|
import com.guwan.common.R;
|
||||||
|
import com.guwan.config.MinioConfig;
|
||||||
|
import com.pig4cloud.plugin.oss.service.OssTemplate;
|
||||||
|
import io.minio.MinioClient;
|
||||||
|
import io.minio.PutObjectOptions;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import lombok.RequiredArgsConstructor;
|
||||||
|
import org.apache.commons.io.FilenameUtils;
|
||||||
|
import org.apache.http.entity.FileEntity;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.time.Duration;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("")
|
||||||
|
@RequiredArgsConstructor
|
||||||
|
public class UploadController {
|
||||||
|
|
||||||
|
|
||||||
|
private final MinioConfig minioConfig;
|
||||||
|
|
||||||
|
private final MinioClient minioClient;
|
||||||
|
|
||||||
|
|
||||||
|
private final OssTemplate template;
|
||||||
|
/**
|
||||||
|
* 上传文件
|
||||||
|
* 文件名采用uuid,避免原始文件名中带"-"符号导致下载的时候解析出现异常
|
||||||
|
* @param file 资源
|
||||||
|
* @return R(bucketName, filename)
|
||||||
|
*/
|
||||||
|
@PostMapping("/upload")
|
||||||
|
public String upload(@RequestParam("file") MultipartFile file) throws IOException {
|
||||||
|
String originalFilename = file.getOriginalFilename();
|
||||||
|
String uuid = UUID.randomUUID().toString().replaceAll("-", "");
|
||||||
|
String fileName = uuid + originalFilename;
|
||||||
|
template.putObject("demo", uuid + originalFilename, file.getInputStream());
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取外链
|
||||||
|
* @param bucketName bucket名称
|
||||||
|
* @param objectName 文件名称
|
||||||
|
* @param minutes 过期时间,单位分钟,请注意该值必须小于7天
|
||||||
|
* @return url
|
||||||
|
*/
|
||||||
|
|
||||||
|
@GetMapping("/getDownloadExternalChain")
|
||||||
|
public String get(String bucketName, String objectName, int minutes) {
|
||||||
|
return template.getObjectURL(bucketName, objectName, Duration.ofMinutes(minutes));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@PostMapping("/GBUpload")
|
||||||
|
public R gbUpload(MultipartFile file) {
|
||||||
|
if (file.isEmpty() || file.getSize() == 0) {
|
||||||
|
System.out.println("文件不能为空");
|
||||||
|
}
|
||||||
|
String fileName = null;
|
||||||
|
|
||||||
|
String catalogue;
|
||||||
|
|
||||||
|
try {
|
||||||
|
String extension = FilenameUtils.getExtension(file.getOriginalFilename()); //后缀名
|
||||||
|
if (extension.equals("png") || extension.equals("jpg")){
|
||||||
|
catalogue = "photo/";
|
||||||
|
}else if (extension.equals("mp4")){
|
||||||
|
catalogue = "video/";
|
||||||
|
}else {
|
||||||
|
return R.error().put("info", "不允许上传此类型!");
|
||||||
|
}
|
||||||
|
|
||||||
|
fileName = catalogue + "t_" +
|
||||||
|
UUID.randomUUID().toString().replace("-","") +
|
||||||
|
"." + extension;
|
||||||
|
InputStream inputStream = file.getInputStream();
|
||||||
|
PutObjectOptions putObjectOptions = new PutObjectOptions(inputStream.available(), -1);
|
||||||
|
putObjectOptions.setContentType(file.getContentType());
|
||||||
|
minioClient.putObject(
|
||||||
|
minioConfig.getBucketName(), fileName, inputStream, putObjectOptions);
|
||||||
|
inputStream.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
System.out.println("方法结束");
|
||||||
|
|
||||||
|
|
||||||
|
UUID uuid = UUID.randomUUID();
|
||||||
|
String replace = uuid.toString().replace("-", "");
|
||||||
|
|
||||||
|
int lastDotIndex = file.getOriginalFilename().lastIndexOf('.');
|
||||||
|
|
||||||
|
String substring = file.getOriginalFilename().substring(0, lastDotIndex);
|
||||||
|
|
||||||
|
/* FileEntity fileEntity = new FileEntity(replace,
|
||||||
|
substring, fileName, new Date());
|
||||||
|
cqFileMapper.insert(fileEntity);
|
||||||
|
|
||||||
|
return R.ok().put("data", fileEntity);*/
|
||||||
|
return R.ok().put("data", minioConfig.getMinioEndpoint() + "/" +
|
||||||
|
minioConfig.getBucketName() + "/" + fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.guwan.controller.login;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class User {
|
||||||
|
private Long id;
|
||||||
|
private String name;
|
||||||
|
private Integer age;
|
||||||
|
private String email;
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
package com.guwan.controller.login;
|
||||||
|
|
||||||
|
import com.guwan.service.TokenService;
|
||||||
|
import com.guwan.util.IPUtils;
|
||||||
|
import jakarta.annotation.security.PermitAll;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/user")
|
||||||
|
public class UserController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TokenService tokenService;
|
||||||
|
|
||||||
|
@GetMapping("/login")
|
||||||
|
@PermitAll
|
||||||
|
@Operation(summary = "使用账号密码登录")
|
||||||
|
public String login(String userId, HttpServletRequest request) {
|
||||||
|
String ip = IPUtils.getIpAddr(request);
|
||||||
|
System.out.println("ip = " + ip);
|
||||||
|
return tokenService.createToken(userId, ip);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/getInfo")
|
||||||
|
@PermitAll
|
||||||
|
@Operation(summary = "查询用户信息")
|
||||||
|
public String getInfo(String token) {
|
||||||
|
|
||||||
|
|
||||||
|
if (!tokenService.checkToken(token)) {
|
||||||
|
return "token无效";
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
tokenService.getInfo(token);
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}finally {
|
||||||
|
tokenService.validateAndExtendToken(token);
|
||||||
|
}
|
||||||
|
return "getInfo";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package com.guwan.controller.login;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface UserMapper extends BaseMapper<User> {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.guwan.controller.login.info;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class UserRequest {
|
||||||
|
private String tempUserId;
|
||||||
|
private WxMaUserInfo wxMaUserInfo;
|
||||||
|
|
||||||
|
// 省略getter和setter方法
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package com.guwan.controller.login.info;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class WxMaUserInfo {
|
||||||
|
private String openId;
|
||||||
|
private String nickName;
|
||||||
|
private String gender;
|
||||||
|
private String avatarUrl;
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
package com.guwan.controller.login.request;
|
||||||
|
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Data
|
||||||
|
public class ScanResult {
|
||||||
|
private int code;
|
||||||
|
|
||||||
|
|
||||||
|
private String msg;
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
/**
|
||||||
|
* Copyright (c) 2020 wuchenxi
|
||||||
|
* walter-blog is licensed under Mulan PSL v2.
|
||||||
|
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||||
|
* You may obtain a copy of Mulan PSL v2 at:
|
||||||
|
* http://license.coscl.org.cn/MulanPSL2
|
||||||
|
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the Mulan PSL v2 for more details.
|
||||||
|
* <p>
|
||||||
|
* <p>
|
||||||
|
* Mulan Permissive Software License,Version 2
|
||||||
|
* <p>
|
||||||
|
* Mulan Permissive Software License,Version 2 (Mulan PSL v2)
|
||||||
|
* January 2020 http://license.coscl.org.cn/MulanPSL2
|
||||||
|
*/
|
||||||
|
package com.guwan.controller.login.response;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一系统响应结果格式
|
||||||
|
*
|
||||||
|
* @author wuchenxi
|
||||||
|
* @date 2020-08-08 10:07:03
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class ResponseKit<T> implements Serializable {
|
||||||
|
|
||||||
|
|
||||||
|
private int code;
|
||||||
|
|
||||||
|
|
||||||
|
private String msg;
|
||||||
|
|
||||||
|
|
||||||
|
private T data;
|
||||||
|
|
||||||
|
private ResponseKit(int code, String msg) {
|
||||||
|
this.code = code;
|
||||||
|
this.msg = msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResponseKit(int code, T data) {
|
||||||
|
this.code = code;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> ResponseKit<T> success() {
|
||||||
|
return new ResponseKit<T>(200, "操作成功!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> ResponseKit<T> error(int code, String msg) {
|
||||||
|
return new ResponseKit<T>(code, msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> ResponseKit<T> success(T data) {
|
||||||
|
return new ResponseKit<T>(200, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResponseKit(){}
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
package com.guwan.service;
|
||||||
|
import com.guwan.config.JsonRedisTemplate;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class TokenService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private JsonRedisTemplate redisTemplate;
|
||||||
|
|
||||||
|
public String createToken(String userId, String ip) {
|
||||||
|
if (userId == null) {
|
||||||
|
throw new RuntimeException("userId 不能为空");
|
||||||
|
}
|
||||||
|
String token;
|
||||||
|
if (redisTemplate.opsForValue().get("User-token:" + userId) != null) {
|
||||||
|
redisTemplate.delete("User-info:" + redisTemplate.opsForValue().get("User-token:" + userId));
|
||||||
|
redisTemplate.delete("User-token:" + userId);
|
||||||
|
}
|
||||||
|
token = UUID.randomUUID().toString();
|
||||||
|
redisTemplate.opsForValue().set("User-token:" + userId, token, 30, TimeUnit.MINUTES);
|
||||||
|
HashMap<String, Object> userInfo = new HashMap<>();
|
||||||
|
userInfo.put("userId", userId);
|
||||||
|
userInfo.put("ip", ip);
|
||||||
|
userInfo.put("token", token);
|
||||||
|
redisTemplate.opsForHash().putAll("User-info:" + token, userInfo);
|
||||||
|
redisTemplate.expire("User-info:" + token, 30, TimeUnit.MINUTES);
|
||||||
|
// 将所有用户信息存储在一个键中
|
||||||
|
//redisTemplate.opsForValue().set("User-info-string:" + token, userInfo, 30, TimeUnit.MINUTES);
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean checkToken(String token) {
|
||||||
|
|
||||||
|
if (token != null) {
|
||||||
|
String key = "User-info:" + token;
|
||||||
|
Object value = redisTemplate.opsForHash().entries(key);
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Map<String, String> map = (Map<String, String>) value;
|
||||||
|
return map.get("userId") != null;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void validateAndExtendToken(String token) {
|
||||||
|
// 重置过期时间
|
||||||
|
//redisTemplate.expire("User-info-string:" + token, 30, TimeUnit.MINUTES);
|
||||||
|
String userId = (String) redisTemplate.opsForHash().get("User-info:" + token, "userId");
|
||||||
|
|
||||||
|
redisTemplate.opsForValue().
|
||||||
|
set("User-token:" + userId, token,
|
||||||
|
30, TimeUnit.MINUTES);
|
||||||
|
redisTemplate.expire("User-info:" + token, 30, TimeUnit.MINUTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void getInfo(String token) {
|
||||||
|
Map<Object, Object> map = redisTemplate.opsForHash().entries("User-info:" + token);
|
||||||
|
if (!map.isEmpty()) {
|
||||||
|
System.out.println(map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,99 @@
|
||||||
|
package com.guwan.util;
|
||||||
|
|
||||||
|
import cn.hutool.core.io.resource.ResourceUtil;
|
||||||
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.lionsoul.ip2region.xdb.Searcher;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IP 工具类
|
||||||
|
*
|
||||||
|
* IP 数据源来自 ip2region.xdb 精简版,基于 <a href="https://gitee.com/zhijiantianya/ip2region"/> 项目
|
||||||
|
*
|
||||||
|
* @author wanglhup
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
public class IPUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化 SEARCHER
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("InstantiationOfUtilityClass")
|
||||||
|
private final static IPUtils INSTANCE = new IPUtils();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* IP 查询器,启动加载到内存中
|
||||||
|
*/
|
||||||
|
private static Searcher SEARCHER;
|
||||||
|
private static final String UNKNOWN = "unknown";
|
||||||
|
|
||||||
|
private static final String LOCAL_IP = "127.0.0.1";
|
||||||
|
/**
|
||||||
|
* 私有化构造
|
||||||
|
*/
|
||||||
|
private IPUtils() {
|
||||||
|
try {
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
byte[] bytes = ResourceUtil.readBytes("ip2region.xdb");
|
||||||
|
SEARCHER = Searcher.newWithBuffer(bytes);
|
||||||
|
log.info("启动加载 IPUtils 成功,耗时 ({}) 毫秒", System.currentTimeMillis() - now);
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("启动加载 IPUtils 失败", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询 IP 对应的地区编号
|
||||||
|
*
|
||||||
|
* @param ip IP 地址,格式为 127.0.0.1
|
||||||
|
* @return 地区id
|
||||||
|
*/
|
||||||
|
@SneakyThrows
|
||||||
|
public static Integer getAreaId(String ip) {
|
||||||
|
return Integer.parseInt(SEARCHER.search(ip.trim()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询 IP 对应的地区编号
|
||||||
|
*
|
||||||
|
* @param ip IP 地址的时间戳,格式参考{@link Searcher#checkIP(String)} 的返回
|
||||||
|
* @return 地区编号
|
||||||
|
*/
|
||||||
|
@SneakyThrows
|
||||||
|
public static Integer getAreaId(long ip) {
|
||||||
|
return Integer.parseInt(SEARCHER.search(ip));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getIpAddr(HttpServletRequest request) {
|
||||||
|
|
||||||
|
if (request == null) {
|
||||||
|
return UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
String ip = request.getHeader("x-forwarded-for");
|
||||||
|
if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||||
|
ip = request.getHeader("Proxy-Client-IP");
|
||||||
|
}
|
||||||
|
if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||||
|
ip = request.getHeader("X-Forwarded-For");
|
||||||
|
}
|
||||||
|
if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||||
|
ip = request.getHeader("WL-Proxy-Client-IP");
|
||||||
|
}
|
||||||
|
if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||||
|
ip = request.getHeader("X-Real-IP");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(ip) || UNKNOWN.equalsIgnoreCase(ip)) {
|
||||||
|
ip = request.getRemoteAddr();
|
||||||
|
}
|
||||||
|
|
||||||
|
return "0:0:0:0:0:0:0:1".equals(ip) ? LOCAL_IP : ip;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
server:
|
||||||
|
port: 8084
|
||||||
|
|
||||||
|
spring:
|
||||||
|
data:
|
||||||
|
redis:
|
||||||
|
host: 1.92.149.170
|
||||||
|
port: 6379
|
||||||
|
password: 123456
|
||||||
|
database: 0
|
||||||
|
datasource:
|
||||||
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
|
url: jdbc:mysql://127.0.0.1:3306/studb
|
||||||
|
username: root
|
||||||
|
password: 123456
|
||||||
|
|
||||||
|
servlet:
|
||||||
|
multipart:
|
||||||
|
max-file-size: 1000MB
|
||||||
|
max-request-size: 1000MB
|
||||||
|
enabled: true
|
||||||
|
file-size-threshold: 1000MB
|
||||||
|
|
||||||
|
|
||||||
|
############## Sa-Token 配置 (文档: https://sa-token.cc) ##############
|
||||||
|
sa-token:
|
||||||
|
# token 名称(同时也是 cookie 名称)
|
||||||
|
token-name: satoken
|
||||||
|
# token 有效期(单位:秒) 默认30天,-1 代表永久有效
|
||||||
|
timeout: 2592000
|
||||||
|
# token 最低活跃频率(单位:秒),如果 token 超过此时间没有访问系统就会被冻结,默认-1 代表不限制,永不冻结
|
||||||
|
active-timeout: -1
|
||||||
|
# 是否允许同一账号多地同时登录 (为 true 时允许一起登录, 为 false 时新登录挤掉旧登录)
|
||||||
|
is-concurrent: true
|
||||||
|
# 在多人登录同一账号时,是否共用一个 token (为 true 时所有登录共用一个 token, 为 false 时每次登录新建一个 token)
|
||||||
|
is-share: true
|
||||||
|
# token 风格(默认可取值:uuid、simple-uuid、random-32、random-64、random-128、tik)
|
||||||
|
token-style: uuid
|
||||||
|
# 是否输出操作日志
|
||||||
|
is-log: true
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
oss:
|
||||||
|
endpoint: http://localhost:9000
|
||||||
|
access-key: admin
|
||||||
|
secret-key: admin123456
|
||||||
|
|
||||||
|
|
||||||
|
global:
|
||||||
|
minio:
|
||||||
|
endpoint: http://127.0.0.1:9000
|
||||||
|
port: 9000
|
||||||
|
accessKey: admin
|
||||||
|
secretKey: admin123456
|
||||||
|
bucketName: yunnni
|
Binary file not shown.
|
@ -0,0 +1,29 @@
|
||||||
|
package com.guwan;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
public class RedisTest {
|
||||||
|
@Autowired
|
||||||
|
private RedisTemplate redisTemplate;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSaveUser() {
|
||||||
|
String key = "user:1";
|
||||||
|
String value = "John Doe";
|
||||||
|
|
||||||
|
redisTemplate.opsForValue().set(key, value); // 保存数据
|
||||||
|
|
||||||
|
// 验证数据是否保存成功
|
||||||
|
String retrievedValue = (String) redisTemplate.opsForValue().get(key);
|
||||||
|
assertEquals(value, retrievedValue, "Retrieved value should match the saved value");
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.guwan;
|
||||||
|
|
||||||
|
import com.guwan.controller.login.User;
|
||||||
|
import com.guwan.controller.login.UserMapper;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
public class SampleTest {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserMapper userMapper;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSelect() {
|
||||||
|
System.out.println(("----- selectAll method test ------"));
|
||||||
|
List<User> userList = userMapper.selectList(null);
|
||||||
|
userList.forEach(System.out::println);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.guwan</groupId>
|
||||||
|
<artifactId>old</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>old-app</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.guwan</groupId>
|
||||||
|
<artifactId>old-nacos</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,15 @@
|
||||||
|
package cn;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class BsApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(BsApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package cn.config;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.api.config.annotation.NacosValue;
|
||||||
|
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Configuration
|
||||||
|
@NacosPropertySource(dataId = "mysql", autoRefreshed = true)
|
||||||
|
public class MysqlNacosConf {
|
||||||
|
|
||||||
|
@NacosValue("${spring.datasource.driver-class-name}")
|
||||||
|
private String driverClassName;
|
||||||
|
@NacosValue("${spring.datasource.url}")
|
||||||
|
private String url;
|
||||||
|
@NacosValue("${spring.datasource.username}")
|
||||||
|
private String username;
|
||||||
|
@NacosValue("${spring.datasource.password}")
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package cn.config;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.api.config.annotation.NacosValue;
|
||||||
|
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Configuration
|
||||||
|
@NacosPropertySource(dataId = "mysql", autoRefreshed = true)
|
||||||
|
public class NacosConfig {
|
||||||
|
|
||||||
|
@NacosValue("${spring.datasource.driver-class-name}")
|
||||||
|
private String driverClassName;
|
||||||
|
@NacosValue("${spring.datasource.url}")
|
||||||
|
private String url;
|
||||||
|
@NacosValue("${spring.datasource.username}")
|
||||||
|
private String username;
|
||||||
|
@NacosValue("${spring.datasource.password}")
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,21 @@
|
||||||
|
package cn.test;
|
||||||
|
|
||||||
|
import cn.config.MysqlNacosConf;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@Component
|
||||||
|
public class Demo {
|
||||||
|
@Autowired
|
||||||
|
private MysqlNacosConf mysqlNacosConf;
|
||||||
|
|
||||||
|
@GetMapping("/get")
|
||||||
|
public String get() {
|
||||||
|
System.out.println("nacosConfig.getDriverClassName() = " + mysqlNacosConf.getUrl());
|
||||||
|
return mysqlNacosConf.getUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
server:
|
||||||
|
port: 8080
|
||||||
|
nacos:
|
||||||
|
config:
|
||||||
|
server-addr: localhost:8848
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.guwan</groupId>
|
||||||
|
<artifactId>old</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>old-cache-redis</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.guwan</groupId>
|
||||||
|
<artifactId>old</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>old-face</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.tencentcloudapi</groupId>
|
||||||
|
<artifactId>tencentcloud-sdk-java</artifactId>
|
||||||
|
<version>3.1.830</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,156 @@
|
||||||
|
/*
|
||||||
|
package com.guwan.controller;
|
||||||
|
|
||||||
|
import com.mapper.UserMapper;
|
||||||
|
import com.pojo.Result;
|
||||||
|
import com.tencentcloudapi.common.AbstractModel;
|
||||||
|
import com.tencentcloudapi.common.Credential;
|
||||||
|
import com.tencentcloudapi.common.exception.TencentCloudSDKException;
|
||||||
|
import com.tencentcloudapi.common.profile.ClientProfile;
|
||||||
|
import com.tencentcloudapi.common.profile.HttpProfile;
|
||||||
|
import com.tencentcloudapi.iai.v20200303.IaiClient;
|
||||||
|
import com.tencentcloudapi.iai.v20200303.models.CreatePersonRequest;
|
||||||
|
import com.tencentcloudapi.iai.v20200303.models.CreatePersonResponse;
|
||||||
|
import com.tencentcloudapi.iai.v20200303.models.PersonExDescriptionInfo;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @author: 顾挽
|
||||||
|
* @description:
|
||||||
|
* @create: 2024-09-06 15:31
|
||||||
|
**//*
|
||||||
|
|
||||||
|
|
||||||
|
@RequestMapping("/face")
|
||||||
|
@RestController
|
||||||
|
public class FaceController {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserMapper userMapper;
|
||||||
|
|
||||||
|
@PostMapping("/upload")
|
||||||
|
public Result uploadFile(
|
||||||
|
@RequestParam("file") MultipartFile file,
|
||||||
|
@RequestParam("username") String username,
|
||||||
|
@RequestParam("realName") String realName,
|
||||||
|
@RequestParam("idCard") String idCard) {
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println("username: " + username);
|
||||||
|
System.out.println("realName: " + realName);
|
||||||
|
System.out.println("idCard: " + idCard);
|
||||||
|
|
||||||
|
if (file.isEmpty()) {
|
||||||
|
return Result.error("File is empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
// 实例化一个认证对象,入参需要传入腾讯云账户 SecretId 和 SecretKey,此处还需注意密钥对的保密
|
||||||
|
// 代码泄露可能会导致 SecretId 和 SecretKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考,建议采用更安全的方式来使用密钥,请参见:https://cloud.tencent.com/document/product/1278/85305
|
||||||
|
// 密钥可前往官网控制台 https://console.cloud.tencent.com/cam/capi 进行获取
|
||||||
|
Credential cred = new Credential("AKIDrhdr2JYdZMzQf2KWiqx47Vps3KsOtQFC",
|
||||||
|
"8PByngyJZkgZGsRrGiLviSIKSnGlI427");
|
||||||
|
// 实例化一个http选项,可选的,没有特殊需求可以跳过
|
||||||
|
HttpProfile httpProfile = new HttpProfile();
|
||||||
|
httpProfile.setEndpoint("iai.tencentcloudapi.com");
|
||||||
|
// 实例化一个client选项,可选的,没有特殊需求可以跳过
|
||||||
|
ClientProfile clientProfile = new ClientProfile();
|
||||||
|
clientProfile.setHttpProfile(httpProfile);
|
||||||
|
// 实例化要请求产品的client对象,clientProfile是可选的
|
||||||
|
IaiClient client = new IaiClient(cred, "ap-beijing", clientProfile);
|
||||||
|
// 实例化一个请求对象,每个接口都会对应一个request对象
|
||||||
|
CreatePersonRequest req = new CreatePersonRequest();
|
||||||
|
req.setGroupId("userRe");
|
||||||
|
req.setPersonName(username);
|
||||||
|
req.setPersonId(idCard);
|
||||||
|
|
||||||
|
PersonExDescriptionInfo[] personExDescriptionInfos1 = new PersonExDescriptionInfo[1];
|
||||||
|
PersonExDescriptionInfo personExDescriptionInfo1 = new PersonExDescriptionInfo();
|
||||||
|
personExDescriptionInfo1.setPersonExDescriptionIndex(0L);
|
||||||
|
personExDescriptionInfo1.setPersonExDescription(realName);
|
||||||
|
personExDescriptionInfos1[0] = personExDescriptionInfo1;
|
||||||
|
|
||||||
|
req.setPersonExDescriptionInfos(personExDescriptionInfos1);
|
||||||
|
|
||||||
|
|
||||||
|
byte[] fileBytes = file.getBytes();
|
||||||
|
|
||||||
|
// 将字节数组转换为 Base64 字符串
|
||||||
|
String base64Encoded = Base64.getEncoder().encodeToString(fileBytes);
|
||||||
|
|
||||||
|
|
||||||
|
req.setImage(base64Encoded);
|
||||||
|
|
||||||
|
|
||||||
|
// 返回的resp是一个CreatePersonResponse的实例,与请求对象对应
|
||||||
|
CreatePersonResponse resp = client.CreatePerson(req);
|
||||||
|
// 输出json格式的字符串回包
|
||||||
|
System.out.println(AbstractModel.toJsonString(resp));
|
||||||
|
|
||||||
|
if (resp.getFaceId() != null){
|
||||||
|
|
||||||
|
|
||||||
|
userMapper.changeFaceState(username);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 获取项目根目录
|
||||||
|
String rootDir = System.getProperty("user.dir");
|
||||||
|
|
||||||
|
// 确保上传目录存在
|
||||||
|
File uploadDir = new File(rootDir + File.separator + "uploads");
|
||||||
|
if (!uploadDir.exists()) {
|
||||||
|
uploadDir.mkdirs();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 保存文件到上传目录
|
||||||
|
String filePath = uploadDir.getPath() + File.separator + file.getOriginalFilename();
|
||||||
|
file.transferTo(new File(filePath));
|
||||||
|
|
||||||
|
System.out.println("File uploaded successfully: " + filePath);
|
||||||
|
|
||||||
|
*/
|
||||||
|
/* return Result.success("File uploaded successfully: " + filePath);*//*
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
*/
|
||||||
|
/* return Result.error("File upload failed");*//*
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
/* return Result.success();*//*
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
return Result.success();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} catch (TencentCloudSDKException e) {
|
||||||
|
System.out.println(e.toString());
|
||||||
|
return Result.error(e.toString());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.guwan.pojo;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class Result {
|
||||||
|
private Integer code;//响应码,1 代表成功; 0 代表失败
|
||||||
|
private String msg; //响应信息 描述字符串
|
||||||
|
private Object data; //返回的数据
|
||||||
|
|
||||||
|
//增删改 成功响应
|
||||||
|
public static Result success(){
|
||||||
|
return new Result(1,"success",null);
|
||||||
|
}
|
||||||
|
//查询 成功响应
|
||||||
|
public static Result success(Object data){
|
||||||
|
return new Result(1,"success",data);
|
||||||
|
}
|
||||||
|
//失败响应
|
||||||
|
public static Result error(String msg){
|
||||||
|
return new Result(0,msg,null);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.guwan</groupId>
|
||||||
|
<artifactId>old</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>old-nacos</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.boot</groupId>
|
||||||
|
<artifactId>nacos-config-spring-boot-starter</artifactId>
|
||||||
|
<version>0.3.0-RC</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,20 @@
|
||||||
|
package config;
|
||||||
|
|
||||||
|
import com.alibaba.nacos.api.config.annotation.NacosValue;
|
||||||
|
import com.alibaba.nacos.spring.context.annotation.config.NacosPropertySource;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@NacosPropertySource(dataId = "mysql", autoRefreshed = true)
|
||||||
|
public class MysqlNacosConf {
|
||||||
|
|
||||||
|
@NacosValue("${spring.datasource.driver-class-name}")
|
||||||
|
private String driverClassName;
|
||||||
|
@NacosValue("${spring.datasource.url}")
|
||||||
|
private String url;
|
||||||
|
@NacosValue("${spring.datasource.username}")
|
||||||
|
private String username;
|
||||||
|
@NacosValue("${spring.datasource.password}")
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>com.guwan</groupId>
|
||||||
|
<artifactId>old</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
<packaging>pom</packaging>
|
||||||
|
<modules>
|
||||||
|
<module>old-cache-redis</module>
|
||||||
|
<module>old-nacos</module>
|
||||||
|
<module>old-app</module>
|
||||||
|
<module>old-face</module>
|
||||||
|
<module>login</module>
|
||||||
|
<module>ss-Demo</module>
|
||||||
|
</modules>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>3.1.5</version>
|
||||||
|
<relativePath/>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Spring Data Redis -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Spring Boot Starter Test (可选) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springdoc</groupId> <!-- 接口文档:使用最新版本的 Swagger 模型 -->
|
||||||
|
<artifactId>springdoc-openapi-starter-webmvc-api</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
|
<version>2.5.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-all</artifactId>
|
||||||
|
<version>5.8.32</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!--mysql-db-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
|
<version>8.0.33</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!--mp-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
|
||||||
|
<version>3.5.7</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.shardingsphere</groupId>
|
||||||
|
<artifactId>shardingsphere-jdbc-core</artifactId>
|
||||||
|
<version>5.4.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- HikariCP -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.zaxxer</groupId>
|
||||||
|
<artifactId>HikariCP</artifactId>
|
||||||
|
<version>5.0.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,20 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.guwan</groupId>
|
||||||
|
<artifactId>old</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>ss-Demo</artifactId>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
</project>
|
|
@ -0,0 +1,19 @@
|
||||||
|
package com.guwan;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
|
import org.springframework.scheduling.annotation.EnableAsync;
|
||||||
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
|
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
@EnableAsync
|
||||||
|
@EnableTransactionManagement
|
||||||
|
public class SsDemoApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(SsDemoApplication.class, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
package com.guwan.controller;
|
||||||
|
|
||||||
|
|
||||||
|
import com.guwan.dal.dataobject.Order;
|
||||||
|
import com.guwan.service.OrderService;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/orders")
|
||||||
|
public class OrderController {
|
||||||
|
@Autowired
|
||||||
|
private OrderService orderService;
|
||||||
|
|
||||||
|
@PostMapping
|
||||||
|
public void createOrder(@RequestBody Order order) {
|
||||||
|
orderService.createOrder(order);
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/{userId}")
|
||||||
|
public List<Order> getOrders(@PathVariable Long userId) {
|
||||||
|
return orderService.getOrdersByUserId(userId);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
package com.guwan.dal.dataobject;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Order {
|
||||||
|
private Long orderId;
|
||||||
|
private Long userId;
|
||||||
|
private String orderContent;
|
||||||
|
}
|
|
@ -0,0 +1,15 @@
|
||||||
|
package com.guwan.dal.mysql;
|
||||||
|
|
||||||
|
|
||||||
|
import com.guwan.dal.dataobject.Order;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Mapper
|
||||||
|
public interface OrderMapper {
|
||||||
|
void insertOrder(Order order);
|
||||||
|
|
||||||
|
List<Order> selectOrdersByUserId(@Param("userId") Long userId);
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package com.guwan.service;
|
||||||
|
|
||||||
|
|
||||||
|
import com.guwan.dal.dataobject.Order;
|
||||||
|
import com.guwan.dal.mysql.OrderMapper;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class OrderService {
|
||||||
|
@Autowired
|
||||||
|
private OrderMapper orderMapper;
|
||||||
|
|
||||||
|
public void createOrder(Order order) {
|
||||||
|
orderMapper.insertOrder(order);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Order> getOrdersByUserId(Long userId) {
|
||||||
|
return orderMapper.selectOrdersByUserId(userId);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
spring:
|
||||||
|
profiles:
|
||||||
|
active: dev
|
||||||
|
application:
|
||||||
|
name: sharging-jdbc-demo
|
||||||
|
shardingsphere:
|
||||||
|
datasource:
|
||||||
|
names: master,slave1
|
||||||
|
master:
|
||||||
|
type: com.zaxxer.hikari.HikariDataSource # 数据源类型
|
||||||
|
url: jdbc:mysql://localhost:3306/course_master_db # 数据库连接地址
|
||||||
|
username: root # 用户名
|
||||||
|
password: 123456 # 密码
|
||||||
|
driver-class-name: com.mysql.jdbc.Driver # 数据库驱动
|
||||||
|
slave1:
|
||||||
|
type: com.zaxxer.hikari.HikariDataSource # 数据源类型
|
||||||
|
url: jdbc:mysql://localhost:3306/course_db # 数据库连接地址
|
||||||
|
username: root # 用户名
|
||||||
|
password: 123456 # 密码
|
||||||
|
driver-class-name: com.mysql.jdbc.Driver # 数据库驱动
|
||||||
|
rules:
|
||||||
|
readwrite-splitting:
|
||||||
|
data-sources:
|
||||||
|
mds: #名字自定义
|
||||||
|
type: static #类型 静态获取
|
||||||
|
props:
|
||||||
|
auto-aware-data-source-name: master
|
||||||
|
write-data-source-name: master
|
||||||
|
read-data-source-names: slave1
|
||||||
|
load-balancer-name: read-random #读写分离规则自定义命名
|
||||||
|
load-balancers:
|
||||||
|
read-random:
|
||||||
|
type: ROUND_ROBIN # 轮询负载均衡
|
||||||
|
props:
|
||||||
|
sql-show: true # 是否打印sql
|
||||||
|
sql-simple: true # 打印简单的sql
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="com.guwan.dal.mysql.OrderMapper">
|
||||||
|
<insert id="insertOrder" parameterType="com.guwan.dal.dataobject.Order">
|
||||||
|
INSERT INTO t_order (order_id, user_id, order_content) VALUES (#{orderId}, #{userId}, #{orderContent})
|
||||||
|
</insert>
|
||||||
|
|
||||||
|
<select id="selectOrdersByUserId" parameterType="Long" resultType="com.guwan.dal.dataobject.Order">
|
||||||
|
SELECT * FROM t_order WHERE user_id = #{userId}
|
||||||
|
</select>
|
||||||
|
</mapper>
|
Loading…
Reference in New Issue