remove yarn.lock

This commit is contained in:
QAIU
2025-05-08 18:18:15 +08:00
parent aff8f88076
commit b77930adfb
22 changed files with 829 additions and 219 deletions

View File

@@ -3,6 +3,7 @@ package cn.qaiu.lz;
import cn.qaiu.WebClientVertxInit;
import cn.qaiu.db.pool.JDBCPoolInit;
import cn.qaiu.lz.common.cache.CacheConfigLoader;
import cn.qaiu.lz.common.interceptorImpl.RateLimiter;
import cn.qaiu.vx.core.Deploy;
import cn.qaiu.vx.core.util.ConfigConstant;
import cn.qaiu.vx.core.util.VertxHolder;
@@ -11,8 +12,9 @@ import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.core.json.jackson.DatabindCodec;
import io.vertx.core.shareddata.LocalMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.commons.lang3.time.DateFormatUtils;
import java.util.Date;
import static cn.qaiu.vx.core.util.ConfigConstant.LOCAL;
@@ -25,8 +27,6 @@ import static cn.qaiu.vx.core.util.ConfigConstant.LOCAL;
*/
public class AppMain {
private static final Logger LOGGER = LoggerFactory.getLogger(AppMain.class);
public static void main(String[] args) {
Deploy.instance().start(args, AppMain::exec);
}
@@ -40,14 +40,22 @@ public class AppMain {
private static void exec(JsonObject jsonObject) {
WebClientVertxInit.init(VertxHolder.getVertxInstance());
DatabindCodec.mapper().registerModule(new JavaTimeModule());
// 限流
if (jsonObject.containsKey("rateLimit")) {
JsonObject rateLimit = jsonObject.getJsonObject("rateLimit");
RateLimiter.init(rateLimit);
}
// 数据库
if (jsonObject.getJsonObject(ConfigConstant.SERVER).getBoolean("enableDatabase")) {
JDBCPoolInit.builder().config(jsonObject.getJsonObject("dataSource"))
.build()
.initPool().onSuccess(PreparedStatement -> {
LOGGER.info("数据库连接成功");
String addr = jsonObject.getJsonObject(ConfigConstant.SERVER).getString("domainName");
LOGGER.info("启动成功: \n本地服务地址: {}", addr);
VertxHolder.getVertxInstance().setTimer(1000, id -> {
System.out.println(DateFormatUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss.SSS"));
System.out.println("数据库连接成功");
String addr = jsonObject.getJsonObject(ConfigConstant.SERVER).getString("domainName");
System.out.println("启动成功: \n本地服务地址: " + addr);
});
});
}
// 缓存

View File

@@ -2,12 +2,15 @@ package cn.qaiu.lz.common.interceptorImpl;
import cn.qaiu.vx.core.annotaions.HandleSortFilter;
import cn.qaiu.vx.core.interceptor.BeforeInterceptor;
import cn.qaiu.vx.core.util.ConfigConstant;
import cn.qaiu.vx.core.util.SharedDataUtil;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.RoutingContext;
import lombok.extern.slf4j.Slf4j;
import static cn.qaiu.vx.core.util.ConfigConstant.IGNORES_REG;
import static io.vertx.core.http.HttpHeaders.CONTENT_TYPE;
/**
* 前置拦截器实现
@@ -20,8 +23,43 @@ public class DefaultInterceptor implements BeforeInterceptor {
@Override
public void handle(RoutingContext ctx) {
// System.out.println("进入前置拦截器1->" + ctx.request().path());
doNext(ctx);
// 读取配置 如果配置了限流 则进行限流
if (!SharedDataUtil.getJsonConfig(ConfigConstant.GLOBAL_CONFIG).containsKey("rateLimit")) {
doNext(ctx);
return;
}
JsonObject rateLimit = SharedDataUtil.getJsonConfig(ConfigConstant.GLOBAL_CONFIG)
.getJsonObject("rateLimit");
// # 限流配置
//rateLimit:
// # 是否启用限流
// enable: true
// # 限流的请求数
// limit: 1000
// # 限流的时间窗口(单位秒)
// timeWindow: 60
if (rateLimit.getBoolean("enable")) {
// 获取当前请求的路径
String path = ctx.request().path();
// 正则匹配路径
if (ignores.stream().anyMatch(ignore -> path.matches(ignore.toString()))) {
// 如果匹配到忽略的路径,则不进行限流
doNext(ctx);
return;
}
RateLimiter.checkRateLimit(ctx.request())
.onSuccess(v -> {
// 继续执行下一个拦截器
doNext(ctx);
})
.onFailure(t -> {
// 限流失败,返回错误响应
log.warn("Rate limit exceeded for path: {}", path);
ctx.response().putHeader(CONTENT_TYPE, "text/html; charset=utf-8")
.setStatusCode(429)
.end(t.getMessage());
});
}
}
}

View File

@@ -0,0 +1,77 @@
package cn.qaiu.lz.common.interceptorImpl;
import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.json.JsonObject;
import lombok.extern.slf4j.Slf4j;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Slf4j
public class RateLimiter {
private static final Map<String, RequestInfo> ipRequestMap = new ConcurrentHashMap<>();
private static int MAX_REQUESTS = 10; // 最大请求次数
private static long TIME_WINDOW = 60 * 1000; // 时间窗口(毫秒)
private static String PATH_REG; // 限流路径正则
public static void init(JsonObject rateLimitConfig) {
MAX_REQUESTS = rateLimitConfig.getInteger("limit", 10);
TIME_WINDOW = rateLimitConfig.getInteger("timeWindow", 60) * 1000L; // 转换为毫秒
PATH_REG = rateLimitConfig.getString("pathReg", "/.*");
log.info("RateLimiter initialized with max requests: {}, time window: {} ms, path regex: {}",
MAX_REQUESTS, TIME_WINDOW, PATH_REG);
}
synchronized public static Future<Void> checkRateLimit(HttpServerRequest request) {
Promise<Void> promise = Promise.promise();
if (!request.path().matches(PATH_REG)) {
// 如果请求路径不匹配正则,则不进行限流
promise.complete();
return promise.future();
}
String ip = request.remoteAddress().host();
ipRequestMap.compute(ip, (key, requestInfo) -> {
long currentTime = System.currentTimeMillis();
if (requestInfo == null || currentTime - requestInfo.timestamp > TIME_WINDOW) {
// 初始化或重置计数器
return new RequestInfo(1, currentTime);
} else {
// 增加计数器
requestInfo.count++;
return requestInfo;
}
});
RequestInfo info = ipRequestMap.get(ip);
if (info.count > MAX_REQUESTS) {
// 超过限制
// 计算剩余时间
long remainingTime = TIME_WINDOW - (System.currentTimeMillis() - info.timestamp);
BigDecimal bigDecimal = BigDecimal.valueOf(remainingTime / 1000.0)
.setScale(2, RoundingMode.HALF_UP);
promise.fail("请求次数太多了,请" + bigDecimal + "秒后再试。");
} else {
// 未超过限制,继续处理
promise.complete();
}
return promise.future();
}
private static class RequestInfo {
int count;
long timestamp;
RequestInfo(int count, long time) {
this.count = count;
this.timestamp = time;
}
}
}

View File

@@ -0,0 +1,36 @@
package cn.qaiu.lz.web.controller;
import cn.qaiu.lz.web.service.ShoutService;
import cn.qaiu.vx.core.annotaions.RouteHandler;
import cn.qaiu.vx.core.annotaions.RouteMapping;
import cn.qaiu.vx.core.enums.RouteMethod;
import cn.qaiu.vx.core.model.JsonResult;
import cn.qaiu.vx.core.util.AsyncServiceUtil;
import io.vertx.core.Future;
import io.vertx.core.json.JsonObject;
import io.vertx.ext.web.RoutingContext;
@RouteHandler("/v2/shout")
public class ShoutController {
private final ShoutService shoutService = AsyncServiceUtil.getAsyncServiceInstance(ShoutService.class);
@RouteMapping(value = "/submit", method = RouteMethod.POST)
public Future<JsonObject> submitMessage(RoutingContext ctx) {
String content = ctx.body().asJsonObject().getString("content");
if (content == null || content.trim().isEmpty()) {
return Future.failedFuture("内容不能为空");
}
return shoutService.submitMessage(content, ctx.request().remoteAddress().host()).compose(code ->
Future.succeededFuture(JsonResult.data(code).toJsonObject()));
}
@RouteMapping(value = "/retrieve", method = RouteMethod.GET)
public Future<JsonObject> retrieveMessage(RoutingContext ctx) {
String code = ctx.request().getParam("code");
if (code == null || code.length() != 6) {
return Future.failedFuture("提取码必须为6位数字");
}
return shoutService.retrieveMessage(code);
}
}

View File

@@ -0,0 +1,40 @@
package cn.qaiu.lz.web.model;
import cn.qaiu.db.ddl.Constraint;
import cn.qaiu.db.ddl.Length;
import cn.qaiu.db.ddl.Table;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.util.Date;
/**
* 隔空喊话消息
*/
@Data
@Table("t_messages")
public class ShoutMessage {
private static final long serialVersionUID = 1L;
@Constraint(autoIncrement= true, notNull = true)
private Long id;
@Length(varcharSize = 16)
@Constraint(notNull = true, uniqueKey = "uk_code")
private String code; // 6位提取码
@Length(varcharSize = 4096)
private String content; // 消息内容
@Length(varcharSize = 32)
private String ip; // 发送者IP
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime = new Date(); // 创建时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date expireTime; // 过期时间
private Boolean isUsed = false; // 是否已使用
}

View File

@@ -0,0 +1,15 @@
package cn.qaiu.lz.web.service;
import cn.qaiu.vx.core.base.BaseAsyncService;
import io.vertx.codegen.annotations.ProxyGen;
import io.vertx.core.Future;
import io.vertx.core.json.JsonObject;
@ProxyGen
public interface ShoutService extends BaseAsyncService {
// 提交消息并返回提取码
Future<String> submitMessage(String content, String host);
// 通过提取码获取消息
Future<JsonObject> retrieveMessage(String code);
}

View File

@@ -0,0 +1,90 @@
package cn.qaiu.lz.web.service.impl;
import cn.qaiu.db.pool.JDBCPoolInit;
import cn.qaiu.lz.web.service.ShoutService;
import cn.qaiu.vx.core.annotaions.Service;
import cn.qaiu.vx.core.model.JsonResult;
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.Tuple;
import lombok.extern.slf4j.Slf4j;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Random;
@Slf4j
@Service
@SuppressWarnings("SqlResolve") // 这里是为了避免检查SQL语句的警告
public class ShoutServiceImpl implements ShoutService {
private static final int CODE_LENGTH = 6;
private static final int EXPIRE_HOURS = 24;
private final JDBCPool jdbcPool = JDBCPoolInit.instance().getPool();
@Override
public Future<String> submitMessage(String content, String host) {
Promise<String> promise = Promise.promise();
String code = generateRandomCode();
// 判断一下当前code是否存在消息
LocalDateTime expireTime = LocalDateTime.now().plusHours(EXPIRE_HOURS);
String sql = "INSERT INTO t_messages (code, content, expire_time, ip) VALUES (?, ?, ?, ?)";
jdbcPool.preparedQuery(sql)
.execute(Tuple.of(code, content,
java.sql.Timestamp.from(expireTime.atZone(ZoneId.systemDefault()).toInstant()),
host))
.onSuccess(res -> {
log.info("Message submitted with code: {}", code);
promise.complete(code);
})
.onFailure(err -> {
log.error("Failed to submit message", err);
promise.fail(err);
});
return promise.future();
}
@Override
public Future<JsonObject> retrieveMessage(String code) {
Promise<JsonObject> promise = Promise.promise();
String sql = "SELECT content FROM t_messages WHERE code = ? AND expire_time > NOW()";
jdbcPool.preparedQuery(sql)
.execute(Tuple.of(code))
.onSuccess(rows -> {
if (rows.size() > 0) {
String content = rows.iterator().next().getString("content");
// 标记为已使用
markAsUsed(code);
promise.complete(JsonResult.data(content).toJsonObject());
} else {
promise.fail("无效的提取码或消息已过期");
}
})
.onFailure(err -> {
log.error("Failed to retrieve message", err);
promise.fail(err);
});
return promise.future();
}
private void markAsUsed(String code) {
String sql = "UPDATE t_messages SET is_used = TRUE WHERE code = ?";
jdbcPool.preparedQuery(sql).execute(Tuple.of(code));
}
private String generateRandomCode() {
Random random = new Random();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < CODE_LENGTH; i++) {
sb.append(random.nextInt(10));
}
return sb.toString();
}
}

View File

@@ -5,7 +5,8 @@ server:
# 使用数据库
enableDatabase: true
# 服务域名或者IP 生成二维码链接时需要
domainName: http://127.0.0.1:6401
# domainName: http://127.0.0.1:6401
domainName: https://lz.qaiu.top
# 反向代理服务器配置路径(不用加后缀)
proxyConf: server-proxy
@@ -25,18 +26,29 @@ custom:
routeTimeOut: 15000
# 拦截器匹配规则
ignoresReg:
- /v2/statisticsInfo
# - /v2/statisticsInfo
- .*/test.*$
# 参数注入的实体类包路径匹配正则 (防止同名类引发歧义)
entityPackagesReg:
- ^cn\.qaiu\.lz\.web\.model\..*
# 限流配置
rateLimit:
# 是否启用限流
enable: true
# 限流的请求数
limit: 5
# 限流的时间窗口(单位秒)
timeWindow: 10
# 路径匹配规则
pathReg: ^/v2/.*
# 数据源配置
dataSource:
#jdbcUrl: jdbc:mysql://127.0.0.1:3306/nfddata?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&serverTimezone=GMT%2B8&useSSL=false
jdbcUrl: jdbc:h2:file:./db/nfdData1;MODE=MySQL;DATABASE_TO_UPPER=FALSE
jdbcUrl: jdbc:h2:file:./db/nfdData;MODE=MySQL;DATABASE_TO_UPPER=FALSE
username: root
password: '123456'
@@ -63,7 +75,8 @@ cache:
mne: 30
mqq: 30
mkg: 30
p115: 5
p115: 30
ct: 30
# httpClient静态代理服务器配置(外网代理)
proxy:

View File

@@ -25,3 +25,4 @@ https://api.ilanzou.com/unproved/file/redirect?uuid=0&devType=6&timestamp=453240
https://www.ilanzou.com/s/zHkna1S
### fileId: 145042258
https://api.ilanzou.com/unproved/recommend/list?devType=6&devModel=Chrome&uuid=AjiM-Wl782OuHyuvKiuaH&extra=2&timestamp=311D0B438400DB5D98F1D2FF5A7A86F1&shareId=jQ9i3F0&type=0&offset=1&limit=60

View File

@@ -101,6 +101,128 @@ referer: https://www.vyuyun.com
https://down2.bilnn.top/uploads/11283/306bdccd233ffd2c.jar?filename=C400003mAan70zUy5O+%282%29.m4a&mime=audio%2Fx-m4a&verify=1729911697-SLZtEHXB4TM*ze1j31WMyNA**p743DY*GN2sajUx5w*2mM**
###
# @no-cookie-jar
# curl 'https://www.vyuyun.com/apiv1/share/getShareDownUrl/QPyZsb/gDZBTm?password=&downcode=Iv7YsjhM_6kzHijjtHyTLfPqlr6xwR5kqVNfMMAdWBEBcW1iNNIK-hDvrwLyzF4a'
# -H 'Accept: */*'
# -H 'Accept-Language: zh-CN,zh;q=0.9,en;q=0.8'
# -H 'Cache-Control: no-cache'
# -H 'Connection: keep-alive'
# -H 'Cookie: Hm_lvt_6e5421de7bb814e1dfc49bbc577c04d3=1734489414,1736133991,1736139184; HMACCOUNT=7C4EDB1414D4E56F; ginmin-session=MTczNjEzOTY5OHxEWDhFQVFMX2dBQUJFQUVRQUFBRV80QUFBQT09fE1kmd-TQNIU-AcLRbEhAMzpcoaTIqnDkU_z1Z2kW64A; Hm_lpvt_6e5421de7bb814e1dfc49bbc577c04d3=1736139719; __gads=ID=710230eb796d6baf:T=1736139187:RT=1736139729:S=ALNI_MauDIW3Tl0IYOZILi-6C0qMU328RA; __gpi=UID=00000fa7e525a50e:T=1736139187:RT=1736139729:S=ALNI_MYOvo89qg4zJq0s35CanMI3lx-zLw; __eoi=ID=df2245386092f112:T=1736139187:RT=1736139729:S=AA-AfjbzvOhiQPaERKQKlmEEC7Ds'
# -H 'DNT: 1'
# -H 'Pragma: no-cache'
# -H 'Referer: https://www.vyuyun.com/s/QPyZsb/file?password='
# -H 'Sec-Fetch-Dest: empty'
# -H 'Sec-Fetch-Mode: cors'
# -H 'Sec-Fetch-Site: same-origin'
# -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36'
# -H 'sec-ch-ua: "Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"'
# -H 'sec-ch-ua-mobile: ?0'
# -H 'sec-ch-ua-platform: "Windows"'
# -H 'token;'
GET https://www.vyuyun.com/apiv1/share/getShareDownUrl/QPyZsb/gDZBTm?password=&downcode=Iv7YsjhM_6kzHijjtHyTLfPqlr6xwR5kqVNfMMAdWBEBcW1iNNIK-hDvrwLyzF4a
Accept: */*
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cache-Control: no-cache
Connection: keep-alive
Cookie: Hm_lvt_6e5421de7bb814e1dfc49bbc577c04d3=1734489414,1736133991,1736139184; HMACCOUNT=7C4EDB1414D4E56F; ginmin-session=MTczNjEzOTY5OHxEWDhFQVFMX2dBQUJFQUVRQUFBRV80QUFBQT09fE1kmd-TQNIU-AcLRbEhAMzpcoaTIqnDkU_z1Z2kW64A; Hm_lpvt_6e5421de7bb814e1dfc49bbc577c04d3=1736139719; __gads=ID=710230eb796d6baf:T=1736139187:RT=1736139729:S=ALNI_MauDIW3Tl0IYOZILi-6C0qMU328RA; __gpi=UID=00000fa7e525a50e:T=1736139187:RT=1736139729:S=ALNI_MYOvo89qg4zJq0s35CanMI3lx-zLw; __eoi=ID=df2245386092f112:T=1736139187:RT=1736139729:S=AA-AfjbzvOhiQPaERKQKlmEEC7Ds
DNT: 1
Pragma: no-cache
Referer: https://www.vyuyun.com/s/QPyZsb/file?password=
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
sec-ch-ua: "Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
token:
###
###
# curl 'https://www.vyuyun.com/apiv1/share/file/QPyZsb?password='
# -H 'Accept: application/json, text/plain, */*'
# -H 'Accept-Language: zh-CN,zh;q=0.9,en;q=0.8'
# -H 'Cache-Control: no-cache'
# -H 'Connection: keep-alive'
# -H 'Cookie: Hm_lvt_6e5421de7bb814e1dfc49bbc577c04d3=1734489414,1736133991; HMACCOUNT=845216228CFDAEF3; ginmin-session=MTczNjEzNzIwNXxEWDhFQVFMX2dBQUJFQUVRQUFBaV80QUFBUVp6ZEhKcGJtY01CUUFEWVdsa0JuTjBjbWx1Wnd3SEFBVXhNVGt3T0E9PXygMqAo7e0FsZpAm5tggrVEAmipmptNAe4RF-StdbItOA==; __gads=ID=02846a0224427b16:T=1729911643:RT=1736137206:S=ALNI_MYN-82qd45RW0rYq1JewWVxCmoZAQ; __gpi=UID=00000f553e085dd5:T=1729911643:RT=1736137206:S=ALNI_Mb2dIMzZrO14lDlqCBOShH29OEfng; __eoi=ID=3e810b8ce65b0a46:T=1729911643:RT=1736137206:S=AA-AfjbN5kpzrPK6QBBlTEmMlxXx; Hm_lpvt_6e5421de7bb814e1dfc49bbc577c04d3=1736137222'
# -H 'DNT: 1'
# -H 'Pragma: no-cache'
# -H 'Referer: https://www.vyuyun.com/s/QPyZsb/file?password='
# -H 'Sec-Fetch-Dest: empty'
# -H 'Sec-Fetch-Mode: cors'
# -H 'Sec-Fetch-Site: same-origin'
# -H 'Token;'
# -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36'
# -H 'X-Requested-With: XMLHttpRequest'
# -H 'sec-ch-ua: "Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"'
# -H 'sec-ch-ua-mobile: ?0'
# -H 'sec-ch-ua-platform: "Windows"'
GET https://www.vyuyun.com/apiv1/share/file/QPyZsb?password=
Accept: application/json, text/plain, */*
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cache-Control: no-cache
Connection: keep-alive
Cookie: Hm_lvt_6e5421de7bb814e1dfc49bbc577c04d3=1734489414,1736133991; HMACCOUNT=845216228CFDAEF3; ginmin-session=MTczNjEzNzIwNXxEWDhFQVFMX2dBQUJFQUVRQUFBaV80QUFBUVp6ZEhKcGJtY01CUUFEWVdsa0JuTjBjbWx1Wnd3SEFBVXhNVGt3T0E9PXygMqAo7e0FsZpAm5tggrVEAmipmptNAe4RF-StdbItOA==; __gads=ID=02846a0224427b16:T=1729911643:RT=1736137206:S=ALNI_MYN-82qd45RW0rYq1JewWVxCmoZAQ; __gpi=UID=00000f553e085dd5:T=1729911643:RT=1736137206:S=ALNI_Mb2dIMzZrO14lDlqCBOShH29OEfng; __eoi=ID=3e810b8ce65b0a46:T=1729911643:RT=1736137206:S=AA-AfjbN5kpzrPK6QBBlTEmMlxXx; Hm_lpvt_6e5421de7bb814e1dfc49bbc577c04d3=1736137222
DNT: 1
Pragma: no-cache
Referer: https://www.vyuyun.com/s/QPyZsb/file?password=
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
Token:
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
X-Requested-With: XMLHttpRequest
sec-ch-ua: "Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
###
# curl 'https://www.vyuyun.com/apiv1/share/getShareDownUrl/QPyZsb/gDZBTm?password=&downcode=Iv7YsjhM_6kzHijjtHyTLT2CySejYHyXEtW_2oI9kqCnevPaRjMpzFDaq4dT4z3R'
# -H 'Accept: */*'
# -H 'Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6'
# -H 'Cache-Control: no-cache'
# -H 'Connection: keep-alive'
# -H 'Cookie: noticeId=1; Hm_lvt_6e5421de7bb814e1dfc49bbc577c04d3=1736134006; HMACCOUNT=DD7A065B1B5C7BCF; ginmin-session=MTczNjEzNDExNXxEWDhFQVFMX2dBQUJFQUVRQUFELUFRal9nQUFEQm5OMGNtbHVad3dIQUFWMGIydGxiZ1p6ZEhKcGJtY01fNjhBXzZ4b1pVOVNMWGRwVVRWemVrTlFhRGxzTjNCRlNHOW5jMWRLU2pKVFluUlZOVWR2UlhkWGNEbElUMEZNYlV0RVMwRkJTeloxVlhaS1UycE5aMXBrTW1jMWJYVlRPVjlOWkVVMWNHMU1iMkZMTW1sR1NHcFhRbWhPWjAxb05FWmpWV2swVWpOU01GZE9aRk5UZUd0WVJFSmphMWw0WVZKVkxYRlhSalZ5UlhSSmRYaG9jbVJuTWpkbmRFWlBWRlpDV0ZkWGMzWjJaVFZtUjFwSWMwRnBlbXhhUVROVFowaEtZakJqTlc4cUJuTjBjbWx1Wnd3SUFBWnZjR1Z1YVdRR2MzUnlhVzVuREFJQUFBWnpkSEpwYm1jTUNnQUlZV1J0YVc1ZmFYTUdjM1J5YVc1bkRBTUFBVEE9fMMethsDCW-b_YQHRj_0KHUVB1AcmohDXI4L4en8_8Nd; Hm_lpvt_6e5421de7bb814e1dfc49bbc577c04d3=1736138831'
# -H 'DNT: 1'
# -H 'Pragma: no-cache'
# -H 'Referer: https://www.vyuyun.com/s/QPyZsb/file?password='
# -H 'Sec-Fetch-Dest: empty'
# -H 'Sec-Fetch-Mode: cors'
# -H 'Sec-Fetch-Site: same-origin'
# -H 'User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0'
# -H 'sec-ch-ua: "Microsoft Edge";v="131", "Chromium";v="131", "Not_A Brand";v="24"'
# -H 'sec-ch-ua-mobile: ?0'
# -H 'sec-ch-ua-platform: "Windows"'
# -H 'token: heOR-wiQ5szCPh9l7pEHogsWJJ2SbtU5GoEwWp9HOALmKDKAAK6uUvJSjMgZd2g5muS9_MdE5pmLoaK2iFHjWBhNgMh4FcUi4R3R0WNdSSxkXDBckYxaRU-qWF5rEtIuxhrdg27gtFOTVBXWWsvve5fGZHsAizlZA3SgHJb0c5o*'
GET https://www.vyuyun.com/apiv1/share/getShareDownUrl/QPyZsb/gDZBTm?password=&downcode=Iv7YsjhM_6kzHijjtHyTLT2CySejYHyXEtW_2oI9kqCnevPaRjMpzFDaq4dT4z3R
Accept: */*
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Cache-Control: no-cache
Connection: keep-alive
Cookie: noticeId=1; Hm_lvt_6e5421de7bb814e1dfc49bbc577c04d3=1736134006; HMACCOUNT=DD7A065B1B5C7BCF; ginmin-session=MTczNjEzNDExNXxEWDhFQVFMX2dBQUJFQUVRQUFELUFRal9nQUFEQm5OMGNtbHVad3dIQUFWMGIydGxiZ1p6ZEhKcGJtY01fNjhBXzZ4b1pVOVNMWGRwVVRWemVrTlFhRGxzTjNCRlNHOW5jMWRLU2pKVFluUlZOVWR2UlhkWGNEbElUMEZNYlV0RVMwRkJTeloxVlhaS1UycE5aMXBrTW1jMWJYVlRPVjlOWkVVMWNHMU1iMkZMTW1sR1NHcFhRbWhPWjAxb05FWmpWV2swVWpOU01GZE9aRk5UZUd0WVJFSmphMWw0WVZKVkxYRlhSalZ5UlhSSmRYaG9jbVJuTWpkbmRFWlBWRlpDV0ZkWGMzWjJaVFZtUjFwSWMwRnBlbXhhUVROVFowaEtZakJqTlc4cUJuTjBjbWx1Wnd3SUFBWnZjR1Z1YVdRR2MzUnlhVzVuREFJQUFBWnpkSEpwYm1jTUNnQUlZV1J0YVc1ZmFYTUdjM1J5YVc1bkRBTUFBVEE9fMMethsDCW-b_YQHRj_0KHUVB1AcmohDXI4L4en8_8Nd; Hm_lpvt_6e5421de7bb814e1dfc49bbc577c04d3=1736138831
DNT: 1
Pragma: no-cache
Referer: https://www.vyuyun.com/s/QPyZsb/file?password=
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: same-origin
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0
sec-ch-ua: "Microsoft Edge";v="131", "Chromium";v="131", "Not_A Brand";v="24"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
token: heOR-wiQ5szCPh9l7pEHogsWJJ2SbtU5GoEwWp9HOALmKDKAAK6uUvJSjMgZd2g5muS9_MdE5pmLoaK2iFHjWBhNgMh4FcUi4R3R0WNdSSxkXDBckYxaRU-qWF5rEtIuxhrdg27gtFOTVBXWWsvve5fGZHsAizlZA3SgHJb0c5o*
###
### 118网盘 https://qaiu.118pan.com/b1228264
#密码qaiu
https://qaiu.118pan.com/b1228264

View File

@@ -0,0 +1,18 @@
###
POST http://127.0.0.1:6400/v2/shout/submit
Content-Type: application/json
{
"content": "CREATE UNIQUE INDEX `idx_uk_code` ON `t_messages` (`code`);"
}
###
GET http://127.0.0.1:6400/v2/shout/retrieve?code=878696
###
响应:
{
"data": "这是一条秘密消息",
"code": 200,
"msg": "success"
}

View File

@@ -55,6 +55,7 @@
<logger name="io.netty" level="warn"/>
<logger name="io.vertx" level="info"/>
<logger name="com.zaxxer.hikari" level="info"/>
<logger name="cn.qaiu" level="debug"/>
<root level="info">
<appender-ref ref="STDOUT"/>
<!-- <appender-ref ref="FILE"/>-->

View File

@@ -0,0 +1,49 @@
package cn.qaiu.db.ddl;
import cn.qaiu.db.pool.JDBCType;
import io.vertx.sqlclient.templates.annotations.Column;
import org.junit.Test;
public class CreateTableTest {
static class TestModel2 {
@Column(name = "id")
@Constraint(autoIncrement = true)
private Long id;
@Column(name = "name")
@Constraint(notNull = true, uniqueKey = "ne_unique")
private String name;
@Column(name = "age")
private Integer age;
@Column(name = "email")
@Constraint(notNull = true, uniqueKey = "ne_unique")
private String email;
@Column(name = "created_at")
private java.util.Date createdAt;
}
@Test
public void getCreateTableSQL() {
// 测试
String sql = String.join("\n", CreateTable.getCreateTableSQL(TestModel2.class, JDBCType.H2DB));
System.out.println(sql);
}
@Test
public void getCreateTableSQL2() {
// 测试
String sql = String.join("\n", CreateTable.getCreateTableSQL(TestModel2.class, JDBCType.MySQL));
System.out.println(sql);
}
@Test
public void getCreateTableSQL3() {
// 测试
String sql = String.join("\n", CreateTable.getCreateTableSQL(TestModel2.class, JDBCType.PostgreSQL));
System.out.println(sql);
}
}