fix(pve): 修复编译错误,确保前后端可编译通过

- services/pve.go: 导入 db 包,DB -> db.DB
- handlers/pve.go: 重写为 Gin 风格(原为标准库 net/http)
- go.mod/go.sum: go mod tidy 更新依赖
- web/dist: 重新构建前端包含 PVEHosts 页面

[金渐层/K2.6-code-preview🐾]
This commit is contained in:
openclaw
2026-04-20 13:16:01 +08:00
parent 8ef3e8c631
commit 8b80c2dd1a
33 changed files with 639 additions and 1155 deletions

3
.gitignore vendored
View File

@@ -14,3 +14,6 @@ docs/SOP.md
# System files # System files
.DS_Store .DS_Store
# Dependencies
web/node_modules/

15
go.mod
View File

@@ -1,6 +1,14 @@
module lan-manager module lan-manager
go 1.21 go 1.25.0
require (
github.com/gin-contrib/sessions v1.1.0
github.com/gin-gonic/gin v1.12.0
golang.org/x/crypto v0.50.0
golang.org/x/net v0.53.0
modernc.org/sqlite v1.48.2
)
require ( require (
github.com/bytedance/gopkg v0.1.3 // indirect github.com/bytedance/gopkg v0.1.3 // indirect
@@ -9,9 +17,7 @@ require (
github.com/cloudwego/base64x v0.1.6 // indirect github.com/cloudwego/base64x v0.1.6 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect github.com/dustin/go-humanize v1.0.1 // indirect
github.com/gabriel-vasile/mimetype v1.4.12 // indirect github.com/gabriel-vasile/mimetype v1.4.12 // indirect
github.com/gin-contrib/sessions v1.1.0 // indirect
github.com/gin-contrib/sse v1.1.0 // indirect github.com/gin-contrib/sse v1.1.0 // indirect
github.com/gin-gonic/gin v1.12.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.30.1 // indirect github.com/go-playground/validator/v10 v10.30.1 // indirect
@@ -36,13 +42,10 @@ require (
github.com/ugorji/go/codec v1.3.1 // indirect github.com/ugorji/go/codec v1.3.1 // indirect
go.mongodb.org/mongo-driver/v2 v2.5.0 // indirect go.mongodb.org/mongo-driver/v2 v2.5.0 // indirect
golang.org/x/arch v0.22.0 // indirect golang.org/x/arch v0.22.0 // indirect
golang.org/x/crypto v0.50.0 // indirect
golang.org/x/net v0.53.0 // indirect
golang.org/x/sys v0.43.0 // indirect golang.org/x/sys v0.43.0 // indirect
golang.org/x/text v0.36.0 // indirect golang.org/x/text v0.36.0 // indirect
google.golang.org/protobuf v1.36.10 // indirect google.golang.org/protobuf v1.36.10 // indirect
modernc.org/libc v1.70.0 // indirect modernc.org/libc v1.70.0 // indirect
modernc.org/mathutil v1.7.1 // indirect modernc.org/mathutil v1.7.1 // indirect
modernc.org/memory v1.11.0 // indirect modernc.org/memory v1.11.0 // indirect
modernc.org/sqlite v1.48.2 // indirect
) )

46
go.sum
View File

@@ -7,6 +7,7 @@ github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCc
github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M= github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=
github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU= github.com/cloudwego/base64x v0.1.6/go.mod h1:OFcloc187FXDaYHvrNIjxSe8ncn0OOM8gEHfghB2IPU=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
@@ -18,6 +19,8 @@ github.com/gin-contrib/sse v1.1.0 h1:n0w2GMuUpWDVp7qSpvze6fAu9iRxJY4Hmj6AmBOU05w
github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM= github.com/gin-contrib/sse v1.1.0/go.mod h1:hxRZ5gVpWMT7Z0B0gSNYqqsSCNIJMjzvm6fqCz9vjwM=
github.com/gin-gonic/gin v1.12.0 h1:b3YAbrZtnf8N//yjKeU2+MQsh2mY5htkZidOM7O0wG8= github.com/gin-gonic/gin v1.12.0 h1:b3YAbrZtnf8N//yjKeU2+MQsh2mY5htkZidOM7O0wG8=
github.com/gin-gonic/gin v1.12.0/go.mod h1:VxccKfsSllpKshkBWgVgRniFFAzFb9csfngsqANjnLc= github.com/gin-gonic/gin v1.12.0/go.mod h1:VxccKfsSllpKshkBWgVgRniFFAzFb9csfngsqANjnLc=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
@@ -28,7 +31,13 @@ github.com/goccy/go-json v0.10.5 h1:Fq85nIqj+gXn/S5ahsiTlK3TmC85qgirsdTP/+DeaC4=
github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= github.com/goccy/go-json v0.10.5/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM= github.com/goccy/go-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/goccy/go-yaml v1.19.2/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e h1:ijClszYn+mADRFY17kjQEVQ1XRhq2/JR1M3sGqeJoxs=
github.com/google/pprof v0.0.0-20250317173921-a4b03ec1a45e/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/context v1.1.2 h1:WRkNAv2uoa03QNIc1A6u4O7DAGMUVoopZhkiXWA2V1o= github.com/gorilla/context v1.1.2 h1:WRkNAv2uoa03QNIc1A6u4O7DAGMUVoopZhkiXWA2V1o=
@@ -37,6 +46,8 @@ github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kX
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
github.com/gorilla/sessions v1.4.0 h1:kpIYOp/oi6MG/p5PgxApU8srsSw9tuFbt46Lt7auzqQ= github.com/gorilla/sessions v1.4.0 h1:kpIYOp/oi6MG/p5PgxApU8srsSw9tuFbt46Lt7auzqQ=
github.com/gorilla/sessions v1.4.0/go.mod h1:FLWm50oby91+hl7p/wRxDth9bWSuk0qVL2emc7lT5ik= github.com/gorilla/sessions v1.4.0/go.mod h1:FLWm50oby91+hl7p/wRxDth9bWSuk0qVL2emc7lT5ik=
github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k=
github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
@@ -54,6 +65,7 @@ github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOF
github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= github.com/ncruces/go-strftime v1.0.0/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4= github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY= github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
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/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/quic-go/qpack v0.6.0 h1:g7W+BMYynC1LbYLSqRt8PBg5Tgwxn214ZZR34VIOjz8= 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/qpack v0.6.0/go.mod h1:lUpLKChi8njB4ty2bFLX2x4gzDqXwUpaO1DP9qMDZII=
@@ -70,34 +82,66 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY= github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY=
github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4= github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
go.mongodb.org/mongo-driver v1.17.3 h1:TQyXhnsWfWtgAhMtOgtYHMTkZIfBTpMTsMnd9ZBeHxQ=
go.mongodb.org/mongo-driver/v2 v2.5.0 h1:yXUhImUjjAInNcpTcAlPHiT7bIXhshCTL3jVBkF3xaE= go.mongodb.org/mongo-driver/v2 v2.5.0 h1:yXUhImUjjAInNcpTcAlPHiT7bIXhshCTL3jVBkF3xaE=
go.mongodb.org/mongo-driver/v2 v2.5.0/go.mod h1:yOI9kBsufol30iFsl1slpdq1I0eHPzybRWdyYUs8K/0= go.mongodb.org/mongo-driver/v2 v2.5.0/go.mod h1:yOI9kBsufol30iFsl1slpdq1I0eHPzybRWdyYUs8K/0=
go.uber.org/mock v0.6.0 h1:hyF9dfmbgIX5EfOdasqLsWD6xqpNZlXblLB/Dbnwv3Y=
go.uber.org/mock v0.6.0/go.mod h1:KiVJ4BqZJaMj4svdfmHM0AUx4NJYO8ZNpPnZn1Z+BBU=
golang.org/x/arch v0.22.0 h1:c/Zle32i5ttqRXjdLyyHZESLD/bB90DCU1g9l/0YBDI= golang.org/x/arch v0.22.0 h1:c/Zle32i5ttqRXjdLyyHZESLD/bB90DCU1g9l/0YBDI=
golang.org/x/arch v0.22.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A= golang.org/x/arch v0.22.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A=
golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI= golang.org/x/crypto v0.50.0 h1:zO47/JPrL6vsNkINmLoo/PH1gcxpls50DNogFvB5ZGI=
golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q= golang.org/x/crypto v0.50.0/go.mod h1:3muZ7vA7PBCE6xgPX7nkzzjiUq87kRItoJQM1Yo8S+Q=
golang.org/x/mod v0.34.0 h1:xIHgNUUnW6sYkcM5Jleh05DvLOtwc6RitGHbDk4akRI=
golang.org/x/mod v0.34.0/go.mod h1:ykgH52iCZe79kzLLMhyCUzhMci+nQj+0XkbXpNYtVjY=
golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA= golang.org/x/net v0.53.0 h1:d+qAbo5L0orcWAr0a9JweQpjXF19LMXJE8Ey7hwOdUA=
golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs= golang.org/x/net v0.53.0/go.mod h1:JvMuJH7rrdiCfbeHoo3fCQU24Lf5JJwT9W3sJFulfgs=
golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI= golang.org/x/sys v0.43.0 h1:Rlag2XtaFTxp19wS8MXlJwTvoh8ArU6ezoyFsMyCTNI=
golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/sys v0.43.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/term v0.42.0 h1:UiKe+zDFmJobeJ5ggPwOshJIVt6/Ft0rcfrXZDLWAWY=
golang.org/x/term v0.42.0/go.mod h1:Dq/D+snpsbazcBG5+F9Q1n2rXV8Ma+71xEjTRufARgY=
golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg= golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164= golang.org/x/text v0.36.0/go.mod h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s=
golang.org/x/tools v0.43.0/go.mod h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0=
google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE= google.golang.org/protobuf v1.36.10 h1:AYd7cD/uASjIL6Q9LiTjz8JLcrh/88q5UObnmY3aOOE=
google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= google.golang.org/protobuf v1.36.10/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
modernc.org/cc/v4 v4.27.1 h1:9W30zRlYrefrDV2JE2O8VDtJ1yPGownxciz5rrbQZis=
modernc.org/cc/v4 v4.27.1/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
modernc.org/ccgo/v4 v4.32.0 h1:hjG66bI/kqIPX1b2yT6fr/jt+QedtP2fqojG2VrFuVw=
modernc.org/ccgo/v4 v4.32.0/go.mod h1:6F08EBCx5uQc38kMGl+0Nm0oWczoo1c7cgpzEry7Uc0=
modernc.org/fileutil v1.4.0 h1:j6ZzNTftVS054gi281TyLjHPp6CPHr2KCxEXjEbD6SM=
modernc.org/fileutil v1.4.0/go.mod h1:EqdKFDxiByqxLk8ozOxObDSfcVOv/54xDs/DUHdvCUU=
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
modernc.org/gc/v3 v3.1.2 h1:ZtDCnhonXSZexk/AYsegNRV1lJGgaNZJuKjJSWKyEqo=
modernc.org/gc/v3 v3.1.2/go.mod h1:HFK/6AGESC7Ex+EZJhJ2Gni6cTaYpSMmU/cT9RmlfYY=
modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks=
modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
modernc.org/libc v1.70.0 h1:U58NawXqXbgpZ/dcdS9kMshu08aiA6b7gusEusqzNkw= modernc.org/libc v1.70.0 h1:U58NawXqXbgpZ/dcdS9kMshu08aiA6b7gusEusqzNkw=
modernc.org/libc v1.70.0/go.mod h1:OVmxFGP1CI/Z4L3E0Q3Mf1PDE0BucwMkcXjjLntvHJo= modernc.org/libc v1.70.0/go.mod h1:OVmxFGP1CI/Z4L3E0Q3Mf1PDE0BucwMkcXjjLntvHJo=
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU= modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg= modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI= modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=
modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw= modernc.org/memory v1.11.0/go.mod h1:/JP4VbVC+K5sU2wZi9bHoq2MAkCnrt2r98UGeSK7Mjw=
modernc.org/opt v0.1.4 h1:2kNGMRiUjrp4LcaPuLY2PzUfqM/w9N23quVwhKt5Qm8=
modernc.org/opt v0.1.4/go.mod h1:03fq9lsNfvkYSfxrfUhZCWPk1lm4cq4N+Bh//bEtgns=
modernc.org/sortutil v1.2.1 h1:+xyoGf15mM3NMlPDnFqrteY07klSFxLElE2PVuWIJ7w=
modernc.org/sortutil v1.2.1/go.mod h1:7ZI3a3REbai7gzCLcotuw9AC4VZVpYMjDzETGsSMqJE=
modernc.org/sqlite v1.48.2 h1:5CnW4uP8joZtA0LedVqLbZV5GD7F/0x91AXeSyjoh5c= modernc.org/sqlite v1.48.2 h1:5CnW4uP8joZtA0LedVqLbZV5GD7F/0x91AXeSyjoh5c=
modernc.org/sqlite v1.48.2/go.mod h1:hWjRO6Tj/5Ik8ieqxQybiEOUXy0NJFNp2tpvVpKlvig= modernc.org/sqlite v1.48.2/go.mod h1:hWjRO6Tj/5Ik8ieqxQybiEOUXy0NJFNp2tpvVpKlvig=
modernc.org/strutil v1.2.1 h1:UneZBkQA+DX2Rp35KcM69cSsNES9ly8mQWD71HKlOA0=
modernc.org/strutil v1.2.1/go.mod h1:EHkiggD70koQxjVdSBM3JKM7k6L0FbGE5eymy9i3B9A=
modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=
modernc.org/token v1.1.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=

View File

@@ -2,10 +2,10 @@ package handlers
import ( import (
"database/sql" "database/sql"
"encoding/json"
"net/http" "net/http"
"strconv" "strconv"
"github.com/gin-gonic/gin"
"lan-manager/server/db" "lan-manager/server/db"
"lan-manager/server/middleware" "lan-manager/server/middleware"
"lan-manager/server/models" "lan-manager/server/models"
@@ -23,15 +23,15 @@ func NewPVEHandler() *PVEHandler {
} }
// List 获取 PVE 主机列表 // List 获取 PVE 主机列表
func (h *PVEHandler) List(w http.ResponseWriter, r *http.Request) { func (h *PVEHandler) List(c *gin.Context) {
if !middleware.IsAdmin(r) { if !middleware.IsAdmin(c) {
http.Error(w, "admin only", http.StatusForbidden) c.JSON(http.StatusForbidden, gin.H{"error": "admin only"})
return return
} }
hosts, err := h.service.GetAll() hosts, err := h.service.GetAll()
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return return
} }
@@ -40,51 +40,51 @@ func (h *PVEHandler) List(w http.ResponseWriter, r *http.Request) {
hosts[i].PasswordEnc = "" hosts[i].PasswordEnc = ""
} }
middleware.JSON(w, hosts) c.JSON(http.StatusOK, hosts)
} }
// Get 获取单个 PVE 主机 // Get 获取单个 PVE 主机
func (h *PVEHandler) Get(w http.ResponseWriter, r *http.Request) { func (h *PVEHandler) Get(c *gin.Context) {
if !middleware.IsAdmin(r) { if !middleware.IsAdmin(c) {
http.Error(w, "admin only", http.StatusForbidden) c.JSON(http.StatusForbidden, gin.H{"error": "admin only"})
return return
} }
id, err := strconv.ParseInt(r.PathValue("id"), 10, 64) id, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil { if err != nil {
http.Error(w, "invalid id", http.StatusBadRequest) c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"})
return return
} }
host, err := h.service.GetByID(id) host, err := h.service.GetByID(id)
if err != nil { if err != nil {
if err == sql.ErrNoRows { if err == sql.ErrNoRows {
http.Error(w, "not found", http.StatusNotFound) c.JSON(http.StatusNotFound, gin.H{"error": "not found"})
return return
} }
http.Error(w, err.Error(), http.StatusInternalServerError) c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return return
} }
host.PasswordEnc = "" host.PasswordEnc = ""
middleware.JSON(w, host) c.JSON(http.StatusOK, host)
} }
// Create 创建 PVE 主机 // Create 创建 PVE 主机
func (h *PVEHandler) Create(w http.ResponseWriter, r *http.Request) { func (h *PVEHandler) Create(c *gin.Context) {
if !middleware.IsAdmin(r) { if !middleware.IsAdmin(c) {
http.Error(w, "admin only", http.StatusForbidden) c.JSON(http.StatusForbidden, gin.H{"error": "admin only"})
return return
} }
var host models.PVEHost var host models.PVEHost
if err := json.NewDecoder(r.Body).Decode(&host); err != nil { if err := c.ShouldBindJSON(&host); err != nil {
http.Error(w, "invalid request", http.StatusBadRequest) c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request"})
return return
} }
if host.Name == "" || host.Hostname == "" || host.Username == "" || host.Password == "" { if host.Name == "" || host.Hostname == "" || host.Username == "" || host.Password == "" {
http.Error(w, "missing required fields", http.StatusBadRequest) c.JSON(http.StatusBadRequest, gin.H{"error": "missing required fields"})
return return
} }
@@ -93,30 +93,30 @@ func (h *PVEHandler) Create(w http.ResponseWriter, r *http.Request) {
} }
if err := h.service.Create(&host); err != nil { if err := h.service.Create(&host); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return return
} }
host.PasswordEnc = "" host.PasswordEnc = ""
middleware.JSON(w, host) c.JSON(http.StatusCreated, host)
} }
// Update 更新 PVE 主机 // Update 更新 PVE 主机
func (h *PVEHandler) Update(w http.ResponseWriter, r *http.Request) { func (h *PVEHandler) Update(c *gin.Context) {
if !middleware.IsAdmin(r) { if !middleware.IsAdmin(c) {
http.Error(w, "admin only", http.StatusForbidden) c.JSON(http.StatusForbidden, gin.H{"error": "admin only"})
return return
} }
id, err := strconv.ParseInt(r.PathValue("id"), 10, 64) id, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil { if err != nil {
http.Error(w, "invalid id", http.StatusBadRequest) c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"})
return return
} }
var host models.PVEHost var host models.PVEHost
if err := json.NewDecoder(r.Body).Decode(&host); err != nil { if err := c.ShouldBindJSON(&host); err != nil {
http.Error(w, "invalid request", http.StatusBadRequest) c.JSON(http.StatusBadRequest, gin.H{"error": "invalid request"})
return return
} }
@@ -126,52 +126,52 @@ func (h *PVEHandler) Update(w http.ResponseWriter, r *http.Request) {
if host.Password == "" { if host.Password == "" {
existing, err := h.service.GetByID(id) existing, err := h.service.GetByID(id)
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return return
} }
host.PasswordEnc = existing.PasswordEnc host.PasswordEnc = existing.PasswordEnc
} }
if err := h.service.Update(&host); err != nil { if err := h.service.Update(&host); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return return
} }
host.PasswordEnc = "" host.PasswordEnc = ""
middleware.JSON(w, host) c.JSON(http.StatusOK, host)
} }
// Delete 删除 PVE 主机 // Delete 删除 PVE 主机
func (h *PVEHandler) Delete(w http.ResponseWriter, r *http.Request) { func (h *PVEHandler) Delete(c *gin.Context) {
if !middleware.IsAdmin(r) { if !middleware.IsAdmin(c) {
http.Error(w, "admin only", http.StatusForbidden) c.JSON(http.StatusForbidden, gin.H{"error": "admin only"})
return return
} }
id, err := strconv.ParseInt(r.PathValue("id"), 10, 64) id, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil { if err != nil {
http.Error(w, "invalid id", http.StatusBadRequest) c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"})
return return
} }
if err := h.service.Delete(id); err != nil { if err := h.service.Delete(id); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return return
} }
middleware.JSON(w, map[string]string{"message": "deleted"}) c.JSON(http.StatusOK, gin.H{"message": "deleted"})
} }
// VMStatus 获取虚拟机状态 // VMStatus 获取虚拟机状态
func (h *PVEHandler) VMStatus(w http.ResponseWriter, r *http.Request) { func (h *PVEHandler) VMStatus(c *gin.Context) {
if !middleware.IsAdmin(r) { if !middleware.IsAdmin(c) {
http.Error(w, "admin only", http.StatusForbidden) c.JSON(http.StatusForbidden, gin.H{"error": "admin only"})
return return
} }
machineID, err := strconv.ParseInt(r.PathValue("id"), 10, 64) machineID, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil { if err != nil {
http.Error(w, "invalid id", http.StatusBadRequest) c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"})
return return
} }
@@ -179,34 +179,34 @@ func (h *PVEHandler) VMStatus(w http.ResponseWriter, r *http.Request) {
var pveVMID sql.NullString var pveVMID sql.NullString
err = db.DB.QueryRow(`SELECT pve_host_id, pve_vmid FROM machines WHERE id = ?`, machineID).Scan(&pveHostID, &pveVMID) err = db.DB.QueryRow(`SELECT pve_host_id, pve_vmid FROM machines WHERE id = ?`, machineID).Scan(&pveHostID, &pveVMID)
if err != nil { if err != nil {
http.Error(w, "machine not found", http.StatusNotFound) c.JSON(http.StatusNotFound, gin.H{"error": "machine not found"})
return return
} }
if pveHostID == nil || !pveVMID.Valid || pveVMID.String == "" { if pveHostID == nil || !pveVMID.Valid || pveVMID.String == "" {
http.Error(w, "machine not linked to PVE VM", http.StatusBadRequest) c.JSON(http.StatusBadRequest, gin.H{"error": "machine not linked to PVE VM"})
return return
} }
status, err := h.service.GetVMStatus(*pveHostID, pveVMID.String) status, err := h.service.GetVMStatus(*pveHostID, pveVMID.String)
if err != nil { if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return return
} }
middleware.JSON(w, status) c.JSON(http.StatusOK, status)
} }
// VMStart 启动虚拟机 // VMStart 启动虚拟机
func (h *PVEHandler) VMStart(w http.ResponseWriter, r *http.Request) { func (h *PVEHandler) VMStart(c *gin.Context) {
if !middleware.IsAdmin(r) { if !middleware.IsAdmin(c) {
http.Error(w, "admin only", http.StatusForbidden) c.JSON(http.StatusForbidden, gin.H{"error": "admin only"})
return return
} }
machineID, err := strconv.ParseInt(r.PathValue("id"), 10, 64) machineID, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil { if err != nil {
http.Error(w, "invalid id", http.StatusBadRequest) c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"})
return return
} }
@@ -214,33 +214,33 @@ func (h *PVEHandler) VMStart(w http.ResponseWriter, r *http.Request) {
var pveVMID sql.NullString var pveVMID sql.NullString
err = db.DB.QueryRow(`SELECT pve_host_id, pve_vmid FROM machines WHERE id = ?`, machineID).Scan(&pveHostID, &pveVMID) err = db.DB.QueryRow(`SELECT pve_host_id, pve_vmid FROM machines WHERE id = ?`, machineID).Scan(&pveHostID, &pveVMID)
if err != nil { if err != nil {
http.Error(w, "machine not found", http.StatusNotFound) c.JSON(http.StatusNotFound, gin.H{"error": "machine not found"})
return return
} }
if pveHostID == nil || !pveVMID.Valid || pveVMID.String == "" { if pveHostID == nil || !pveVMID.Valid || pveVMID.String == "" {
http.Error(w, "machine not linked to PVE VM", http.StatusBadRequest) c.JSON(http.StatusBadRequest, gin.H{"error": "machine not linked to PVE VM"})
return return
} }
if err := h.service.StartVM(*pveHostID, pveVMID.String); err != nil { if err := h.service.StartVM(*pveHostID, pveVMID.String); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return return
} }
middleware.JSON(w, map[string]string{"message": "started"}) c.JSON(http.StatusOK, gin.H{"message": "started"})
} }
// VMStop 停止虚拟机 // VMStop 停止虚拟机
func (h *PVEHandler) VMStop(w http.ResponseWriter, r *http.Request) { func (h *PVEHandler) VMStop(c *gin.Context) {
if !middleware.IsAdmin(r) { if !middleware.IsAdmin(c) {
http.Error(w, "admin only", http.StatusForbidden) c.JSON(http.StatusForbidden, gin.H{"error": "admin only"})
return return
} }
machineID, err := strconv.ParseInt(r.PathValue("id"), 10, 64) machineID, err := strconv.ParseInt(c.Param("id"), 10, 64)
if err != nil { if err != nil {
http.Error(w, "invalid id", http.StatusBadRequest) c.JSON(http.StatusBadRequest, gin.H{"error": "invalid id"})
return return
} }
@@ -248,19 +248,19 @@ func (h *PVEHandler) VMStop(w http.ResponseWriter, r *http.Request) {
var pveVMID sql.NullString var pveVMID sql.NullString
err = db.DB.QueryRow(`SELECT pve_host_id, pve_vmid FROM machines WHERE id = ?`, machineID).Scan(&pveHostID, &pveVMID) err = db.DB.QueryRow(`SELECT pve_host_id, pve_vmid FROM machines WHERE id = ?`, machineID).Scan(&pveHostID, &pveVMID)
if err != nil { if err != nil {
http.Error(w, "machine not found", http.StatusNotFound) c.JSON(http.StatusNotFound, gin.H{"error": "machine not found"})
return return
} }
if pveHostID == nil || !pveVMID.Valid || pveVMID.String == "" { if pveHostID == nil || !pveVMID.Valid || pveVMID.String == "" {
http.Error(w, "machine not linked to PVE VM", http.StatusBadRequest) c.JSON(http.StatusBadRequest, gin.H{"error": "machine not linked to PVE VM"})
return return
} }
if err := h.service.StopVM(*pveHostID, pveVMID.String); err != nil { if err := h.service.StopVM(*pveHostID, pveVMID.String); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError) c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return return
} }
middleware.JSON(w, map[string]string{"message": "stopped"}) c.JSON(http.StatusOK, gin.H{"message": "stopped"})
} }

