Compare commits

..

10 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
24025e0ae6 Remove unused user system residual code (SysUser, UserService, UserServiceImpl, JwtUtil)
Agent-Logs-Url: https://github.com/qaiu/netdisk-fast-download/sessions/1ce8d72f-79b3-4be4-b9a3-4cab8bbe7b19

Co-authored-by: qaiu <29825328+qaiu@users.noreply.github.com>
2026-04-11 01:37:21 +00:00
copilot-swe-agent[bot]
d8bffc19ce Initial plan 2026-04-11 01:35:41 +00:00
qaiu
a420bad305 Update README.md 2026-04-09 16:46:29 +08:00
qaiu
6ef6e47580 Update README.md 2026-04-07 08:39:41 +08:00
qaiu
94f83ec296 Fix duplicate Trendshift badge in README
Removed duplicate Trendshift badge from README.
2026-04-07 08:23:44 +08:00
qaiu
702569c701 Add Trendshift badge to README
Added Trendshift badge to README for repository tracking.
2026-04-07 08:22:40 +08:00
qaiu
d4940ca9ee fixed: 123-YePan: Fix regex pattern for share key extraction 2026-04-07 08:20:06 +08:00
qaiu
dbd1c138ca Merge pull request #173 from qaiu/copilot/identify-yifang-cloud-new-format
feat: recognize new Fangcloud /share/ URL format
2026-04-05 17:59:54 +08:00
copilot-swe-agent[bot]
0b49c55cf3 feat: recognize new Fangcloud /share/ URL format in addition to /sharing/ and /s/
Agent-Logs-Url: https://github.com/qaiu/netdisk-fast-download/sessions/dc483348-3899-4448-80ce-c2352e6bc23e

Co-authored-by: qaiu <29825328+qaiu@users.noreply.github.com>
2026-04-05 08:20:46 +00:00
copilot-swe-agent[bot]
b1ec3b2eea Initial plan 2026-04-05 08:16:46 +00:00
7 changed files with 16 additions and 720 deletions

View File

