完善认证逻辑,添加用户信息 introspect 接口,更新 .gitignore 忽略 scripts 目录
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -12,4 +12,5 @@ bin/
|
|||||||
*.pem
|
*.pem
|
||||||
*.http
|
*.http
|
||||||
|
|
||||||
*/playground/
|
*/playground/
|
||||||
|
scripts/
|
||||||
@@ -22,6 +22,10 @@
|
|||||||
- [ ] Limiter
|
- [ ] Limiter
|
||||||
- [ ] Compress
|
- [ ] Compress
|
||||||
|
|
||||||
|
检查 device 权限验证,限制到特定于 web 客户端的权限
|
||||||
|
|
||||||
|
白名单限制可输入网段
|
||||||
|
|
||||||
废弃 password 授权模式,迁移到 authorization code 授权模式
|
废弃 password 授权模式,迁移到 authorization code 授权模式
|
||||||
|
|
||||||
使用 fiber 自带 validator 进行参数验证
|
使用 fiber 自带 validator 进行参数验证
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
name: platform-dev
|
|
||||||
|
|
||||||
services:
|
|
||||||
|
|
||||||
postgres:
|
|
||||||
image: postgres:17
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
POSTGRES_USER: ${DB_USERNAME}
|
|
||||||
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
|
||||||
POSTGRES_DB: ${DB_NAME}
|
|
||||||
ports:
|
|
||||||
- "5432:5432"
|
|
||||||
volumes:
|
|
||||||
- postgres_data:/var/lib/postgresql/data
|
|
||||||
|
|
||||||
redis:
|
|
||||||
image: redis:7.4
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- "6379:6379"
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
postgres_data:
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
name: platform-prev
|
|
||||||
|
|
||||||
services:
|
|
||||||
|
|
||||||
postgres:
|
|
||||||
image: postgres:17
|
|
||||||
restart: always
|
|
||||||
environment:
|
|
||||||
POSTGRES_USER: ${DB_USERNAME}
|
|
||||||
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
|
||||||
POSTGRES_DB: ${DB_NAME}
|
|
||||||
ports:
|
|
||||||
- "5432:5432"
|
|
||||||
volumes:
|
|
||||||
- postgres_data:/var/lib/postgresql/data
|
|
||||||
|
|
||||||
redis:
|
|
||||||
image: redis:7.4
|
|
||||||
restart: always
|
|
||||||
ports:
|
|
||||||
- "6379:6379"
|
|
||||||
command: redis-server --requirepass ${REDIS_PASS}
|
|
||||||
volumes:
|
|
||||||
- redis_data:/data
|
|
||||||
|
|
||||||
platform:
|
|
||||||
build:
|
|
||||||
context: ../..
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
depends_on:
|
|
||||||
- postgres
|
|
||||||
- redis
|
|
||||||
ports:
|
|
||||||
- 8080:8080
|
|
||||||
env_file:
|
|
||||||
- ../../.env
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
postgres_data:
|
|
||||||
redis_data:
|
|
||||||
@@ -1,220 +0,0 @@
|
|||||||
110.40.82.248|10000|bx8365|242469
|
|
||||||
110.40.82.248|10001|eu9328|493237
|
|
||||||
110.40.82.248|10002|tn6479|247579
|
|
||||||
110.40.82.248|10003|yx8657|232695
|
|
||||||
110.40.82.248|10004|ru8396|776448
|
|
||||||
110.40.82.248|10005|hk2957|897393
|
|
||||||
110.40.82.248|10006|fk5569|979277
|
|
||||||
110.40.82.248|10007|nn8859|622638
|
|
||||||
110.40.82.248|10008|kf4546|927798
|
|
||||||
110.40.82.248|10009|xd3275|763356
|
|
||||||
110.40.82.248|10010|jj3257|343429
|
|
||||||
110.40.82.248|10011|jg2356|944246
|
|
||||||
110.40.82.248|10012|nc8746|545784
|
|
||||||
110.40.82.248|10013|vu8328|763628
|
|
||||||
110.40.82.248|10014|cn2486|725339
|
|
||||||
110.40.82.248|10015|sn7499|959423
|
|
||||||
110.40.82.248|10016|am3336|995524
|
|
||||||
110.40.82.248|10017|tv2487|756939
|
|
||||||
110.40.82.248|10018|af3324|395465
|
|
||||||
110.40.82.248|10019|jr3978|279833
|
|
||||||
110.40.82.248|10020|cd8436|463733
|
|
||||||
110.40.82.248|10021|cx5686|926872
|
|
||||||
110.40.82.248|10022|gy7228|769775
|
|
||||||
110.40.82.248|10023|kk5434|494548
|
|
||||||
110.40.82.248|10024|fs8824|573884
|
|
||||||
110.40.82.248|10025|ta3545|994543
|
|
||||||
110.40.82.248|10026|nu6993|346966
|
|
||||||
110.40.82.248|10027|qm6599|797659
|
|
||||||
110.40.82.248|10028|ag3955|322752
|
|
||||||
110.40.82.248|10029|rp5937|553687
|
|
||||||
110.40.82.248|10030|qx5558|967645
|
|
||||||
110.40.82.248|10031|bt4494|426495
|
|
||||||
110.40.82.248|10032|ng6876|235567
|
|
||||||
110.40.82.248|10033|un6855|386394
|
|
||||||
110.40.82.248|10034|yu8965|377993
|
|
||||||
110.40.82.248|10035|cc5532|366957
|
|
||||||
110.40.82.248|10036|mc8998|388652
|
|
||||||
110.40.82.248|10037|hy9866|953847
|
|
||||||
110.40.82.248|10038|zy3654|677364
|
|
||||||
110.40.82.248|10039|bw7278|573267
|
|
||||||
110.40.82.248|10040|cu9527|985595
|
|
||||||
110.40.82.248|10041|pg9832|843382
|
|
||||||
110.40.82.248|10042|qm3297|899273
|
|
||||||
110.40.82.248|10043|gs7356|282863
|
|
||||||
110.40.82.248|10044|gm7877|432425
|
|
||||||
110.40.82.248|10045|hm4697|758247
|
|
||||||
110.40.82.248|10046|tf9359|633623
|
|
||||||
110.40.82.248|10047|wb8726|863766
|
|
||||||
110.40.82.248|10048|ah2743|878986
|
|
||||||
110.40.82.248|10049|pq3996|363742
|
|
||||||
110.40.82.248|10050|nn3345|632583
|
|
||||||
110.40.82.248|10051|sc5535|673946
|
|
||||||
110.40.82.248|10052|rm3356|357357
|
|
||||||
110.40.82.248|10053|je4855|682973
|
|
||||||
110.40.82.248|10054|mk9733|697479
|
|
||||||
110.40.82.248|10055|zk5548|394528
|
|
||||||
110.40.82.248|10056|et7965|793473
|
|
||||||
110.40.82.248|10057|xt9423|898449
|
|
||||||
110.40.82.248|10058|qa5527|645327
|
|
||||||
110.40.82.248|10059|um2688|289728
|
|
||||||
110.40.82.248|10060|nk5828|242476
|
|
||||||
110.40.82.248|10061|yx9554|856994
|
|
||||||
110.40.82.248|10062|ns4939|759352
|
|
||||||
110.40.82.248|10063|vb7485|874824
|
|
||||||
110.40.82.248|10064|zb2372|528727
|
|
||||||
110.40.82.248|10065|ar6253|955428
|
|
||||||
110.40.82.248|10066|fr9365|642756
|
|
||||||
110.40.82.248|10067|zd2644|943294
|
|
||||||
110.40.82.248|10068|hs4394|675892
|
|
||||||
110.40.82.248|10069|sh2332|489286
|
|
||||||
110.40.82.248|10070|cd5293|634294
|
|
||||||
110.40.82.248|10071|gn6398|839753
|
|
||||||
110.40.82.248|10072|fc4557|664265
|
|
||||||
110.40.82.248|10073|ay3762|247893
|
|
||||||
110.40.82.248|10074|ka2877|796724
|
|
||||||
110.40.82.248|10075|du8626|278792
|
|
||||||
110.40.82.248|10076|wq4238|569397
|
|
||||||
110.40.82.248|10077|ug4962|992737
|
|
||||||
110.40.82.248|10078|cn4882|642566
|
|
||||||
110.40.82.248|10079|tq6329|377375
|
|
||||||
110.40.82.248|10080|dp9622|765854
|
|
||||||
110.40.82.248|10081|kr8825|849629
|
|
||||||
110.40.82.248|10082|uk9472|869689
|
|
||||||
110.40.82.248|10083|hm3646|892348
|
|
||||||
110.40.82.248|10084|bg9252|497243
|
|
||||||
110.40.82.248|10085|uh6946|739494
|
|
||||||
110.40.82.248|10086|rg5298|587796
|
|
||||||
110.40.82.248|10087|tj7977|726453
|
|
||||||
110.40.82.248|10088|ze3987|222244
|
|
||||||
110.40.82.248|10089|em8588|227953
|
|
||||||
110.40.82.248|10090|tr6446|679972
|
|
||||||
110.40.82.248|10091|gk8868|298239
|
|
||||||
110.40.82.248|10092|ut3822|668853
|
|
||||||
110.40.82.248|10093|pm6427|672442
|
|
||||||
110.40.82.248|10094|gb2833|755822
|
|
||||||
110.40.82.248|10095|zm6949|369698
|
|
||||||
110.40.82.248|10096|xq2658|852574
|
|
||||||
110.40.82.248|10097|qe8839|464228
|
|
||||||
110.40.82.248|10098|fp2923|937235
|
|
||||||
110.40.82.248|10099|xc6925|999539
|
|
||||||
110.40.82.248|10100|wa8574|732452
|
|
||||||
110.40.82.248|10101|yx8465|375486
|
|
||||||
110.40.82.248|10102|ww5494|739866
|
|
||||||
110.40.82.248|10103|jr7442|567485
|
|
||||||
110.40.82.248|10104|sd6985|959745
|
|
||||||
110.40.82.248|10105|xb2244|595966
|
|
||||||
110.40.82.248|10106|yn7857|372255
|
|
||||||
110.40.82.248|10107|vw4566|538227
|
|
||||||
110.40.82.248|10108|pv4723|686467
|
|
||||||
110.40.82.248|10109|hu8226|222586
|
|
||||||
110.40.82.248|10110|zr6555|863735
|
|
||||||
110.40.82.248|10111|rw9996|565957
|
|
||||||
110.40.82.248|10112|fb4287|549768
|
|
||||||
110.40.82.248|10113|av8488|877575
|
|
||||||
110.40.82.248|10114|xv2597|747758
|
|
||||||
110.40.82.248|10115|bv6832|434947
|
|
||||||
110.40.82.248|10116|zx3462|674699
|
|
||||||
110.40.82.248|10117|et4423|272678
|
|
||||||
110.40.82.248|10118|mr6542|974889
|
|
||||||
110.40.82.248|10119|df4937|259752
|
|
||||||
110.40.82.248|10120|rb5549|483455
|
|
||||||
110.40.82.248|10121|pf6353|588782
|
|
||||||
110.40.82.248|10122|gp2463|979239
|
|
||||||
110.40.82.248|10123|zn4727|939486
|
|
||||||
110.40.82.248|10124|nc8972|223754
|
|
||||||
110.40.82.248|10125|uc6742|568289
|
|
||||||
110.40.82.248|10126|wf5342|225866
|
|
||||||
110.40.82.248|10127|pk6252|767436
|
|
||||||
110.40.82.248|10128|kg4699|665633
|
|
||||||
110.40.82.248|10129|rr4552|433777
|
|
||||||
110.40.82.248|10130|bb4524|465625
|
|
||||||
110.40.82.248|10131|tj6876|789928
|
|
||||||
110.40.82.248|10132|je6786|579265
|
|
||||||
110.40.82.248|10133|jd2567|679592
|
|
||||||
110.40.82.248|10134|ay5885|592344
|
|
||||||
110.40.82.248|10135|xt3862|866283
|
|
||||||
110.40.82.248|10136|nb7497|683947
|
|
||||||
110.40.82.248|10137|nx2353|256249
|
|
||||||
110.40.82.248|10138|qv7433|664945
|
|
||||||
110.40.82.248|10139|py2642|833672
|
|
||||||
110.40.82.248|10140|ap2489|568855
|
|
||||||
110.40.82.248|10141|td8773|266242
|
|
||||||
110.40.82.248|10142|xw2452|593488
|
|
||||||
110.40.82.248|10143|ff5337|954543
|
|
||||||
110.40.82.248|10144|tz9987|963433
|
|
||||||
110.40.82.248|10145|fb8376|985273
|
|
||||||
110.40.82.248|10146|su2894|323982
|
|
||||||
110.40.82.248|10147|nb7495|823237
|
|
||||||
110.40.82.248|10148|yg2564|592488
|
|
||||||
110.40.82.248|10149|kn9899|227429
|
|
||||||
110.40.82.248|10150|cg4848|684686
|
|
||||||
110.40.82.248|10151|tn2256|249727
|
|
||||||
110.40.82.248|10152|ej3365|335369
|
|
||||||
110.40.82.248|10153|gx4888|279465
|
|
||||||
110.40.82.248|10154|hx7765|876632
|
|
||||||
110.40.82.248|10155|fm7674|254868
|
|
||||||
110.40.82.248|10156|cv7899|724934
|
|
||||||
110.40.82.248|10157|za7794|492886
|
|
||||||
110.40.82.248|10158|es6893|452285
|
|
||||||
110.40.82.248|10159|wt6853|675724
|
|
||||||
110.40.82.248|10160|av6876|758346
|
|
||||||
110.40.82.248|10161|mx7959|885764
|
|
||||||
110.40.82.248|10162|dy6887|388742
|
|
||||||
110.40.82.248|10163|nj8722|754387
|
|
||||||
110.40.82.248|10164|hc9946|863228
|
|
||||||
110.40.82.248|10165|qz9557|235287
|
|
||||||
110.40.82.248|10166|ge3847|927394
|
|
||||||
110.40.82.248|10167|cy8372|767252
|
|
||||||
110.40.82.248|10168|jj7654|982787
|
|
||||||
110.40.82.248|10169|zk8335|959346
|
|
||||||
110.40.82.248|10170|xn5586|639796
|
|
||||||
110.40.82.248|10171|ad6755|374686
|
|
||||||
110.40.82.248|10172|ks4839|489756
|
|
||||||
110.40.82.248|10173|yc9737|546796
|
|
||||||
110.40.82.248|10174|aq2328|853237
|
|
||||||
110.40.82.248|10175|wg7776|358652
|
|
||||||
110.40.82.248|10176|px4656|596576
|
|
||||||
110.40.82.248|10177|xs2728|453736
|
|
||||||
110.40.82.248|10178|gy4535|876755
|
|
||||||
110.40.82.248|10179|gb5937|723928
|
|
||||||
110.40.82.248|10180|pr2285|748893
|
|
||||||
110.40.82.248|10181|xd9847|336452
|
|
||||||
110.40.82.248|10182|td9655|785479
|
|
||||||
110.40.82.248|10183|rd4335|634744
|
|
||||||
110.40.82.248|10184|zx5458|674622
|
|
||||||
110.40.82.248|10185|xq8773|253948
|
|
||||||
110.40.82.248|10186|cs2696|496264
|
|
||||||
110.40.82.248|10187|at6665|653586
|
|
||||||
110.40.82.248|10188|eq7974|549797
|
|
||||||
110.40.82.248|10189|ty9272|772364
|
|
||||||
110.40.82.248|10190|tc2559|569529
|
|
||||||
110.40.82.248|10191|vq7798|855826
|
|
||||||
110.40.82.248|10192|xa4844|942872
|
|
||||||
110.40.82.248|10193|gy5679|996892
|
|
||||||
110.40.82.248|10194|xx7573|242397
|
|
||||||
110.40.82.248|10195|sg5662|545365
|
|
||||||
110.40.82.248|10196|be3787|924628
|
|
||||||
110.40.82.248|10197|pz6235|278446
|
|
||||||
110.40.82.248|10198|rh9632|349377
|
|
||||||
110.40.82.248|10199|xr2236|446398
|
|
||||||
110.40.82.248|10200|gf7455|288766
|
|
||||||
110.40.82.248|10201|yy5269|687478
|
|
||||||
110.40.82.248|10202|am7328|282833
|
|
||||||
110.40.82.248|10203|nh5229|759947
|
|
||||||
110.40.82.248|10204|hm5592|674869
|
|
||||||
110.40.82.248|10205|zj5449|622724
|
|
||||||
110.40.82.248|10206|uv8246|773676
|
|
||||||
110.40.82.248|10207|yv4955|253927
|
|
||||||
110.40.82.248|10208|er6533|932487
|
|
||||||
110.40.82.248|10209|ab8686|938948
|
|
||||||
110.40.82.248|10210|cu8395|495276
|
|
||||||
110.40.82.248|10211|nx8453|822793
|
|
||||||
110.40.82.248|10212|xv3389|885536
|
|
||||||
110.40.82.248|10213|yj9724|798479
|
|
||||||
110.40.82.248|10214|uz7896|435885
|
|
||||||
110.40.82.248|10215|hm9372|243792
|
|
||||||
110.40.82.248|10216|he7489|387683
|
|
||||||
110.40.82.248|10217|aw8368|956565
|
|
||||||
110.40.82.248|10218|cf4883|976237
|
|
||||||
110.40.82.248|10219|ur6422|388325
|
|
||||||
@@ -1,172 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# 检查是否提供了URL参数
|
|
||||||
if [ $# -eq 0 ]; then
|
|
||||||
echo "使用方法: $0 <要测试的URL>"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
TARGET_URL="$1"
|
|
||||||
LINKS_FILE="$(dirname "$0")/links.txt"
|
|
||||||
HIGH_LATENCY_THRESHOLD=400 # 高延迟阈值,修改为400毫秒
|
|
||||||
TIMEOUT=10 # curl 超时时间,单位秒
|
|
||||||
MAX_RETRIES=1 # 失败重试次数
|
|
||||||
|
|
||||||
# 检查links.txt文件是否存在
|
|
||||||
if [ ! -f "$LINKS_FILE" ]; then
|
|
||||||
echo "错误: $LINKS_FILE 文件不存在"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "开始测试代理速度,目标URL: $TARGET_URL"
|
|
||||||
echo "--------------------------------------"
|
|
||||||
|
|
||||||
# 初始化变量
|
|
||||||
total_latency=0
|
|
||||||
count=0
|
|
||||||
success_count=0
|
|
||||||
fail_count=0
|
|
||||||
retry_success_count=0
|
|
||||||
high_latency_proxies=""
|
|
||||||
failed_proxies=""
|
|
||||||
|
|
||||||
# 读取并测试每个代理
|
|
||||||
while IFS='|' read -r ip port username password || [ -n "$ip" ]; do
|
|
||||||
# 跳过空行和注释行
|
|
||||||
[[ -z "$ip" || "$ip" =~ ^# ]] && continue
|
|
||||||
|
|
||||||
# 去除可能的空白字符
|
|
||||||
ip=$(echo "$ip" | tr -d '[:space:]')
|
|
||||||
port=$(echo "$port" | tr -d '[:space:]')
|
|
||||||
username=$(echo "$username" | tr -d '[:space:]')
|
|
||||||
password=$(echo "$password" | tr -d '[:space:]')
|
|
||||||
|
|
||||||
proxy_url="http://$username:$password@$ip:$port"
|
|
||||||
echo -n "测试代理: $ip:$port ... "
|
|
||||||
|
|
||||||
# 测试逻辑封装成函数以便重试
|
|
||||||
test_proxy() {
|
|
||||||
local start_time=$(date +%s%N)
|
|
||||||
local response=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout $TIMEOUT --max-time $TIMEOUT -x "$proxy_url" "$TARGET_URL" 2>/dev/null)
|
|
||||||
local end_time=$(date +%s%N)
|
|
||||||
local latency=0
|
|
||||||
|
|
||||||
if [ "$response" = "200" ]; then
|
|
||||||
latency=$(( (end_time - start_time) / 1000000 ))
|
|
||||||
echo "$response $latency"
|
|
||||||
else
|
|
||||||
echo "$response 0"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# 第一次尝试
|
|
||||||
count=$((count + 1))
|
|
||||||
result=$(test_proxy)
|
|
||||||
response=$(echo $result | cut -d ' ' -f 1)
|
|
||||||
latency=$(echo $result | cut -d ' ' -f 2)
|
|
||||||
|
|
||||||
# 判断是否需要重试
|
|
||||||
if [ "$response" != "200" ]; then
|
|
||||||
echo -n "失败 - HTTP状态码: $response,正在重试... "
|
|
||||||
|
|
||||||
# 重试
|
|
||||||
result=$(test_proxy)
|
|
||||||
response=$(echo $result | cut -d ' ' -f 1)
|
|
||||||
latency=$(echo $result | cut -d ' ' -f 2)
|
|
||||||
|
|
||||||
if [ "$response" = "200" ]; then
|
|
||||||
retry_success_count=$((retry_success_count + 1))
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 处理最终结果
|
|
||||||
if [ "$response" = "200" ]; then
|
|
||||||
echo "成功 - 延迟: ${latency}ms"
|
|
||||||
|
|
||||||
# 累加总延迟
|
|
||||||
total_latency=$((total_latency + latency))
|
|
||||||
success_count=$((success_count + 1))
|
|
||||||
|
|
||||||
# 检查是否为高延迟代理
|
|
||||||
if [ $latency -gt $HIGH_LATENCY_THRESHOLD ]; then
|
|
||||||
high_latency_proxies="${high_latency_proxies}$ip:$port (${latency}ms)\n"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "最终失败 - HTTP状态码: $response"
|
|
||||||
fail_count=$((fail_count + 1))
|
|
||||||
failed_proxies="${failed_proxies}$ip:$port (状态码: $response)\n"
|
|
||||||
fi
|
|
||||||
done < "$LINKS_FILE"
|
|
||||||
|
|
||||||
echo "--------------------------------------"
|
|
||||||
|
|
||||||
# 输出统计结果
|
|
||||||
echo "测试结果汇总:"
|
|
||||||
echo "总测试代理数量: $count"
|
|
||||||
echo "成功代理数量: $success_count (含重试成功: $retry_success_count)"
|
|
||||||
echo "失败代理数量: $fail_count"
|
|
||||||
echo "成功率: $(( success_count * 100 / count ))%"
|
|
||||||
|
|
||||||
if [ $success_count -gt 0 ]; then
|
|
||||||
average_latency=$(( total_latency / success_count ))
|
|
||||||
echo "平均延迟: ${average_latency}ms"
|
|
||||||
|
|
||||||
if [ -n "$high_latency_proxies" ]; then
|
|
||||||
echo -e "\n高延迟代理 (>${HIGH_LATENCY_THRESHOLD}ms):"
|
|
||||||
echo -e "$high_latency_proxies"
|
|
||||||
else
|
|
||||||
echo -e "\n没有发现高延迟代理。"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -n "$failed_proxies" ]; then
|
|
||||||
echo -e "\n连接失败的代理:"
|
|
||||||
echo -e "$failed_proxies"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# 输出延迟分布情况
|
|
||||||
if [ $success_count -gt 0 ]; then
|
|
||||||
echo -e "\n延迟分布统计:"
|
|
||||||
# 重新统计以生成延迟分布
|
|
||||||
low_latency=0 # <100ms
|
|
||||||
medium_latency=0 # 100-200ms
|
|
||||||
high_latency=0 # 200-400ms
|
|
||||||
very_high_latency=0 # >400ms
|
|
||||||
|
|
||||||
while IFS='|' read -r ip port username password || [ -n "$ip" ]; do
|
|
||||||
# 跳过空行和注释行
|
|
||||||
[[ -z "$ip" || "$ip" =~ ^# ]] && continue
|
|
||||||
|
|
||||||
# 去除可能的空白字符
|
|
||||||
ip=$(echo "$ip" | tr -d '[:space:]')
|
|
||||||
port=$(echo "$port" | tr -d '[:space:]')
|
|
||||||
username=$(echo "$username" | tr -d '[:space:]')
|
|
||||||
password=$(echo "$password" | tr -d '[:space:]')
|
|
||||||
|
|
||||||
proxy_url="http://$username:$password@$ip:$port"
|
|
||||||
|
|
||||||
# 只测量一次以获取延迟数据,不进行重试统计
|
|
||||||
start_time=$(date +%s%N)
|
|
||||||
response=$(curl -s -o /dev/null -w "%{http_code}" --connect-timeout $TIMEOUT --max-time $TIMEOUT -x "$proxy_url" "$TARGET_URL" 2>/dev/null)
|
|
||||||
end_time=$(date +%s%N)
|
|
||||||
|
|
||||||
if [ "$response" = "200" ]; then
|
|
||||||
latency=$(( (end_time - start_time) / 1000000 ))
|
|
||||||
|
|
||||||
if [ $latency -lt 100 ]; then
|
|
||||||
low_latency=$((low_latency + 1))
|
|
||||||
elif [ $latency -lt 200 ]; then
|
|
||||||
medium_latency=$((medium_latency + 1))
|
|
||||||
elif [ $latency -lt 400 ]; then
|
|
||||||
high_latency=$((high_latency + 1))
|
|
||||||
else
|
|
||||||
very_high_latency=$((very_high_latency + 1))
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done < "$LINKS_FILE"
|
|
||||||
|
|
||||||
echo " < 100ms: $low_latency ($(( low_latency * 100 / success_count ))%)"
|
|
||||||
echo "100-200ms: $medium_latency ($(( medium_latency * 100 / success_count ))%)"
|
|
||||||
echo "200-400ms: $high_latency ($(( high_latency * 100 / success_count ))%)"
|
|
||||||
echo " > 400ms: $very_high_latency ($(( very_high_latency * 100 / success_count ))%)"
|
|
||||||
fi
|
|
||||||
@@ -1,860 +0,0 @@
|
|||||||
-- 清空数据表
|
|
||||||
do
|
|
||||||
$$
|
|
||||||
declare
|
|
||||||
r record;
|
|
||||||
begin
|
|
||||||
for r in (
|
|
||||||
select
|
|
||||||
tablename
|
|
||||||
from
|
|
||||||
pg_tables
|
|
||||||
where
|
|
||||||
schemaname = 'public'
|
|
||||||
) loop
|
|
||||||
execute 'DROP TABLE IF EXISTS ' || quote_ident(r.tablename) || ' CASCADE';
|
|
||||||
end loop;
|
|
||||||
end
|
|
||||||
$$;
|
|
||||||
|
|
||||||
-- ====================
|
|
||||||
-- region 管理员信息
|
|
||||||
-- ====================
|
|
||||||
|
|
||||||
-- admin
|
|
||||||
drop table if exists admin cascade;
|
|
||||||
create table admin (
|
|
||||||
id serial primary key,
|
|
||||||
username varchar(255) not null unique,
|
|
||||||
password varchar(255) not null,
|
|
||||||
name varchar(255),
|
|
||||||
avatar varchar(255),
|
|
||||||
phone varchar(255),
|
|
||||||
email varchar(255),
|
|
||||||
status int not null default 1,
|
|
||||||
last_login timestamp,
|
|
||||||
last_login_host varchar(45),
|
|
||||||
last_login_agent varchar(255),
|
|
||||||
created_at timestamp default current_timestamp,
|
|
||||||
updated_at timestamp default current_timestamp,
|
|
||||||
deleted_at timestamp
|
|
||||||
);
|
|
||||||
create index admin_status_index on admin (status);
|
|
||||||
create index admin_deleted_at_index on admin (deleted_at);
|
|
||||||
|
|
||||||
-- admin表字段注释
|
|
||||||
comment on table admin is '管理员表';
|
|
||||||
comment on column admin.id is '管理员ID';
|
|
||||||
comment on column admin.username is '用户名';
|
|
||||||
comment on column admin.password is '密码';
|
|
||||||
comment on column admin.name is '真实姓名';
|
|
||||||
comment on column admin.avatar is '头像URL';
|
|
||||||
comment on column admin.phone is '手机号码';
|
|
||||||
comment on column admin.email is '邮箱';
|
|
||||||
comment on column admin.status is '状态:1-正常,0-禁用';
|
|
||||||
comment on column admin.last_login is '最后登录时间';
|
|
||||||
comment on column admin.last_login_host is '最后登录地址';
|
|
||||||
comment on column admin.last_login_agent is '最后登录代理';
|
|
||||||
comment on column admin.created_at is '创建时间';
|
|
||||||
comment on column admin.updated_at is '更新时间';
|
|
||||||
comment on column admin.deleted_at is '删除时间';
|
|
||||||
|
|
||||||
-- admin_role
|
|
||||||
drop table if exists admin_role cascade;
|
|
||||||
create table admin_role (
|
|
||||||
id serial primary key,
|
|
||||||
name varchar(255) not null unique,
|
|
||||||
description varchar(255),
|
|
||||||
active bool default true,
|
|
||||||
sort int default 0,
|
|
||||||
created_at timestamp default current_timestamp,
|
|
||||||
updated_at timestamp default current_timestamp,
|
|
||||||
deleted_at timestamp
|
|
||||||
);
|
|
||||||
create index admin_role_deleted_at_index on admin_role (deleted_at);
|
|
||||||
|
|
||||||
-- admin_role表字段注释
|
|
||||||
comment on table admin_role is '管理员角色关联表';
|
|
||||||
comment on column admin_role.id is '管理员角色ID';
|
|
||||||
comment on column admin_role.name is '角色名称';
|
|
||||||
comment on column admin_role.description is '角色描述';
|
|
||||||
comment on column admin_role.active is '是否激活';
|
|
||||||
comment on column admin_role.sort is '排序';
|
|
||||||
comment on column admin_role.created_at is '创建时间';
|
|
||||||
comment on column admin_role.updated_at is '更新时间';
|
|
||||||
comment on column admin_role.deleted_at is '删除时间';
|
|
||||||
|
|
||||||
-- endregion
|
|
||||||
|
|
||||||
-- ====================
|
|
||||||
-- region 用户信息
|
|
||||||
-- ====================
|
|
||||||
|
|
||||||
-- user
|
|
||||||
drop table if exists "user" cascade;
|
|
||||||
create table "user" (
|
|
||||||
id serial primary key,
|
|
||||||
admin_id int references admin (id) --
|
|
||||||
on update cascade --
|
|
||||||
on delete set null,
|
|
||||||
phone varchar(255) not null unique,
|
|
||||||
username varchar(255),
|
|
||||||
email varchar(255),
|
|
||||||
password varchar(255),
|
|
||||||
name varchar(255),
|
|
||||||
avatar varchar(255),
|
|
||||||
status int not null default 1,
|
|
||||||
balance decimal(12, 2) not null default 0,
|
|
||||||
id_type int not null default 0,
|
|
||||||
id_no varchar(255),
|
|
||||||
id_token varchar(255),
|
|
||||||
contact_qq varchar(255),
|
|
||||||
contact_wechat varchar(255),
|
|
||||||
last_login timestamp,
|
|
||||||
last_login_host varchar(45),
|
|
||||||
last_login_agent varchar(255),
|
|
||||||
created_at timestamp default current_timestamp,
|
|
||||||
updated_at timestamp default current_timestamp,
|
|
||||||
deleted_at timestamp
|
|
||||||
);
|
|
||||||
create index user_admin_id_index on "user" (admin_id);
|
|
||||||
create index user_username_index on "user" (username);
|
|
||||||
create index user_email_index on "user" (email);
|
|
||||||
create index user_status_index on "user" (status);
|
|
||||||
create index user_deleted_at_index on "user" (deleted_at);
|
|
||||||
|
|
||||||
-- user表字段注释
|
|
||||||
comment on table "user" is '用户表';
|
|
||||||
comment on column "user".id is '用户ID';
|
|
||||||
comment on column "user".admin_id is '管理员ID';
|
|
||||||
comment on column "user".password is '用户密码';
|
|
||||||
comment on column "user".username is '用户名';
|
|
||||||
comment on column "user".phone is '手机号码';
|
|
||||||
comment on column "user".name is '真实姓名';
|
|
||||||
comment on column "user".avatar is '头像URL';
|
|
||||||
comment on column "user".status is '用户状态:1-正常,0-禁用';
|
|
||||||
comment on column "user".balance is '账户余额';
|
|
||||||
comment on column "user".id_type is '认证类型:0-未认证,1-个人认证,2-企业认证';
|
|
||||||
comment on column "user".id_no is '身份证号或营业执照号';
|
|
||||||
comment on column "user".id_token is '身份验证标识';
|
|
||||||
comment on column "user".contact_qq is 'QQ联系方式';
|
|
||||||
comment on column "user".contact_wechat is '微信联系方式';
|
|
||||||
comment on column "user".last_login is '最后登录时间';
|
|
||||||
comment on column "user".last_login_host is '最后登录地址';
|
|
||||||
comment on column "user".last_login_agent is '最后登录代理';
|
|
||||||
comment on column "user".created_at is '创建时间';
|
|
||||||
comment on column "user".updated_at is '更新时间';
|
|
||||||
comment on column "user".deleted_at is '删除时间';
|
|
||||||
|
|
||||||
-- user_role
|
|
||||||
drop table if exists user_role cascade;
|
|
||||||
create table user_role (
|
|
||||||
id serial primary key,
|
|
||||||
name varchar(255) not null unique,
|
|
||||||
description varchar(255),
|
|
||||||
active bool default true,
|
|
||||||
sort int default 0,
|
|
||||||
created_at timestamp default current_timestamp,
|
|
||||||
updated_at timestamp default current_timestamp,
|
|
||||||
deleted_at timestamp
|
|
||||||
);
|
|
||||||
create index user_role_deleted_at_index on user_role (deleted_at);
|
|
||||||
|
|
||||||
-- user_role表字段注释
|
|
||||||
comment on table user_role is '用户角色表';
|
|
||||||
comment on column user_role.id is '角色ID';
|
|
||||||
comment on column user_role.name is '角色名称';
|
|
||||||
comment on column user_role.description is '角色描述';
|
|
||||||
comment on column user_role.active is '是否激活';
|
|
||||||
comment on column user_role.sort is '排序';
|
|
||||||
comment on column user_role.created_at is '创建时间';
|
|
||||||
comment on column user_role.updated_at is '更新时间';
|
|
||||||
comment on column user_role.deleted_at is '删除时间';
|
|
||||||
|
|
||||||
-- endregion
|
|
||||||
|
|
||||||
-- ====================
|
|
||||||
-- region 客户端信息
|
|
||||||
-- ====================
|
|
||||||
|
|
||||||
drop table if exists client cascade;
|
|
||||||
create table client (
|
|
||||||
id serial primary key,
|
|
||||||
client_id varchar(255) not null unique,
|
|
||||||
client_secret varchar(255) not null,
|
|
||||||
redirect_uri varchar(255),
|
|
||||||
grant_code bool not null default false,
|
|
||||||
grant_client bool not null default false,
|
|
||||||
grant_refresh bool not null default false,
|
|
||||||
grant_password bool not null default false,
|
|
||||||
spec int not null,
|
|
||||||
name varchar(255) not null,
|
|
||||||
icon varchar(255),
|
|
||||||
status int not null default 1,
|
|
||||||
created_at timestamp default current_timestamp,
|
|
||||||
updated_at timestamp default current_timestamp,
|
|
||||||
deleted_at timestamp
|
|
||||||
);
|
|
||||||
|
|
||||||
create index client_client_id_index on client (client_id);
|
|
||||||
create index client_name_index on client (name);
|
|
||||||
create index client_status_index on client (status);
|
|
||||||
create index client_deleted_at_index on client (deleted_at);
|
|
||||||
|
|
||||||
-- client表字段注释
|
|
||||||
comment on table client is '客户端表';
|
|
||||||
comment on column client.id is '客户端ID';
|
|
||||||
comment on column client.client_id is 'OAuth2客户端标识符';
|
|
||||||
comment on column client.client_secret is 'OAuth2客户端密钥';
|
|
||||||
comment on column client.redirect_uri is 'OAuth2 重定向URI';
|
|
||||||
comment on column client.grant_code is '允许授权码授予';
|
|
||||||
comment on column client.grant_client is '允许客户端凭证授予';
|
|
||||||
comment on column client.grant_refresh is '允许刷新令牌授予';
|
|
||||||
comment on column client.grant_password is '允许密码授予';
|
|
||||||
comment on column client.spec is '安全规范:0-web,1-native,2-browser';
|
|
||||||
comment on column client.name is '名称';
|
|
||||||
comment on column client.icon is '图标URL';
|
|
||||||
comment on column client.status is '状态:1-正常,0-禁用';
|
|
||||||
comment on column client.created_at is '创建时间';
|
|
||||||
comment on column client.updated_at is '更新时间';
|
|
||||||
comment on column client.deleted_at is '删除时间';
|
|
||||||
|
|
||||||
-- endregion
|
|
||||||
|
|
||||||
-- ====================
|
|
||||||
-- region 权限信息
|
|
||||||
-- ====================
|
|
||||||
|
|
||||||
-- permission
|
|
||||||
drop table if exists permission cascade;
|
|
||||||
create table permission (
|
|
||||||
id serial primary key,
|
|
||||||
parent_id int references permission (id)
|
|
||||||
on update cascade
|
|
||||||
on delete cascade,
|
|
||||||
name varchar(255) not null unique,
|
|
||||||
description varchar(255),
|
|
||||||
created_at timestamp default current_timestamp,
|
|
||||||
updated_at timestamp default current_timestamp,
|
|
||||||
deleted_at timestamp
|
|
||||||
);
|
|
||||||
create index permission_parent_id_index on permission (parent_id);
|
|
||||||
create index permission_name_index on permission (name);
|
|
||||||
create index permission_deleted_at_index on permission (deleted_at);
|
|
||||||
|
|
||||||
-- permission表字段注释
|
|
||||||
comment on table permission is '权限表';
|
|
||||||
comment on column permission.id is '权限ID';
|
|
||||||
comment on column permission.parent_id is '父权限ID';
|
|
||||||
comment on column permission.name is '权限名称';
|
|
||||||
comment on column permission.description is '权限描述';
|
|
||||||
comment on column permission.created_at is '创建时间';
|
|
||||||
comment on column permission.updated_at is '更新时间';
|
|
||||||
comment on column permission.deleted_at is '删除时间';
|
|
||||||
|
|
||||||
-- user_role_link
|
|
||||||
drop table if exists user_role_link cascade;
|
|
||||||
create table user_role_link (
|
|
||||||
id serial primary key,
|
|
||||||
user_id int not null references "user" (id)
|
|
||||||
on update cascade
|
|
||||||
on delete cascade,
|
|
||||||
role_id int not null references user_role (id)
|
|
||||||
on update cascade
|
|
||||||
on delete cascade,
|
|
||||||
created_at timestamp default current_timestamp,
|
|
||||||
updated_at timestamp default current_timestamp,
|
|
||||||
deleted_at timestamp
|
|
||||||
);
|
|
||||||
create index user_role_link_user_id_index on user_role_link (user_id);
|
|
||||||
create index user_role_link_role_id_index on user_role_link (role_id);
|
|
||||||
create index user_role_link_deleted_at_index on user_role_link (deleted_at);
|
|
||||||
|
|
||||||
-- user_role_link表字段注释
|
|
||||||
comment on table user_role_link is '用户角色关联表';
|
|
||||||
comment on column user_role_link.id is '关联ID';
|
|
||||||
comment on column user_role_link.user_id is '用户ID';
|
|
||||||
comment on column user_role_link.role_id is '角色ID';
|
|
||||||
comment on column user_role_link.created_at is '创建时间';
|
|
||||||
comment on column user_role_link.updated_at is '更新时间';
|
|
||||||
comment on column user_role_link.deleted_at is '删除时间';
|
|
||||||
|
|
||||||
-- admin_role_link
|
|
||||||
drop table if exists admin_role_link cascade;
|
|
||||||
create table admin_role_link (
|
|
||||||
id serial primary key,
|
|
||||||
admin_id int not null references admin (id)
|
|
||||||
on update cascade
|
|
||||||
on delete cascade,
|
|
||||||
role_id int not null references admin_role (id)
|
|
||||||
on update cascade
|
|
||||||
on delete cascade,
|
|
||||||
created_at timestamp default current_timestamp,
|
|
||||||
updated_at timestamp default current_timestamp,
|
|
||||||
deleted_at timestamp
|
|
||||||
);
|
|
||||||
create index admin_role_link_admin_id_index on admin_role_link (admin_id);
|
|
||||||
create index admin_role_link_role_id_index on admin_role_link (role_id);
|
|
||||||
create index admin_role_link_deleted_at_index on admin_role_link (deleted_at);
|
|
||||||
|
|
||||||
-- admin_role_link表字段注释
|
|
||||||
comment on table admin_role_link is '管理员角色关联表';
|
|
||||||
comment on column admin_role_link.id is '关联ID';
|
|
||||||
comment on column admin_role_link.admin_id is '管理员ID';
|
|
||||||
comment on column admin_role_link.role_id is '角色ID';
|
|
||||||
comment on column admin_role_link.created_at is '创建时间';
|
|
||||||
comment on column admin_role_link.updated_at is '更新时间';
|
|
||||||
comment on column admin_role_link.deleted_at is '删除时间';
|
|
||||||
|
|
||||||
-- user_role_permission_link
|
|
||||||
drop table if exists user_role_permission_link cascade;
|
|
||||||
create table user_role_permission_link (
|
|
||||||
id serial primary key,
|
|
||||||
role_id int not null references user_role (id)
|
|
||||||
on update cascade
|
|
||||||
on delete cascade,
|
|
||||||
permission_id int not null references permission (id)
|
|
||||||
on update cascade
|
|
||||||
on delete cascade,
|
|
||||||
created_at timestamp default current_timestamp,
|
|
||||||
updated_at timestamp default current_timestamp,
|
|
||||||
deleted_at timestamp
|
|
||||||
);
|
|
||||||
create index user_role_permission_link_role_id_index on user_role_permission_link (role_id);
|
|
||||||
create index user_role_permission_link_permission_id_index on user_role_permission_link (permission_id);
|
|
||||||
create index user_role_permission_link_deleted_at_index on user_role_permission_link (deleted_at);
|
|
||||||
|
|
||||||
-- user_role_permission_link表字段注释
|
|
||||||
comment on table user_role_permission_link is '用户角色权限关联表';
|
|
||||||
comment on column user_role_permission_link.id is '关联ID';
|
|
||||||
comment on column user_role_permission_link.role_id is '角色ID';
|
|
||||||
comment on column user_role_permission_link.permission_id is '权限ID';
|
|
||||||
comment on column user_role_permission_link.created_at is '创建时间';
|
|
||||||
comment on column user_role_permission_link.updated_at is '更新时间';
|
|
||||||
comment on column user_role_permission_link.deleted_at is '删除时间';
|
|
||||||
|
|
||||||
-- admin_role_permission_link
|
|
||||||
drop table if exists admin_role_permission_link cascade;
|
|
||||||
create table admin_role_permission_link (
|
|
||||||
id serial primary key,
|
|
||||||
role_id int not null references admin_role (id)
|
|
||||||
on update cascade
|
|
||||||
on delete cascade,
|
|
||||||
permission_id int not null references permission (id)
|
|
||||||
on update cascade
|
|
||||||
on delete cascade,
|
|
||||||
created_at timestamp default current_timestamp,
|
|
||||||
updated_at timestamp default current_timestamp,
|
|
||||||
deleted_at timestamp
|
|
||||||
);
|
|
||||||
create index admin_role_permission_link_role_id_index on admin_role_permission_link (role_id);
|
|
||||||
create index admin_role_permission_link_permission_id_index on admin_role_permission_link (permission_id);
|
|
||||||
create index admin_role_permission_link_deleted_at_index on admin_role_permission_link (deleted_at);
|
|
||||||
|
|
||||||
-- admin_role_permission_link表字段注释
|
|
||||||
comment on table admin_role_permission_link is '管理员角色权限关联表';
|
|
||||||
comment on column admin_role_permission_link.id is '关联ID';
|
|
||||||
comment on column admin_role_permission_link.role_id is '角色ID';
|
|
||||||
comment on column admin_role_permission_link.permission_id is '权限ID';
|
|
||||||
comment on column admin_role_permission_link.created_at is '创建时间';
|
|
||||||
comment on column admin_role_permission_link.updated_at is '更新时间';
|
|
||||||
comment on column admin_role_permission_link.deleted_at is '删除时间';
|
|
||||||
|
|
||||||
-- client_permission_link
|
|
||||||
drop table if exists client_permission_link cascade;
|
|
||||||
create table client_permission_link (
|
|
||||||
id serial primary key,
|
|
||||||
client_id int not null references client (id)
|
|
||||||
on update cascade
|
|
||||||
on delete cascade,
|
|
||||||
permission_id int not null references permission (id)
|
|
||||||
on update cascade
|
|
||||||
on delete cascade,
|
|
||||||
created_at timestamp default current_timestamp,
|
|
||||||
updated_at timestamp default current_timestamp,
|
|
||||||
deleted_at timestamp
|
|
||||||
);
|
|
||||||
create index client_permission_link_client_id_index on client_permission_link (client_id);
|
|
||||||
create index client_permission_link_permission_id_index on client_permission_link (permission_id);
|
|
||||||
create index client_permission_link_deleted_at_index on client_permission_link (deleted_at);
|
|
||||||
|
|
||||||
-- client_permission_link表字段注释
|
|
||||||
comment on table client_permission_link is '客户端权限关联表';
|
|
||||||
comment on column client_permission_link.id is '关联ID';
|
|
||||||
comment on column client_permission_link.client_id is '客户端ID';
|
|
||||||
comment on column client_permission_link.permission_id is '权限ID';
|
|
||||||
comment on column client_permission_link.created_at is '创建时间';
|
|
||||||
comment on column client_permission_link.updated_at is '更新时间';
|
|
||||||
comment on column client_permission_link.deleted_at is '删除时间';
|
|
||||||
|
|
||||||
-- endregion
|
|
||||||
|
|
||||||
-- ====================
|
|
||||||
-- region 节点信息
|
|
||||||
-- ====================
|
|
||||||
|
|
||||||
-- proxy
|
|
||||||
drop table if exists proxy cascade;
|
|
||||||
create table proxy (
|
|
||||||
id serial primary key,
|
|
||||||
version int not null,
|
|
||||||
name varchar(255) not null unique,
|
|
||||||
host varchar(255) not null,
|
|
||||||
type int not null default 0,
|
|
||||||
secret varchar(255),
|
|
||||||
created_at timestamp default current_timestamp,
|
|
||||||
updated_at timestamp default current_timestamp,
|
|
||||||
deleted_at timestamp
|
|
||||||
);
|
|
||||||
create index proxy_name_index on proxy (name);
|
|
||||||
create index proxy_host_index on proxy (host);
|
|
||||||
create index proxy_deleted_at_index on proxy (deleted_at);
|
|
||||||
|
|
||||||
-- proxy表字段注释
|
|
||||||
comment on table proxy is '代理服务表';
|
|
||||||
comment on column proxy.id is '代理服务ID';
|
|
||||||
comment on column proxy.version is '代理服务版本';
|
|
||||||
comment on column proxy.name is '代理服务名称';
|
|
||||||
comment on column proxy.host is '代理服务地址';
|
|
||||||
comment on column proxy.type is '代理服务类型:0-自有,1-三方';
|
|
||||||
comment on column proxy.secret is '代理服务密钥';
|
|
||||||
comment on column proxy.created_at is '创建时间';
|
|
||||||
comment on column proxy.updated_at is '更新时间';
|
|
||||||
comment on column proxy.deleted_at is '删除时间';
|
|
||||||
|
|
||||||
-- node
|
|
||||||
drop table if exists node cascade;
|
|
||||||
create table node (
|
|
||||||
id serial primary key,
|
|
||||||
proxy_id int references proxy (id)
|
|
||||||
on update cascade
|
|
||||||
on delete cascade,
|
|
||||||
version int not null,
|
|
||||||
name varchar(255) not null unique,
|
|
||||||
host varchar(255) not null,
|
|
||||||
isp int not null,
|
|
||||||
prov varchar(255) not null,
|
|
||||||
city varchar(255) not null,
|
|
||||||
proxy_port int,
|
|
||||||
status int not null default 0,
|
|
||||||
rtt int default 0,
|
|
||||||
loss int default 0,
|
|
||||||
created_at timestamp default current_timestamp,
|
|
||||||
updated_at timestamp default current_timestamp,
|
|
||||||
deleted_at timestamp
|
|
||||||
);
|
|
||||||
create index node_isp_index on node (isp);
|
|
||||||
create index node_prov_index on node (prov);
|
|
||||||
create index node_city_index on node (city);
|
|
||||||
create index node_proxy_id_index on node (proxy_id);
|
|
||||||
create index node_deleted_at_index on node (deleted_at);
|
|
||||||
|
|
||||||
-- node表字段注释
|
|
||||||
comment on table node is '节点表';
|
|
||||||
comment on column node.id is '节点ID';
|
|
||||||
comment on column node.version is '节点版本';
|
|
||||||
comment on column node.name is '节点名称';
|
|
||||||
comment on column node.host is '节点地址';
|
|
||||||
comment on column node.isp is '运营商:0-其他,1-电信,2-联通,3-移动';
|
|
||||||
comment on column node.prov is '省份';
|
|
||||||
comment on column node.city is '城市';
|
|
||||||
comment on column node.proxy_id is '代理ID';
|
|
||||||
comment on column node.proxy_port is '代理端口';
|
|
||||||
comment on column node.status is '节点状态:0-离线,1-正常';
|
|
||||||
comment on column node.rtt is '延迟';
|
|
||||||
comment on column node.loss is '丢包率';
|
|
||||||
comment on column node.created_at is '创建时间';
|
|
||||||
comment on column node.updated_at is '更新时间';
|
|
||||||
comment on column node.deleted_at is '删除时间';
|
|
||||||
|
|
||||||
-- whitelist
|
|
||||||
drop table if exists whitelist cascade;
|
|
||||||
create table whitelist (
|
|
||||||
id serial primary key,
|
|
||||||
user_id int not null references "user" (id)
|
|
||||||
on update cascade
|
|
||||||
on delete cascade,
|
|
||||||
host varchar(45) not null,
|
|
||||||
remark varchar(255),
|
|
||||||
created_at timestamp default current_timestamp,
|
|
||||||
updated_at timestamp default current_timestamp,
|
|
||||||
deleted_at timestamp
|
|
||||||
);
|
|
||||||
create index whitelist_user_id_index on whitelist (user_id);
|
|
||||||
create index whitelist_host_index on whitelist (host);
|
|
||||||
create index whitelist_deleted_at_index on whitelist (deleted_at);
|
|
||||||
|
|
||||||
-- whitelist表字段注释
|
|
||||||
comment on table whitelist is '白名单表';
|
|
||||||
comment on column whitelist.id is '白名单ID';
|
|
||||||
comment on column whitelist.user_id is '用户ID';
|
|
||||||
comment on column whitelist.host is 'IP地址';
|
|
||||||
comment on column whitelist.remark is '备注';
|
|
||||||
comment on column whitelist.created_at is '创建时间';
|
|
||||||
comment on column whitelist.updated_at is '更新时间';
|
|
||||||
comment on column whitelist.deleted_at is '删除时间';
|
|
||||||
|
|
||||||
-- channel
|
|
||||||
drop table if exists channel cascade;
|
|
||||||
create table channel (
|
|
||||||
id serial primary key,
|
|
||||||
user_id int not null references "user" (id)
|
|
||||||
on update cascade
|
|
||||||
on delete cascade,
|
|
||||||
proxy_id int not null references proxy (id) --
|
|
||||||
on update cascade --
|
|
||||||
on delete set null,
|
|
||||||
node_id int references node (id) --
|
|
||||||
on update cascade --
|
|
||||||
on delete set null,
|
|
||||||
proxy_host varchar(255) not null default '',
|
|
||||||
proxy_port int not null,
|
|
||||||
node_host varchar(255),
|
|
||||||
protocol int,
|
|
||||||
auth_ip bool not null default false,
|
|
||||||
user_host varchar(255),
|
|
||||||
auth_pass bool not null default false,
|
|
||||||
username varchar(255),
|
|
||||||
password varchar(255),
|
|
||||||
expiration timestamp not null,
|
|
||||||
created_at timestamp default current_timestamp,
|
|
||||||
updated_at timestamp default current_timestamp,
|
|
||||||
deleted_at timestamp
|
|
||||||
);
|
|
||||||
create index channel_user_id_index on channel (user_id);
|
|
||||||
create index channel_proxy_id_index on channel (proxy_id);
|
|
||||||
create index channel_node_id_index on channel (node_id);
|
|
||||||
create index channel_proxy_host_index on channel (proxy_host);
|
|
||||||
create index channel_proxy_port_index on channel (proxy_port);
|
|
||||||
create index channel_node_host_index on channel (node_host);
|
|
||||||
create index channel_auth_ip_index on channel (auth_ip);
|
|
||||||
create index channel_user_host_index on channel (user_host);
|
|
||||||
create index channel_auth_pass_index on channel (auth_pass);
|
|
||||||
create index channel_username_index on channel (username);
|
|
||||||
create index channel_expiration_index on channel (expiration);
|
|
||||||
create index channel_deleted_at_index on channel (deleted_at);
|
|
||||||
|
|
||||||
-- channel表字段注释
|
|
||||||
comment on table channel is '通道表';
|
|
||||||
comment on column channel.id is '通道ID';
|
|
||||||
comment on column channel.user_id is '用户ID';
|
|
||||||
comment on column channel.proxy_id is '代理ID';
|
|
||||||
comment on column channel.node_id is '节点ID';
|
|
||||||
comment on column channel.user_host is '用户地址';
|
|
||||||
comment on column channel.proxy_port is '转发端口';
|
|
||||||
comment on column channel.node_host is '节点地址';
|
|
||||||
comment on column channel.auth_ip is 'IP认证';
|
|
||||||
comment on column channel.auth_pass is '密码认证';
|
|
||||||
comment on column channel.protocol is '协议类型:1-http,2-https,3-socks5';
|
|
||||||
comment on column channel.username is '用户名';
|
|
||||||
comment on column channel.password is '密码';
|
|
||||||
comment on column channel.expiration is '过期时间';
|
|
||||||
comment on column channel.created_at is '创建时间';
|
|
||||||
comment on column channel.updated_at is '更新时间';
|
|
||||||
comment on column channel.deleted_at is '删除时间';
|
|
||||||
|
|
||||||
-- endregion
|
|
||||||
|
|
||||||
-- ====================
|
|
||||||
-- region 产品信息
|
|
||||||
-- ====================
|
|
||||||
|
|
||||||
-- product
|
|
||||||
drop table if exists product cascade;
|
|
||||||
create table product (
|
|
||||||
id serial primary key,
|
|
||||||
code varchar(255) not null unique,
|
|
||||||
name varchar(255) not null,
|
|
||||||
description varchar(255),
|
|
||||||
sort int not null default 0,
|
|
||||||
status int not null default 1,
|
|
||||||
created_at timestamp default current_timestamp,
|
|
||||||
updated_at timestamp default current_timestamp,
|
|
||||||
deleted_at timestamp
|
|
||||||
);
|
|
||||||
create index product_deleted_at_index on product (deleted_at);
|
|
||||||
|
|
||||||
-- product表字段注释
|
|
||||||
comment on table product is '产品表';
|
|
||||||
comment on column product.id is '产品ID';
|
|
||||||
comment on column product.code is '产品代码';
|
|
||||||
comment on column product.name is '产品名称';
|
|
||||||
comment on column product.description is '产品描述';
|
|
||||||
comment on column product.sort is '排序';
|
|
||||||
comment on column product.status is '产品状态:1-正常,0-禁用';
|
|
||||||
comment on column product.created_at is '创建时间';
|
|
||||||
comment on column product.updated_at is '更新时间';
|
|
||||||
comment on column product.deleted_at is '删除时间';
|
|
||||||
|
|
||||||
-- resource
|
|
||||||
drop table if exists resource cascade;
|
|
||||||
create table resource (
|
|
||||||
id serial primary key,
|
|
||||||
user_id int not null references "user" (id)
|
|
||||||
on update cascade
|
|
||||||
on delete cascade,
|
|
||||||
resource_no varchar(255) unique,
|
|
||||||
active bool not null default true,
|
|
||||||
type int not null,
|
|
||||||
created_at timestamp default current_timestamp,
|
|
||||||
updated_at timestamp default current_timestamp,
|
|
||||||
deleted_at timestamp
|
|
||||||
);
|
|
||||||
create index resource_user_id_index on resource (user_id);
|
|
||||||
create index resource_resource_no_index on resource (resource_no);
|
|
||||||
create index resource_active_index on resource (active);
|
|
||||||
create index resource_type_index on resource (type);
|
|
||||||
create index resource_deleted_at_index on resource (deleted_at);
|
|
||||||
|
|
||||||
-- resource表字段注释
|
|
||||||
comment on table resource is '套餐表';
|
|
||||||
comment on column resource.id is '套餐ID';
|
|
||||||
comment on column resource.user_id is '用户ID';
|
|
||||||
comment on column resource.resource_no is '套餐编号';
|
|
||||||
comment on column resource.active is '套餐状态';
|
|
||||||
comment on column resource.type is '套餐类型:1-动态,2-隧道,3-独享';
|
|
||||||
comment on column resource.created_at is '创建时间';
|
|
||||||
comment on column resource.updated_at is '更新时间';
|
|
||||||
comment on column resource.deleted_at is '删除时间';
|
|
||||||
|
|
||||||
-- resource_pss
|
|
||||||
drop table if exists resource_pss cascade;
|
|
||||||
create table resource_pss (
|
|
||||||
id serial primary key,
|
|
||||||
resource_id int not null references resource (id)
|
|
||||||
on update cascade
|
|
||||||
on delete cascade,
|
|
||||||
type int,
|
|
||||||
live int,
|
|
||||||
expire timestamp,
|
|
||||||
quota int,
|
|
||||||
used int not null default 0,
|
|
||||||
daily_limit int not null default 0,
|
|
||||||
daily_used int not null default 0,
|
|
||||||
daily_last timestamp
|
|
||||||
);
|
|
||||||
create index resource_pss_resource_id_index on resource_pss (resource_id);
|
|
||||||
|
|
||||||
-- resource_pss表字段注释
|
|
||||||
comment on table resource_pss is '动态代理套餐表';
|
|
||||||
comment on column resource_pss.id is 'ID';
|
|
||||||
comment on column resource_pss.resource_id is '套餐ID';
|
|
||||||
comment on column resource_pss.type is '套餐类型:1-包时,2-包量';
|
|
||||||
comment on column resource_pss.live is '可用时长(秒)';
|
|
||||||
comment on column resource_pss.quota is '配额数量';
|
|
||||||
comment on column resource_pss.used is '已用数量';
|
|
||||||
comment on column resource_pss.expire is '过期时间';
|
|
||||||
comment on column resource_pss.daily_limit is '每日限制';
|
|
||||||
comment on column resource_pss.daily_used is '今日已用数量';
|
|
||||||
comment on column resource_pss.daily_last is '今日最后使用时间';
|
|
||||||
|
|
||||||
-- resource_psr
|
|
||||||
drop table if exists resource_psr cascade;
|
|
||||||
create table resource_psr (
|
|
||||||
id serial primary key,
|
|
||||||
resource_id int not null references resource (id)
|
|
||||||
on update cascade
|
|
||||||
on delete cascade,
|
|
||||||
live int,
|
|
||||||
conn int,
|
|
||||||
expire timestamp,
|
|
||||||
used bool
|
|
||||||
);
|
|
||||||
create index resource_psr_resource_id_index on resource_psr (resource_id);
|
|
||||||
|
|
||||||
-- resource_psr表字段注释
|
|
||||||
comment on table resource_psr is '隧道代理套餐表';
|
|
||||||
comment on column resource_psr.id is 'ID';
|
|
||||||
comment on column resource_psr.resource_id is '套餐ID';
|
|
||||||
comment on column resource_psr.live is '轮换周期(秒)';
|
|
||||||
comment on column resource_psr.conn is '最大连接数';
|
|
||||||
comment on column resource_psr.expire is '过期时间';
|
|
||||||
comment on column resource_psr.used is '是否已使用';
|
|
||||||
|
|
||||||
-- resource_pps
|
|
||||||
drop table if exists resource_pps cascade;
|
|
||||||
create table resource_pps (
|
|
||||||
id serial primary key,
|
|
||||||
resource_id int not null references resource (id)
|
|
||||||
on update cascade
|
|
||||||
on delete cascade
|
|
||||||
);
|
|
||||||
create index resource_pps_resource_id_index on resource_pps (resource_id);
|
|
||||||
|
|
||||||
-- resource_pps表字段注释
|
|
||||||
comment on table resource_pps is '独享代理套餐表';
|
|
||||||
comment on column resource_pps.id is 'ID';
|
|
||||||
comment on column resource_pps.resource_id is '套餐ID';
|
|
||||||
|
|
||||||
-- endregion
|
|
||||||
|
|
||||||
-- ====================
|
|
||||||
-- region 订单信息
|
|
||||||
-- ====================
|
|
||||||
|
|
||||||
-- trade
|
|
||||||
drop table if exists trade cascade;
|
|
||||||
create table trade (
|
|
||||||
id serial primary key,
|
|
||||||
user_id int not null references "user" (id)
|
|
||||||
on update cascade
|
|
||||||
on delete cascade,
|
|
||||||
inner_no varchar(255) not null unique,
|
|
||||||
outer_no varchar(255),
|
|
||||||
type int not null,
|
|
||||||
subject varchar(255) not null,
|
|
||||||
remark varchar(255),
|
|
||||||
amount decimal(12, 2) not null default 0,
|
|
||||||
payment decimal(12, 2) not null default 0,
|
|
||||||
method int not null,
|
|
||||||
status int not null default 0,
|
|
||||||
pay_url text,
|
|
||||||
paid_at timestamp,
|
|
||||||
cancel_at timestamp,
|
|
||||||
created_at timestamp default current_timestamp,
|
|
||||||
updated_at timestamp default current_timestamp,
|
|
||||||
deleted_at timestamp
|
|
||||||
);
|
|
||||||
create index trade_user_id_index on trade (user_id);
|
|
||||||
create index trade_outer_no_index on trade (outer_no);
|
|
||||||
create index trade_type_index on trade (type);
|
|
||||||
create index trade_status_index on trade (status);
|
|
||||||
create index trade_deleted_at_index on trade (deleted_at);
|
|
||||||
|
|
||||||
-- trade表字段注释
|
|
||||||
comment on table trade is '订单表';
|
|
||||||
comment on column trade.id is '订单ID';
|
|
||||||
comment on column trade.user_id is '用户ID';
|
|
||||||
comment on column trade.inner_no is '内部订单号';
|
|
||||||
comment on column trade.outer_no is '外部订单号';
|
|
||||||
comment on column trade.type is '订单类型:0-充值余额,1-购买产品';
|
|
||||||
comment on column trade.subject is '订单主题';
|
|
||||||
comment on column trade.remark is '订单备注';
|
|
||||||
comment on column trade.amount is '订单总金额';
|
|
||||||
comment on column trade.payment is '支付金额';
|
|
||||||
comment on column trade.method is '支付方式:1-支付宝,2-微信';
|
|
||||||
comment on column trade.status is '订单状态:0-待支付,1-已支付,2-已取消,3-已退款';
|
|
||||||
comment on column trade.pay_url is '支付链接';
|
|
||||||
comment on column trade.paid_at is '支付时间';
|
|
||||||
comment on column trade.cancel_at is '取消时间';
|
|
||||||
comment on column trade.created_at is '创建时间';
|
|
||||||
comment on column trade.updated_at is '更新时间';
|
|
||||||
comment on column trade.deleted_at is '删除时间';
|
|
||||||
|
|
||||||
-- refund
|
|
||||||
drop table if exists refund cascade;
|
|
||||||
create table refund (
|
|
||||||
id serial primary key,
|
|
||||||
trade_id int not null references trade (id)
|
|
||||||
on update cascade
|
|
||||||
on delete cascade,
|
|
||||||
product_id int references product (id) --
|
|
||||||
on update cascade --
|
|
||||||
on delete set null,
|
|
||||||
amount decimal(12, 2) not null default 0,
|
|
||||||
reason varchar(255),
|
|
||||||
status int not null default 0,
|
|
||||||
created_at timestamp default current_timestamp,
|
|
||||||
updated_at timestamp default current_timestamp,
|
|
||||||
deleted_at timestamp
|
|
||||||
);
|
|
||||||
create index refund_trade_id_index on refund (trade_id);
|
|
||||||
create index refund_product_id_index on refund (product_id);
|
|
||||||
create index refund_deleted_at_index on refund (deleted_at);
|
|
||||||
|
|
||||||
-- refund表字段注释
|
|
||||||
comment on table refund is '退款记录表';
|
|
||||||
comment on column refund.id is '退款ID';
|
|
||||||
comment on column refund.trade_id is '订单ID';
|
|
||||||
comment on column refund.product_id is '产品ID';
|
|
||||||
comment on column refund.amount is '退款金额';
|
|
||||||
comment on column refund.reason is '退款原因';
|
|
||||||
comment on column refund.status is '退款状态:0-待处理,1-已退款,2-已拒绝';
|
|
||||||
comment on column refund.created_at is '创建时间';
|
|
||||||
comment on column refund.updated_at is '更新时间';
|
|
||||||
comment on column refund.deleted_at is '删除时间';
|
|
||||||
|
|
||||||
-- bill
|
|
||||||
drop table if exists bill cascade;
|
|
||||||
create table bill (
|
|
||||||
id serial primary key,
|
|
||||||
user_id int not null references "user" (id)
|
|
||||||
on update cascade
|
|
||||||
on delete cascade,
|
|
||||||
trade_id int references trade (id) --
|
|
||||||
on update cascade --
|
|
||||||
on delete set null,
|
|
||||||
resource_id int references resource (id) --
|
|
||||||
on update cascade --
|
|
||||||
on delete set null,
|
|
||||||
refund_id int references refund (id) --
|
|
||||||
on update cascade --
|
|
||||||
on delete set null,
|
|
||||||
bill_no varchar(255) not null unique,
|
|
||||||
info varchar(255),
|
|
||||||
type int not null,
|
|
||||||
amount decimal(12, 2) not null default 0,
|
|
||||||
created_at timestamp default current_timestamp,
|
|
||||||
updated_at timestamp default current_timestamp,
|
|
||||||
deleted_at timestamp
|
|
||||||
);
|
|
||||||
create index bill_user_id_index on bill (user_id);
|
|
||||||
create index bill_trade_id_index on bill (trade_id);
|
|
||||||
create index bill_resource_id_index on bill (resource_id);
|
|
||||||
create index bill_refund_id_index on bill (refund_id);
|
|
||||||
create index bill_bill_no_index on bill (bill_no);
|
|
||||||
create index bill_type_index on bill (type);
|
|
||||||
create index bill_deleted_at_index on bill (deleted_at);
|
|
||||||
|
|
||||||
-- bill表字段注释
|
|
||||||
comment on table bill is '账单表';
|
|
||||||
comment on column bill.id is '账单ID';
|
|
||||||
comment on column bill.user_id is '用户ID';
|
|
||||||
comment on column bill.trade_id is '订单ID';
|
|
||||||
comment on column bill.resource_id is '套餐ID';
|
|
||||||
comment on column bill.refund_id is '退款ID';
|
|
||||||
comment on column bill.bill_no is '易读账单号';
|
|
||||||
comment on column bill.info is '产品可读信息';
|
|
||||||
comment on column bill.type is '账单类型:0-充值,1-消费,2-退款';
|
|
||||||
comment on column bill.amount is '账单金额';
|
|
||||||
comment on column bill.created_at is '创建时间';
|
|
||||||
comment on column bill.updated_at is '更新时间';
|
|
||||||
comment on column bill.deleted_at is '删除时间';
|
|
||||||
|
|
||||||
-- coupon 优惠券
|
|
||||||
drop table if exists coupon cascade;
|
|
||||||
create table coupon (
|
|
||||||
id serial primary key,
|
|
||||||
user_id int references "user" (id)
|
|
||||||
on update cascade
|
|
||||||
on delete cascade,
|
|
||||||
code varchar(255) not null unique,
|
|
||||||
remark varchar(255),
|
|
||||||
amount decimal(12, 2) not null default 0,
|
|
||||||
min_amount decimal(12, 2) not null default 0,
|
|
||||||
status int not null default 0,
|
|
||||||
expire_at timestamp,
|
|
||||||
created_at timestamp default current_timestamp,
|
|
||||||
updated_at timestamp default current_timestamp,
|
|
||||||
deleted_at timestamp
|
|
||||||
);
|
|
||||||
create index coupon_user_id_index on coupon (user_id);
|
|
||||||
create index coupon_code_index on coupon (code);
|
|
||||||
create index coupon_status_index on coupon (status);
|
|
||||||
create index coupon_deleted_at_index on coupon (deleted_at);
|
|
||||||
|
|
||||||
-- coupon表字段注释
|
|
||||||
comment on table coupon is '优惠券表';
|
|
||||||
comment on column coupon.id is '优惠券ID';
|
|
||||||
comment on column coupon.user_id is '用户ID';
|
|
||||||
comment on column coupon.code is '优惠券代码';
|
|
||||||
comment on column coupon.remark is '优惠券备注';
|
|
||||||
comment on column coupon.amount is '优惠券金额';
|
|
||||||
comment on column coupon.min_amount is '最低消费金额';
|
|
||||||
comment on column coupon.status is '优惠券状态:0-未使用,1-已使用,2-已过期';
|
|
||||||
comment on column coupon.expire_at is '过期时间';
|
|
||||||
comment on column coupon.created_at is '创建时间';
|
|
||||||
comment on column coupon.updated_at is '更新时间';
|
|
||||||
comment on column coupon.deleted_at is '删除时间';
|
|
||||||
|
|
||||||
-- endregion
|
|
||||||
@@ -111,18 +111,24 @@ func Protect(c *fiber.Ctx, types []services.PayloadType, permissions []string) (
|
|||||||
var auth *services.AuthContext
|
var auth *services.AuthContext
|
||||||
var err error
|
var err error
|
||||||
switch split[0] {
|
switch split[0] {
|
||||||
|
|
||||||
case "Bearer":
|
case "Bearer":
|
||||||
auth, err = authBearer(c.Context(), token)
|
auth, err = authBearer(c.Context(), token)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fiber.NewError(fiber.StatusUnauthorized, "没有权限")
|
||||||
|
}
|
||||||
|
|
||||||
case "Basic":
|
case "Basic":
|
||||||
if !slices.Contains(types, services.PayloadClientConfidential) {
|
if !slices.Contains(types, services.PayloadClientConfidential) {
|
||||||
return nil, fiber.NewError(fiber.StatusForbidden, "没有权限")
|
return nil, fiber.NewError(fiber.StatusForbidden, "没有权限")
|
||||||
}
|
}
|
||||||
auth, err = authBasic(c.Context(), token)
|
auth, err = authBasic(c.Context(), token)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fiber.NewError(fiber.StatusUnauthorized, "没有权限")
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return nil, fiber.NewError(fiber.StatusUnauthorized, "没有权限")
|
return nil, fiber.NewError(fiber.StatusForbidden, "没有权限")
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
return nil, fiber.NewError(fiber.StatusUnauthorized, "没有权限")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 检查权限
|
// 检查权限
|
||||||
|
|||||||
@@ -11,3 +11,9 @@ type AuthForbiddenErr string
|
|||||||
func (e AuthForbiddenErr) Error() string {
|
func (e AuthForbiddenErr) Error() string {
|
||||||
return string(e)
|
return string(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DataErr string
|
||||||
|
|
||||||
|
func (e DataErr) Error() string {
|
||||||
|
return string(e)
|
||||||
|
}
|
||||||
|
|||||||
@@ -268,7 +268,7 @@ type RevokeReq struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func Revoke(c *fiber.Ctx) error {
|
func Revoke(c *fiber.Ctx) error {
|
||||||
_, err := auth.Protect(c, []s.PayloadType{s.PayloadUser}, []string{})
|
_, err := auth.Protect(c, []s.PayloadType{s.PayloadClientConfidential}, []string{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// 用户未登录
|
// 用户未登录
|
||||||
return nil
|
return nil
|
||||||
@@ -290,3 +290,30 @@ func Revoke(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// endregion
|
// endregion
|
||||||
|
|
||||||
|
// region /profile
|
||||||
|
|
||||||
|
type IntrospectResp struct {
|
||||||
|
m.User
|
||||||
|
}
|
||||||
|
|
||||||
|
func Introspect(c *fiber.Ctx) error {
|
||||||
|
// 验证权限
|
||||||
|
authCtx, err := auth.Protect(c, []s.PayloadType{s.PayloadUser}, []string{})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取用户信息
|
||||||
|
profile, err := q.User.
|
||||||
|
Where(q.User.ID.Eq(authCtx.Payload.Id)).
|
||||||
|
Omit(q.User.Password, q.User.DeletedAt).
|
||||||
|
Take()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(IntrospectResp{*profile})
|
||||||
|
}
|
||||||
|
|
||||||
|
// endregion
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"platform/web/auth"
|
"platform/web/auth"
|
||||||
q "platform/web/queries"
|
q "platform/web/queries"
|
||||||
s "platform/web/services"
|
s "platform/web/services"
|
||||||
@@ -9,48 +8,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gofiber/fiber/v2"
|
"github.com/gofiber/fiber/v2"
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// region GetUserByToken
|
|
||||||
|
|
||||||
type GetUserByTokenReq struct {
|
|
||||||
Token string `json:"token" validate:"required"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUserByToken 通过token获取用户信息
|
|
||||||
func GetUserByToken(c *fiber.Ctx) error {
|
|
||||||
|
|
||||||
// 解析请求参数
|
|
||||||
req := new(GetUserByTokenReq)
|
|
||||||
if err := c.BodyParser(req); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询会话信息
|
|
||||||
session, err := s.Session.Find(c.Context(), req.Token)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询用户信息
|
|
||||||
user, err := q.User.Debug().
|
|
||||||
Omit(q.User.Password, q.User.DeletedAt).
|
|
||||||
Where(q.User.ID.Eq(session.Payload.Id)).
|
|
||||||
Take()
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
return fiber.NewError(fiber.StatusNotFound, "用户不存在")
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 返回用户信息
|
|
||||||
return c.JSON(user)
|
|
||||||
}
|
|
||||||
|
|
||||||
// endregion
|
|
||||||
|
|
||||||
// region recharge
|
// region recharge
|
||||||
|
|
||||||
type RechargePrepareReq struct {
|
type RechargePrepareReq struct {
|
||||||
|
|||||||
@@ -14,8 +14,18 @@ func ApplyRouters(app *fiber.App) {
|
|||||||
auth := api.Group("/auth")
|
auth := api.Group("/auth")
|
||||||
auth.Post("/token", handlers.Token)
|
auth.Post("/token", handlers.Token)
|
||||||
auth.Post("/revoke", handlers.Revoke)
|
auth.Post("/revoke", handlers.Revoke)
|
||||||
|
auth.Post("/introspect", handlers.Introspect)
|
||||||
auth.Post("/verify/sms", handlers.SmsCode)
|
auth.Post("/verify/sms", handlers.SmsCode)
|
||||||
|
|
||||||
|
// 用户
|
||||||
|
user := api.Group("/user")
|
||||||
|
user.Post("/identify", handlers.Identify)
|
||||||
|
user.Post("/identify/callback", handlers.IdentifyCallback)
|
||||||
|
user.Post("/recharge/prepare/alipay", handlers.RechargePrepareAlipay)
|
||||||
|
user.Post("/recharge/confirm/alipay", handlers.RechargeConfirmAlipay)
|
||||||
|
user.Post("/recharge/prepare/wechat", handlers.RechargePrepareWechat)
|
||||||
|
user.Post("/recharge/confirm/wechat", handlers.RechargeConfirmWechat)
|
||||||
|
|
||||||
// 通道
|
// 通道
|
||||||
channel := api.Group("/channel")
|
channel := api.Group("/channel")
|
||||||
channel.Post("/create", handlers.CreateChannel)
|
channel.Post("/create", handlers.CreateChannel)
|
||||||
@@ -38,16 +48,6 @@ func ApplyRouters(app *fiber.App) {
|
|||||||
resource.Post("/prepare/wechat", handlers.PrepareResourceByWechat)
|
resource.Post("/prepare/wechat", handlers.PrepareResourceByWechat)
|
||||||
resource.Post("/create/wechat", handlers.CreateResourceByWechat)
|
resource.Post("/create/wechat", handlers.CreateResourceByWechat)
|
||||||
|
|
||||||
// 用户
|
|
||||||
user := api.Group("/user")
|
|
||||||
user.Post("/get/token", handlers.GetUserByToken)
|
|
||||||
user.Post("/identify", handlers.Identify)
|
|
||||||
user.Post("/identify/callback", handlers.IdentifyCallback)
|
|
||||||
user.Post("/recharge/prepare/alipay", handlers.RechargePrepareAlipay)
|
|
||||||
user.Post("/recharge/confirm/alipay", handlers.RechargeConfirmAlipay)
|
|
||||||
user.Post("/recharge/prepare/wechat", handlers.RechargePrepareWechat)
|
|
||||||
user.Post("/recharge/confirm/wechat", handlers.RechargeConfirmWechat)
|
|
||||||
|
|
||||||
// 账单
|
// 账单
|
||||||
bill := api.Group("/bill")
|
bill := api.Group("/bill")
|
||||||
bill.Post("/list", handlers.ListBill)
|
bill.Post("/list", handlers.ListBill)
|
||||||
|
|||||||
@@ -134,11 +134,6 @@ func (s *sessionService) Refresh(ctx context.Context, refreshToken string, confi
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除旧的令牌
|
|
||||||
pipeline := tx.Pipeline()
|
|
||||||
pipeline.Del(ctx, accessKey(refreshData.AccessToken))
|
|
||||||
pipeline.Del(ctx, refreshKey(refreshToken))
|
|
||||||
|
|
||||||
// 生成新的令牌
|
// 生成新的令牌
|
||||||
newAccessToken := genToken()
|
newAccessToken := genToken()
|
||||||
newRefreshToken := genToken()
|
newRefreshToken := genToken()
|
||||||
@@ -155,9 +150,16 @@ func (s *sessionService) Refresh(ctx context.Context, refreshToken string, confi
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pipeline := tx.Pipeline()
|
||||||
|
|
||||||
|
// 保存新的令牌
|
||||||
pipeline.Set(ctx, accessKey(newAccessToken), authData, cfg.AccessTokenDuration)
|
pipeline.Set(ctx, accessKey(newAccessToken), authData, cfg.AccessTokenDuration)
|
||||||
pipeline.Set(ctx, refreshKey(newRefreshToken), newRefreshData, cfg.RefreshTokenDuration)
|
pipeline.Set(ctx, refreshKey(newRefreshToken), newRefreshData, cfg.RefreshTokenDuration)
|
||||||
|
|
||||||
|
// 删除旧的令牌
|
||||||
|
pipeline.Del(ctx, accessKey(refreshData.AccessToken))
|
||||||
|
pipeline.Del(ctx, refreshKey(refreshToken))
|
||||||
|
|
||||||
_, err = pipeline.Exec(ctx)
|
_, err = pipeline.Exec(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
Reference in New Issue
Block a user