View File

@@ -10,6 +10,7 @@ import (
"strings" "strings"
"time" "time"
"lan-manager/server/db"
"lan-manager/server/models" "lan-manager/server/models"
"lan-manager/server/utils" "lan-manager/server/utils"
) )
@@ -282,7 +283,7 @@ func NewPVEHostService() *PVEHostService {
// GetAll 获取所有 PVE 主机 // GetAll 获取所有 PVE 主机
func (s *PVEHostService) GetAll() ([]models.PVEHost, error) { func (s *PVEHostService) GetAll() ([]models.PVEHost, error) {
rows, err := DB.Query(`SELECT id, name, hostname, port, username, password_enc, verify_ssl, created_at, updated_at FROM pve_hosts ORDER BY id`) rows, err := db.DB.Query(`SELECT id, name, hostname, port, username, password_enc, verify_ssl, created_at, updated_at FROM pve_hosts ORDER BY id`)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@@ -305,7 +306,7 @@ func (s *PVEHostService) GetAll() ([]models.PVEHost, error) {
func (s *PVEHostService) GetByID(id int64) (*models.PVEHost, error) { func (s *PVEHostService) GetByID(id int64) (*models.PVEHost, error) {
var h models.PVEHost var h models.PVEHost
var verifySSL int var verifySSL int
err := DB.QueryRow(`SELECT id, name, hostname, port, username, password_enc, verify_ssl, created_at, updated_at FROM pve_hosts WHERE id = ?`, id). err := db.DB.QueryRow(`SELECT id, name, hostname, port, username, password_enc, verify_ssl, created_at, updated_at FROM pve_hosts WHERE id = ?`, id).
Scan(&h.ID, &h.Name, &h.Hostname, &h.Port, &h.Username, &h.PasswordEnc, &verifySSL, &h.CreatedAt, &h.UpdatedAt) Scan(&h.ID, &h.Name, &h.Hostname, &h.Port, &h.Username, &h.PasswordEnc, &verifySSL, &h.CreatedAt, &h.UpdatedAt)
if err != nil { if err != nil {
return nil, err return nil, err
@@ -322,7 +323,7 @@ func (s *PVEHostService) Create(host *models.PVEHost) error {
return fmt.Errorf("encrypt password failed: %w", err) return fmt.Errorf("encrypt password failed: %w", err)
} }
result, err := DB.Exec(`INSERT INTO pve_hosts (name, hostname, port, username, password_enc, verify_ssl) VALUES (?, ?, ?, ?, ?, ?)`, result, err := db.DB.Exec(`INSERT INTO pve_hosts (name, hostname, port, username, password_enc, verify_ssl) VALUES (?, ?, ?, ?, ?, ?)`,
host.Name, host.Hostname, host.Port, host.Username, encPassword, boolToInt(host.VerifySSL)) host.Name, host.Hostname, host.Port, host.Username, encPassword, boolToInt(host.VerifySSL))
if err != nil { if err != nil {
return err return err
@@ -344,12 +345,12 @@ func (s *PVEHostService) Update(host *models.PVEHost) error {
if err != nil { if err != nil {
return fmt.Errorf("encrypt password failed: %w", err) return fmt.Errorf("encrypt password failed: %w", err)
} }
_, err = DB.Exec(`UPDATE pve_hosts SET name=?, hostname=?, port=?, username=?, password_enc=?, verify_ssl=?, updated_at=CURRENT_TIMESTAMP WHERE id=?`, _, err = db.DB.Exec(`UPDATE pve_hosts SET name=?, hostname=?, port=?, username=?, password_enc=?, verify_ssl=?, updated_at=CURRENT_TIMESTAMP WHERE id=?`,
host.Name, host.Hostname, host.Port, host.Username, encPassword, boolToInt(host.VerifySSL), host.ID) host.Name, host.Hostname, host.Port, host.Username, encPassword, boolToInt(host.VerifySSL), host.ID)
return err return err
} }
_, err := DB.Exec(`UPDATE pve_hosts SET name=?, hostname=?, port=?, username=?, verify_ssl=?, updated_at=CURRENT_TIMESTAMP WHERE id=?`, _, err := db.DB.Exec(`UPDATE pve_hosts SET name=?, hostname=?, port=?, username=?, verify_ssl=?, updated_at=CURRENT_TIMESTAMP WHERE id=?`,
host.Name, host.Hostname, host.Port, host.Username, boolToInt(host.VerifySSL), host.ID) host.Name, host.Hostname, host.Port, host.Username, boolToInt(host.VerifySSL), host.ID)
return err return err
} }
@@ -357,10 +358,10 @@ func (s *PVEHostService) Update(host *models.PVEHost) error {
// Delete 删除 PVE 主机 // Delete 删除 PVE 主机
func (s *PVEHostService) Delete(id int64) error { func (s *PVEHostService) Delete(id int64) error {
// 先清除关联机器的 PVE 字段 // 先清除关联机器的 PVE 字段
if _, err := DB.Exec(`UPDATE machines SET pve_host_id = NULL, pve_vmid = NULL WHERE pve_host_id = ?`, id); err != nil { if _, err := db.DB.Exec(`UPDATE machines SET pve_host_id = NULL, pve_vmid = NULL WHERE pve_host_id = ?`, id); err != nil {
return err return err
} }
_, err := DB.Exec(`DELETE FROM pve_hosts WHERE id = ?`, id) _, err := db.DB.Exec(`DELETE FROM pve_hosts WHERE id = ?`, id)
return err return err
} }

View File

@@ -1 +1 @@
import{o as b,c as x,a as o,b as s,w as l,r as g,d as u,u as k,e as v,f as N,g as w,l as z,h as y,E as d,i as C,s as V,j as M}from"./index-Chagxl0Z.js";import{_ as A}from"./_plugin-vue_export-helper-DlAUqK2U.js";const B={class:"login-page"},E={class:"login-card"},K={class:"input-wrap"},U={class:"input-wrap"},$={class:"login-guest"},j={__name:"Login",setup(I){const c=k(),a=g({username:"",password:""}),n=g(!1);async function r(){if(!a.value.username||!a.value.password){d.warning("请输入用户名和密码");return}n.value=!0;try{const t=await C(a.value);V(t.data),d.success("登录成功"),c.push("/")}catch{}n.value=!1}async function h(){n.value=!0;try{const t=await M();V(t.data),d.success("已进入访客模式"),c.push("/")}catch{}n.value=!1}return(t,e)=>{const p=u("el-icon"),_=u("el-input"),m=u("el-form-item"),f=u("el-button"),L=u("el-form");return b(),x("div",B,[o("div",E,[e[4]||(e[4]=o("div",{class:"login-header"},[o("div",{class:"logo"},"LM"),o("h1",null,"LAN Manager"),o("p",null,"轻量级局域网资产管理平台")],-1)),s(L,{model:a.value,class:"login-form"},{default:l(()=>[s(m,null,{default:l(()=>[o("div",K,[s(p,{class:"input-icon"},{default:l(()=>[s(v(N))]),_:1}),s(_,{modelValue:a.value.username,"onUpdate:modelValue":e[0]||(e[0]=i=>a.value.username=i),placeholder:"用户名",size:"large",onKeydown:w(r,["enter"])},null,8,["modelValue"])])]),_:1}),s(m,null,{default:l(()=>[o("div",U,[s(p,{class:"input-icon"},{default:l(()=>[s(v(z))]),_:1}),s(_,{modelValue:a.value.password,"onUpdate:modelValue":e[1]||(e[1]=i=>a.value.password=i),type:"password","show-password":"",placeholder:"密码",size:"large",onKeydown:w(r,["enter"])},null,8,["modelValue"])])]),_:1}),s(f,{type:"primary",size:"large",class:"login-btn",loading:n.value,onClick:r},{default:l(()=>[...e[2]||(e[2]=[y("登录",-1)])]),_:1},8,["loading"]),o("div",$,[s(f,{text:"",size:"small",onClick:h},{default:l(()=>[...e[3]||(e[3]=[y("访客模式进入",-1)])]),_:1})])]),_:1},8,["model"])]),e[5]||(e[5]=o("div",{class:"login-footer"}," © LAN Manager ",-1))])}}},q=A(j,[["__scopeId","data-v-92ccba4b"]]);export{q as default}; import{o as b,c as x,a as o,b as s,w as l,r as g,d as u,u as k,e as v,f as N,g as w,l as z,h as y,E as d,i as C,s as V,j as M}from"./index-BFjouPFU.js";import{_ as A}from"./_plugin-vue_export-helper-DlAUqK2U.js";const B={class:"login-page"},E={class:"login-card"},K={class:"input-wrap"},U={class:"input-wrap"},$={class:"login-guest"},j={__name:"Login",setup(I){const c=k(),a=g({username:"",password:""}),n=g(!1);async function r(){if(!a.value.username||!a.value.password){d.warning("请输入用户名和密码");return}n.value=!0;try{const t=await C(a.value);V(t.data),d.success("登录成功"),c.push("/")}catch{}n.value=!1}async function h(){n.value=!0;try{const t=await M();V(t.data),d.success("已进入访客模式"),c.push("/")}catch{}n.value=!1}return(t,e)=>{const p=u("el-icon"),_=u("el-input"),m=u("el-form-item"),f=u("el-button"),L=u("el-form");return b(),x("div",B,[o("div",E,[e[4]||(e[4]=o("div",{class:"login-header"},[o("div",{class:"logo"},"LM"),o("h1",null,"LAN Manager"),o("p",null,"轻量级局域网资产管理平台")],-1)),s(L,{model:a.value,class:"login-form"},{default:l(()=>[s(m,null,{default:l(()=>[o("div",K,[s(p,{class:"input-icon"},{default:l(()=>[s(v(N))]),_:1}),s(_,{modelValue:a.value.username,"onUpdate:modelValue":e[0]||(e[0]=i=>a.value.username=i),placeholder:"用户名",size:"large",onKeydown:w(r,["enter"])},null,8,["modelValue"])])]),_:1}),s(m,null,{default:l(()=>[o("div",U,[s(p,{class:"input-icon"},{default:l(()=>[s(v(z))]),_:1}),s(_,{modelValue:a.value.password,"onUpdate:modelValue":e[1]||(e[1]=i=>a.value.password=i),type:"password","show-password":"",placeholder:"密码",size:"large",onKeydown:w(r,["enter"])},null,8,["modelValue"])])]),_:1}),s(f,{type:"primary",size:"large",class:"login-btn",loading:n.value,onClick:r},{default:l(()=>[...e[2]||(e[2]=[y("登录",-1)])]),_:1},8,["loading"]),o("div",$,[s(f,{text:"",size:"small",onClick:h},{default:l(()=>[...e[3]||(e[3]=[y("访客模式进入",-1)])]),_:1})])]),_:1},8,["model"])]),e[5]||(e[5]=o("div",{class:"login-footer"}," © LAN Manager ",-1))])}}},q=A(j,[["__scopeId","data-v-92ccba4b"]]);export{q as default};

View File

@@ -1 +0,0 @@
import{o as b,c as x,a as o,b as s,w as l,r as g,d as u,u as k,e as v,f as N,g as w,l as z,h as y,E as d,i as C,s as V,j as M}from"./index-C_uWT3cF.js";import{_ as A}from"./_plugin-vue_export-helper-DlAUqK2U.js";const B={class:"login-page"},E={class:"login-card"},K={class:"input-wrap"},U={class:"input-wrap"},$={class:"login-guest"},j={__name:"Login",setup(I){const c=k(),a=g({username:"",password:""}),n=g(!1);async function r(){if(!a.value.username||!a.value.password){d.warning("请输入用户名和密码");return}n.value=!0;try{const t=await C(a.value);V(t.data),d.success("登录成功"),c.push("/")}catch{}n.value=!1}async function h(){n.value=!0;try{const t=await M();V(t.data),d.success("已进入访客模式"),c.push("/")}catch{}n.value=!1}return(t,e)=>{const p=u("el-icon"),_=u("el-input"),m=u("el-form-item"),f=u("el-button"),L=u("el-form");return b(),x("div",B,[o("div",E,[e[4]||(e[4]=o("div",{class:"login-header"},[o("div",{class:"logo"},"LM"),o("h1",null,"LAN Manager"),o("p",null,"轻量级局域网资产管理平台")],-1)),s(L,{model:a.value,class:"login-form"},{default:l(()=>[s(m,null,{default:l(()=>[o("div",K,[s(p,{class:"input-icon"},{default:l(()=>[s(v(N))]),_:1}),s(_,{modelValue:a.value.username,"onUpdate:modelValue":e[0]||(e[0]=i=>a.value.username=i),placeholder:"用户名",size:"large",onKeydown:w(r,["enter"])},null,8,["modelValue"])])]),_:1}),s(m,null,{default:l(()=>[o("div",U,[s(p,{class:"input-icon"},{default:l(()=>[s(v(z))]),_:1}),s(_,{modelValue:a.value.password,"onUpdate:modelValue":e[1]||(e[1]=i=>a.value.password=i),type:"password","show-password":"",placeholder:"密码",size:"large",onKeydown:w(r,["enter"])},null,8,["modelValue"])])]),_:1}),s(f,{type:"primary",size:"large",class:"login-btn",loading:n.value,onClick:r},{default:l(()=>[...e[2]||(e[2]=[y("登录",-1)])]),_:1},8,["loading"]),o("div",$,[s(f,{text:"",size:"small",onClick:h},{default:l(()=>[...e[3]||(e[3]=[y("访客模式进入",-1)])]),_:1})])]),_:1},8,["model"])]),e[5]||(e[5]=o("div",{class:"login-footer"}," © LAN Manager ",-1))])}}},q=A(j,[["__scopeId","data-v-92ccba4b"]]);export{q as default};

View File

@@ -1 +0,0 @@
import{k as S,ak as V,o as w,c as $,a as o,b as t,w as d,t as f,al as N,m as B,r as i,d as r,am as C,h as b}from"./index-C_uWT3cF.js";import{_ as L}from"./_plugin-vue_export-helper-DlAUqK2U.js";const M={class:"page"},T={class:"page-header"},U={class:"header-actions"},I={class:"card"},E={class:"table-header"},F={class:"pagination-bar"},H={__name:"Logs",setup(P){const h=i([]),p=i(0),c=i(1),u=i(20),_=i(""),g=i(!1);S(()=>v());async function v(){g.value=!0;const l=await V({page:c.value,page_size:u.value,search:_.value});h.value=l.data.list,p.value=l.data.total,g.value=!1}function y(l){if(!l)return"-";const e=new Date(l);if(isNaN(e.getTime()))return l;const s=m=>String(m).padStart(2,"0");return`${e.getFullYear()}-${s(e.getMonth()+1)}-${s(e.getDate())} ${s(e.getHours())}:${s(e.getMinutes())}:${s(e.getSeconds())}`}return(l,e)=>{const s=r("el-input"),m=r("el-button"),n=r("el-table-column"),z=r("el-tag"),x=r("el-table"),k=r("el-pagination"),D=C("loading");return w(),$("div",M,[o("div",T,[e[4]||(e[4]=o("div",null,[o("div",{class:"page-title"},"操作日志"),o("div",{class:"page-subtitle"},"查看最近的系统操作记录")],-1)),o("div",U,[t(s,{modelValue:_.value,"onUpdate:modelValue":e[0]||(e[0]=a=>_.value=a),placeholder:"搜索操作内容",clearable:"",style:{width:"240px"}},null,8,["modelValue"]),t(m,{type:"primary",onClick:v},{default:d(()=>[...e[3]||(e[3]=[b("查询",-1)])]),_:1})])]),o("div",I,[o("div",E,"共 "+f(p.value)+" 条记录",1),N((w(),B(x,{data:h.value,stripe:"",style:{width:"100%"},class:"modern-table"},{default:d(()=>[t(n,{prop:"id",label:"ID",width:"70"}),t(n,{prop:"action",label:"操作",width:"140"}),t(n,{prop:"target_type",label:"对象",width:"100"},{default:d(({row:a})=>[t(z,{size:"small",effect:"plain",round:""},{default:d(()=>[b(f(a.target_type),1)]),_:2},1024)]),_:1}),t(n,{prop:"target_name",label:"对象名称","min-width":"160"}),t(n,{prop:"details",label:"详情","min-width":"240","show-overflow-tooltip":""}),t(n,{prop:"created_at",label:"时间",width:"170"},{default:d(({row:a})=>[b(f(y(a.created_at)),1)]),_:1})]),_:1},8,["data"])),[[D,g.value]]),o("div",F,[t(k,{"current-page":c.value,"onUpdate:currentPage":e[1]||(e[1]=a=>c.value=a),"page-size":u.value,"onUpdate:pageSize":e[2]||(e[2]=a=>u.value=a),"page-sizes":[10,20,50,100],layout:"total, sizes, prev, pager, next",total:p.value,onChange:v},null,8,["current-page","page-size","total"])])])])}}},q=L(H,[["__scopeId","data-v-b1b09e4f"]]);export{q as default};

View File

@@ -1 +1 @@
import{k as S,aj as V,o as w,c as $,a as o,b as t,w as d,t as f,ak as N,m as B,r as i,d as r,al as C,h as b}from"./index-Chagxl0Z.js";import{_ as L}from"./_plugin-vue_export-helper-DlAUqK2U.js";const M={class:"page"},T={class:"page-header"},U={class:"header-actions"},I={class:"card"},j={class:"table-header"},E={class:"pagination-bar"},F={__name:"Logs",setup(H){const h=i([]),p=i(0),c=i(1),u=i(20),_=i(""),g=i(!1);S(()=>v());async function v(){g.value=!0;const l=await V({page:c.value,page_size:u.value,search:_.value});h.value=l.data.list,p.value=l.data.total,g.value=!1}function y(l){if(!l)return"-";const e=new Date(l);if(isNaN(e.getTime()))return l;const s=m=>String(m).padStart(2,"0");return`${e.getFullYear()}-${s(e.getMonth()+1)}-${s(e.getDate())} ${s(e.getHours())}:${s(e.getMinutes())}:${s(e.getSeconds())}`}return(l,e)=>{const s=r("el-input"),m=r("el-button"),n=r("el-table-column"),z=r("el-tag"),x=r("el-table"),k=r("el-pagination"),D=C("loading");return w(),$("div",M,[o("div",T,[e[4]||(e[4]=o("div",null,[o("div",{class:"page-title"},"操作日志"),o("div",{class:"page-subtitle"},"查看最近的系统操作记录")],-1)),o("div",U,[t(s,{modelValue:_.value,"onUpdate:modelValue":e[0]||(e[0]=a=>_.value=a),placeholder:"搜索操作内容",clearable:"",style:{width:"240px"}},null,8,["modelValue"]),t(m,{type:"primary",onClick:v},{default:d(()=>[...e[3]||(e[3]=[b("查询",-1)])]),_:1})])]),o("div",I,[o("div",j,"共 "+f(p.value)+" 条记录",1),N((w(),B(x,{data:h.value,stripe:"",style:{width:"100%"},class:"modern-table"},{default:d(()=>[t(n,{prop:"id",label:"ID",width:"70"}),t(n,{prop:"action",label:"操作",width:"140"}),t(n,{prop:"target_type",label:"对象",width:"100"},{default:d(({row:a})=>[t(z,{size:"small",effect:"plain",round:""},{default:d(()=>[b(f(a.target_type),1)]),_:2},1024)]),_:1}),t(n,{prop:"target_name",label:"对象名称","min-width":"160"}),t(n,{prop:"details",label:"详情","min-width":"240","show-overflow-tooltip":""}),t(n,{prop:"created_at",label:"时间",width:"170"},{default:d(({row:a})=>[b(f(y(a.created_at)),1)]),_:1})]),_:1},8,["data"])),[[D,g.value]]),o("div",E,[t(k,{"current-page":c.value,"onUpdate:currentPage":e[1]||(e[1]=a=>c.value=a),"page-size":u.value,"onUpdate:pageSize":e[2]||(e[2]=a=>u.value=a),"page-sizes":[10,20,50,100],layout:"total, sizes, prev, pager, next",total:p.value,onChange:v},null,8,["current-page","page-size","total"])])])])}}},q=L(F,[["__scopeId","data-v-b1b09e4f"]]);export{q as default}; import{k as V,ap as $,o as w,c as k,a as o,b as t,w as d,t as f,aq as N,m as B,r as i,d as r,ar as C,h as b}from"./index-BFjouPFU.js";import{_ as L}from"./_plugin-vue_export-helper-DlAUqK2U.js";const M={class:"page"},T={class:"page-header"},U={class:"header-actions"},I={class:"card"},q={class:"table-header"},E={class:"pagination-bar"},F={__name:"Logs",setup(H){const h=i([]),p=i(0),c=i(1),u=i(20),_=i(""),g=i(!1);V(()=>v());async function v(){g.value=!0;const l=await $({page:c.value,page_size:u.value,search:_.value});h.value=l.data.list,p.value=l.data.total,g.value=!1}function y(l){if(!l)return"-";const e=new Date(l);if(isNaN(e.getTime()))return l;const s=m=>String(m).padStart(2,"0");return`${e.getFullYear()}-${s(e.getMonth()+1)}-${s(e.getDate())} ${s(e.getHours())}:${s(e.getMinutes())}:${s(e.getSeconds())}`}return(l,e)=>{const s=r("el-input"),m=r("el-button"),n=r("el-table-column"),z=r("el-tag"),x=r("el-table"),D=r("el-pagination"),S=C("loading");return w(),k("div",M,[o("div",T,[e[4]||(e[4]=o("div",null,[o("div",{class:"page-title"},"操作日志"),o("div",{class:"page-subtitle"},"查看最近的系统操作记录")],-1)),o("div",U,[t(s,{modelValue:_.value,"onUpdate:modelValue":e[0]||(e[0]=a=>_.value=a),placeholder:"搜索操作内容",clearable:"",style:{width:"240px"}},null,8,["modelValue"]),t(m,{type:"primary",onClick:v},{default:d(()=>[...e[3]||(e[3]=[b("查询",-1)])]),_:1})])]),o("div",I,[o("div",q,"共 "+f(p.value)+" 条记录",1),N((w(),B(x,{data:h.value,stripe:"",style:{width:"100%"},class:"modern-table"},{default:d(()=>[t(n,{prop:"id",label:"ID",width:"70"}),t(n,{prop:"action",label:"操作",width:"140"}),t(n,{prop:"target_type",label:"对象",width:"100"},{default:d(({row:a})=>[t(z,{size:"small",effect:"plain",round:""},{default:d(()=>[b(f(a.target_type),1)]),_:2},1024)]),_:1}),t(n,{prop:"target_name",label:"对象名称","min-width":"160"}),t(n,{prop:"details",label:"详情","min-width":"240","show-overflow-tooltip":""}),t(n,{prop:"created_at",label:"时间",width:"170"},{default:d(({row:a})=>[b(f(y(a.created_at)),1)]),_:1})]),_:1},8,["data"])),[[S,g.value]]),o("div",E,[t(D,{"current-page":c.value,"onUpdate:currentPage":e[1]||(e[1]=a=>c.value=a),"page-size":u.value,"onUpdate:pageSize":e[2]||(e[2]=a=>u.value=a),"page-sizes":[10,20,50,100],layout:"total, sizes, prev, pager, next",total:p.value,onChange:v},null,8,["current-page","page-size","total"])])])])}}},j=L(F,[["__scopeId","data-v-b1b09e4f"]]);export{j as default};

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
.toolbar[data-v-cae8dc77]{display:flex;align-items:center;gap:12px;margin-bottom:20px}.search-wrap[data-v-cae8dc77]{position:relative;flex:1;max-width:360px}.search-wrap[data-v-cae8dc77] .el-input__wrapper{padding-left:34px;border-radius:10px;box-shadow:0 0 0 1px var(--border) inset}.search-icon[data-v-cae8dc77]{position:absolute;left:10px;top:50%;transform:translateY(-50%);color:var(--text-muted);font-size:16px;z-index:1}.os-select[data-v-cae8dc77] .el-input__wrapper{border-radius:10px;box-shadow:0 0 0 1px var(--border) inset}.cards-grid[data-v-cae8dc77]{display:grid;grid-template-columns:repeat(2,1fr);gap:16px}@media (max-width: 900px){.cards-grid[data-v-cae8dc77]{grid-template-columns:1fr}}.server-card[data-v-cae8dc77]{background:var(--surface);border-radius:var(--radius);padding:18px;box-shadow:var(--shadow);border:1px solid var(--border);border-top-width:3px;border-top-color:var(--border-strong);cursor:pointer;transition:transform .12s ease,box-shadow .2s ease,opacity .2s ease,border-color .2s ease}.server-card[data-v-cae8dc77]:hover{transform:translateY(-2px);box-shadow:var(--shadow-lg);border-color:var(--border-strong)}.server-card.guest-card[data-v-cae8dc77]{cursor:default}.server-card.guest-card[data-v-cae8dc77]:hover{transform:none;box-shadow:var(--shadow);border-color:var(--border)}.server-card.offline-card[data-v-cae8dc77]{opacity:.65;border-top-color:var(--border)}.server-card.offline-card .hostname[data-v-cae8dc77]{color:var(--text-muted)}.card-header[data-v-cae8dc77]{display:flex;flex-direction:column;gap:6px}.title-row[data-v-cae8dc77]{display:flex;align-items:center;gap:10px}.os-dot[data-v-cae8dc77]{width:10px;height:10px;border-radius:50%;flex-shrink:0;box-shadow:inset 0 0 0 1px #00000014}.os-dot.os-linux[data-v-cae8dc77]{background:#3b82f6}.os-dot.os-windows[data-v-cae8dc77]{background:#22c55e}.os-dot.os-macos[data-v-cae8dc77]{background:#a855f7}.os-dot.os-other[data-v-cae8dc77]{background:#64748b}.status-badge[data-v-cae8dc77]{font-size:11px;padding:2px 8px;border-radius:999px;font-weight:600;line-height:1}.status-badge.online[data-v-cae8dc77]{background:#22c55e1f;color:#15803d}.status-badge.offline[data-v-cae8dc77]{background:#ef44441a;color:#b91c1c}html.dark .status-badge.online[data-v-cae8dc77]{background:#34d39926;color:#34d399}html.dark .status-badge.offline[data-v-cae8dc77]{background:#f8717126;color:#f87171}.hostname[data-v-cae8dc77]{font-weight:700;font-size:15px;color:var(--text)}.svc-tag[data-v-cae8dc77]{font-size:11px;height:18px;padding:0 8px;color:var(--text-secondary);border-color:var(--border)}.meta-row[data-v-cae8dc77]{display:flex;align-items:center;flex-wrap:wrap;gap:6px 0;font-size:12px;color:var(--text-secondary)}.meta-ip[data-v-cae8dc77]{color:var(--text);font-weight:500;background:var(--surface-hover);border:1px solid var(--border);padding:1px 6px;border-radius:4px}.meta-item+.meta-item[data-v-cae8dc77]:before,.meta-uptime[data-v-cae8dc77]:before{content:"·";margin:0 6px;color:var(--text-muted)}.meta-uptime[data-v-cae8dc77]{color:var(--success)}.stats-row[data-v-cae8dc77]{margin-top:14px;display:grid;grid-template-columns:repeat(3,1fr);gap:10px}.stat-pill[data-v-cae8dc77]{background:var(--pill-bg);border:1px solid var(--pill-border);border-radius:10px;padding:9px 10px;color:var(--pill-text);display:flex;align-items:center;gap:8px;transition:background .2s ease,border-color .2s ease}.pill-icon[data-v-cae8dc77]{width:22px;height:22px;border-radius:5px;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:800;background:#ffffff1a;flex-shrink:0}.pill-icon.cpu[data-v-cae8dc77]{color:#7dd3fc}.pill-icon.mem[data-v-cae8dc77]{color:#86efac}.pill-icon.disk[data-v-cae8dc77]{color:#93c5fd}.pill-body[data-v-cae8dc77]{flex:1;display:flex;flex-direction:column;gap:4px;min-width:0}.pill-label[data-v-cae8dc77]{font-size:10px;color:#ffffffd9;font-weight:600}.pill-bar[data-v-cae8dc77]{height:3px;background:#ffffff26;border-radius:2px;overflow:hidden}.pill-fill[data-v-cae8dc77]{height:100%;border-radius:2px;background:#ffffffe6;transition:width .3s ease}.pill-value[data-v-cae8dc77]{font-size:11px;font-weight:700;color:#fff;white-space:nowrap}.ports-row[data-v-cae8dc77]{margin-top:12px;display:flex;flex-wrap:wrap;gap:6px}.port-tag[data-v-cae8dc77]{font-size:11px;height:20px;padding:0 8px;color:var(--text-secondary);border-color:var(--border)}.more-ports[data-v-cae8dc77]{font-size:11px;color:var(--text-muted);line-height:20px}.sync-time[data-v-cae8dc77]{margin-top:10px;font-size:11px;color:var(--text-muted)}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +0,0 @@
import{k as h,o as c,c as m,a as s,b as e,w as t,m as d,n as _,t as v,p as C,r as x,q as w,d as i,u as L,e as n,v as M,x as A,y as B,z as E,A as D,B as N,f as V,C as z,D as I,E as S,F as q,G as F}from"./index-Chagxl0Z.js";import{_ as G}from"./_plugin-vue_export-helper-DlAUqK2U.js";const R={class:"layout"},T={key:0,class:"sidebar"},$={class:"nav"},j={class:"sidebar-footer"},H={class:"user-info"},J={class:"user-name"},K={class:"main-inner"},O={__name:"MainLayout",setup(P){const f=L(),u=w(()=>q().is_admin),o=x(!1);h(()=>{o.value=document.documentElement.classList.contains("dark")});function p(){o.value=!o.value,document.documentElement.classList.toggle("dark",o.value),localStorage.setItem("theme",o.value?"dark":"light")}async function g(){try{await I()}catch{}F(),S.success("已退出"),f.push("/login")}return(k,a)=>{const l=i("el-icon"),r=i("router-link"),y=i("el-button"),b=i("router-view");return c(),m("div",R,[u.value?(c(),m("aside",T,[a[4]||(a[4]=s("div",{class:"brand"},[s("div",{class:"brand-logo"},"LM"),s("div",{class:"brand-text"},"LAN Manager")],-1)),s("nav",$,[e(r,{to:"/machines",class:"nav-item","active-class":"active"},{default:t(()=>[e(l,null,{default:t(()=>[e(n(M))]),_:1}),a[0]||(a[0]=s("span",null,"机器列表",-1))]),_:1}),u.value?(c(),d(r,{key:0,to:"/topology",class:"nav-item","active-class":"active"},{default:t(()=>[e(l,null,{default:t(()=>[e(n(A))]),_:1}),a[1]||(a[1]=s("span",null,"拓扑图",-1))]),_:1})):_("",!0),u.value?(c(),d(r,{key:1,to:"/logs",class:"nav-item","active-class":"active"},{default:t(()=>[e(l,null,{default:t(()=>[e(n(B))]),_:1}),a[2]||(a[2]=s("span",null,"操作日志",-1))]),_:1})):_("",!0)]),s("div",{class:"theme-toggle",onClick:p},[e(l,{class:"theme-icon"},{default:t(()=>[(c(),d(E(o.value?n(D):n(N))))]),_:1}),s("span",null,v(o.value?"浅色模式":"深色模式"),1)]),s("div",j,[s("div",H,[e(l,{class:"user-icon"},{default:t(()=>[e(n(V))]),_:1}),s("span",J,v(u.value?"管理员":"访客"),1)]),e(y,{text:"",class:"logout-btn",onClick:g},{default:t(()=>[e(l,null,{default:t(()=>[e(n(z))]),_:1}),a[3]||(a[3]=s("span",null,"退出",-1))]),_:1})])])):_("",!0),s("main",{class:C(["main",{"no-sidebar":!u.value}])},[s("div",K,[e(b)])],2)])}}},W=G(O,[["__scopeId","data-v-a4c6174b"]]);export{W as default};

View File

@@ -1 +0,0 @@
.layout[data-v-a4c6174b]{display:flex;min-height:100vh}.sidebar[data-v-a4c6174b]{width:220px;background:#0f172a;color:#fff;display:flex;flex-direction:column;position:fixed;left:0;top:0;bottom:0;z-index:100}.brand[data-v-a4c6174b]{padding:22px 18px 14px;display:flex;align-items:center;gap:10px;border-bottom:1px solid rgba(255,255,255,.06)}.brand-logo[data-v-a4c6174b]{width:32px;height:32px;border-radius:8px;background:linear-gradient(135deg,#3b82f6,#60a5fa);display:flex;align-items:center;justify-content:center;font-weight:800;font-size:13px}.brand-text[data-v-a4c6174b]{font-weight:700;font-size:14px;letter-spacing:.3px}.nav[data-v-a4c6174b]{flex:1;padding:12px 10px;display:flex;flex-direction:column;gap:4px}.nav-item[data-v-a4c6174b]{display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:8px;color:#ffffffa6;text-decoration:none;font-size:13px;transition:background .15s ease,color .15s ease}.nav-item[data-v-a4c6174b]:hover{background:#ffffff0f;color:#ffffffe6}.nav-item.active[data-v-a4c6174b]{background:#3b82f62e;color:#60a5fa;font-weight:600}.nav-item .el-icon[data-v-a4c6174b]{font-size:16px}.sidebar-footer[data-v-a4c6174b]{padding:12px 10px 16px;border-top:1px solid rgba(255,255,255,.06);display:flex;flex-direction:column;gap:6px}.user-info[data-v-a4c6174b]{display:flex;align-items:center;gap:8px;padding:8px 10px;font-size:12px;color:#ffffff8c}.user-icon[data-v-a4c6174b]{font-size:14px}.user-name[data-v-a4c6174b]{font-weight:500;color:#ffffffd9}.logout-btn[data-v-a4c6174b]{justify-content:flex-start;width:100%;color:#ffffff8c;padding:8px 10px;border-radius:8px}.logout-btn[data-v-a4c6174b]:hover{color:#fff;background:#ffffff0f}.logout-btn span[data-v-a4c6174b]{margin-left:8px;font-size:12px}.main[data-v-a4c6174b]{flex:1;margin-left:220px;min-height:100vh;background:var(--bg)}.main-inner[data-v-a4c6174b]{padding:10px}.theme-toggle[data-v-a4c6174b]{margin:0 10px 10px;display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:8px;color:#ffffff8c;font-size:13px;cursor:pointer;transition:background .15s ease,color .15s ease}.theme-toggle[data-v-a4c6174b]:hover{background:#ffffff0f;color:#ffffffe6}.theme-icon[data-v-a4c6174b]{font-size:16px}.main.no-sidebar[data-v-a4c6174b]{margin-left:0}@media (max-width: 768px){.sidebar[data-v-a4c6174b]{width:64px}.brand-text[data-v-a4c6174b],.nav-item span[data-v-a4c6174b],.user-name[data-v-a4c6174b],.logout-btn span[data-v-a4c6174b]{display:none}.brand[data-v-a4c6174b]{justify-content:center;padding:18px 10px}.nav-item[data-v-a4c6174b]{justify-content:center}.main[data-v-a4c6174b]{margin-left:64px}.main.no-sidebar[data-v-a4c6174b]{margin-left:0}}

View File

@@ -0,0 +1 @@
import{k as h,o as i,c as m,a as s,b as e,w as t,m as d,n as r,t as v,p as C,r as x,q as w,d as _,u as E,e as l,v as L,x as M,y as A,z as B,A as D,B as N,C as V,f as z,D as I,F as S,E as q,G as F,H as G}from"./index-BFjouPFU.js";import{_ as H}from"./_plugin-vue_export-helper-DlAUqK2U.js";const P={class:"layout"},R={key:0,class:"sidebar"},T={class:"nav"},$={class:"sidebar-footer"},j={class:"user-info"},J={class:"user-name"},K={class:"main-inner"},O={__name:"MainLayout",setup(Q){const f=E(),u=w(()=>F().is_admin),o=x(!1);h(()=>{o.value=document.documentElement.classList.contains("dark")});function p(){o.value=!o.value,document.documentElement.classList.toggle("dark",o.value),localStorage.setItem("theme",o.value?"dark":"light")}async function g(){try{await S()}catch{}G(),q.success("已退出"),f.push("/login")}return(k,a)=>{const n=_("el-icon"),c=_("router-link"),y=_("el-button"),b=_("router-view");return i(),m("div",P,[u.value?(i(),m("aside",R,[a[5]||(a[5]=s("div",{class:"brand"},[s("div",{class:"brand-logo"},"LM"),s("div",{class:"brand-text"},"LAN Manager")],-1)),s("nav",T,[e(c,{to:"/machines",class:"nav-item","active-class":"active"},{default:t(()=>[e(n,null,{default:t(()=>[e(l(L))]),_:1}),a[0]||(a[0]=s("span",null,"机器列表",-1))]),_:1}),u.value?(i(),d(c,{key:0,to:"/topology",class:"nav-item","active-class":"active"},{default:t(()=>[e(n,null,{default:t(()=>[e(l(M))]),_:1}),a[1]||(a[1]=s("span",null,"拓扑图",-1))]),_:1})):r("",!0),u.value?(i(),d(c,{key:1,to:"/logs",class:"nav-item","active-class":"active"},{default:t(()=>[e(n,null,{default:t(()=>[e(l(A))]),_:1}),a[2]||(a[2]=s("span",null,"操作日志",-1))]),_:1})):r("",!0),u.value?(i(),d(c,{key:2,to:"/pve-hosts",class:"nav-item","active-class":"active"},{default:t(()=>[e(n,null,{default:t(()=>[e(l(B))]),_:1}),a[3]||(a[3]=s("span",null,"PVE 主机",-1))]),_:1})):r("",!0)]),s("div",{class:"theme-toggle",onClick:p},[e(n,{class:"theme-icon"},{default:t(()=>[(i(),d(D(o.value?l(N):l(V))))]),_:1}),s("span",null,v(o.value?"浅色模式":"深色模式"),1)]),s("div",$,[s("div",j,[e(n,{class:"user-icon"},{default:t(()=>[e(l(z))]),_:1}),s("span",J,v(u.value?"管理员":"访客"),1)]),e(y,{text:"",class:"logout-btn",onClick:g},{default:t(()=>[e(n,null,{default:t(()=>[e(l(I))]),_:1}),a[4]||(a[4]=s("span",null,"退出",-1))]),_:1})])])):r("",!0),s("main",{class:C(["main",{"no-sidebar":!u.value}])},[s("div",K,[e(b)])],2)])}}},X=H(O,[["__scopeId","data-v-dac2493b"]]);export{X as default};

View File

@@ -1 +0,0 @@
import{k as h,o as c,c as m,a as s,b as e,w as t,m as d,n as _,t as v,p as C,r as x,q as w,d as i,u as L,e as n,v as M,x as A,y as B,z as E,A as D,B as N,f as V,C as z,D as I,E as S,F as q,G as F}from"./index-C_uWT3cF.js";import{_ as G}from"./_plugin-vue_export-helper-DlAUqK2U.js";const R={class:"layout"},T={key:0,class:"sidebar"},$={class:"nav"},j={class:"sidebar-footer"},H={class:"user-info"},J={class:"user-name"},K={class:"main-inner"},O={__name:"MainLayout",setup(P){const f=L(),u=w(()=>q().is_admin),o=x(!1);h(()=>{o.value=document.documentElement.classList.contains("dark")});function p(){o.value=!o.value,document.documentElement.classList.toggle("dark",o.value),localStorage.setItem("theme",o.value?"dark":"light")}async function g(){try{await I()}catch{}F(),S.success("已退出"),f.push("/login")}return(k,a)=>{const l=i("el-icon"),r=i("router-link"),y=i("el-button"),b=i("router-view");return c(),m("div",R,[u.value?(c(),m("aside",T,[a[4]||(a[4]=s("div",{class:"brand"},[s("div",{class:"brand-logo"},"LM"),s("div",{class:"brand-text"},"LAN Manager")],-1)),s("nav",$,[e(r,{to:"/machines",class:"nav-item","active-class":"active"},{default:t(()=>[e(l,null,{default:t(()=>[e(n(M))]),_:1}),a[0]||(a[0]=s("span",null,"机器列表",-1))]),_:1}),u.value?(c(),d(r,{key:0,to:"/topology",class:"nav-item","active-class":"active"},{default:t(()=>[e(l,null,{default:t(()=>[e(n(A))]),_:1}),a[1]||(a[1]=s("span",null,"拓扑图",-1))]),_:1})):_("",!0),u.value?(c(),d(r,{key:1,to:"/logs",class:"nav-item","active-class":"active"},{default:t(()=>[e(l,null,{default:t(()=>[e(n(B))]),_:1}),a[2]||(a[2]=s("span",null,"操作日志",-1))]),_:1})):_("",!0)]),s("div",{class:"theme-toggle",onClick:p},[e(l,{class:"theme-icon"},{default:t(()=>[(c(),d(E(o.value?n(D):n(N))))]),_:1}),s("span",null,v(o.value?"浅色模式":"深色模式"),1)]),s("div",j,[s("div",H,[e(l,{class:"user-icon"},{default:t(()=>[e(n(V))]),_:1}),s("span",J,v(u.value?"管理员":"访客"),1)]),e(y,{text:"",class:"logout-btn",onClick:g},{default:t(()=>[e(l,null,{default:t(()=>[e(n(z))]),_:1}),a[3]||(a[3]=s("span",null,"退出",-1))]),_:1})])])):_("",!0),s("main",{class:C(["main",{"no-sidebar":!u.value}])},[s("div",K,[e(b)])],2)])}}},W=G(O,[["__scopeId","data-v-a4c6174b"]]);export{W as default};

View File

@@ -0,0 +1 @@
.layout[data-v-dac2493b]{display:flex;min-height:100vh}.sidebar[data-v-dac2493b]{width:220px;background:#0f172a;color:#fff;display:flex;flex-direction:column;position:fixed;left:0;top:0;bottom:0;z-index:100}.brand[data-v-dac2493b]{padding:22px 18px 14px;display:flex;align-items:center;gap:10px;border-bottom:1px solid rgba(255,255,255,.06)}.brand-logo[data-v-dac2493b]{width:32px;height:32px;border-radius:8px;background:linear-gradient(135deg,#3b82f6,#60a5fa);display:flex;align-items:center;justify-content:center;font-weight:800;font-size:13px}.brand-text[data-v-dac2493b]{font-weight:700;font-size:14px;letter-spacing:.3px}.nav[data-v-dac2493b]{flex:1;padding:12px 10px;display:flex;flex-direction:column;gap:4px}.nav-item[data-v-dac2493b]{display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:8px;color:#ffffffa6;text-decoration:none;font-size:13px;transition:background .15s ease,color .15s ease}.nav-item[data-v-dac2493b]:hover{background:#ffffff0f;color:#ffffffe6}.nav-item.active[data-v-dac2493b]{background:#3b82f62e;color:#60a5fa;font-weight:600}.nav-item .el-icon[data-v-dac2493b]{font-size:16px}.sidebar-footer[data-v-dac2493b]{padding:12px 10px 16px;border-top:1px solid rgba(255,255,255,.06);display:flex;flex-direction:column;gap:6px}.user-info[data-v-dac2493b]{display:flex;align-items:center;gap:8px;padding:8px 10px;font-size:12px;color:#ffffff8c}.user-icon[data-v-dac2493b]{font-size:14px}.user-name[data-v-dac2493b]{font-weight:500;color:#ffffffd9}.logout-btn[data-v-dac2493b]{justify-content:flex-start;width:100%;color:#ffffff8c;padding:8px 10px;border-radius:8px}.logout-btn[data-v-dac2493b]:hover{color:#fff;background:#ffffff0f}.logout-btn span[data-v-dac2493b]{margin-left:8px;font-size:12px}.main[data-v-dac2493b]{flex:1;margin-left:220px;min-height:100vh;background:var(--bg)}.main-inner[data-v-dac2493b]{padding:10px}.theme-toggle[data-v-dac2493b]{margin:0 10px 10px;display:flex;align-items:center;gap:10px;padding:10px 12px;border-radius:8px;color:#ffffff8c;font-size:13px;cursor:pointer;transition:background .15s ease,color .15s ease}.theme-toggle[data-v-dac2493b]:hover{background:#ffffff0f;color:#ffffffe6}.theme-icon[data-v-dac2493b]{font-size:16px}.main.no-sidebar[data-v-dac2493b]{margin-left:0}@media (max-width: 768px){.sidebar[data-v-dac2493b]{width:64px}.brand-text[data-v-dac2493b],.nav-item span[data-v-dac2493b],.user-name[data-v-dac2493b],.logout-btn span[data-v-dac2493b]{display:none}.brand[data-v-dac2493b]{justify-content:center;padding:18px 10px}.nav-item[data-v-dac2493b]{justify-content:center}.main[data-v-dac2493b]{margin-left:64px}.main.no-sidebar[data-v-dac2493b]{margin-left:0}}

1
web/dist/assets/PVEHosts-BMDl3QRA.css vendored Normal file
View File

@@ -0,0 +1 @@
.toolbar[data-v-c935d190]{display:flex;align-items:center;justify-content:space-between;margin-bottom:20px}.page-title[data-v-c935d190]{margin:0;font-size:20px;font-weight:600}.hosts-grid[data-v-c935d190]{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:16px}.host-card[data-v-c935d190]{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius);padding:16px}.host-header[data-v-c935d190]{display:flex;align-items:center;gap:10px;margin-bottom:12px}.host-icon[data-v-c935d190]{font-size:20px;color:var(--el-color-primary)}.host-name[data-v-c935d190]{font-size:16px;font-weight:600}.host-info[data-v-c935d190]{margin-bottom:12px}.info-row[data-v-c935d190]{display:flex;font-size:13px;margin-bottom:4px}.info-row .label[data-v-c935d190]{color:var(--text-secondary);width:50px}.info-row .value[data-v-c935d190]{color:var(--text)}.host-actions[data-v-c935d190]{display:flex;gap:8px}

1
web/dist/assets/PVEHosts-Ch6D9CK9.js vendored Normal file
View File

@@ -0,0 +1 @@
import{k as N,Q as $,o as m,c as f,a as t,b as s,w as o,e as b,M,m as S,n as k,N as z,O as D,r as y,d,h as p,v as L,t as c,a8 as F,as as I,E as V,at as O,au as Q}from"./index-BFjouPFU.js";import{_ as T}from"./_plugin-vue_export-helper-DlAUqK2U.js";const j={class:"page"},A={class:"toolbar"},G={key:1,class:"hosts-grid"},J={class:"host-header"},K={class:"host-name"},R={class:"host-info"},W={class:"info-row"},X={class:"value"},Y={class:"info-row"},Z={class:"value"},ee={class:"host-actions"},le={__name:"PVEHosts",setup(ae){const v=y([]),i=y(!1),l=y({name:"",hostname:"",port:8006,username:"",password:"",verify_ssl:!1});N(()=>{w()});async function w(){const n=await $();v.value=n.data}function g(n){l.value=n?{...n,password:""}:{name:"",hostname:"",port:8006,username:"",password:"",verify_ssl:!1},i.value=!0}async function E(){if(!l.value.name||!l.value.hostname||!l.value.username){V.warning("请填写必填项");return}if(!l.value.id&&!l.value.password){V.warning("请填写密码");return}try{l.value.id?await O(l.value.id,l.value):await Q(l.value),V.success("保存成功"),i.value=!1,w()}catch{}}async function C(n){try{await F.confirm(`确定要删除主机 "${n.name}" 吗?`,"确认删除",{type:"warning"}),await I(n.id),V.success("删除成功"),w()}catch{}}return(n,e)=>{const r=d("el-button"),x=d("el-empty"),P=d("el-icon"),_=d("el-input"),u=d("el-form-item"),H=d("el-input-number"),U=d("el-switch"),h=d("el-form"),q=d("el-dialog");return m(),f("div",j,[t("div",A,[e[10]||(e[10]=t("h2",{class:"page-title"},"PVE 主机管理",-1)),s(r,{type:"primary",icon:b(M),onClick:e[0]||(e[0]=a=>g())},{default:o(()=>[...e[9]||(e[9]=[p("添加主机",-1)])]),_:1},8,["icon"])]),v.value.length?k("",!0):(m(),S(x,{key:0,description:"暂无 PVE 主机"})),v.value.length?(m(),f("div",G,[(m(!0),f(z,null,D(v.value,a=>(m(),f("div",{key:a.id,class:"host-card"},[t("div",J,[s(P,{class:"host-icon"},{default:o(()=>[s(b(L))]),_:1}),t("span",K,c(a.name),1)]),t("div",R,[t("div",W,[e[11]||(e[11]=t("span",{class:"label"},"地址:",-1)),t("span",X,c(a.hostname)+":"+c(a.port),1)]),t("div",Y,[e[12]||(e[12]=t("span",{class:"label"},"用户:",-1)),t("span",Z,c(a.username),1)])]),t("div",ee,[s(r,{size:"small",onClick:B=>g(a)},{default:o(()=>[...e[13]||(e[13]=[p("编辑",-1)])]),_:1},8,["onClick"]),s(r,{size:"small",type:"danger",onClick:B=>C(a)},{default:o(()=>[...e[14]||(e[14]=[p("删除",-1)])]),_:1},8,["onClick"])])]))),128))])):k("",!0),s(q,{modelValue:i.value,"onUpdate:modelValue":e[8]||(e[8]=a=>i.value=a),title:l.value.id?"编辑主机":"添加主机",width:"480px",class:"modern-dialog","destroy-on-close":""},{footer:o(()=>[s(r,{onClick:e[7]||(e[7]=a=>i.value=!1)},{default:o(()=>[...e[15]||(e[15]=[p("取消",-1)])]),_:1}),s(r,{type:"primary",onClick:E},{default:o(()=>[...e[16]||(e[16]=[p("保存",-1)])]),_:1})]),default:o(()=>[s(h,{model:l.value,"label-width":"90px"},{default:o(()=>[s(u,{label:"名称",required:""},{default:o(()=>[s(_,{modelValue:l.value.name,"onUpdate:modelValue":e[1]||(e[1]=a=>l.value.name=a),placeholder:"如 PVE-01"},null,8,["modelValue"])]),_:1}),s(u,{label:"地址",required:""},{default:o(()=>[s(_,{modelValue:l.value.hostname,"onUpdate:modelValue":e[2]||(e[2]=a=>l.value.hostname=a),placeholder:"192.168.1.100"},null,8,["modelValue"])]),_:1}),s(u,{label:"端口"},{default:o(()=>[s(H,{modelValue:l.value.port,"onUpdate:modelValue":e[3]||(e[3]=a=>l.value.port=a),min:1,max:65535,style:{width:"100%"}},null,8,["modelValue"])]),_:1}),s(u,{label:"用户名",required:""},{default:o(()=>[s(_,{modelValue:l.value.username,"onUpdate:modelValue":e[4]||(e[4]=a=>l.value.username=a),placeholder:"root@pam 或 root@vmbr0"},null,8,["modelValue"])]),_:1}),s(u,{label:"密码",required:!l.value.id},{default:o(()=>[s(_,{modelValue:l.value.password,"onUpdate:modelValue":e[5]||(e[5]=a=>l.value.password=a),type:"password","show-password":"",placeholder:l.value.id?"留空保持不变":"必填"},null,8,["modelValue","placeholder"])]),_:1},8,["required"]),s(u,{label:"SSL 验证"},{default:o(()=>[s(U,{modelValue:l.value.verify_ssl,"onUpdate:modelValue":e[6]||(e[6]=a=>l.value.verify_ssl=a)},null,8,["modelValue"])]),_:1})]),_:1},8,["model"])]),_:1},8,["modelValue","title"])])}}},te=T(le,[["__scopeId","data-v-c935d190"]]);export{te as default};

File diff suppressed because one or more lines are too long

467
web/dist/assets/Topology-BoCWnE97.js vendored Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2
web/dist/index.html vendored
View File

@@ -5,7 +5,7 @@
<link rel="icon" href="/favicon.ico" /> <link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>局域网机器管理后台</title> <title>局域网机器管理后台</title>
<script type="module" crossorigin src="/assets/index-C_uWT3cF.js"></script> <script type="module" crossorigin src="/assets/index-BFjouPFU.js"></script>
<link rel="stylesheet" crossorigin href="/assets/index-DHYRt9JF.css"> <link rel="stylesheet" crossorigin href="/assets/index-DHYRt9JF.css">
</head> </head>
<body> <body>