@@ -1,5 +1,17 @@
<div align="center" style="display:flex; justify-content:center; gap:10px; align-items:flex-start;">
<img
src="https://github.com/user-attachments/assets/bf266d0a-aaf8-4772-9231-e38a4b7bb6cb"
alt="image1"
style="width:300px; max-width:300px; flex:none;"
>
<img
src="https://github.com/user-attachments/assets/bb7a85f0-c256-4b4a-a11b-3ceb55afc302"
alt="image2"
style="width:300px; max-width:300px; flex:none;"
>
</div>
<p align="center"> <p align="center">
<img src="https://github.com/user-attachments/assets/87401aae-b0b6-4ffb-bbeb-44756404d26f" alt="项目预览图" /> <a href="https://trendshift.io/repositories/12101" target="_blank"><img src="https://trendshift.io/api/badge/repositories/12101" alt="qaiu%2Fnetdisk-fast-download | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
</p> </p>
<p align="center"> <p align="center">
@@ -8,11 +20,6 @@
<a href="https://vertx-china.github.io"><img src="https://img.shields.io/badge/vert.x-4.5.22-blue?style=flat"></a> <a href="https://vertx-china.github.io"><img src="https://img.shields.io/badge/vert.x-4.5.22-blue?style=flat"></a>
<a href="https://raw.githubusercontent.com/qaiu/netdisk-fast-download/master/LICENSE"><img src="https://img.shields.io/github/license/qaiu/netdisk-fast-download?style=flat"></a> <a href="https://raw.githubusercontent.com/qaiu/netdisk-fast-download/master/LICENSE"><img src="https://img.shields.io/github/license/qaiu/netdisk-fast-download?style=flat"></a>
<a href="https://github.com/qaiu/netdisk-fast-download/releases/"><img src="https://img.shields.io/github/v/release/qaiu/netdisk-fast-download?style=flat"></a> <a href="https://github.com/qaiu/netdisk-fast-download/releases/"><img src="https://img.shields.io/github/v/release/qaiu/netdisk-fast-download?style=flat"></a>
<a href="https://trendshift.io/repositories/12101" target="_blank"><img src="https://trendshift.io/api/badge/repositories/12101" alt="qaiu%2Fnetdisk-fast-download | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
</p>
# netdisk-fast-download 网盘分享链接云解析服务 # netdisk-fast-download 网盘分享链接云解析服务
QQ交流群1017480890 QQ交流群1017480890
@@ -62,7 +69,6 @@ main分支依赖JDK17, 提供了JDK11分支[main-jdk11](https://github.com/qaiu/
- [蓝奏云-lz](https://pc.woozooo.com/) - [蓝奏云-lz](https://pc.woozooo.com/)
- [蓝奏云优享-iz](https://www.ilanzou.com/) - [蓝奏云优享-iz](https://www.ilanzou.com/)
- [奶牛快传-cow](https://cowtransfer.com/)
- [移动云云空间-ec](https://www.ecpan.cn/web) - [移动云云空间-ec](https://www.ecpan.cn/web)
- [小飞机网盘-fj](https://www.feijipan.com/) - [小飞机网盘-fj](https://www.feijipan.com/)
- [亿方云-fc](https://www.fangcloud.com/) - [亿方云-fc](https://www.fangcloud.com/)

View File

@@ -121,7 +121,7 @@ public enum PanDomainTemplate {
// https://v2.fangcloud.com/s/ // https://v2.fangcloud.com/s/
FC("亿方云", FC("亿方云",
compile("https://v2\\.fangcloud\\.(com|cn)/(s|sharing)/(?<KEY>.+)"), compile("https://v2\\.fangcloud\\.(com|cn)/(s|share|sharing)/(?<KEY>.+)"),
"https://v2.fangcloud.com/s/{shareKey}", "https://v2.fangcloud.com/s/{shareKey}",
"https://www.fangcloud.com/", "https://www.fangcloud.com/",
FcTool.class), FcTool.class),
@@ -230,7 +230,7 @@ public enum PanDomainTemplate {
"123635\\.com|" + "123635\\.com|" +
"123242\\.com|" + "123242\\.com|" +
"123795\\.com" + "123795\\.com" +
")/s/(?<KEY>.+)(.html)?"), ")/s/(?<KEY>[a-zA-Z0-9_-]+)(?:\\.html)?"),
"https://www.123pan.com/s/{shareKey}", "https://www.123pan.com/s/{shareKey}",
Ye2Tool.class), Ye2Tool.class),
// https://www.ecpan.cn/web/#/yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data={code}&isShare=1 // https://www.ecpan.cn/web/#/yunpanProxy?path=%2F%23%2Fdrive%2Foutside&data={code}&isShare=1

View File

@@ -274,7 +274,7 @@
name: '联想乐云' name: '联想乐云'
}, },
fangcloud: { fangcloud: {
reg: /https:\/\/v2\.fangcloud\.(com|cn)\/(s|sharing)\/.+/, reg: /https:\/\/v2\.fangcloud\.(com|cn)\/(s|share|sharing)\/.+/,
host: /fangcloud\.(com|cn)/, host: /fangcloud\.(com|cn)/,
name: '亿方云' name: '亿方云'
}, },

View File

@@ -1,185 +0,0 @@
package cn.qaiu.lz.common.util;
import cn.qaiu.lz.web.model.SysUser;
import io.vertx.core.json.JsonObject;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Base64;
import java.util.Date;
/**
* JWT工具类用于生成和验证JWT token
*/
public class JwtUtil {
private static final long EXPIRE_TIME = 24 * 60 * 60 * 1000; // token过期时间24小时
private static final String SECRET_KEY = "netdisk-fast-download-jwt-secret-key"; // 密钥
private static final String ALGORITHM = "HmacSHA256";
/**
* 生成JWT token
*
* @param user 用户信息
* @return JWT token
*/
public static String generateToken(SysUser user) {
long expireTime = getExpireTime();
// Header
JsonObject header = new JsonObject()
.put("alg", "HS256")
.put("typ", "JWT");
// Payload
JsonObject payload = new JsonObject()
.put("id", user.getId())
.put("username", user.getUsername())
.put("role", user.getRole())
.put("exp", expireTime)
.put("iat", System.currentTimeMillis())
.put("iss", "netdisk-fast-download");
// Base64 encode header and payload
String encodedHeader = Base64.getUrlEncoder().withoutPadding().encodeToString(header.encode().getBytes(StandardCharsets.UTF_8));
String encodedPayload = Base64.getUrlEncoder().withoutPadding().encodeToString(payload.encode().getBytes(StandardCharsets.UTF_8));
// Create signature
String signature = hmacSha256(encodedHeader + "." + encodedPayload, SECRET_KEY);
// Combine to form JWT
return encodedHeader + "." + encodedPayload + "." + signature;
}
/**
* 使用HMAC-SHA256算法生成签名
*
* @param data 要签名的数据
* @param key 密钥
* @return 签名
*/
private static String hmacSha256(String data, String key) {
try {
Mac sha256Hmac = Mac.getInstance(ALGORITHM);
SecretKeySpec secretKey = new SecretKeySpec(key.getBytes(StandardCharsets.UTF_8), ALGORITHM);
sha256Hmac.init(secretKey);
byte[] signedBytes = sha256Hmac.doFinal(data.getBytes(StandardCharsets.UTF_8));
return Base64.getUrlEncoder().withoutPadding().encodeToString(signedBytes);
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
throw new RuntimeException("Error creating HMAC SHA256 signature", e);
}
}
/**
* 验证JWT token
*
* @param token JWT token
* @return 如果token有效返回true否则返回false
*/
public static boolean validateToken(String token) {
try {
String[] parts = token.split("\\.");
if (parts.length != 3) {
return false;
}
String encodedHeader = parts[0];
String encodedPayload = parts[1];
String signature = parts[2];
// 验证签名
String expectedSignature = hmacSha256(encodedHeader + "." + encodedPayload, SECRET_KEY);
if (!expectedSignature.equals(signature)) {
return false;
}
// 验证过期时间
String payload = new String(Base64.getUrlDecoder().decode(encodedPayload), StandardCharsets.UTF_8);
JsonObject payloadJson = new JsonObject(payload);
long expTime = payloadJson.getLong("exp", 0L);
return System.currentTimeMillis() < expTime;
} catch (Exception e) {
return false;
}
}
/**
* 从token中获取用户ID
*
* @param token JWT token
* @return 用户ID
*/
public static String getUserIdFromToken(String token) {
String[] parts = token.split("\\.");
if (parts.length != 3) {
return null;
}
// Base64解码
String payload = new String(Base64.getUrlDecoder().decode(parts[1]), StandardCharsets.UTF_8);
JsonObject jsonObject = new JsonObject(payload);
return jsonObject.getString("id");
}
/**
* 从token中获取用户名
*
* @param token JWT token
* @return 用户名
*/
public static String getUsernameFromToken(String token) {
String[] parts = token.split("\\.");
if (parts.length != 3) {
return null;
}
// Base64解码
String payload = new String(Base64.getUrlDecoder().decode(parts[1]), StandardCharsets.UTF_8);
JsonObject jsonObject = new JsonObject(payload);
return jsonObject.getString("username");
}
/**
* 从token中获取用户角色
*
* @param token JWT token
* @return 用户角色
*/
public static String getRoleFromToken(String token) {
String[] parts = token.split("\\.");
if (parts.length != 3) {
return null;
}
// Base64解码
String payload = new String(Base64.getUrlDecoder().decode(parts[1]), StandardCharsets.UTF_8);
JsonObject jsonObject = new JsonObject(payload);
return jsonObject.getString("role");
}
/**
* 获取过期时间
*
* @return 过期时间戳
*/
private static long getExpireTime() {
return System.currentTimeMillis() + EXPIRE_TIME;
}
/**
* 将过期时间戳转换为LocalDateTime
*
* @param expireTime 过期时间戳
* @return LocalDateTime
*/
public static LocalDateTime getExpireTimeAsLocalDateTime(long expireTime) {
return LocalDateTime.ofInstant(Instant.ofEpochMilli(expireTime), ZoneId.systemDefault());
}
}

View File

@@ -1,60 +0,0 @@
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;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
@Data
@DataObject
@NoArgsConstructor
@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;
public SysUser(JsonObject json) {
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"));
}
}
}

View File

@@ -1,51 +0,0 @@
package cn.qaiu.lz.web.service;
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;
/**
* 用户服务接口
* <br>Create date 2021/8/27 14:06
*
* @author <a href="https://qaiu.top">QAIU</a>
*/
@ProxyGen
public interface UserService extends BaseAsyncService {
/**
* 用户登录
* @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);
}

View File

@@ -1,414 +0,0 @@
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.sql.Timestamp;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.UUID;
/**
* 用户服务实现类
* <br>Create date 2021/8/27 14:09
*
* @author <a href="https://qaiu.top">QAIU</a>
*/
@Slf4j
@Service
public class UserServiceImpl implements UserService {
private final JDBCPool jdbcPool = JDBCPoolInit.instance().getPool();
// 初始化方法,确保管理员用户存在
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();
}
}