mirror of
https://github.com/qaiu/netdisk-fast-download.git
synced 2025-12-16 12:23:03 +00:00
添加支持 QQ闪传,微雨云,优化前端逻辑
This commit is contained in:
@@ -3,6 +3,7 @@ package cn.qaiu.lz.web.model;
|
||||
import cn.qaiu.db.ddl.Table;
|
||||
import cn.qaiu.lz.common.ToJson;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import io.vertx.codegen.annotations.DataObject;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import lombok.Data;
|
||||
@@ -14,12 +15,27 @@ import java.time.format.DateTimeFormatter;
|
||||
@Data
|
||||
@DataObject
|
||||
@NoArgsConstructor
|
||||
@Table("t_user")
|
||||
@Table("sys_user")
|
||||
public class SysUser implements ToJson {
|
||||
private String id;
|
||||
private String username;
|
||||
|
||||
private String password;
|
||||
|
||||
private String email;
|
||||
private String phone;
|
||||
private String avatar;
|
||||
|
||||
// 用户状态:0-禁用,1-正常
|
||||
private Integer status;
|
||||
|
||||
// 用户角色:admin-管理员,user-普通用户
|
||||
private String role;
|
||||
|
||||
// 最后登录时间
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
|
||||
private LocalDateTime lastLoginTime;
|
||||
|
||||
private Integer age;
|
||||
@JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
|
||||
private LocalDateTime createTime;
|
||||
@@ -28,9 +44,17 @@ public class SysUser implements ToJson {
|
||||
this.id = json.getString("id");
|
||||
this.username = json.getString("username");
|
||||
this.password = json.getString("password");
|
||||
this.email = json.getString("email");
|
||||
this.phone = json.getString("phone");
|
||||
this.avatar = json.getString("avatar");
|
||||
this.status = json.getInteger("status");
|
||||
this.role = json.getString("role");
|
||||
this.age = json.getInteger("age");
|
||||
if (json.getString("createTime") != null) {
|
||||
this.createTime = LocalDateTime.parse(json.getString("createTime"));
|
||||
}
|
||||
if (json.getString("lastLoginTime") != null) {
|
||||
this.lastLoginTime = LocalDateTime.parse(json.getString("lastLoginTime"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,14 +4,48 @@ import cn.qaiu.lz.web.model.SysUser;
|
||||
import cn.qaiu.vx.core.base.BaseAsyncService;
|
||||
import io.vertx.codegen.annotations.ProxyGen;
|
||||
import io.vertx.core.Future;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
|
||||
/**
|
||||
* lz-web
|
||||
* 用户服务接口
|
||||
* <br>Create date 2021/8/27 14:06
|
||||
*
|
||||
* @author <a href="https://qaiu.top">QAIU</a>
|
||||
*/
|
||||
@ProxyGen
|
||||
public interface UserService extends BaseAsyncService {
|
||||
Future<SysUser> login(SysUser user);
|
||||
/**
|
||||
* 用户登录
|
||||
* @param user 包含用户名和密码的用户对象
|
||||
* @return 登录成功返回用户信息和token,失败返回错误信息
|
||||
*/
|
||||
Future<JsonObject> login(SysUser user);
|
||||
|
||||
/**
|
||||
* 根据用户名获取用户信息
|
||||
* @param username 用户名
|
||||
* @return 用户信息
|
||||
*/
|
||||
Future<SysUser> getUserByUsername(String username);
|
||||
|
||||
/**
|
||||
* 创建新用户
|
||||
* @param user 用户信息
|
||||
* @return 创建成功返回用户信息,失败返回错误信息
|
||||
*/
|
||||
Future<SysUser> createUser(SysUser user);
|
||||
|
||||
/**
|
||||
* 更新用户信息
|
||||
* @param user 用户信息
|
||||
* @return 更新成功返回用户信息,失败返回错误信息
|
||||
*/
|
||||
Future<SysUser> updateUser(SysUser user);
|
||||
|
||||
/**
|
||||
* 验证token
|
||||
* @param token JWT token
|
||||
* @return 验证成功返回用户信息,失败返回错误信息
|
||||
*/
|
||||
Future<JsonObject> validateToken(String token);
|
||||
}
|
||||
|
||||
@@ -1,29 +1,414 @@
|
||||
package cn.qaiu.lz.web.service.impl;
|
||||
|
||||
import cn.qaiu.db.pool.JDBCPoolInit;
|
||||
import cn.qaiu.lz.common.util.JwtUtil;
|
||||
import cn.qaiu.lz.common.util.PasswordUtil;
|
||||
import cn.qaiu.lz.web.model.SysUser;
|
||||
import cn.qaiu.lz.web.service.UserService;
|
||||
import cn.qaiu.vx.core.annotaions.Service;
|
||||
import io.vertx.core.Future;
|
||||
import io.vertx.core.Promise;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.jdbcclient.JDBCPool;
|
||||
import io.vertx.sqlclient.Row;
|
||||
import io.vertx.sqlclient.RowSet;
|
||||
import io.vertx.sqlclient.Tuple;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* lz-web
|
||||
* 用户服务实现类
|
||||
* <br>Create date 2021/8/27 14:09
|
||||
*
|
||||
* @author <a href="https://qaiu.top">QAIU</a>
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class UserServiceImpl implements UserService {
|
||||
|
||||
@Override
|
||||
public Future<SysUser> login(SysUser user) {
|
||||
private final JDBCPool jdbcPool = JDBCPoolInit.instance().getPool();
|
||||
|
||||
// try {
|
||||
// TimeUnit.SECONDS.sleep(2);
|
||||
// } catch (InterruptedException e) {
|
||||
// throw new RuntimeException(e);
|
||||
// }
|
||||
return Future.succeededFuture(user);
|
||||
// 初始化方法,确保管理员用户存在
|
||||
public void init() {
|
||||
// 检查管理员用户是否存在
|
||||
getUserByUsername("admin")
|
||||
.onSuccess(user -> {
|
||||
log.info("管理员用户已存在");
|
||||
})
|
||||
.onFailure(err -> {
|
||||
// 创建管理员用户
|
||||
SysUser admin = new SysUser();
|
||||
admin.setId(UUID.randomUUID().toString());
|
||||
admin.setUsername("admin");
|
||||
admin.setPassword(PasswordUtil.hashPassword("admin123"));
|
||||
admin.setEmail("admin@example.com");
|
||||
admin.setRole("admin");
|
||||
admin.setStatus(1);
|
||||
admin.setCreateTime(LocalDateTime.now());
|
||||
|
||||
createUser(admin)
|
||||
.onSuccess(result -> log.info("管理员用户创建成功"))
|
||||
.onFailure(error -> log.error("管理员用户创建失败", error));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// 新增一个工具方法来过滤敏感信息
|
||||
private SysUser filterSensitiveInfo(SysUser user) {
|
||||
if (user != null) {
|
||||
SysUser filtered = new SysUser();
|
||||
// 复制除密码外的所有字段
|
||||
filtered.setId(user.getId());
|
||||
filtered.setUsername(user.getUsername());
|
||||
filtered.setEmail(user.getEmail());
|
||||
filtered.setPhone(user.getPhone());
|
||||
filtered.setAvatar(user.getAvatar());
|
||||
filtered.setRole(user.getRole());
|
||||
filtered.setStatus(user.getStatus());
|
||||
filtered.setCreateTime(user.getCreateTime());
|
||||
filtered.setLastLoginTime(user.getLastLoginTime());
|
||||
return filtered;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// 将Row转换为SysUser对象
|
||||
private SysUser rowToUser(Row row) {
|
||||
if (row == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
SysUser user = new SysUser();
|
||||
user.setId(row.getString("id"));
|
||||
user.setUsername(row.getString("username"));
|
||||
user.setPassword(row.getString("password"));
|
||||
user.setEmail(row.getString("email"));
|
||||
user.setPhone(row.getString("phone"));
|
||||
user.setAvatar(row.getString("avatar"));
|
||||
user.setRole(row.getString("role"));
|
||||
user.setStatus(row.getInteger("status"));
|
||||
|
||||
// 处理日期时间字段
|
||||
LocalDateTime createTime = row.getLocalDateTime("create_time");
|
||||
if (createTime != null) {
|
||||
user.setCreateTime(createTime);
|
||||
}
|
||||
|
||||
LocalDateTime lastLoginTime = row.getLocalDateTime("last_login_time");
|
||||
if (lastLoginTime != null) {
|
||||
user.setLastLoginTime(lastLoginTime);
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<JsonObject> login(SysUser user) {
|
||||
// 参数校验
|
||||
if (user == null || user.getUsername() == null || user.getPassword() == null) {
|
||||
return Future.succeededFuture(new JsonObject()
|
||||
.put("success", false)
|
||||
.put("message", "用户名和密码不能为空"));
|
||||
}
|
||||
|
||||
Promise<JsonObject> promise = Promise.promise();
|
||||
|
||||
// 查询用户
|
||||
String sql = "SELECT * FROM sys_user WHERE username = ?";
|
||||
|
||||
jdbcPool.preparedQuery(sql)
|
||||
.execute(Tuple.of(user.getUsername()))
|
||||
.onSuccess(rows -> {
|
||||
if (rows.size() == 0) {
|
||||
promise.complete(new JsonObject()
|
||||
.put("success", false)
|
||||
.put("message", "用户不存在"));
|
||||
return;
|
||||
}
|
||||
|
||||
Row row = rows.iterator().next();
|
||||
SysUser existUser = rowToUser(row);
|
||||
|
||||
// 验证密码
|
||||
if (!PasswordUtil.checkPassword(user.getPassword(), existUser.getPassword())) {
|
||||
promise.complete(new JsonObject()
|
||||
.put("success", false)
|
||||
.put("message", "密码错误"));
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新最后登录时间
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
existUser.setLastLoginTime(now);
|
||||
|
||||
// 更新数据库中的最后登录时间
|
||||
String updateSql = "UPDATE sys_user SET last_login_time = ? WHERE username = ?";
|
||||
jdbcPool.preparedQuery(updateSql)
|
||||
.execute(Tuple.of(
|
||||
Timestamp.from(now.atZone(ZoneId.systemDefault()).toInstant()),
|
||||
existUser.getUsername()
|
||||
))
|
||||
.onFailure(err -> log.error("更新最后登录时间失败", err));
|
||||
|
||||
// 生成token
|
||||
String token = JwtUtil.generateToken(existUser);
|
||||
|
||||
// 返回用户信息和token
|
||||
JsonObject value = JsonObject.mapFrom(existUser);
|
||||
value.remove("password");
|
||||
promise.complete(new JsonObject()
|
||||
.put("success", true)
|
||||
.put("message", "登录成功")
|
||||
.put("token", token)
|
||||
.put("user", value));
|
||||
})
|
||||
.onFailure(err -> {
|
||||
log.error("登录查询失败", err);
|
||||
promise.complete(new JsonObject()
|
||||
.put("success", false)
|
||||
.put("message", "登录失败: " + err.getMessage()));
|
||||
});
|
||||
|
||||
return promise.future();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<SysUser> getUserByUsername(String username) {
|
||||
if (username == null || username.isEmpty()) {
|
||||
return Future.failedFuture("用户名不能为空");
|
||||
}
|
||||
|
||||
Promise<SysUser> promise = Promise.promise();
|
||||
|
||||
String sql = "SELECT * FROM sys_user WHERE username = ?";
|
||||
|
||||
jdbcPool.preparedQuery(sql)
|
||||
.execute(Tuple.of(username))
|
||||
.onSuccess(rows -> {
|
||||
if (rows.size() == 0) {
|
||||
promise.fail("用户不存在");
|
||||
return;
|
||||
}
|
||||
|
||||
Row row = rows.iterator().next();
|
||||
SysUser user = rowToUser(row);
|
||||
promise.complete(filterSensitiveInfo(user));
|
||||
})
|
||||
.onFailure(err -> {
|
||||
log.error("查询用户失败", err);
|
||||
promise.fail("查询用户失败: " + err.getMessage());
|
||||
});
|
||||
|
||||
return promise.future();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<SysUser> createUser(SysUser user) {
|
||||
// 参数校验
|
||||
if (user == null || user.getUsername() == null || user.getPassword() == null) {
|
||||
return Future.failedFuture("用户名和密码不能为空");
|
||||
}
|
||||
|
||||
Promise<SysUser> promise = Promise.promise();
|
||||
|
||||
// 先检查用户是否已存在
|
||||
String checkSql = "SELECT COUNT(*) as count FROM sys_user WHERE username = ?";
|
||||
|
||||
jdbcPool.preparedQuery(checkSql)
|
||||
.execute(Tuple.of(user.getUsername()))
|
||||
.onSuccess(rows -> {
|
||||
Row row = rows.iterator().next();
|
||||
long count = row.getLong("count");
|
||||
|
||||
if (count > 0) {
|
||||
promise.fail("用户名已存在");
|
||||
return;
|
||||
}
|
||||
|
||||
// 设置用户ID和创建时间
|
||||
if (user.getId() == null) {
|
||||
user.setId(UUID.randomUUID().toString());
|
||||
}
|
||||
if (user.getCreateTime() == null) {
|
||||
user.setCreateTime(LocalDateTime.now());
|
||||
}
|
||||
|
||||
// 设置默认角色和状态
|
||||
if (user.getRole() == null) {
|
||||
user.setRole("user");
|
||||
}
|
||||
if (user.getStatus() == null) {
|
||||
user.setStatus(1);
|
||||
}
|
||||
|
||||
// 对密码进行加密
|
||||
String plainPassword = user.getPassword();
|
||||
user.setPassword(PasswordUtil.hashPassword(plainPassword));
|
||||
|
||||
// 插入用户
|
||||
String insertSql = "INSERT INTO sys_user (id, username, password, email, phone, avatar, role, status, create_time) " +
|
||||
"VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
|
||||
jdbcPool.preparedQuery(insertSql)
|
||||
.execute(Tuple.of(
|
||||
user.getId(),
|
||||
user.getUsername(),
|
||||
user.getPassword(),
|
||||
user.getEmail(),
|
||||
user.getPhone(),
|
||||
user.getAvatar(),
|
||||
user.getRole(),
|
||||
user.getStatus(),
|
||||
Timestamp.from(user.getCreateTime().atZone(ZoneId.systemDefault()).toInstant())
|
||||
))
|
||||
.onSuccess(result -> {
|
||||
promise.complete(filterSensitiveInfo(user));
|
||||
})
|
||||
.onFailure(err -> {
|
||||
log.error("创建用户失败", err);
|
||||
promise.fail("创建用户失败: " + err.getMessage());
|
||||
});
|
||||
})
|
||||
.onFailure(err -> {
|
||||
log.error("检查用户是否存在失败", err);
|
||||
promise.fail("创建用户失败: " + err.getMessage());
|
||||
});
|
||||
|
||||
return promise.future();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<SysUser> updateUser(SysUser user) {
|
||||
// 参数校验
|
||||
if (user == null || user.getUsername() == null) {
|
||||
return Future.failedFuture("用户名不能为空");
|
||||
}
|
||||
|
||||
Promise<SysUser> promise = Promise.promise();
|
||||
|
||||
// 先检查用户是否存在
|
||||
String checkSql = "SELECT * FROM sys_user WHERE username = ?";
|
||||
|
||||
jdbcPool.preparedQuery(checkSql)
|
||||
.execute(Tuple.of(user.getUsername()))
|
||||
.onSuccess(rows -> {
|
||||
if (rows.size() == 0) {
|
||||
promise.fail("用户不存在");
|
||||
return;
|
||||
}
|
||||
|
||||
Row row = rows.iterator().next();
|
||||
SysUser existUser = rowToUser(row);
|
||||
|
||||
// 构建更新SQL
|
||||
StringBuilder updateSql = new StringBuilder("UPDATE sys_user SET ");
|
||||
Tuple params = Tuple.tuple();
|
||||
|
||||
if (user.getEmail() != null) {
|
||||
updateSql.append("email = ?, ");
|
||||
params.addValue(user.getEmail());
|
||||
}
|
||||
|
||||
if (user.getPhone() != null) {
|
||||
updateSql.append("phone = ?, ");
|
||||
params.addValue(user.getPhone());
|
||||
}
|
||||
|
||||
if (user.getAvatar() != null) {
|
||||
updateSql.append("avatar = ?, ");
|
||||
params.addValue(user.getAvatar());
|
||||
}
|
||||
|
||||
if (user.getStatus() != null) {
|
||||
updateSql.append("status = ?, ");
|
||||
params.addValue(user.getStatus());
|
||||
}
|
||||
|
||||
if (user.getRole() != null) {
|
||||
updateSql.append("role = ?, ");
|
||||
params.addValue(user.getRole());
|
||||
}
|
||||
|
||||
if (user.getPassword() != null) {
|
||||
updateSql.append("password = ?, ");
|
||||
params.addValue(PasswordUtil.hashPassword(user.getPassword()));
|
||||
}
|
||||
|
||||
// 移除最后的逗号和空格
|
||||
String sql = updateSql.toString();
|
||||
if (sql.endsWith(", ")) {
|
||||
sql = sql.substring(0, sql.length() - 2);
|
||||
}
|
||||
|
||||
// 如果没有要更新的字段,直接返回
|
||||
if (params.size() == 0) {
|
||||
promise.complete(filterSensitiveInfo(existUser));
|
||||
return;
|
||||
}
|
||||
|
||||
// 添加WHERE条件
|
||||
sql += " WHERE username = ?";
|
||||
params.addValue(user.getUsername());
|
||||
|
||||
// 执行更新
|
||||
jdbcPool.preparedQuery(sql)
|
||||
.execute(params)
|
||||
.onSuccess(result -> {
|
||||
// 重新查询用户信息
|
||||
getUserByUsername(user.getUsername())
|
||||
.onSuccess(promise::complete)
|
||||
.onFailure(promise::fail);
|
||||
})
|
||||
.onFailure(err -> {
|
||||
log.error("更新用户失败", err);
|
||||
promise.fail("更新用户失败: " + err.getMessage());
|
||||
});
|
||||
})
|
||||
.onFailure(err -> {
|
||||
log.error("查询用户失败", err);
|
||||
promise.fail("更新用户失败: " + err.getMessage());
|
||||
});
|
||||
|
||||
return promise.future();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Future<JsonObject> validateToken(String token) {
|
||||
if (token == null || token.isEmpty()) {
|
||||
return Future.succeededFuture(new JsonObject()
|
||||
.put("success", false)
|
||||
.put("message", "Token不能为空"));
|
||||
}
|
||||
|
||||
// 验证token
|
||||
boolean isValid = JwtUtil.validateToken(token);
|
||||
if (!isValid) {
|
||||
return Future.succeededFuture(new JsonObject()
|
||||
.put("success", false)
|
||||
.put("message", "Token无效或已过期"));
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
String username = JwtUtil.getUsernameFromToken(token);
|
||||
|
||||
Promise<JsonObject> promise = Promise.promise();
|
||||
|
||||
getUserByUsername(username)
|
||||
.onSuccess(user -> {
|
||||
promise.complete(new JsonObject()
|
||||
.put("success", true)
|
||||
.put("message", "Token有效")
|
||||
.put("user", JsonObject.mapFrom(user)));
|
||||
})
|
||||
.onFailure(err -> {
|
||||
promise.complete(new JsonObject()
|
||||
.put("success", false)
|
||||
.put("message", "用户不存在"));
|
||||
});
|
||||
|
||||
return promise.future();
|
||||
}
|
||||
}
|
||||
@@ -36,15 +36,15 @@ custom:
|
||||
- ^cn\.qaiu\.lz\.web\.model\..*
|
||||
|
||||
# 限流配置
|
||||
rateLimit:
|
||||
# 是否启用限流
|
||||
enable: true
|
||||
# 限流的请求数
|
||||
limit: 10
|
||||
# 限流的时间窗口(单位秒)
|
||||
timeWindow: 10
|
||||
# 路径匹配规则
|
||||
pathReg: ^/v2/.*
|
||||
#rateLimit:
|
||||
# # 是否启用限流
|
||||
# enable: true
|
||||
# # 限流的请求数
|
||||
# limit: 10
|
||||
# # 限流的时间窗口(单位秒)
|
||||
# timeWindow: 10
|
||||
# # 路径匹配规则
|
||||
# pathReg: ^/v2/.*
|
||||
|
||||
|
||||
# 数据源配置
|
||||
|
||||
Reference in New Issue
Block a user