mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-09-22 00:00:50 +00:00
feat: Cache List Page Filter Conditions (#13314)
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"github.com/1Panel-dev/1Panel/agent/utils/common"
|
||||
)
|
||||
|
||||
const (
|
||||
vllmAppKeyForUpgrade = "vllm"
|
||||
vllmImageEnvKey = "IMAGE"
|
||||
vllmImageTypeNvidia = "nvidia"
|
||||
vllmImageTypeIntel = "intel"
|
||||
vllmImageTypeAscend = "ascend"
|
||||
)
|
||||
|
||||
func resolveVllmVersionFamily(version, image string) string {
|
||||
normalizedVersion := strings.ToLower(strings.TrimSpace(version))
|
||||
if strings.HasPrefix(normalizedVersion, vllmImageTypeIntel+"-") {
|
||||
return vllmImageTypeIntel
|
||||
}
|
||||
if strings.HasPrefix(normalizedVersion, vllmImageTypeAscend+"-") {
|
||||
return vllmImageTypeAscend
|
||||
}
|
||||
if strings.HasPrefix(normalizedVersion, vllmImageTypeNvidia+"-") {
|
||||
return vllmImageTypeNvidia
|
||||
}
|
||||
normalizedImage := strings.ToLower(strings.TrimSpace(image))
|
||||
if strings.Contains(normalizedImage, "intel/") || strings.Contains(normalizedImage, "llm-scaler-vllm") {
|
||||
return vllmImageTypeIntel
|
||||
}
|
||||
if strings.Contains(normalizedImage, "ascend/") || strings.Contains(normalizedImage, "vllm-ascend") {
|
||||
return vllmImageTypeAscend
|
||||
}
|
||||
return vllmImageTypeNvidia
|
||||
}
|
||||
|
||||
func trimVllmVersionFamily(version string) string {
|
||||
trimmed := strings.TrimSpace(version)
|
||||
normalized := strings.ToLower(trimmed)
|
||||
for _, family := range []string{vllmImageTypeNvidia, vllmImageTypeIntel, vllmImageTypeAscend} {
|
||||
prefix := family + "-"
|
||||
if strings.HasPrefix(normalized, prefix) {
|
||||
return strings.TrimSpace(trimmed[len(prefix):])
|
||||
}
|
||||
}
|
||||
return trimmed
|
||||
}
|
||||
|
||||
func buildDefaultVllmImageByVersion(version string) string {
|
||||
tag := trimVllmVersionFamily(version)
|
||||
family := resolveVllmVersionFamily(version, "")
|
||||
if family == vllmImageTypeIntel {
|
||||
return "intel/llm-scaler-vllm:" + tag
|
||||
}
|
||||
if tag != "" && !strings.HasPrefix(strings.ToLower(tag), "v") {
|
||||
tag = "v" + tag
|
||||
}
|
||||
if family == vllmImageTypeAscend {
|
||||
return "quay.io/ascend/vllm-ascend:" + tag
|
||||
}
|
||||
return "vllm/vllm-openai:" + tag
|
||||
}
|
||||
|
||||
func isVllmUpgradeVersionAllowed(currentVersion, targetVersion, currentImage string) bool {
|
||||
currentFamily := resolveVllmVersionFamily(currentVersion, currentImage)
|
||||
targetFamily := resolveVllmVersionFamily(targetVersion, "")
|
||||
return currentFamily == targetFamily
|
||||
}
|
||||
|
||||
func hasVllmVersionFamilyPrefix(version string) bool {
|
||||
normalized := strings.ToLower(strings.TrimSpace(version))
|
||||
return strings.HasPrefix(normalized, vllmImageTypeNvidia+"-") ||
|
||||
strings.HasPrefix(normalized, vllmImageTypeIntel+"-") ||
|
||||
strings.HasPrefix(normalized, vllmImageTypeAscend+"-")
|
||||
}
|
||||
|
||||
func isVllmUpgradeCandidate(currentVersion, targetVersion, currentImage string) bool {
|
||||
if strings.TrimSpace(currentVersion) == strings.TrimSpace(targetVersion) {
|
||||
return false
|
||||
}
|
||||
if !isVllmUpgradeVersionAllowed(currentVersion, targetVersion, currentImage) {
|
||||
return false
|
||||
}
|
||||
if common.CompareVersion(targetVersion, currentVersion) {
|
||||
return true
|
||||
}
|
||||
return !hasVllmVersionFamilyPrefix(currentVersion) &&
|
||||
resolveVllmVersionFamily(targetVersion, "") == vllmImageTypeNvidia &&
|
||||
trimVllmVersionFamily(currentVersion) == trimVllmVersionFamily(targetVersion)
|
||||
}
|
||||
|
||||
func buildVllmUpgradeImage(currentImage, currentVersion, targetVersion string) string {
|
||||
trimmedImage := strings.TrimSpace(currentImage)
|
||||
if trimmedImage == "" || trimmedImage == buildDefaultVllmImageByVersion(currentVersion) {
|
||||
return buildDefaultVllmImageByVersion(targetVersion)
|
||||
}
|
||||
return trimmedImage
|
||||
}
|
||||
|
||||
func loadVllmImageFromEnv(raw string) string {
|
||||
envs := make(map[string]interface{})
|
||||
if strings.TrimSpace(raw) == "" {
|
||||
return ""
|
||||
}
|
||||
if err := json.Unmarshal([]byte(raw), &envs); err != nil {
|
||||
return ""
|
||||
}
|
||||
if image, ok := envs[vllmImageEnvKey].(string); ok {
|
||||
return strings.TrimSpace(image)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func setVllmImageInEnvContent(content []byte, image string) []byte {
|
||||
normalizedImage := strings.TrimSpace(image)
|
||||
if normalizedImage == "" {
|
||||
return content
|
||||
}
|
||||
lines := strings.Split(string(content), "\n")
|
||||
replaced := false
|
||||
for index, line := range lines {
|
||||
if strings.HasPrefix(line, vllmImageEnvKey+"=") {
|
||||
lines[index] = vllmImageEnvKey + "=" + normalizedImage
|
||||
replaced = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !replaced {
|
||||
if len(lines) > 0 && lines[len(lines)-1] == "" {
|
||||
lines[len(lines)-1] = vllmImageEnvKey + "=" + normalizedImage
|
||||
lines = append(lines, "")
|
||||
} else {
|
||||
lines = append(lines, vllmImageEnvKey+"="+normalizedImage)
|
||||
}
|
||||
}
|
||||
return []byte(strings.Join(lines, "\n"))
|
||||
}
|
||||
+6
-7
@@ -8,7 +8,7 @@ require (
|
||||
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible
|
||||
github.com/compose-spec/compose-go/v2 v2.13.0
|
||||
github.com/creack/pty v1.1.24
|
||||
github.com/docker/cli v29.6.1+incompatible
|
||||
github.com/docker/cli v29.6.2+incompatible
|
||||
github.com/docker/docker v28.5.2+incompatible
|
||||
github.com/docker/go-connections v0.7.0
|
||||
github.com/fsnotify/fsnotify v1.10.1
|
||||
@@ -36,8 +36,8 @@ require (
|
||||
github.com/oschwald/maxminddb-golang v1.13.1
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/pkg/sftp v1.13.10
|
||||
github.com/qiniu/go-sdk/v7 v7.26.15
|
||||
github.com/pkg/sftp v1.13.11
|
||||
github.com/qiniu/go-sdk/v7 v7.26.16
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/shirou/gopsutil/v4 v4.26.6
|
||||
github.com/sirupsen/logrus v1.9.4
|
||||
@@ -50,10 +50,10 @@ require (
|
||||
github.com/tomasen/fcgi_client v0.0.0-20180423082037-2bb3d819fd19
|
||||
github.com/upyun/go-sdk v2.1.0+incompatible
|
||||
go.mongodb.org/mongo-driver/v2 v2.8.0
|
||||
golang.org/x/crypto v0.53.0
|
||||
golang.org/x/net v0.56.0
|
||||
golang.org/x/crypto v0.54.0
|
||||
golang.org/x/net v0.57.0
|
||||
golang.org/x/sync v0.22.0
|
||||
golang.org/x/sys v0.46.0
|
||||
golang.org/x/sys v0.47.0
|
||||
golang.org/x/text v0.40.0
|
||||
golang.org/x/time v0.15.0
|
||||
google.golang.org/genproto v0.0.0-20260414002931-afd174a4e478
|
||||
@@ -113,7 +113,6 @@ require (
|
||||
github.com/ebitengine/purego v0.10.0 // indirect
|
||||
github.com/felixge/httpsnoop v1.0.4 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.13 // indirect
|
||||
github.com/gammazero/toposort v0.1.1 // indirect
|
||||
github.com/gin-contrib/sse v1.1.1 // indirect
|
||||
github.com/glebarez/go-sqlite v1.22.0 // indirect
|
||||
github.com/go-acme/alidns-20150109/v5 v5.4.1 // indirect
|
||||
|
||||
+14
-16
@@ -225,8 +225,8 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr
|
||||
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
|
||||
github.com/dlclark/regexp2 v1.12.0 h1:0j4c5qQmnC6XOWNjP3PIXURXN2gWx76rd3KvgdPkCz8=
|
||||
github.com/dlclark/regexp2 v1.12.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
|
||||
github.com/docker/cli v29.6.1+incompatible h1:oO7F4nn3Ovr/5TlfTUWFbMwBSS/B7Xs6Epv26gBrUP8=
|
||||
github.com/docker/cli v29.6.1+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/cli v29.6.2+incompatible h1:/bjePvcbbFTnRrMfWJBY7AjfICdsiLVgHn6LwTVOcqw=
|
||||
github.com/docker/cli v29.6.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
|
||||
github.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaftjlSWt4AFexzM=
|
||||
github.com/docker/docker v28.5.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
|
||||
github.com/docker/docker-credential-helpers v0.9.5 h1:EFNN8DHvaiK8zVqFA2DT6BjXE0GzfLOZ38ggPTKePkY=
|
||||
@@ -274,8 +274,6 @@ github.com/fsnotify/fsnotify v1.10.1 h1:b0/UzAf9yR5rhf3RPm9gf3ehBPpf0oZKIjtpKrx5
|
||||
github.com/fsnotify/fsnotify v1.10.1/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo=
|
||||
github.com/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9Ufpk2AcUM=
|
||||
github.com/gabriel-vasile/mimetype v1.4.13/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
|
||||
github.com/gammazero/toposort v0.1.1 h1:OivGxsWxF3U3+U80VoLJ+f50HcPU1MIqE1JlKzoJ2Eg=
|
||||
github.com/gammazero/toposort v0.1.1/go.mod h1:H2cozTnNpMw0hg2VHAYsAxmkHXBYroNangj2NTBQDvw=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gin-contrib/sse v1.1.1 h1:uGYpNwTacv5R68bSGMapo62iLTRa9l5zxGCps4hK6ko=
|
||||
github.com/gin-contrib/sse v1.1.1/go.mod h1:QXzuVkA0YO7o/gun03UI1Q+FTI8ZV/n5t03kIQAI89s=
|
||||
@@ -696,8 +694,8 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
|
||||
github.com/pkg/sftp v1.13.10 h1:+5FbKNTe5Z9aspU88DPIKJ9z2KZoaGCu6Sr6kKR/5mU=
|
||||
github.com/pkg/sftp v1.13.10/go.mod h1:bJ1a7uDhrX/4OII+agvy28lzRvQrmIQuaHrcI1HbeGA=
|
||||
github.com/pkg/sftp v1.13.11 h1:0N92SLTB8JqASJB14ZLHHzFnBV8mG9zw4K7jghEFWuE=
|
||||
github.com/pkg/sftp v1.13.11/go.mod h1:uNkH9roSXglNJqM+glJJi+TQXQUm0fXFWqCFmT8hsN0=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
@@ -725,8 +723,8 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx
|
||||
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
|
||||
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
|
||||
github.com/qiniu/go-sdk/v7 v7.26.15 h1:CaKVcP29ZnOp/pqE7U3RAZxqwL7CmtMTWlV1gAV71H0=
|
||||
github.com/qiniu/go-sdk/v7 v7.26.15/go.mod h1:ri7fGwbio0pRDFr8EK5TUpx0DbnpIMJ2bMSDxGWfCbk=
|
||||
github.com/qiniu/go-sdk/v7 v7.26.16 h1:WzPUb0XdBgWnjV8n9revG13vTUcUO4LMcWoacMneH2M=
|
||||
github.com/qiniu/go-sdk/v7 v7.26.16/go.mod h1:pTwVR1B+8SXcPLhDzBUasiKFTD9F7jRglRDR553BW3k=
|
||||
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8=
|
||||
github.com/quic-go/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
|
||||
github.com/quic-go/quic-go v0.59.0 h1:OLJkp1Mlm/aS7dpKgTc6cnpynnD2Xg7C1pwL6vy/SAw=
|
||||
@@ -950,8 +948,8 @@ golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDf
|
||||
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
|
||||
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
|
||||
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
|
||||
golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto=
|
||||
golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio=
|
||||
golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw=
|
||||
golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk=
|
||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
@@ -1049,8 +1047,8 @@ golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
|
||||
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
|
||||
golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o=
|
||||
golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec=
|
||||
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
|
||||
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -1152,8 +1150,8 @@ golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
|
||||
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
|
||||
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
@@ -1167,8 +1165,8 @@ golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
|
||||
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
|
||||
golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY=
|
||||
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0=
|
||||
golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc=
|
||||
golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y=
|
||||
golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
|
||||
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
||||
+5
-5
@@ -21,7 +21,7 @@ require (
|
||||
github.com/oschwald/maxminddb-golang v1.13.1
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible
|
||||
github.com/pkg/errors v0.9.1
|
||||
github.com/pkg/sftp v1.13.10
|
||||
github.com/pkg/sftp v1.13.11
|
||||
github.com/robfig/cron/v3 v3.0.1
|
||||
github.com/shirou/gopsutil/v4 v4.26.6
|
||||
github.com/sirupsen/logrus v1.9.4
|
||||
@@ -32,10 +32,10 @@ require (
|
||||
github.com/swaggo/files/v2 v2.0.2
|
||||
github.com/swaggo/swag v1.16.6
|
||||
github.com/xlzd/gotp v0.1.0
|
||||
golang.org/x/crypto v0.53.0
|
||||
golang.org/x/net v0.56.0
|
||||
golang.org/x/sys v0.46.0
|
||||
golang.org/x/term v0.44.0
|
||||
golang.org/x/crypto v0.54.0
|
||||
golang.org/x/net v0.57.0
|
||||
golang.org/x/sys v0.47.0
|
||||
golang.org/x/term v0.45.0
|
||||
golang.org/x/text v0.40.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
gopkg.in/yaml.v3 v3.0.1
|
||||
|
||||
+10
-10
@@ -182,8 +182,8 @@ github.com/phpdave11/gofpdi v1.0.15/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/sftp v1.13.10 h1:+5FbKNTe5Z9aspU88DPIKJ9z2KZoaGCu6Sr6kKR/5mU=
|
||||
github.com/pkg/sftp v1.13.10/go.mod h1:bJ1a7uDhrX/4OII+agvy28lzRvQrmIQuaHrcI1HbeGA=
|
||||
github.com/pkg/sftp v1.13.11 h1:0N92SLTB8JqASJB14ZLHHzFnBV8mG9zw4K7jghEFWuE=
|
||||
github.com/pkg/sftp v1.13.11/go.mod h1:uNkH9roSXglNJqM+glJJi+TQXQUm0fXFWqCFmT8hsN0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
|
||||
@@ -267,8 +267,8 @@ golang.org/x/arch v0.26.0 h1:jZ6dpec5haP/fUv1kLCbuJy6dnRrfX6iVK08lZBFpk4=
|
||||
golang.org/x/arch v0.26.0/go.mod h1:0X+GdSIP+kL5wPmpK7sdkEVTt2XoYP0cSjQSbZBwOi8=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto=
|
||||
golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio=
|
||||
golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw=
|
||||
golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk=
|
||||
golang.org/x/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.39.0 h1:skVYidAEVKgn8lZ602XO75asgXBgLj9G/FE3RbuPFww=
|
||||
golang.org/x/image v0.39.0/go.mod h1:sIbmppfU+xFLPIG0FoVUTvyBMmgng1/XAMhQ2ft0hpA=
|
||||
@@ -276,8 +276,8 @@ golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ=
|
||||
golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o=
|
||||
golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec=
|
||||
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
|
||||
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
|
||||
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
|
||||
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -285,10 +285,10 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
|
||||
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc=
|
||||
golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y=
|
||||
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
|
||||
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
|
||||
golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
|
||||
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs=
|
||||
|
||||
Generated
+89
-89
@@ -52,12 +52,12 @@
|
||||
"@tailwindcss/postcss": "^4.3.0",
|
||||
"@types/node": "^26.1.1",
|
||||
"@types/uuid": "^11.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.63.0",
|
||||
"@typescript-eslint/parser": "^8.63.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.64.0",
|
||||
"@typescript-eslint/parser": "^8.64.0",
|
||||
"@vitejs/plugin-vue": "^6.0.7",
|
||||
"@vitejs/plugin-vue-jsx": "^5.1.6",
|
||||
"@vue/compiler-sfc": "^3.5.35",
|
||||
"autoprefixer": "^10.5.0",
|
||||
"autoprefixer": "^10.5.4",
|
||||
"esbuild": "^0.28.1",
|
||||
"eslint": "^10.6.0",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
@@ -66,9 +66,9 @@
|
||||
"lint-staged": "^17.0.7",
|
||||
"postcss": "^8.5.14",
|
||||
"postcss-html": "^1.8.1",
|
||||
"prettier": "^3.8.2",
|
||||
"prettier": "^3.9.5",
|
||||
"rollup-plugin-visualizer": "^5.5.4",
|
||||
"sass": "^1.100.0",
|
||||
"sass": "^1.101.0",
|
||||
"standard-version": "^9.5.0",
|
||||
"tailwindcss": "^4.3.0",
|
||||
"typescript": "^6.0.3",
|
||||
@@ -3057,17 +3057,17 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||
"version": "8.63.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.63.0.tgz",
|
||||
"integrity": "sha512-rvwSgqT+DHpWdzfSzPatRLm02a0GlESt++9iy3hLCDY4BgkaLcl8LBi9Yh7XGFBpwcBE/K3024QuXWTpbz4FfQ==",
|
||||
"version": "8.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.64.0.tgz",
|
||||
"integrity": "sha512-CGvQPBxN3wZLu6Rz2kFUpZeoCm78xUic92ck39KPePkO1NPOwjCqdQnm5Q87tpWw9vcBvW8XLrDXjH9PWYtJ3Q==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@eslint-community/regexpp": "^4.12.2",
|
||||
"@typescript-eslint/scope-manager": "8.63.0",
|
||||
"@typescript-eslint/type-utils": "8.63.0",
|
||||
"@typescript-eslint/utils": "8.63.0",
|
||||
"@typescript-eslint/visitor-keys": "8.63.0",
|
||||
"@typescript-eslint/scope-manager": "8.64.0",
|
||||
"@typescript-eslint/type-utils": "8.64.0",
|
||||
"@typescript-eslint/utils": "8.64.0",
|
||||
"@typescript-eslint/visitor-keys": "8.64.0",
|
||||
"ignore": "^7.0.5",
|
||||
"natural-compare": "^1.4.0",
|
||||
"ts-api-utils": "^2.5.0"
|
||||
@@ -3080,7 +3080,7 @@
|
||||
"url": "https://opencollective.com/typescript-eslint"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@typescript-eslint/parser": "^8.63.0",
|
||||
"@typescript-eslint/parser": "^8.64.0",
|
||||
"eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
|
||||
"typescript": ">=4.8.4 <6.1.0"
|
||||
}
|
||||
@@ -3096,17 +3096,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/parser": {
|
||||
"version": "8.63.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.63.0.tgz",
|
||||
"integrity": "sha512-gwh4gvvlaVDKKxyfxMG+Gnu1u9X0OQBwyGLkbwB65dIzBKnxeRiJlNFqlI3zwVhNXJIs6qV7mlFCn/BIajlVig==",
|
||||
"version": "8.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.64.0.tgz",
|
||||
"integrity": "sha512-KA0OshtlcCCXmbfqyZkM5pV3/WNraJf7DkJRLpyrmwPtud57H5BDX7C3k0LPSPxpprfRL+cJDGabF10mvNCoCw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@typescript-eslint/scope-manager": "8.63.0",
|
||||
"@typescript-eslint/types": "8.63.0",
|
||||
"@typescript-eslint/typescript-estree": "8.63.0",
|
||||
"@typescript-eslint/visitor-keys": "8.63.0",
|
||||
"@typescript-eslint/scope-manager": "8.64.0",
|
||||
"@typescript-eslint/types": "8.64.0",
|
||||
"@typescript-eslint/typescript-estree": "8.64.0",
|
||||
"@typescript-eslint/visitor-keys": "8.64.0",
|
||||
"debug": "^4.4.3"
|
||||
},
|
||||
"engines": {
|
||||
@@ -3122,14 +3122,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/project-service": {
|
||||
"version": "8.63.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.63.0.tgz",
|
||||
"integrity": "sha512-e5dh0/UI0ok53AlZ5wRkXCB32z/f2jUZqPR/ygAw5WYaSw8j9EoJWlS7wQjr/dmOaqWjnPIn2m+HhVPCMWGZVQ==",
|
||||
"version": "8.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.64.0.tgz",
|
||||
"integrity": "sha512-tk4WpOJ6IEbGrVHaNmM0YRrwAD3exZlIK3iadQNAxh4YKk6jvUQ4ecq18n+v7+meh+cJ3j+D8nbk8sRKhlwLQg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/tsconfig-utils": "^8.63.0",
|
||||
"@typescript-eslint/types": "^8.63.0",
|
||||
"@typescript-eslint/tsconfig-utils": "^8.64.0",
|
||||
"@typescript-eslint/types": "^8.64.0",
|
||||
"debug": "^4.4.3"
|
||||
},
|
||||
"engines": {
|
||||
@@ -3144,14 +3144,14 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/scope-manager": {
|
||||
"version": "8.63.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.63.0.tgz",
|
||||
"integrity": "sha512-uUyfMWCnDSN8bCpcrY8nGP2BLkQ9Xn0GsipcONcpIDWhwhO4ZSyHvyS14U3X75mzxWxL3I2UZIrenTzdzcJO8A==",
|
||||
"version": "8.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.64.0.tgz",
|
||||
"integrity": "sha512-CXEaFdYXjSTgKhisNkwCcJwTP8Pl+fmRrEQrri4nm3vU743bALrxzLmq7fHG/7e6a5xO0lDYeURpZmBuhHk54w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "8.63.0",
|
||||
"@typescript-eslint/visitor-keys": "8.63.0"
|
||||
"@typescript-eslint/types": "8.64.0",
|
||||
"@typescript-eslint/visitor-keys": "8.64.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
@@ -3162,9 +3162,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/tsconfig-utils": {
|
||||
"version": "8.63.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.63.0.tgz",
|
||||
"integrity": "sha512-sUAbkulqBAsncKnbRP3+7CtQFRKicexnj7ZwNC6ddCR7EmrXvjvdCYMJbUIqMd6lwoEriZjwLo08aS5tSjVMHg==",
|
||||
"version": "8.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.64.0.tgz",
|
||||
"integrity": "sha512-2yo8rRNKuzbVWQp5kslhANqZ2uDAeROQHBRZNPu8JDsHmeFNj/XJJhX/FhNUWmkHHvoNsKa6+tHJiig87EzsQw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@@ -3179,15 +3179,15 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/type-utils": {
|
||||
"version": "8.63.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.63.0.tgz",
|
||||
"integrity": "sha512-Nzzh/OGxVCOjObjaj1CQF2RUasyYy2Jfuh+zZ3PjLzG2fYRriAiZLib9UKtO+CpQAS3YHiAS+ckZDclwqI1TPA==",
|
||||
"version": "8.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.64.0.tgz",
|
||||
"integrity": "sha512-XWG4Fmmv/6SvyS9nH8jWrKs6terwJvE8cyRt1CzYYqzp9OrPhCT4cMc/f7C6RZCwG+qMmiffJS1/qJP8G1URtg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "8.63.0",
|
||||
"@typescript-eslint/typescript-estree": "8.63.0",
|
||||
"@typescript-eslint/utils": "8.63.0",
|
||||
"@typescript-eslint/types": "8.64.0",
|
||||
"@typescript-eslint/typescript-estree": "8.64.0",
|
||||
"@typescript-eslint/utils": "8.64.0",
|
||||
"debug": "^4.4.3",
|
||||
"ts-api-utils": "^2.5.0"
|
||||
},
|
||||
@@ -3204,9 +3204,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/types": {
|
||||
"version": "8.63.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.63.0.tgz",
|
||||
"integrity": "sha512-xyLtl9DUBBFrcJS4x2pIqGLH68/tC2uOa4Z7pUteW09D3bXnnXUom4dyPikzWgB7llmIc1zoeI3aoUdC4rPK/Q==",
|
||||
"version": "8.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.64.0.tgz",
|
||||
"integrity": "sha512-qjhfuTfLXjA4IOzXvz0rTjT01BqEiIgPoUeMwiEjnaHKJMTNo8rH5pYW1a2L/0Dnux2fPC85AeyJoWaGa8WxTA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@@ -3218,16 +3218,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/typescript-estree": {
|
||||
"version": "8.63.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.63.0.tgz",
|
||||
"integrity": "sha512-ygBkU+B7ex5UI/gKhaqexWev79uISfIv7XQCRNYO/jmD8rGLPyWLAb3KMRT6nd8Gt9bmUBi9+iX6tBdYfOY81Q==",
|
||||
"version": "8.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.64.0.tgz",
|
||||
"integrity": "sha512-Pztpsn1aCE1oWDvDEfUk31nngvvF7vUB5SwHFEaZIFpvw7WJtqUHHL4plBZDA9HfWJJjL13BdG0YrJInTUvoVA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/project-service": "8.63.0",
|
||||
"@typescript-eslint/tsconfig-utils": "8.63.0",
|
||||
"@typescript-eslint/types": "8.63.0",
|
||||
"@typescript-eslint/visitor-keys": "8.63.0",
|
||||
"@typescript-eslint/project-service": "8.64.0",
|
||||
"@typescript-eslint/tsconfig-utils": "8.64.0",
|
||||
"@typescript-eslint/types": "8.64.0",
|
||||
"@typescript-eslint/visitor-keys": "8.64.0",
|
||||
"debug": "^4.4.3",
|
||||
"minimatch": "^10.2.2",
|
||||
"semver": "^7.7.3",
|
||||
@@ -3285,16 +3285,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/utils": {
|
||||
"version": "8.63.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.63.0.tgz",
|
||||
"integrity": "sha512-fUKaeAvrTuQg/Tgt3nliAUSZHJM6DlCcfyEmxCvlX8kieWSStBX+5O5Fnidtc3i2JrH+9c/GL4RY2iasd/GPTA==",
|
||||
"version": "8.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.64.0.tgz",
|
||||
"integrity": "sha512-aJUGVB3+U0htrrCjoA8qukw8cm8fNCGAxK/tVoS70k8aeb7DETKeFozRiVFIwEeN9WJLsjaP3ph8I60tY2XZoQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@eslint-community/eslint-utils": "^4.9.1",
|
||||
"@typescript-eslint/scope-manager": "8.63.0",
|
||||
"@typescript-eslint/types": "8.63.0",
|
||||
"@typescript-eslint/typescript-estree": "8.63.0"
|
||||
"@typescript-eslint/scope-manager": "8.64.0",
|
||||
"@typescript-eslint/types": "8.64.0",
|
||||
"@typescript-eslint/typescript-estree": "8.64.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
@@ -3309,13 +3309,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@typescript-eslint/visitor-keys": {
|
||||
"version": "8.63.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.63.0.tgz",
|
||||
"integrity": "sha512-UexrHGnGTpbuQHct2ExOc2ZcFbGUS9FOesCxxqdBGcpI1BxYu/LZ6U8Aq6/72XtF/qRBk9nhuGHFJIXXMhPMdw==",
|
||||
"version": "8.64.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.64.0.tgz",
|
||||
"integrity": "sha512-mrtuL8Nsn6gi2H4mo5KMTp823M+3Q19Ew/i+Zlikq20tIMm99C3Ez0dCmkWWnxut20esQvTg8aUSEhMcAOXhEw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@typescript-eslint/types": "8.63.0",
|
||||
"@typescript-eslint/types": "8.64.0",
|
||||
"eslint-visitor-keys": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
@@ -3920,9 +3920,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/autoprefixer": {
|
||||
"version": "10.5.0",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.0.tgz",
|
||||
"integrity": "sha512-FMhOoZV4+qR6aTUALKX2rEqGG+oyATvwBt9IIzVR5rMa2HRWPkxf+P+PAJLD1I/H5/II+HuZcBJYEFBpq39ong==",
|
||||
"version": "10.5.4",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.5.4.tgz",
|
||||
"integrity": "sha512-MaU0U/za7N3r6brxD4YB/l4NSrFzLPlANv6wEuQVaIPlD3L4W9rFcQPbL/EilY9BHhHvhfcz3gInDLrEtWT4EA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -3940,8 +3940,8 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"browserslist": "^4.28.2",
|
||||
"caniuse-lite": "^1.0.30001787",
|
||||
"browserslist": "^4.28.6",
|
||||
"caniuse-lite": "^1.0.30001806",
|
||||
"fraction.js": "^5.3.4",
|
||||
"picocolors": "^1.1.1",
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
@@ -3976,9 +3976,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/baseline-browser-mapping": {
|
||||
"version": "2.10.35",
|
||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.35.tgz",
|
||||
"integrity": "sha512-honAfLBde0HAFLdNyBEfuuENkF6zR+ozxqxa/2zJKHBe1qzLqyTSeRKpdPEHAP03rlDGyQOPnCSxnVpVqQo9Mg==",
|
||||
"version": "2.10.44",
|
||||
"resolved": "https://registry.npmjs.org/baseline-browser-mapping/-/baseline-browser-mapping-2.10.44.tgz",
|
||||
"integrity": "sha512-T3ghW+sl/ZJ8w1v/yQx3qvJ9040DWoLBz8JT/CILbAKcFyG9b2MRe75v6W5uXjv6uH1lumK2Kv46y2zSkcej0Q==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
@@ -4030,9 +4030,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/browserslist": {
|
||||
"version": "4.28.2",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.2.tgz",
|
||||
"integrity": "sha512-48xSriZYYg+8qXna9kwqjIVzuQxi+KYWp2+5nCYnYKPTr0LvD89Jqk2Or5ogxz0NUMfIjhh2lIUX/LyX9B4oIg==",
|
||||
"version": "4.28.6",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.28.6.tgz",
|
||||
"integrity": "sha512-FQBYNK15VMslhLHpA7+n+n1GOlF1kId2xcCg7/j95f24AOF6VDYMNH4mFxF7KuaTdv627faazpOAjFzMrfJOUw==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -4051,10 +4051,10 @@
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"baseline-browser-mapping": "^2.10.12",
|
||||
"caniuse-lite": "^1.0.30001782",
|
||||
"electron-to-chromium": "^1.5.328",
|
||||
"node-releases": "^2.0.36",
|
||||
"baseline-browser-mapping": "^2.10.42",
|
||||
"caniuse-lite": "^1.0.30001803",
|
||||
"electron-to-chromium": "^1.5.389",
|
||||
"node-releases": "^2.0.51",
|
||||
"update-browserslist-db": "^1.2.3"
|
||||
},
|
||||
"bin": {
|
||||
@@ -4129,9 +4129,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001797",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001797.tgz",
|
||||
"integrity": "sha512-l8xKG+gwAIExZGl9FrF7KUwuOmk6wbEPC9Xoy/RtnWv1XG0Q4LFlagaLpUv3Kiza3W/wm27zy0yWJEieYKAP6w==",
|
||||
"version": "1.0.30001806",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001806.tgz",
|
||||
"integrity": "sha512-72Cuvd95zbSYPKq6Fhg8eDJRlzgWDf7/mtoZv6Qe/DYNCEBdNxoA3+rZAU2ZhGCpZlns3EssFavaZomckT5Uuw==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
@@ -5154,9 +5154,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.5.376",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.376.tgz",
|
||||
"integrity": "sha512-cUVA7/RvbFTEuw/i3obUwDTRIXojaxkResf+ibByPFxjc6XK3VNtcQXV0NSbAlJ0FMjcJGgftVVB4Qo184EXvA==",
|
||||
"version": "1.5.394",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.394.tgz",
|
||||
"integrity": "sha512-Wmt2Gm0o8JWBuGgmc4XZ0u9s1RaCRqhxP47phplmfg04+qypTUurpeJGP45A7Fhv7jdrrVH44PLlR9qXo37cVQ==",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
@@ -7914,9 +7914,9 @@
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/node-releases": {
|
||||
"version": "2.0.48",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.48.tgz",
|
||||
"integrity": "sha512-1uz8041X6LoI6ZSdZacM9lVY28vuzDlSKitnpbSNK0RfKoIJkX29NBPVEFXhnuSuEOA9Ww0xnPJ+ILWbGAv8DA==",
|
||||
"version": "2.0.51",
|
||||
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.51.tgz",
|
||||
"integrity": "sha512-wRNIrw4DmVLKQlbgOMdkMx27Wrpzes2hh5Jtbi2bjPd+4wJstWIqP5A+lscnqbm0xxmT5Bpg8Lec5ItEBwx6BQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
@@ -8344,9 +8344,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "3.8.2",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.2.tgz",
|
||||
"integrity": "sha512-8c3mgTe0ASwWAJK+78dpviD+A8EqhndQPUBpNUIPt6+xWlIigCwfN01lWr9MAede4uqXGTEKeQWTvzb3vjia0Q==",
|
||||
"version": "3.9.5",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.5.tgz",
|
||||
"integrity": "sha512-/FVl766LpUfB5vXgCYOYa0MeV/441Ia99AeICQIQFTY/Nw0roZwULcXpku5i1/m5kt/baz+s4Zogspd839HSMg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
@@ -8813,9 +8813,9 @@
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/sass": {
|
||||
"version": "1.100.0",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.100.0.tgz",
|
||||
"integrity": "sha512-B5j0rYMlinhhOo9tjQebMVVn0TfyXAF+wB3b2ggZUuJ/is/Y+7+JGjirAMxHZ9Z3hIP98NPfamlAkBHa1lAaXQ==",
|
||||
"version": "1.101.0",
|
||||
"resolved": "https://registry.npmjs.org/sass/-/sass-1.101.0.tgz",
|
||||
"integrity": "sha512-OL3GoQyoUdDt843DpVmDO6y2k1sc5IhUDSpu8XucEI+35neq5QivZ1iuegnpraEVTJXlQGK1gl27zKcTLEPbQw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
|
||||
@@ -63,12 +63,12 @@
|
||||
"@tailwindcss/postcss": "^4.3.0",
|
||||
"@types/node": "^26.1.1",
|
||||
"@types/uuid": "^11.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.63.0",
|
||||
"@typescript-eslint/parser": "^8.63.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.64.0",
|
||||
"@typescript-eslint/parser": "^8.64.0",
|
||||
"@vitejs/plugin-vue": "^6.0.7",
|
||||
"@vitejs/plugin-vue-jsx": "^5.1.6",
|
||||
"@vue/compiler-sfc": "^3.5.35",
|
||||
"autoprefixer": "^10.5.0",
|
||||
"autoprefixer": "^10.5.4",
|
||||
"esbuild": "^0.28.1",
|
||||
"eslint": "^10.6.0",
|
||||
"eslint-config-prettier": "^10.1.8",
|
||||
@@ -77,9 +77,9 @@
|
||||
"lint-staged": "^17.0.7",
|
||||
"postcss": "^8.5.14",
|
||||
"postcss-html": "^1.8.1",
|
||||
"prettier": "^3.8.2",
|
||||
"prettier": "^3.9.5",
|
||||
"rollup-plugin-visualizer": "^5.5.4",
|
||||
"sass": "^1.100.0",
|
||||
"sass": "^1.101.0",
|
||||
"standard-version": "^9.5.0",
|
||||
"tailwindcss": "^4.3.0",
|
||||
"typescript": "^6.0.3",
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { reactive, type UnwrapNestedRefs } from 'vue';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useGlobalStore } from '@/composables/useGlobalStore';
|
||||
import { getPageState } from '@/utils/page-state-cache';
|
||||
|
||||
export const usePageState = <T extends object>(factory: () => T): UnwrapNestedRefs<T> => {
|
||||
const route = useRoute();
|
||||
const { currentNode } = useGlobalStore();
|
||||
const key = `${currentNode.value}:${String(route.name || route.path)}`;
|
||||
return reactive(getPageState(key, factory));
|
||||
};
|
||||
@@ -4835,6 +4835,7 @@ const message = {
|
||||
provinceRuleLabel: 'Province',
|
||||
openRestyFeatureVersionAlert: 'OpenResty must be newer than 1.31.1.1-0 for {0} to take effect.',
|
||||
ipLocation: 'IP Location',
|
||||
ipLocationSearchHelper: 'Enter an IP location, fuzzy search supported',
|
||||
action: 'Action',
|
||||
ruleType: 'Attack Type',
|
||||
ipHelper: 'Enter the IP address',
|
||||
@@ -5042,6 +5043,9 @@ const message = {
|
||||
observationModeConfirm:
|
||||
'In observation mode, all WAF matches are logged without blocking requests. Continue?',
|
||||
globalStrictRequired: 'Enable strict mode in global settings first',
|
||||
websiteSearchHelper: 'Enter a website domain, alias, or remark',
|
||||
configReadFailed: 'Failed to load configuration',
|
||||
detailSetting: 'Detailed settings',
|
||||
observe: 'Observe',
|
||||
saveLog: 'Save Log',
|
||||
remoteURLHelper: 'The remote URL needs to ensure one IP per line and no other characters',
|
||||
|
||||
@@ -4885,6 +4885,7 @@ const message = {
|
||||
provinceRuleLabel: 'Provincia',
|
||||
openRestyFeatureVersionAlert: 'OpenResty debe ser posterior a la versión 1.31.1.1-0 para que {0} funcione.',
|
||||
ipLocation: 'Ubicación IP',
|
||||
ipLocationSearchHelper: 'Introduzca la ubicación de la IP; se admite búsqueda aproximada',
|
||||
action: 'Acción',
|
||||
ruleType: 'Tipo de ataque',
|
||||
ipHelper: 'Introduce la dirección IP',
|
||||
@@ -5086,6 +5087,9 @@ const message = {
|
||||
observationModeConfirm:
|
||||
'En el modo de observación, todas las coincidencias del WAF se registran sin bloquear solicitudes. ¿Continuar?',
|
||||
globalStrictRequired: 'Primero habilite el modo estricto en la configuración global',
|
||||
websiteSearchHelper: 'Introduzca el dominio, alias o comentario del sitio web',
|
||||
configReadFailed: 'No se pudo cargar la configuración',
|
||||
detailSetting: 'Configuración detallada',
|
||||
observe: 'Observar',
|
||||
saveLog: 'Guardar log',
|
||||
remoteURLHelper: 'La URL remota debe tener solo una IP por línea y sin otros caracteres',
|
||||
|
||||
@@ -4796,6 +4796,7 @@ const message = {
|
||||
provincePolicy: 'سیاست استان',
|
||||
openRestyFeatureVersionAlert: 'برای فعال شدن {0}، نسخه OpenResty باید جدیدتر از 1.31.1.1-0 باشد.',
|
||||
ipLocation: 'مکان IP',
|
||||
ipLocationSearchHelper: 'موقعیت IP را وارد کنید؛ جستوجوی تقریبی پشتیبانی میشود',
|
||||
action: 'اقدام',
|
||||
ruleType: 'نوع حمله',
|
||||
ipHelper: 'آدرس IP را وارد کنید',
|
||||
@@ -4991,6 +4992,17 @@ const message = {
|
||||
crlf: 'تزریق CRLF',
|
||||
strict: 'حالت سختگیرانه',
|
||||
strictHelper: 'از قوانین سختگیرانهتر برای تأیید درخواستها استفاده کنید',
|
||||
executionStrategy: 'راهبرد اجرا',
|
||||
detectionStrength: 'شدت تشخیص',
|
||||
protectionMode: 'حالت محافظت',
|
||||
observationMode: 'حالت مشاهده',
|
||||
standardMode: 'حالت استاندارد',
|
||||
observationModeConfirm:
|
||||
'در حالت مشاهده، تمام موارد منطبق WAF فقط ثبت میشوند و درخواستها مسدود نمیشوند. ادامه میدهید؟',
|
||||
globalStrictRequired: 'ابتدا حالت سختگیرانه را در تنظیمات سراسری فعال کنید',
|
||||
websiteSearchHelper: 'دامنه، نام مستعار یا توضیحات وبسایت را وارد کنید',
|
||||
configReadFailed: 'بارگذاری پیکربندی ناموفق بود',
|
||||
detailSetting: 'تنظیمات دقیق',
|
||||
saveLog: 'ذخیره لاگ',
|
||||
remoteURLHelper: 'URL از راه دور باید تضمین کند که هر خط یک IP است و هیچ کاراکتر دیگری ندارد',
|
||||
notFound: 'یافت نشد (۴۰۴)',
|
||||
|
||||
@@ -4849,6 +4849,7 @@ const message = {
|
||||
openRestyFeatureVersionAlert:
|
||||
'{0} を有効にするには、OpenResty のバージョンが 1.31.1.1-0 より新しい必要があります。',
|
||||
ipLocation: 'IP位置',
|
||||
ipLocationSearchHelper: 'IP の所在地を入力してください(あいまい検索対応)',
|
||||
action: 'アクション',
|
||||
ruleType: '攻撃タイプ',
|
||||
ipHelper: 'IPアドレスを入力してください',
|
||||
@@ -5053,6 +5054,9 @@ const message = {
|
||||
observationModeConfirm:
|
||||
'監視モードでは、すべての WAF 検出をログに記録し、リクエストをブロックしません。続行しますか?',
|
||||
globalStrictRequired: '先にグローバル設定で厳格モードを有効にしてください',
|
||||
websiteSearchHelper: 'サイトのドメイン、エイリアス、または備考を入力してください',
|
||||
configReadFailed: '設定の読み込みに失敗しました',
|
||||
detailSetting: '詳細設定',
|
||||
observe: '監視',
|
||||
saveLog: 'ログを保存',
|
||||
remoteURLHelper: 'リモート URL は、1行に1つのIPで、他の文字がないことを保証する必要があります',
|
||||
|
||||
@@ -4753,6 +4753,7 @@ const message = {
|
||||
provinceRuleLabel: '성',
|
||||
openRestyFeatureVersionAlert: '{0}을(를) 적용하려면 OpenResty 버전이 1.31.1.1-0보다 높아야 합니다.',
|
||||
ipLocation: 'IP 위치',
|
||||
ipLocationSearchHelper: 'IP 위치를 입력하세요. 부분 검색을 지원합니다',
|
||||
action: '동작',
|
||||
ruleType: '공격 유형',
|
||||
ipHelper: 'IP 주소를 입력하세요',
|
||||
@@ -4953,6 +4954,9 @@ const message = {
|
||||
observationModeConfirm:
|
||||
'관찰 모드에서는 모든 WAF 탐지를 기록하지만 요청을 차단하지 않습니다. 계속하시겠습니까?',
|
||||
globalStrictRequired: '먼저 전역 설정에서 엄격 모드를 활성화하세요',
|
||||
websiteSearchHelper: '웹사이트 도메인, 별칭 또는 비고를 입력하세요',
|
||||
configReadFailed: '설정을 불러오지 못했습니다',
|
||||
detailSetting: '상세 설정',
|
||||
observe: '관찰',
|
||||
saveLog: '로그 저장',
|
||||
remoteURLHelper: '원격 URL은 한 줄에 하나의 IP만 포함하고 다른 문자는 포함하지 않아야 합니다',
|
||||
|
||||
@@ -4912,6 +4912,7 @@ const message = {
|
||||
provinceRuleLabel: 'Wilayah pentadbiran',
|
||||
openRestyFeatureVersionAlert: 'OpenResty mesti lebih baharu daripada 1.31.1.1-0 agar {0} berfungsi.',
|
||||
ipLocation: 'Lokasi IP',
|
||||
ipLocationSearchHelper: 'Masukkan lokasi IP; carian kabur disokong',
|
||||
action: 'Tindakan',
|
||||
ruleType: 'Jenis Serangan',
|
||||
ipHelper: 'Masukkan alamat IP',
|
||||
@@ -5118,6 +5119,9 @@ const message = {
|
||||
observationModeConfirm:
|
||||
'Dalam mod pemerhatian, semua padanan WAF direkod tanpa menyekat permintaan. Teruskan?',
|
||||
globalStrictRequired: 'Dayakan mod strict dalam tetapan global terlebih dahulu',
|
||||
websiteSearchHelper: 'Masukkan domain, alias atau catatan laman web',
|
||||
configReadFailed: 'Gagal memuatkan konfigurasi',
|
||||
detailSetting: 'Tetapan terperinci',
|
||||
observe: 'Perhati',
|
||||
saveLog: 'Simpan Log',
|
||||
remoteURLHelper: 'URL jauh perlu memastikan satu IP setiap baris dan tiada aksara lain',
|
||||
|
||||
@@ -5054,6 +5054,7 @@ const message = {
|
||||
provinceRuleLabel: 'Província',
|
||||
openRestyFeatureVersionAlert: 'A versão do OpenResty deve ser superior a 1.31.1.1-0 para que {0} funcione.',
|
||||
ipLocation: 'Localização do IP',
|
||||
ipLocationSearchHelper: 'Insira a localização do IP; pesquisa aproximada é suportada',
|
||||
action: 'Ação',
|
||||
ruleType: 'Tipo de ataque',
|
||||
ipHelper: 'Digite o endereço IP',
|
||||
@@ -5262,6 +5263,9 @@ const message = {
|
||||
observationModeConfirm:
|
||||
'No modo de observação, todas as correspondências do WAF são registradas sem bloquear solicitações. Continuar?',
|
||||
globalStrictRequired: 'Primeiro habilite o modo estrito nas configurações globais',
|
||||
websiteSearchHelper: 'Digite o domínio, alias ou observação do site',
|
||||
configReadFailed: 'Falha ao carregar a configuração',
|
||||
detailSetting: 'Configurações detalhadas',
|
||||
observe: 'Observar',
|
||||
saveLog: 'Salvar log',
|
||||
remoteURLHelper: 'O URL remoto precisa garantir um IP por linha e nenhum outro caractere',
|
||||
|
||||
@@ -4900,6 +4900,7 @@ const message = {
|
||||
provinceRuleLabel: 'Провинция',
|
||||
openRestyFeatureVersionAlert: 'Для работы функции «{0}» требуется версия OpenResty новее 1.31.1.1-0.',
|
||||
ipLocation: 'Местоположение IP',
|
||||
ipLocationSearchHelper: 'Введите местоположение IP; поддерживается нечеткий поиск',
|
||||
action: 'Действие',
|
||||
ruleType: 'Тип атаки',
|
||||
ipHelper: 'Введите IP-адрес',
|
||||
@@ -5108,6 +5109,9 @@ const message = {
|
||||
observationModeConfirm:
|
||||
'В режиме наблюдения все срабатывания WAF записываются без блокировки запросов. Продолжить?',
|
||||
globalStrictRequired: 'Сначала включите строгий режим в глобальных настройках',
|
||||
websiteSearchHelper: 'Введите домен, псевдоним или примечание сайта',
|
||||
configReadFailed: 'Не удалось загрузить конфигурацию',
|
||||
detailSetting: 'Подробные настройки',
|
||||
observe: 'Наблюдение',
|
||||
saveLog: 'Сохранить лог',
|
||||
remoteURLHelper: 'Удаленный URL должен содержать один IP на строку и не содержать других символов',
|
||||
|
||||
@@ -4897,6 +4897,7 @@ const message = {
|
||||
openRestyFeatureVersionAlert:
|
||||
'{0} özelliğinin çalışması için OpenResty sürümü 1.31.1.1-0 sürümünden daha yeni olmalıdır.',
|
||||
ipLocation: 'IP Konumu',
|
||||
ipLocationSearchHelper: 'IP konumunu girin; bulanık arama desteklenir',
|
||||
action: 'Eylem',
|
||||
ruleType: 'Saldırı Türü',
|
||||
ipHelper: 'IP adresini girin',
|
||||
@@ -5103,6 +5104,9 @@ const message = {
|
||||
observationModeConfirm:
|
||||
'Gözlem modunda tüm WAF eşleşmeleri istekler engellenmeden kaydedilir. Devam edilsin mi?',
|
||||
globalStrictRequired: 'Önce genel ayarlarda katı modu etkinleştirin',
|
||||
websiteSearchHelper: 'Web sitesi alan adı, takma adı veya açıklaması girin',
|
||||
configReadFailed: 'Yapılandırma yüklenemedi',
|
||||
detailSetting: 'Ayrıntılı ayarlar',
|
||||
observe: 'Gözlem',
|
||||
saveLog: 'Günlüğü Kaydet',
|
||||
remoteURLHelper: 'Uzak URL, her satırda bir IP içermeli ve başka karakter olmamalıdır',
|
||||
|
||||
@@ -4498,6 +4498,7 @@ const message = {
|
||||
provinceRuleLabel: '省份',
|
||||
openRestyFeatureVersionAlert: 'OpenResty 版本需高於 1.31.1.1-0,{0}才會生效。',
|
||||
ipLocation: 'IP 歸屬地',
|
||||
ipLocationSearchHelper: '請輸入 IP 歸屬地,支援模糊搜尋',
|
||||
action: '動作',
|
||||
ruleType: '攻擊類型',
|
||||
ipHelper: '請輸入 IP',
|
||||
@@ -4691,6 +4692,9 @@ const message = {
|
||||
observationModeHelper: '僅檢測並記錄日誌,不會攔截請求',
|
||||
observationModeConfirm: '開啟觀察模式後,所有 WAF 命中都只記錄日誌,不會攔截請求,是否繼續?',
|
||||
globalStrictRequired: '需要先在全域設定中開啟嚴格模式',
|
||||
websiteSearchHelper: '請輸入網站網域、別名或備註',
|
||||
configReadFailed: '設定讀取失敗',
|
||||
detailSetting: '詳細設定',
|
||||
observe: '觀察',
|
||||
saveLog: '儲存日誌',
|
||||
remoteURLHelper: '遠端 URL 需要保證每行一個 IP 並且沒有其他字元',
|
||||
|
||||
@@ -3956,6 +3956,7 @@ const message = {
|
||||
provinceRuleLabel: '省份',
|
||||
openRestyFeatureVersionAlert: 'OpenResty 版本需高于 1.31.1.1-0,{0}才会生效。',
|
||||
ipLocation: 'IP 归属地',
|
||||
ipLocationSearchHelper: '请输入 IP 归属地,支持模糊搜索',
|
||||
action: '动作',
|
||||
ruleType: '攻击类型',
|
||||
ipHelper: '请输入 IP',
|
||||
@@ -4149,6 +4150,9 @@ const message = {
|
||||
observationModeHelper: '仅检测并记录日志,不会拦截请求',
|
||||
observationModeConfirm: '开启观察模式后,所有 WAF 命中都只记录日志,不会拦截请求,是否继续?',
|
||||
globalStrictRequired: '需要先在全局设置中开启严格模式',
|
||||
websiteSearchHelper: '请输入网站域名、别名或备注',
|
||||
configReadFailed: '配置读取失败',
|
||||
detailSetting: '详细设置',
|
||||
observe: '观察',
|
||||
saveLog: '保存日志',
|
||||
remoteURLHelper: '远程 URL 需要保证每行一个 IP 并且没有其他字符',
|
||||
|
||||
@@ -5,6 +5,7 @@ import { GlobalState } from '../interface';
|
||||
import { DeviceType } from '@/enums/app';
|
||||
import i18n, { setActiveLocale } from '@/lang';
|
||||
import { isMasterOnlyPermissionCode, setMasterOnlyPermissionCodes, toManageCode } from '@/utils/permission-codes';
|
||||
import { clearPageStateCache } from '@/utils/page-state-cache';
|
||||
|
||||
const CN_DOCS_URL = 'https://1panel.cn/docs/v2';
|
||||
const INTL_DOCS_URL = 'https://docs.1panel.pro/v2';
|
||||
@@ -121,6 +122,7 @@ const GlobalStore = defineStore('GlobalState', {
|
||||
setMasterOnlyPermissionCodes(this.masterOnlyPermissions);
|
||||
},
|
||||
clearAuthInfo() {
|
||||
clearPageStateCache();
|
||||
this.permissions = [];
|
||||
this.masterOnlyPermissions = [];
|
||||
this.nodeRoles = [];
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
const pageStateCache = new Map<string, object>();
|
||||
|
||||
export const getPageState = <T extends object>(key: string, factory: () => T): T => {
|
||||
const cached = pageStateCache.get(key) as T | undefined;
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
const state = factory();
|
||||
pageStateCache.set(key, state);
|
||||
return state;
|
||||
};
|
||||
|
||||
export const clearPageStateCache = () => {
|
||||
pageStateCache.clear();
|
||||
};
|
||||
@@ -61,6 +61,11 @@
|
||||
<template #main>
|
||||
<ComplexTable
|
||||
:pagination-config="paginationConfig"
|
||||
:default-sort="
|
||||
paginationConfig.order !== 'null'
|
||||
? { prop: paginationConfig.orderBy, order: paginationConfig.order }
|
||||
: undefined
|
||||
"
|
||||
v-model:view-mode="viewMode"
|
||||
v-model:selects="selects"
|
||||
@sort-change="search"
|
||||
@@ -268,7 +273,7 @@
|
||||
import Records from '@/views/cronjob/cronjob/record/index.vue';
|
||||
import Backups from '@/views/cronjob/cronjob/backup/index.vue';
|
||||
import Import from '@/views/cronjob/cronjob/import/index.vue';
|
||||
import { onMounted, reactive, ref } from 'vue';
|
||||
import { onMounted, ref, toRefs } from 'vue';
|
||||
import {
|
||||
deleteCronjob,
|
||||
editCronjobGroup,
|
||||
@@ -288,6 +293,7 @@ import { getGroupList } from '@/api/modules/group';
|
||||
import { routerToNameWithQuery } from '@/utils/router';
|
||||
import { useGlobalStore } from '@/composables/useGlobalStore';
|
||||
import { useOperateNodeContext } from '@/composables/useOperateNodeContext';
|
||||
import { usePageState } from '@/composables/usePageState';
|
||||
|
||||
const { currentNode, isMobile } = useGlobalStore();
|
||||
useOperateNodeContext(currentNode);
|
||||
@@ -306,24 +312,29 @@ const opExportRef = ref();
|
||||
const dialogImportRef = ref();
|
||||
|
||||
const data = ref();
|
||||
const paginationConfig = reactive({
|
||||
cacheSizeKey: 'cronjob-page-size',
|
||||
currentPage: 1,
|
||||
pageSize: Number(localStorage.getItem('cronjob-page-size')) || 20,
|
||||
total: 0,
|
||||
orderBy: 'createdAt',
|
||||
order: 'null',
|
||||
});
|
||||
const searchName = ref();
|
||||
|
||||
const defaultGroupID = ref<number>();
|
||||
const searchGroupID = ref<number>();
|
||||
const groupOptions = ref();
|
||||
const dialogGroupRef = ref();
|
||||
const pageState = usePageState(() => ({
|
||||
paginationConfig: {
|
||||
cacheSizeKey: 'cronjob-page-size',
|
||||
currentPage: 1,
|
||||
pageSize: Number(localStorage.getItem('cronjob-page-size')) || 20,
|
||||
total: 0,
|
||||
orderBy: 'createdAt',
|
||||
order: 'null',
|
||||
},
|
||||
defaultGroupID: undefined as number | undefined,
|
||||
searchName: undefined as string | undefined,
|
||||
searchGroupID: undefined as number | undefined,
|
||||
}));
|
||||
const paginationConfig = pageState.paginationConfig;
|
||||
const { defaultGroupID, searchName, searchGroupID } = toRefs(pageState);
|
||||
|
||||
const search = async (column?: any) => {
|
||||
paginationConfig.orderBy = column?.order ? column.prop : paginationConfig.orderBy;
|
||||
paginationConfig.order = column?.order ? column.order : paginationConfig.order;
|
||||
if (column) {
|
||||
paginationConfig.orderBy = column.order ? column.prop : 'createdAt';
|
||||
paginationConfig.order = column.order || 'null';
|
||||
}
|
||||
let groupIDs;
|
||||
if (searchGroupID.value) {
|
||||
groupIDs = searchGroupID.value === defaultGroupID.value ? [searchGroupID.value, 0] : [searchGroupID.value];
|
||||
@@ -454,6 +465,11 @@ const onSubmitExport = async () => {
|
||||
const loadGroups = async () => {
|
||||
const res = await getGroupList('cronjob');
|
||||
groupOptions.value = res.data || [];
|
||||
const invalidGroup = searchGroupID.value && !groupOptions.value.some((group) => group.id === searchGroupID.value);
|
||||
if (invalidGroup) {
|
||||
searchGroupID.value = undefined;
|
||||
paginationConfig.currentPage = 1;
|
||||
}
|
||||
for (const group of groupOptions.value) {
|
||||
if (group.name === 'Default') {
|
||||
defaultGroupID.value = group.id;
|
||||
@@ -478,6 +494,9 @@ const loadGroups = async () => {
|
||||
item.groupBelong = '-';
|
||||
}
|
||||
}
|
||||
if (invalidGroup) {
|
||||
search();
|
||||
}
|
||||
};
|
||||
|
||||
const updateGroup = async (row: any) => {
|
||||
|
||||
@@ -67,6 +67,7 @@
|
||||
<template v-if="!openNginxConfig" #main>
|
||||
<ComplexTable
|
||||
:pagination-config="paginationConfig"
|
||||
:default-sort="tableSort.order ? tableSort : undefined"
|
||||
v-model:view-mode="viewMode"
|
||||
:data="data"
|
||||
@sort-change="changeSort"
|
||||
@@ -371,6 +372,7 @@ import { getWebsiteTypes } from '@/global/mimetype';
|
||||
import { routerToFileWithPath, routerToNameWithParams, routerToNameWithQuery } from '@/utils/router';
|
||||
import { useGlobalStore } from '@/composables/useGlobalStore';
|
||||
import { useOperateNodeContext } from '@/composables/useOperateNodeContext';
|
||||
import { usePageState } from '@/composables/usePageState';
|
||||
|
||||
const { currentNode, isMobile } = useGlobalStore();
|
||||
useOperateNodeContext(currentNode);
|
||||
@@ -423,21 +425,30 @@ const batchSetHttpsRef = ref();
|
||||
const nginxVersion = ref();
|
||||
const appStatusRef = ref();
|
||||
|
||||
const paginationConfig = reactive({
|
||||
cacheSizeKey: 'website-page-size',
|
||||
currentPage: 1,
|
||||
pageSize: Number(localStorage.getItem('website-page-size')) || 20,
|
||||
total: 0,
|
||||
});
|
||||
let req = reactive({
|
||||
name: '',
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
orderBy: 'favorite',
|
||||
order: 'descending',
|
||||
websiteGroupId: 0,
|
||||
type: '',
|
||||
});
|
||||
const pageState = usePageState(() => ({
|
||||
paginationConfig: {
|
||||
cacheSizeKey: 'website-page-size',
|
||||
currentPage: 1,
|
||||
pageSize: Number(localStorage.getItem('website-page-size')) || 20,
|
||||
total: 0,
|
||||
},
|
||||
req: {
|
||||
name: '',
|
||||
page: 1,
|
||||
pageSize: 10,
|
||||
orderBy: 'favorite',
|
||||
order: 'descending',
|
||||
websiteGroupId: 0,
|
||||
type: '',
|
||||
},
|
||||
tableSort: {
|
||||
prop: '',
|
||||
order: null as 'ascending' | 'descending' | null,
|
||||
},
|
||||
}));
|
||||
const paginationConfig = pageState.paginationConfig;
|
||||
const req = pageState.req;
|
||||
const tableSort = pageState.tableSort;
|
||||
|
||||
const goRouter = async (key: string) => {
|
||||
routerToNameWithQuery('AppAll', { install: key });
|
||||
@@ -466,6 +477,8 @@ const disabledConfig = computed(() => {
|
||||
});
|
||||
|
||||
const changeSort = ({ prop, order }) => {
|
||||
tableSort.prop = prop || '';
|
||||
tableSort.order = order || null;
|
||||
if (order) {
|
||||
switch (prop) {
|
||||
case 'primaryDomain':
|
||||
@@ -502,9 +515,16 @@ const search = async () => {
|
||||
});
|
||||
};
|
||||
|
||||
const listGroup = async () => {
|
||||
const listGroup = async (searchOnReset = true) => {
|
||||
const res = await getAgentGroupList('website');
|
||||
groups.value = res.data;
|
||||
if (req.websiteGroupId !== 0 && !groups.value.some((group) => group.id === req.websiteGroupId)) {
|
||||
req.websiteGroupId = 0;
|
||||
paginationConfig.currentPage = 1;
|
||||
if (searchOnReset) {
|
||||
search();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const setting = () => {
|
||||
@@ -728,9 +748,13 @@ const batchOp = () => {
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
onMounted(async () => {
|
||||
try {
|
||||
await listGroup(false);
|
||||
} catch {
|
||||
// The request interceptor already reports the error; website loading should continue.
|
||||
}
|
||||
search();
|
||||
listGroup();
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
import assert from 'node:assert/strict';
|
||||
import test from 'node:test';
|
||||
import { clearPageStateCache, getPageState } from '../src/utils/page-state-cache.ts';
|
||||
|
||||
test('reuses state for the same page key', () => {
|
||||
clearPageStateCache();
|
||||
const first = getPageState('local:Website', () => ({ name: '' }));
|
||||
first.name = 'example.com';
|
||||
|
||||
const second = getPageState('local:Website', () => ({ name: 'ignored' }));
|
||||
|
||||
assert.equal(second.name, 'example.com');
|
||||
assert.equal(second, first);
|
||||
});
|
||||
|
||||
test('isolates state by page key', () => {
|
||||
clearPageStateCache();
|
||||
const local = getPageState('local:Website', () => ({ name: 'local' }));
|
||||
const remote = getPageState('remote:Website', () => ({ name: 'remote' }));
|
||||
|
||||
assert.notEqual(remote, local);
|
||||
assert.equal(remote.name, 'remote');
|
||||
});
|
||||
|
||||
test('creates fresh state after clearing the cache', () => {
|
||||
const first = getPageState('local:Website', () => ({ page: 2 }));
|
||||
clearPageStateCache();
|
||||
|
||||
const second = getPageState('local:Website', () => ({ page: 1 }));
|
||||
|
||||
assert.notEqual(second, first);
|
||||
assert.equal(second.page, 1);
|
||||
});
|
||||
Reference in New Issue
Block a user