fix(admin): 添加管理操作错误处理及更新模板样式
- 管理后台帖子与用户审核操作中添加失败错误重定向处理 - 管理后台帖子、用户、评论删除操作中添加错误检查及提示 - 用户角色更新操作失败时添加错误重定向 - 用户封禁通知失败时添加相应错误提示 - 登录登出时session保存加入错误处理 - 讨论区上传目录创建失败时显示错误提示 - 移除admin_dashboard.html多余样式及修正侧边栏当前页高亮 - admin_posts.html和admin_users.html添加状态样式动态使用的隐藏span元素 - admin_users.html为角色选择添加label以提升无障碍性 - 升级项目依赖版本,包含gin、gorm、validator等核心库版本更新
This commit is contained in:
@@ -17,7 +17,9 @@ func main() {
|
||||
}
|
||||
|
||||
authSvc := services.NewAuthService()
|
||||
authSvc.InitAdmin()
|
||||
if err := authSvc.InitAdmin(); err != nil {
|
||||
log.Fatalf("Failed to initialize admin: %v", err)
|
||||
}
|
||||
|
||||
r := routes.SetupRouter()
|
||||
|
||||
|
||||
64
go.mod
64
go.mod
@@ -1,51 +1,57 @@
|
||||
module lv8girl
|
||||
|
||||
go 1.21
|
||||
go 1.25.0
|
||||
|
||||
require (
|
||||
github.com/gin-contrib/sessions v1.0.1
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
github.com/glebarez/sqlite v1.10.0
|
||||
golang.org/x/crypto v0.22.0
|
||||
gorm.io/gorm v1.25.8
|
||||
github.com/gin-contrib/sessions v1.0.4
|
||||
github.com/gin-gonic/gin v1.11.0
|
||||
github.com/glebarez/sqlite v1.11.0
|
||||
golang.org/x/crypto v0.48.0
|
||||
gorm.io/gorm v1.31.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/bytedance/sonic v1.11.3 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d // indirect
|
||||
github.com/chenzhuoyu/iasm v0.9.1 // indirect
|
||||
github.com/bytedance/gopkg v0.1.3 // indirect
|
||||
github.com/bytedance/sonic v1.15.0 // indirect
|
||||
github.com/bytedance/sonic/loader v0.5.0 // indirect
|
||||
github.com/cloudwego/base64x v0.1.6 // indirect
|
||||
github.com/dustin/go-humanize v1.0.1 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/glebarez/go-sqlite v1.21.2 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.13 // indirect
|
||||
github.com/gin-contrib/sse v1.1.0 // indirect
|
||||
github.com/glebarez/go-sqlite v1.22.0 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.19.0 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/go-playground/validator/v10 v10.30.1 // indirect
|
||||
github.com/goccy/go-json v0.10.5 // indirect
|
||||
github.com/goccy/go-yaml v1.19.2 // indirect
|
||||
github.com/google/uuid v1.6.0 // indirect
|
||||
github.com/gorilla/context v1.1.2 // indirect
|
||||
github.com/gorilla/securecookie v1.1.2 // indirect
|
||||
github.com/gorilla/sessions v1.2.2 // indirect
|
||||
github.com/gorilla/sessions v1.4.0 // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
||||
github.com/leodido/go-urn v1.4.0 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.0 // indirect
|
||||
github.com/ncruces/go-strftime v1.0.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
|
||||
github.com/quic-go/qpack v0.6.0 // indirect
|
||||
github.com/quic-go/quic-go v0.59.0 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.12 // indirect
|
||||
golang.org/x/arch v0.7.0 // indirect
|
||||
golang.org/x/net v0.24.0 // indirect
|
||||
golang.org/x/sys v0.19.0 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
modernc.org/libc v1.22.5 // indirect
|
||||
modernc.org/mathutil v1.5.0 // indirect
|
||||
modernc.org/memory v1.5.0 // indirect
|
||||
modernc.org/sqlite v1.23.1 // indirect
|
||||
github.com/ugorji/go/codec v1.3.1 // indirect
|
||||
go.uber.org/mock v0.6.0 // indirect
|
||||
golang.org/x/arch v0.24.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa // indirect
|
||||
golang.org/x/net v0.50.0 // indirect
|
||||
golang.org/x/sys v0.41.0 // indirect
|
||||
golang.org/x/text v0.34.0 // indirect
|
||||
google.golang.org/protobuf v1.36.11 // indirect
|
||||
modernc.org/libc v1.68.0 // indirect
|
||||
modernc.org/mathutil v1.7.1 // indirect
|
||||
modernc.org/memory v1.11.0 // indirect
|
||||
modernc.org/sqlite v1.46.1 // indirect
|
||||
)
|
||||
|
||||
180
go.sum
180
go.sum
@@ -1,66 +1,65 @@
|
||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||
github.com/bytedance/sonic v1.10.0-rc/go.mod h1:ElCzW+ufi8qKqNW0FY314xriJhyJhuoJ3gFZdAHF7NM=
|
||||
github.com/bytedance/sonic v1.11.3 h1:jRN+yEjakWh8aK5FzrciUHG8OFXK+4/KrAX/ysEtHAA=
|
||||
github.com/bytedance/sonic v1.11.3/go.mod h1:iZcSUejdk5aukTND/Eu/ivjQuEL0Cu9/rf50Hi0u/g4=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d h1:77cEq6EriyTZ0g/qfRdp61a3Uu/AWrgIq2s0ClJV1g0=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20230717121745-296ad89f973d/go.mod h1:8EPpVsBuRksnlj1mLy4AWzRNQYxauNi62uWcE3to6eA=
|
||||
github.com/chenzhuoyu/iasm v0.9.0/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
|
||||
github.com/chenzhuoyu/iasm v0.9.1 h1:tUHQJXo3NhBqw6s33wkGn9SP3bvrWLdlVIJ3hQBL7P0=
|
||||
github.com/chenzhuoyu/iasm v0.9.1/go.mod h1:Xjy2NpN3h7aUqeqM+woSuuvxmIe6+DDsiNLIrkAmYog=
|
||||
github.com/bytedance/gopkg v0.1.3 h1:TPBSwH8RsouGCBcMBktLt1AymVo2TVsBVCY4b6TnZ/M=
|
||||
github.com/bytedance/gopkg v0.1.3/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM=
|
||||
github.com/bytedance/sonic v1.15.0 h1:/PXeWFaR5ElNcVE84U0dOHjiMHQOwNIx3K4ymzh/uSE=
|
||||
github.com/bytedance/sonic v1.15.0/go.mod h1:tFkWrPz0/CUCLEF4ri4UkHekCIcdnkqXw9VduqpJh0k=
|
||||
github.com/bytedance/sonic/loader v0.5.0 h1:gXH3KVnatgY7loH5/TkeVyXPfESoqSBSBEiDd5VjlgE=
|
||||
github.com/bytedance/sonic/loader v0.5.0/go.mod h1:AR4NYCk5DdzZizZ5djGqQ92eEhCCcdf5x77udYiSJRo=
|
||||
github.com/cloudwego/base64x v0.1.6 h1:t11wG9AECkCDk5fMSoxmufanudBtJ+/HemLstXDLI2M=
|
||||
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.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
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/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
|
||||
github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
|
||||
github.com/gin-contrib/sessions v1.0.1 h1:3hsJyNs7v7N8OtelFmYXFrulAf6zSR7nW/putcPEHxI=
|
||||
github.com/gin-contrib/sessions v1.0.1/go.mod h1:ouxSFM24/OgIud5MJYQJLpy6AwxQ5EYO9yLhbtObGkM=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
|
||||
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
|
||||
github.com/glebarez/go-sqlite v1.21.2 h1:3a6LFC4sKahUunAmynQKLZceZCOzUthkRkEAl9gAXWo=
|
||||
github.com/glebarez/go-sqlite v1.21.2/go.mod h1:sfxdZyhQjTM2Wry3gVYWaW072Ri1WMdWJi0k6+3382k=
|
||||
github.com/glebarez/sqlite v1.10.0 h1:u4gt8y7OND/cCei/NMHmfbLxF6xP2wgKcT/BJf2pYkc=
|
||||
github.com/glebarez/sqlite v1.10.0/go.mod h1:IJ+lfSOmiekhQsFTJRx/lHtGYmCdtAiTaf5wI9u5uHA=
|
||||
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/gin-contrib/sessions v1.0.4 h1:ha6CNdpYiTOK/hTp05miJLbpTSNfOnFg5Jm2kbcqy8U=
|
||||
github.com/gin-contrib/sessions v1.0.4/go.mod h1:ccmkrb2z6iU2osiAHZG3x3J4suJK+OU27oqzlWOqQgs=
|
||||
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-gonic/gin v1.11.0 h1:OW/6PLjyusp2PPXtyxKHU0RbX6I/l28FTdDlae5ueWk=
|
||||
github.com/gin-gonic/gin v1.11.0/go.mod h1:+iq/FyxlGzII0KHiBGjuNn4UNENUlKbGlNmc+W50Dls=
|
||||
github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ=
|
||||
github.com/glebarez/go-sqlite v1.22.0/go.mod h1:PlBIdHe0+aUEFn+r2/uthrWq4FxbzugL0L8Li6yQJbc=
|
||||
github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GMw=
|
||||
github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ=
|
||||
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/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/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.19.0 h1:ol+5Fu+cSq9JD7SoSqe04GMI92cbn0+wvQ3bZ8b/AU4=
|
||||
github.com/go-playground/validator/v10 v10.19.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/go-playground/validator/v10 v10.30.1 h1:f3zDSN/zOma+w6+1Wswgd9fLkdwy06ntQJp0BBvFG0w=
|
||||
github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5hc2Tu889bF0Idm9Dg26cM=
|
||||
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-yaml v1.19.2 h1:PmFC1S6h8ljIz6gMRBopkjP1TVT7xuwrButHID66PoM=
|
||||
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.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-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
|
||||
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
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/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/context v1.1.2 h1:WRkNAv2uoa03QNIc1A6u4O7DAGMUVoopZhkiXWA2V1o=
|
||||
github.com/gorilla/context v1.1.2/go.mod h1:KDPwT9i/MeWHiLl90fuTgrt4/wPcv75vFAZLaOOcbxM=
|
||||
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
|
||||
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
|
||||
github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY=
|
||||
github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ=
|
||||
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/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/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
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/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM=
|
||||
github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
|
||||
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ=
|
||||
github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
@@ -70,11 +69,16 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/pelletier/go-toml/v2 v2.2.0 h1:QLgLl2yMN7N+ruc31VynXs1vhMZa7CeHHejIeBAsoHo=
|
||||
github.com/pelletier/go-toml/v2 v2.2.0/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
github.com/ncruces/go-strftime v1.0.0 h1:HMFp8mLCTPp341M/ZnA4qaf7ZlsbTc+miZjCLOFAw7w=
|
||||
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/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/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
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=
|
||||
github.com/quic-go/quic-go v0.59.0/go.mod h1:upnsH4Ju1YkqpLXC305eW3yDZ4NfnNbmQRCMWS58IKU=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
@@ -82,48 +86,70 @@ github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSS
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.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/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE=
|
||||
github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.7.0 h1:pskyeJh/3AmoQ8CPE95vxHLqp1G1GfGNXTmcl9NEKTc=
|
||||
golang.org/x/arch v0.7.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys=
|
||||
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
|
||||
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
|
||||
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
|
||||
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
github.com/ugorji/go/codec v1.3.1 h1:waO7eEiFDwidsBN6agj1vJQ4AG7lh2yqXyOXqhgQuyY=
|
||||
github.com/ugorji/go/codec v1.3.1/go.mod h1:pRBVtBSKl77K30Bv8R2P+cLSGaTtex6fsA2Wjqmfxj4=
|
||||
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.24.0 h1:qlJ3M9upxvFfwRM51tTg3Yl+8CP9vCC1E7vlFpgv99Y=
|
||||
golang.org/x/arch v0.24.0/go.mod h1:dNHoOeKiyja7GTvF9NJS1l3Z2yntpQNzgrjh1cU103A=
|
||||
golang.org/x/crypto v0.48.0 h1:/VRzVqiRSggnhY7gNRxPauEQ5Drw9haKdM0jqfcCFts=
|
||||
golang.org/x/crypto v0.48.0/go.mod h1:r0kV5h3qnFPlQnBSrULhlsRfryS2pmewsg+XfMgkVos=
|
||||
golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa h1:Zt3DZoOFFYkKhDT3v7Lm9FDMEV06GpzjG2jrqW+QTE0=
|
||||
golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA=
|
||||
golang.org/x/mod v0.33.0 h1:tHFzIWbBifEmbwtGz65eaWyGiGZatSrT9prnU8DbVL8=
|
||||
golang.org/x/mod v0.33.0/go.mod h1:swjeQEj+6r7fODbD2cqrnje9PnziFuw4bmLbBZFrQ5w=
|
||||
golang.org/x/net v0.50.0 h1:ucWh9eiCGyDR3vtzso0WMQinm2Dnt8cFMuQa9K33J60=
|
||||
golang.org/x/net v0.50.0/go.mod h1:UgoSli3F/pBgdJBHCTc+tp3gmrU4XswgGRgtnwWTfyM=
|
||||
golang.org/x/sync v0.19.0 h1:vV+1eWNmZ5geRlYjzm2adRgW2/mcpevXNg50YZtPCE4=
|
||||
golang.org/x/sync v0.19.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
|
||||
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
|
||||
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
golang.org/x/sys v0.41.0 h1:Ivj+2Cp/ylzLiEU89QhWblYnOE9zerudt9Ftecq2C6k=
|
||||
golang.org/x/sys v0.41.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
|
||||
golang.org/x/text v0.34.0 h1:oL/Qq0Kdaqxa1KbNeMKwQq0reLCCaFtqu2eNuSeNHbk=
|
||||
golang.org/x/text v0.34.0/go.mod h1:homfLqTYRFyVYemLBFl5GgL/DWEiH5wcsQ5gSh1yziA=
|
||||
golang.org/x/tools v0.42.0 h1:uNgphsn75Tdz5Ji2q36v/nsFSfR/9BRFvqhGBaJGd5k=
|
||||
golang.org/x/tools v0.42.0/go.mod h1:Ma6lCIwGZvHK6XtgbswSoWroEkhugApmsXyrUmBhfr0=
|
||||
google.golang.org/protobuf v1.36.11 h1:fV6ZwhNocDyBLK0dj+fg8ektcVegBBuEolpbTQyBNVE=
|
||||
google.golang.org/protobuf v1.36.11/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco=
|
||||
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.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/gorm v1.25.8 h1:WAGEZ/aEcznN4D03laj8DKnehe1e9gYQAjW8xyPRdeo=
|
||||
gorm.io/gorm v1.25.8/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
|
||||
modernc.org/libc v1.22.5 h1:91BNch/e5B0uPbJFgqbxXuOnxBQjlS//icfQEGmvyjE=
|
||||
modernc.org/libc v1.22.5/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY=
|
||||
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
|
||||
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds=
|
||||
modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
|
||||
modernc.org/sqlite v1.23.1 h1:nrSBg4aRQQwq59JpvGEQ15tNxoO5pX/kUjcRNwSAGQM=
|
||||
modernc.org/sqlite v1.23.1/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk=
|
||||
nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
gorm.io/gorm v1.31.1 h1:7CA8FTFz/gRfgqgpeKIBcervUn3xSyPUmr6B2WXJ7kg=
|
||||
gorm.io/gorm v1.31.1/go.mod h1:XyQVbO2k6YkOis7C2437jSit3SsDK72s7n7rsSHd+Gs=
|
||||
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.30.2 h1:4yPaaq9dXYXZ2V8s1UgrC3KIj580l2N4ClrLwnbv2so=
|
||||
modernc.org/ccgo/v4 v4.30.2/go.mod h1:yZMnhWEdW0qw3EtCndG1+ldRrVGS+bIwyWmAWzS0XEw=
|
||||
modernc.org/fileutil v1.3.40 h1:ZGMswMNc9JOCrcrakF1HrvmergNLAmxOPjizirpfqBA=
|
||||
modernc.org/fileutil v1.3.40/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc=
|
||||
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.68.0 h1:PJ5ikFOV5pwpW+VqCK1hKJuEWsonkIJhhIXyuF/91pQ=
|
||||
modernc.org/libc v1.68.0/go.mod h1:NnKCYeoYgsEqnY3PgvNgAeaJnso968ygU8Z0DxjoEc0=
|
||||
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
|
||||
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/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.46.1 h1:eFJ2ShBLIEnUWlLy12raN0Z1plqmFX9Qe3rjQTKt6sU=
|
||||
modernc.org/sqlite v1.46.1/go.mod h1:CzbrU2lSB1DKUusvwGz7rqEKIq+NUd8GWuBBZDs9/nA=
|
||||
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=
|
||||
|
||||
@@ -4,9 +4,10 @@ import (
|
||||
"net/http"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"lv8girl/internal/middleware"
|
||||
"lv8girl/internal/services"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type AdminController struct {
|
||||
@@ -50,10 +51,16 @@ func (c *AdminController) ApprovePost(ctx *gin.Context) {
|
||||
action := ctx.Param("action")
|
||||
|
||||
if action == "approve" {
|
||||
c.adminSvc.ApprovePost(postID)
|
||||
if err := c.adminSvc.ApprovePost(postID); err != nil {
|
||||
ctx.Redirect(http.StatusFound, "/admin/pending_posts?msg=审核失败")
|
||||
return
|
||||
}
|
||||
ctx.Redirect(http.StatusFound, "/admin/pending_posts?msg=帖子已通过审核")
|
||||
} else if action == "reject" {
|
||||
c.adminSvc.RejectPost(postID)
|
||||
if err := c.adminSvc.RejectPost(postID); err != nil {
|
||||
ctx.Redirect(http.StatusFound, "/admin/pending_posts?msg=拒绝失败")
|
||||
return
|
||||
}
|
||||
ctx.Redirect(http.StatusFound, "/admin/pending_posts?msg=帖子已拒绝")
|
||||
} else {
|
||||
ctx.Redirect(http.StatusFound, "/admin/pending_posts")
|
||||
@@ -78,12 +85,24 @@ func (c *AdminController) ApproveUser(ctx *gin.Context) {
|
||||
adminID, _ := ctx.Get("user_id")
|
||||
|
||||
if action == "approve" {
|
||||
c.adminSvc.ApproveUser(userID)
|
||||
c.messageSvc.NotifyUserApproved(adminID.(uint), userID)
|
||||
if err := c.adminSvc.ApproveUser(userID); err != nil {
|
||||
ctx.Redirect(http.StatusFound, "/admin/pending_users?msg=审核失败")
|
||||
return
|
||||
}
|
||||
if err := c.messageSvc.NotifyUserApproved(adminID.(uint), userID); err != nil {
|
||||
ctx.Redirect(http.StatusFound, "/admin/pending_users?msg=审核通过但通知失败")
|
||||
return
|
||||
}
|
||||
ctx.Redirect(http.StatusFound, "/admin/pending_users?msg=用户已通过审核")
|
||||
} else if action == "reject" {
|
||||
c.adminSvc.RejectUser(userID)
|
||||
c.messageSvc.NotifyUserRejected(adminID.(uint), userID)
|
||||
if err := c.adminSvc.RejectUser(userID); err != nil {
|
||||
ctx.Redirect(http.StatusFound, "/admin/pending_users?msg=拒绝失败")
|
||||
return
|
||||
}
|
||||
if err := c.messageSvc.NotifyUserRejected(adminID.(uint), userID); err != nil {
|
||||
ctx.Redirect(http.StatusFound, "/admin/pending_users?msg=拒绝成功但通知失败")
|
||||
return
|
||||
}
|
||||
ctx.Redirect(http.StatusFound, "/admin/pending_users?msg=用户已拒绝")
|
||||
} else {
|
||||
ctx.Redirect(http.StatusFound, "/admin/pending_users")
|
||||
@@ -104,7 +123,10 @@ func (c *AdminController) Posts(ctx *gin.Context) {
|
||||
|
||||
func (c *AdminController) DeletePost(ctx *gin.Context) {
|
||||
postID := parseUint(ctx.Param("id"))
|
||||
c.adminSvc.DeletePost(postID)
|
||||
if err := c.adminSvc.DeletePost(postID); err != nil {
|
||||
ctx.Redirect(http.StatusFound, "/admin/posts?msg=删除失败")
|
||||
return
|
||||
}
|
||||
ctx.Redirect(http.StatusFound, "/admin/posts?msg=帖子已删除")
|
||||
}
|
||||
|
||||
@@ -134,10 +156,16 @@ func (c *AdminController) UpdateUserRole(ctx *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
c.adminSvc.UpdateUserRole(uint(userID), newRole)
|
||||
if err := c.adminSvc.UpdateUserRole(uint(userID), newRole); err != nil {
|
||||
ctx.Redirect(http.StatusFound, "/admin/users?msg=更新失败")
|
||||
return
|
||||
}
|
||||
|
||||
if newRole == "banned" {
|
||||
c.messageSvc.NotifyUserBanned(currentUserID.(uint), uint(userID))
|
||||
if err := c.messageSvc.NotifyUserBanned(currentUserID.(uint), uint(userID)); err != nil {
|
||||
ctx.Redirect(http.StatusFound, "/admin/users?msg=封禁成功但通知失败")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
ctx.Redirect(http.StatusFound, "/admin/users?msg=用户角色已更新")
|
||||
@@ -152,7 +180,10 @@ func (c *AdminController) DeleteUser(ctx *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
c.adminSvc.DeleteUser(userID)
|
||||
if err := c.adminSvc.DeleteUser(userID); err != nil {
|
||||
ctx.Redirect(http.StatusFound, "/admin/users?msg=删除失败")
|
||||
return
|
||||
}
|
||||
ctx.Redirect(http.StatusFound, "/admin/users?msg=用户已删除")
|
||||
}
|
||||
|
||||
@@ -170,7 +201,10 @@ func (c *AdminController) Comments(ctx *gin.Context) {
|
||||
|
||||
func (c *AdminController) DeleteComment(ctx *gin.Context) {
|
||||
commentID := parseUint(ctx.Param("id"))
|
||||
c.adminSvc.DeleteComment(commentID)
|
||||
if err := c.adminSvc.DeleteComment(commentID); err != nil {
|
||||
ctx.Redirect(http.StatusFound, "/admin/comments?msg=删除失败")
|
||||
return
|
||||
}
|
||||
ctx.Redirect(http.StatusFound, "/admin/comments?msg=评论已删除")
|
||||
}
|
||||
|
||||
|
||||
@@ -3,9 +3,10 @@ package controllers
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"lv8girl/internal/services"
|
||||
|
||||
"github.com/gin-contrib/sessions"
|
||||
"github.com/gin-gonic/gin"
|
||||
"lv8girl/internal/services"
|
||||
)
|
||||
|
||||
type AuthController struct {
|
||||
@@ -51,7 +52,10 @@ func (c *AuthController) Login(ctx *gin.Context) {
|
||||
session.Set("user_id", result.User.ID)
|
||||
session.Set("username", result.User.Username)
|
||||
session.Set("user_role", result.User.Role)
|
||||
session.Save()
|
||||
if err := session.Save(); err != nil {
|
||||
ctx.HTML(http.StatusOK, "login.html", gin.H{"Error": "登录失败,请重试"})
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Redirect(http.StatusFound, "/")
|
||||
}
|
||||
@@ -94,6 +98,9 @@ func (c *AuthController) Register(ctx *gin.Context) {
|
||||
func (c *AuthController) Logout(ctx *gin.Context) {
|
||||
session := sessions.Default(ctx)
|
||||
session.Clear()
|
||||
session.Save()
|
||||
if err := session.Save(); err != nil {
|
||||
ctx.String(http.StatusInternalServerError, "退出失败")
|
||||
return
|
||||
}
|
||||
ctx.Redirect(http.StatusFound, "/")
|
||||
}
|
||||
|
||||
@@ -7,9 +7,10 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"lv8girl/internal/middleware"
|
||||
"lv8girl/internal/services"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type DiscussionController struct {
|
||||
@@ -72,7 +73,17 @@ func (c *DiscussionController) CreatePost(ctx *gin.Context) {
|
||||
uploadDir := "uploads/posts"
|
||||
|
||||
if _, err := os.Stat(uploadDir); os.IsNotExist(err) {
|
||||
os.MkdirAll(uploadDir, 0755)
|
||||
if err := os.MkdirAll(uploadDir, 0755); err != nil {
|
||||
ctx.HTML(http.StatusOK, "post_discussion.html", gin.H{
|
||||
"IsLoggedIn": true,
|
||||
"UserID": userID,
|
||||
"Username": username,
|
||||
"UserRole": userRole,
|
||||
"Error": "创建上传目录失败",
|
||||
"Success": "",
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
imagePath = filepath.Join(uploadDir, filename)
|
||||
|
||||
@@ -4,11 +4,12 @@ import (
|
||||
"net/http"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/gin-contrib/sessions"
|
||||
"github.com/gin-gonic/gin"
|
||||
"lv8girl/internal/middleware"
|
||||
"lv8girl/internal/repositories"
|
||||
"lv8girl/internal/services"
|
||||
|
||||
"github.com/gin-contrib/sessions"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type HomeController struct {
|
||||
@@ -36,7 +37,7 @@ func (c *HomeController) Index(ctx *gin.Context) {
|
||||
|
||||
if isLoggedIn {
|
||||
userRepo := repositories.NewUserRepository()
|
||||
userRepo.UpdateLastActive(userID)
|
||||
_ = userRepo.UpdateLastActive(userID)
|
||||
}
|
||||
|
||||
posts, _ := c.discussionSvc.GetApprovedPosts(30)
|
||||
@@ -86,10 +87,10 @@ func (c *HomeController) ShowPost(ctx *gin.Context) {
|
||||
}
|
||||
|
||||
if !viewedMap[postID] {
|
||||
c.discussionSvc.IncrementViews(postID)
|
||||
_ = c.discussionSvc.IncrementViews(postID)
|
||||
viewedMap[postID] = true
|
||||
session.Set(viewedKey, viewedMap)
|
||||
session.Save()
|
||||
_ = session.Save()
|
||||
}
|
||||
|
||||
detail, err := c.discussionSvc.GetPostDetail(postID, userID)
|
||||
@@ -129,7 +130,7 @@ func (c *HomeController) LikePost(ctx *gin.Context) {
|
||||
}
|
||||
|
||||
postID := parseUint(ctx.Param("id"))
|
||||
c.discussionSvc.AddLike(postID, userID)
|
||||
_ = c.discussionSvc.AddLike(postID, userID)
|
||||
ctx.Redirect(http.StatusFound, "/post/"+ctx.Param("id"))
|
||||
}
|
||||
|
||||
@@ -144,7 +145,7 @@ func (c *HomeController) AddComment(ctx *gin.Context) {
|
||||
content := ctx.PostForm("content")
|
||||
|
||||
if content != "" {
|
||||
c.discussionSvc.AddComment(postID, userID, content)
|
||||
_ = c.discussionSvc.AddComment(postID, userID, content)
|
||||
}
|
||||
|
||||
ctx.Redirect(http.StatusFound, "/post/"+ctx.Param("id"))
|
||||
|
||||
@@ -4,10 +4,11 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"lv8girl/internal/middleware"
|
||||
"lv8girl/internal/repositories"
|
||||
"lv8girl/internal/services"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type MessageController struct {
|
||||
@@ -79,7 +80,10 @@ func (c *MessageController) SendMessage(ctx *gin.Context) {
|
||||
return
|
||||
}
|
||||
|
||||
c.messageSvc.SendMessage(currentUserID, toUserID, content)
|
||||
err := c.messageSvc.SendMessage(currentUserID, toUserID, content)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ctx.HTML(http.StatusOK, "send_message.html", gin.H{
|
||||
"Receiver": receiver,
|
||||
|
||||
@@ -8,9 +8,10 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"lv8girl/internal/middleware"
|
||||
"lv8girl/internal/services"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
type UserController struct {
|
||||
@@ -86,7 +87,10 @@ func (c *UserController) UploadAvatar(ctx *gin.Context) {
|
||||
uploadDir := "uploads/avatars"
|
||||
|
||||
if _, err := os.Stat(uploadDir); os.IsNotExist(err) {
|
||||
os.MkdirAll(uploadDir, 0755)
|
||||
if err := os.MkdirAll(uploadDir, 0755); err != nil {
|
||||
ctx.Redirect(http.StatusFound, "/profile?error=创建上传目录失败")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
imagePath := filepath.Join(uploadDir, filename)
|
||||
@@ -97,6 +101,9 @@ func (c *UserController) UploadAvatar(ctx *gin.Context) {
|
||||
|
||||
// 将路径转换为 URL 友好的格式(使用正斜杠)
|
||||
avatarPath := filepath.ToSlash(imagePath)
|
||||
c.userSvc.UpdateAvatar(userID, avatarPath)
|
||||
if err := c.userSvc.UpdateAvatar(userID, avatarPath); err != nil {
|
||||
ctx.Redirect(http.StatusFound, "/profile?error=头像更新失败")
|
||||
return
|
||||
}
|
||||
ctx.Redirect(http.StatusFound, "/profile?success=头像更新成功")
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
)
|
||||
|
||||
type User struct {
|
||||
//goland:noinspection SpellCheckingInspection
|
||||
ID uint `gorm:"primaryKey" json:"id"`
|
||||
Username string `gorm:"size:50;uniqueIndex;not null" json:"username"`
|
||||
Email string `gorm:"size:100;uniqueIndex;not null" json:"email"`
|
||||
|
||||
@@ -3,8 +3,9 @@ package repositories
|
||||
import (
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
"lv8girl/internal/models"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type DiscussionRepository struct{}
|
||||
|
||||
@@ -3,8 +3,9 @@ package repositories
|
||||
import (
|
||||
"time"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
"lv8girl/internal/models"
|
||||
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
type UserRepository struct{}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
package routes
|
||||
|
||||
import (
|
||||
"github.com/gin-contrib/sessions"
|
||||
"github.com/gin-contrib/sessions/cookie"
|
||||
"github.com/gin-gonic/gin"
|
||||
"lv8girl/internal/config"
|
||||
"lv8girl/internal/controllers"
|
||||
"lv8girl/internal/middleware"
|
||||
|
||||
"github.com/gin-contrib/sessions"
|
||||
"github.com/gin-contrib/sessions/cookie"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func SetupRouter() *gin.Engine {
|
||||
|
||||
@@ -44,7 +44,7 @@ func (s *AuthService) Login(login, password string) LoginResult {
|
||||
return LoginResult{Success: false, Error: "账号状态异常,请联系管理员"}
|
||||
}
|
||||
|
||||
s.userRepo.UpdateLastActive(user.ID)
|
||||
_ = s.userRepo.UpdateLastActive(user.ID)
|
||||
return LoginResult{Success: true, User: user}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
package utils
|
||||
|
||||
func Substring(s string, length int) string {
|
||||
runes := []rune(s)
|
||||
if len(runes) <= length {
|
||||
return s
|
||||
}
|
||||
return string(runes[:length])
|
||||
}
|
||||
@@ -40,18 +40,6 @@
|
||||
.stat-card { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 20px; display: flex; flex-direction: column; align-items: center; justify-content: center; text-align: center; }
|
||||
.stat-number { font-size: 2.5rem; font-weight: 700; color: var(--primary); line-height: 1.2; margin-bottom: 4px; }
|
||||
.stat-label { color: var(--text-hint); font-size: 0.95rem; }
|
||||
.table-card { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; overflow: hidden; }
|
||||
table { width: 100%; border-collapse: collapse; }
|
||||
th { background: var(--surface-light); padding: 12px 15px; text-align: left; font-weight: 600; color: var(--primary); border-bottom: 1px solid var(--border); }
|
||||
td { padding: 12px 15px; border-bottom: 1px solid var(--border); color: var(--text-soft); }
|
||||
tr:last-child td { border-bottom: none; }
|
||||
tr:hover { background: var(--surface-light); }
|
||||
.actions a { margin-right: 10px; color: var(--text-hint); text-decoration: none; }
|
||||
.actions a:hover { color: var(--primary); }
|
||||
.actions .delete { color: #ff6b6b; }
|
||||
.actions .delete:hover { color: #ff4d4d; }
|
||||
.actions .approve { color: var(--primary); }
|
||||
.actions .approve:hover { color: var(--primary-light); }
|
||||
.message { background: var(--surface-light); border-left: 4px solid var(--primary); padding: 12px 20px; margin-bottom: 20px; border-radius: 8px; color: var(--text); }
|
||||
@media (max-width: 768px) { .admin-wrapper { flex-direction: column; } .sidebar { width: 100%; height: auto; position: static; } }
|
||||
</style>
|
||||
@@ -64,7 +52,7 @@
|
||||
<p>管理面板</p>
|
||||
</div>
|
||||
<ul class="sidebar-menu">
|
||||
<li><a href="/admin" class="{{if eq .Page "dashboard"}}active{{end}}">📊 仪表盘</a></li>
|
||||
<li><a href="/admin" class="active">📊 仪表盘</a></li>
|
||||
<li><a href="/admin/pending_posts" class="{{if eq .Page "pending_posts"}}active{{end}}">⏳ 待审核帖子</a></li>
|
||||
<li><a href="/admin/pending_users" class="{{if eq .Page "pending_users"}}active{{end}}">👥 待审核用户</a></li>
|
||||
<li><a href="/admin/posts" class="{{if eq .Page "posts"}}active{{end}}">📝 帖子管理</a></li>
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
tr:hover { background: var(--surface-light); }
|
||||
.actions a { margin-right: 10px; color: var(--text-hint); text-decoration: none; }
|
||||
.actions .delete { color: #ff6b6b; }
|
||||
/* 状态样式通过模板动态应用: status-{{.Status}} */
|
||||
.status-approved { color: var(--primary); }
|
||||
.status-pending { color: #ffb347; }
|
||||
.status-rejected { color: #ff6b6b; }
|
||||
@@ -42,6 +43,8 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- 状态样式类通过模板动态使用: status-approved, status-pending, status-rejected -->
|
||||
<span style="display:none;" class="status-approved status-pending status-rejected"></span>
|
||||
<div class="admin-wrapper">
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-header"><div class="logo">lv8girl</div><p>管理面板</p></div>
|
||||
|
||||
@@ -43,6 +43,8 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<!-- 状态样式类通过模板动态使用: status-approved, status-pending, status-rejected -->
|
||||
<span style="display:none;" class="status-approved status-pending status-rejected"></span>
|
||||
<div class="admin-wrapper">
|
||||
<aside class="sidebar">
|
||||
<div class="sidebar-header"><div class="logo">lv8girl</div><p>管理面板</p></div>
|
||||
@@ -78,7 +80,8 @@
|
||||
{{else}}
|
||||
<form method="post" action="/admin/users/role" style="display:inline;">
|
||||
<input type="hidden" name="user_id" value="{{.ID}}">
|
||||
<select name="new_role" onchange="this.form.submit()">
|
||||
<label for="role-{{.ID}}" style="display:none;">角色</label>
|
||||
<select id="role-{{.ID}}" name="new_role" onchange="this.form.submit()">
|
||||
<option value="user" {{if eq .Role "user"}}selected{{end}}>用户</option>
|
||||
<option value="admin" {{if eq .Role "admin"}}selected{{end}}>管理员</option>
|
||||
<option value="banned" {{if eq .Role "banned"}}selected{{end}}>封禁</option>
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<body class="dark-mode">
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<div class="top-bar">
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
.footer-text a:hover { text-decoration: underline; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<body class="dark-mode">
|
||||
<div class="login-wrapper">
|
||||
<div class="header">
|
||||
<div class="logo">lv8girl<span>绿坝娘</span></div>
|
||||
@@ -61,12 +61,12 @@
|
||||
{{if .Error}}<div class="error-message">{{.Error}}</div>{{end}}
|
||||
<form method="post">
|
||||
<div class="form-group">
|
||||
<label>用户名 / 邮箱</label>
|
||||
<input type="text" name="login" placeholder="请输入用户名或邮箱" required>
|
||||
<label for="login">用户名 / 邮箱</label>
|
||||
<input type="text" id="login" name="login" placeholder="请输入用户名或邮箱" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>密码</label>
|
||||
<input type="password" name="password" placeholder="请输入密码" required>
|
||||
<label for="password">密码</label>
|
||||
<input type="password" id="password" name="password" placeholder="请输入密码" required>
|
||||
</div>
|
||||
<button type="submit" class="btn">登 录</button>
|
||||
</form>
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
.footer a:hover { color: var(--accent); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<body class="dark-mode">
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<div class="logo">lv8girl<span>绿坝娘</span></div>
|
||||
|
||||
@@ -104,7 +104,9 @@
|
||||
@media (max-width: 800px) { .main-layout { flex-direction: column; } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<body class="dark-mode">
|
||||
<!-- liked 类通过模板动态应用 -->
|
||||
<span style="display:none;" class="like-btn liked"></span>
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<div class="logo">lv8girl<span>绿坝娘</span></div>
|
||||
@@ -160,7 +162,8 @@
|
||||
<h2 class="comments-title">评论 ({{len .Comments}})</h2>
|
||||
{{if .IsLoggedIn}}
|
||||
<form method="post" action="/post/{{.Post.ID}}/comment" class="comment-form">
|
||||
<textarea name="content" placeholder="写下你的评论..." required></textarea>
|
||||
<label for="comment-content" style="display:none;">评论内容</label>
|
||||
<textarea id="comment-content" name="content" placeholder="写下你的评论..." required></textarea>
|
||||
<button type="submit">发表评论</button>
|
||||
</form>
|
||||
{{else}}
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
.footer-links a:hover { color: var(--accent); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<body class="dark-mode">
|
||||
<div class="post-wrapper">
|
||||
<div class="header">
|
||||
<div class="logo">lv8girl<span>绿坝娘</span></div>
|
||||
@@ -68,16 +68,16 @@
|
||||
{{else}}
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
<div class="form-group">
|
||||
<label>标题</label>
|
||||
<input type="text" name="title" placeholder="请输入标题" required>
|
||||
<label for="title">标题</label>
|
||||
<input type="text" id="title" name="title" placeholder="请输入标题" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>内容</label>
|
||||
<textarea name="content" placeholder="请输入帖子内容..." required></textarea>
|
||||
<label for="content">内容</label>
|
||||
<textarea id="content" name="content" placeholder="请输入帖子内容..." required></textarea>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>上传图片(可选,不超过2MB)</label>
|
||||
<input type="file" name="image" accept="image/*">
|
||||
<label for="image">上传图片(可选,不超过2MB)</label>
|
||||
<input type="file" id="image" name="image" accept="image/*">
|
||||
<div class="file-note">支持 JPEG、PNG、GIF、WEBP 格式</div>
|
||||
</div>
|
||||
<button type="submit" class="btn">发 布</button>
|
||||
|
||||
@@ -46,9 +46,6 @@
|
||||
.dropdown a:hover { background: var(--surface-light); }
|
||||
.theme-toggle { background: var(--surface-light); border: none; color: var(--text); font-size: 1.3rem; width: 38px; height: 38px; border-radius: 50%; cursor: pointer; display: flex; align-items: center; justify-content: center; transition: 0.2s; }
|
||||
.theme-toggle:hover { background: var(--accent); color: var(--surface); }
|
||||
.success-message, .error-message { padding: 12px 20px; border-radius: 8px; margin-bottom: 20px; }
|
||||
.success-message { background: var(--primary); color: white; }
|
||||
.error-message { background: #ff6b6b; color: white; }
|
||||
.profile-card { background: var(--surface); border: 1px solid var(--border); border-radius: 12px; padding: 25px; margin-bottom: 30px; display: flex; gap: 25px; flex-wrap: wrap; }
|
||||
.profile-avatar { width: 100px; height: 100px; border-radius: 50%; background: var(--gradient); overflow: hidden; display: flex; align-items: center; justify-content: center; color: white; font-size: 2.5rem; font-weight: 600; flex-shrink: 0; }
|
||||
.profile-avatar img { width: 100%; height: 100%; object-fit: cover; }
|
||||
@@ -85,7 +82,7 @@
|
||||
.footer a:hover { color: var(--accent); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<body class="dark-mode">
|
||||
<div class="container">
|
||||
<div class="header">
|
||||
<div class="logo">lv8girl<span>绿坝娘</span></div>
|
||||
@@ -135,6 +132,7 @@
|
||||
</form>
|
||||
</div>
|
||||
{{else}}
|
||||
<!--suppress HtmlUnknownTarget-->
|
||||
<a href="/send-message?to={{.User.ID}}" class="edit-btn" style="margin-top:10px;">📩 发送私信</a>
|
||||
{{end}}
|
||||
</div>
|
||||
@@ -187,8 +185,11 @@
|
||||
themeToggle.textContent = document.body.classList.contains('dark-mode') ? '☀️' : '🌓';
|
||||
});
|
||||
function toggleUpload() {
|
||||
var form = document.getElementById('uploadForm');
|
||||
form.style.display = form.style.display === 'none' ? 'block' : 'none';
|
||||
/** @type {HTMLElement|null} */
|
||||
const form = document.getElementById('uploadForm');
|
||||
if (form instanceof HTMLElement) {
|
||||
form.style.display = form.style.display === 'none' ? 'block' : 'none';
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
.footer-text a:hover { text-decoration: underline; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<body class="dark-mode">
|
||||
<div class="register-wrapper">
|
||||
<div class="header">
|
||||
<div class="logo">lv8girl<span>绿坝娘</span></div>
|
||||
@@ -69,20 +69,20 @@
|
||||
{{else}}
|
||||
<form method="post">
|
||||
<div class="form-group">
|
||||
<label>用户名</label>
|
||||
<input type="text" name="username" placeholder="3-20个字符,支持中文、字母、数字、下划线" required>
|
||||
<label for="username">用户名</label>
|
||||
<input type="text" id="username" name="username" placeholder="3-20个字符,支持中文、字母、数字、下划线" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>邮箱</label>
|
||||
<input type="email" name="email" placeholder="请输入有效邮箱" required>
|
||||
<label for="email">邮箱</label>
|
||||
<input type="email" id="email" name="email" placeholder="请输入有效邮箱" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>密码</label>
|
||||
<input type="password" name="password" placeholder="至少6位" required>
|
||||
<label for="password">密码</label>
|
||||
<input type="password" id="password" name="password" placeholder="至少6位" required>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label>确认密码</label>
|
||||
<input type="password" name="confirm_password" placeholder="请再次输入密码" required>
|
||||
<label for="confirm_password">确认密码</label>
|
||||
<input type="password" id="confirm_password" name="confirm_password" placeholder="请再次输入密码" required>
|
||||
</div>
|
||||
<div class="checkbox-group">
|
||||
<input type="checkbox" name="agree" id="agree" required>
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
.footer-links a:hover { color: var(--accent); }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<body class="dark-mode">
|
||||
<div class="wrapper">
|
||||
<div class="header">
|
||||
<div class="logo">lv8girl<span>绿坝娘</span></div>
|
||||
@@ -62,8 +62,8 @@
|
||||
{{if .Success}}<div class="success-message">{{.Success}}</div>{{end}}
|
||||
<form method="post">
|
||||
<div class="form-group">
|
||||
<label>内容</label>
|
||||
<textarea name="content" placeholder="请输入私信内容..."></textarea>
|
||||
<label for="content">内容</label>
|
||||
<textarea id="content" name="content" placeholder="请输入私信内容..."></textarea>
|
||||
</div>
|
||||
<button type="submit" class="btn">发送</button>
|
||||
</form>
|
||||
|
||||
Reference in New Issue
Block a user