任务三

This commit is contained in:
Yvan 2026-01-07 11:53:56 +08:00
parent 05e12a2e2a
commit a017d93dbf
10 changed files with 1082 additions and 119 deletions

View File

@ -7,6 +7,7 @@ import (
"gorm.io/driver/mysql"
"gorm.io/gen"
"gorm.io/gen/field"
"gorm.io/gorm"
)
@ -39,12 +40,45 @@ func main() {
// 字段名映射,避免与方法名冲突
fieldOpts := []gen.ModelOpt{
gen.FieldRename("table_name", "TblName"),
gen.FieldRename("table", "TblName"), // 避免与Table()方法冲突
gen.FieldRename("table", "TblName"),
}
// 生成所有表的model和query
allTables := g.GenerateAllTable(fieldOpts...)
g.ApplyBasic(allTables...)
// SysUser 关联配置
sysUserOpts := append(fieldOpts,
// Authority: belongs to SysAuthority
gen.FieldRelate(field.HasOne, "Authority", g.GenerateModel("sys_authorities"),
&field.RelateConfig{
GORMTag: field.GormTag{
"foreignKey": []string{"AuthorityID"},
"references": []string{"AuthorityID"},
},
}),
// Authorities: many2many through sys_user_authority
gen.FieldRelate(field.Many2Many, "Authorities", g.GenerateModel("sys_authorities"),
&field.RelateConfig{
GORMTag: field.GormTag{
"many2many": []string{"sys_user_authority"},
"joinForeignKey": []string{"SysUserID"},
"joinReferences": []string{"SysAuthorityAuthorityID"},
},
}),
)
// 生成带关联的SysUser
sysUser := g.GenerateModel("sys_users", sysUserOpts...)
// 生成其他表不含sys_users
tables, _ := db.Migrator().GetTables()
var models []interface{}
for _, table := range tables {
if table == "sys_users" {
continue
}
models = append(models, g.GenerateModel(table, fieldOpts...))
}
g.ApplyBasic(sysUser)
g.ApplyBasic(models...)
// 执行生成
g.Execute()

24
go.mod
View File

@ -5,7 +5,6 @@ go 1.24.6
toolchain go1.24.7
require (
entgo.io/ent v0.14.5
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible
github.com/aws/aws-sdk-go-v2 v1.41.0
github.com/aws/aws-sdk-go-v2/config v1.32.6
@ -13,7 +12,6 @@ require (
github.com/aws/aws-sdk-go-v2/service/s3 v1.95.0
github.com/casbin/casbin/v2 v2.103.0
github.com/casbin/gorm-adapter/v3 v3.32.0
github.com/go-kratos/aip-go/ents v0.0.0-20251213081434-74ffa1fc1588
github.com/go-kratos/kratos/v2 v2.8.0
github.com/go-sql-driver/mysql v1.8.1
github.com/golang-jwt/jwt/v5 v5.2.2
@ -26,25 +24,26 @@ require (
github.com/redis/go-redis/v9 v9.7.0
github.com/robfig/cron/v3 v3.0.1
github.com/tencentyun/cos-go-sdk-v5 v0.7.60
github.com/xuri/excelize/v2 v2.9.0
go.einride.tech/aip v0.78.0
go.uber.org/automaxprocs v1.6.0
golang.org/x/crypto v0.38.0
google.golang.org/genproto/googleapis/api v0.0.0-20251213004720-97cd9d5aeac2
google.golang.org/grpc v1.74.2
google.golang.org/protobuf v1.36.10
gorm.io/driver/mysql v1.5.7
gorm.io/driver/postgres v1.5.11
gorm.io/driver/sqlite v1.6.0
gorm.io/gen v0.3.27
gorm.io/gorm v1.30.0
gorm.io/plugin/dbresolver v1.6.2
)
require (
ariga.io/atlas v0.32.1-0.20250325101103-175b25e1c1b9 // indirect
dario.cat/mergo v1.0.0 // indirect
filippo.io/edwards25519 v1.1.0 // indirect
github.com/BurntSushi/toml v1.3.2 // indirect
github.com/agext/levenshtein v1.2.3 // indirect
github.com/alex-ant/gomath v0.0.0-20160516115720-89013a210a82 // indirect
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.18.16 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.4.16 // indirect
@ -60,7 +59,6 @@ require (
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.35.12 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.41.5 // indirect
github.com/aws/smithy-go v1.24.0 // indirect
github.com/bmatcuk/doublestar v1.3.4 // indirect
github.com/bmatcuk/doublestar/v4 v4.6.1 // indirect
github.com/casbin/govaluate v1.3.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
@ -75,19 +73,16 @@ require (
github.com/go-kratos/aegis v0.2.0 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/inflect v0.19.0 // indirect
github.com/go-playground/form/v4 v4.2.0 // indirect
github.com/goccy/go-json v0.10.4 // indirect
github.com/gofrs/flock v0.8.1 // indirect
github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect
github.com/golang-sql/sqlexp v0.1.0 // indirect
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
github.com/google/go-cmp v0.7.0 // indirect
github.com/google/go-querystring v1.0.0 // indirect
github.com/gorilla/mux v1.8.1 // indirect
github.com/hashicorp/hcl/v2 v2.18.1 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 // indirect
github.com/jackc/pgx/v5 v5.5.5 // indirect
github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
@ -98,7 +93,6 @@ require (
github.com/mattn/go-sqlite3 v1.14.22 // indirect
github.com/microsoft/go-mssqldb v1.6.0 // indirect
github.com/minio/md5-simd v1.1.2 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect
github.com/mozillazg/go-httpheader v0.2.1 // indirect
@ -107,15 +101,11 @@ require (
github.com/richardlehane/msoleps v1.0.4 // indirect
github.com/rs/xid v1.6.0 // indirect
github.com/xuri/efp v0.0.0-20240408161823-9ad904a10d6d // indirect
github.com/xuri/excelize/v2 v2.9.0 // indirect
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 // indirect
github.com/zclconf/go-cty v1.14.4 // indirect
github.com/zclconf/go-cty-yaml v1.1.0 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/otel v1.36.0 // indirect
go.opentelemetry.io/otel/metric v1.36.0 // indirect
go.opentelemetry.io/otel/trace v1.36.0 // indirect
golang.org/x/crypto v0.38.0 // indirect
golang.org/x/image v0.23.0 // indirect
golang.org/x/mod v0.23.0 // indirect
golang.org/x/net v0.40.0 // indirect
@ -123,10 +113,12 @@ require (
golang.org/x/sys v0.33.0 // indirect
golang.org/x/text v0.25.0 // indirect
golang.org/x/time v0.14.0 // indirect
golang.org/x/tools v0.30.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20251124214823-79d6a2a48846 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gorm.io/datatypes v1.2.4 // indirect
gorm.io/driver/sqlserver v1.5.3 // indirect
gorm.io/plugin/dbresolver v1.6.2 // indirect
gorm.io/hints v1.1.0 // indirect
modernc.org/fileutil v1.0.0 // indirect
modernc.org/libc v1.22.5 // indirect
modernc.org/mathutil v1.5.0 // indirect

48
go.sum
View File

@ -1,11 +1,7 @@
ariga.io/atlas v0.32.1-0.20250325101103-175b25e1c1b9 h1:E0wvcUXTkgyN4wy4LGtNzMNGMytJN8afmIWXJVMi4cc=
ariga.io/atlas v0.32.1-0.20250325101103-175b25e1c1b9/go.mod h1:Oe1xWPuu5q9LzyrWfbZmEZxFYeu4BHTyzfjeW2aZp/w=
cel.dev/expr v0.24.0 h1:56OvJKSH3hDGL0ml5uSxZmz3/3Pq4tJ+fb1unVLAFcY=
cel.dev/expr v0.24.0/go.mod h1:hLPLo1W4QUmuYdA72RBX06QTs6MXw941piREPl3Yfiw=
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
entgo.io/ent v0.14.5 h1:Rj2WOYJtCkWyFo6a+5wB3EfBRP0rnx1fMk6gGA0UUe4=
entgo.io/ent v0.14.5/go.mod h1:zTzLmWtPvGpmSwtkaayM2cm5m819NdM7z7tYPq3vN0U=
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.4.0/go.mod h1:ON4tFdPTwRcgWEaVDrN3584Ef+b7GgSJaXxe5fW9t4M=
@ -28,17 +24,11 @@ github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0 h1:HCc0+LpPfpC
github.com/AzureAD/microsoft-authentication-library-for-go v1.1.0/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/QcloudApi/qcloud_sign_golang v0.0.0-20141224014652-e4130a326409/go.mod h1:1pk82RBxDY/JZnPQrtqHlUFfCctgdorsd9M06fMynOM=
github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
github.com/alex-ant/gomath v0.0.0-20160516115720-89013a210a82 h1:7dONQ3WNZ1zy960TmkxJPuwoolZwL7xKtpcM04MBnt4=
github.com/alex-ant/gomath v0.0.0-20160516115720-89013a210a82/go.mod h1:nLnM0KdK1CmygvjpDUO6m1TjSsiQtL61juhNsvV/JVI=
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible h1:8psS8a+wKfiLt1iVDX79F7Y6wUM49Lcha2FMXt4UM8g=
github.com/aliyun/aliyun-oss-go-sdk v3.0.2+incompatible/go.mod h1:T/Aws4fEfogEE9v+HPhhw+CntffsBHJ8nXQCwKr0/g8=
github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY=
github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4=
github.com/aws/aws-sdk-go-v2 v1.41.0 h1:tNvqh1s+v0vFYdA1xq0aOJH+Y5cRyZ5upu6roPgPKd4=
github.com/aws/aws-sdk-go-v2 v1.41.0/go.mod h1:MayyLB8y+buD9hZqkCW3kX1AKq07Y5pXxtgB+rRFhz0=
github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.7.4 h1:489krEF9xIGkOaaX3CE/Be2uWjiXrkCH6gUX+bZA/BU=
@ -77,8 +67,6 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.41.5 h1:SciGFVNZ4mHdm7gpD1dgZYnCuVdX
github.com/aws/aws-sdk-go-v2/service/sts v1.41.5/go.mod h1:iW40X4QBmUxdP+fZNOpfmkdMZqsovezbAeO+Ubiv2pk=
github.com/aws/smithy-go v1.24.0 h1:LpilSUItNPFr1eY85RYgTIg5eIEPtvFbskaFcmmIUnk=
github.com/aws/smithy-go v1.24.0/go.mod h1:LEj2LM3rBRQJxPZTB4KuzZkaZYnZPnvgIhb4pu07mx0=
github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0=
github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE=
github.com/bmatcuk/doublestar/v4 v4.6.1 h1:FH9SifrbvJhnlQpztAx++wlkk70QBf0iBWDwNy7PA4I=
github.com/bmatcuk/doublestar/v4 v4.6.1/go.mod h1:xBQ8jztBU6kakFMg+8WGxn0c6z1fTSPVIjEY1Wr7jzc=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
@ -125,8 +113,6 @@ github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-kratos/aegis v0.2.0 h1:dObzCDWn3XVjUkgxyBp6ZeWtx/do0DPZ7LY3yNSJLUQ=
github.com/go-kratos/aegis v0.2.0/go.mod h1:v0R2m73WgEEYB3XYu6aE2WcMwsZkJ/Rzuf5eVccm7bI=
github.com/go-kratos/aip-go/ents v0.0.0-20251213081434-74ffa1fc1588 h1:e0dWyNWFeTgGCH7cRMROahTwMaQYtmHce/6fxVmA6yI=
github.com/go-kratos/aip-go/ents v0.0.0-20251213081434-74ffa1fc1588/go.mod h1:ifKMm4eJmaQz5WNKKhfClpCng8UxUB3sArof8wjwG78=
github.com/go-kratos/kratos/v2 v2.8.0 h1:qr27WRTRrI3o4jzJzNKf4XVVoMYIqnQD+4ws1C46yhM=
github.com/go-kratos/kratos/v2 v2.8.0/go.mod h1:+Vfe3FzF0d+BfMdajA11jT0rAyJWublRE/seZQNZVxE=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
@ -134,8 +120,6 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-openapi/inflect v0.19.0 h1:9jCH9scKIbHeV9m12SmPilScz6krDxKRasNNSNPXu/4=
github.com/go-openapi/inflect v0.19.0/go.mod h1:lHpZVlpIQqLyKwJ4N+YSc9hchQy/i12fJykb83CRBH4=
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/form/v4 v4.2.0 h1:N1wh+Goz61e6w66vo8vJkQt+uwZSoLz50kZPJWR8eic=
@ -148,8 +132,6 @@ github.com/go-playground/validator/v10 v10.7.0/go.mod h1:xm76BBt941f7yWdGnI2DVPF
github.com/go-sql-driver/mysql v1.7.0/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/goccy/go-json v0.10.4 h1:JSwxQzIqKfmFX1swYPpUThQZp/Ka4wzJdK0LWVytLPM=
github.com/goccy/go-json v0.10.4/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M=
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
@ -191,15 +173,13 @@ github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+
github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM=
github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
github.com/hashicorp/hcl/v2 v2.18.1 h1:6nxnOJFku1EuSawSD81fuviYUV8DxFr3fp2dUi3ZYSo=
github.com/hashicorp/hcl/v2 v2.18.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE=
github.com/huaweicloud/huaweicloud-sdk-go-obs v3.24.9+incompatible h1:XQVXdk+WAJ4fSNB6mMRuYNvFWou7BZs6SZB925hPrnk=
github.com/huaweicloud/huaweicloud-sdk-go-obs v3.24.9+incompatible/go.mod h1:l7VUhRbTKCzdOacdT4oWCwATKyvZqUOlOqr0Ous3k4s=
github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho=
github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM=
github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk=
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9 h1:L0QtFUgDarD7Fpv9jeVMgy/+Ec0mtnmYuImjTz6dtDA=
github.com/jackc/pgservicefile v0.0.0-20231201235250-de7065d80cb9/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM=
github.com/jackc/pgx/v5 v5.5.5 h1:amBjrZVmksIdNjxGW/IiIMzxMKZFelXbUoPNb+8sjQw=
github.com/jackc/pgx/v5 v5.5.5/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A=
github.com/jackc/puddle/v2 v2.2.1 h1:RhxXJtFG022u4ibrCSMSiu5aOq1i77R3OHKNJj77OAk=
@ -213,6 +193,7 @@ github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJk
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
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.2/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
@ -237,6 +218,7 @@ github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-sqlite3 v1.14.8/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=
github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/microsoft/go-mssqldb v1.6.0 h1:mM3gYdVwEPFrlg/Dvr2DNVEgYFG7L42l+dGc67NNNpc=
@ -245,8 +227,6 @@ github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
github.com/minio/minio-go/v7 v7.0.84 h1:D1HVmAF8JF8Bpi6IU4V9vIEj+8pc+xU88EWMs2yed0E=
github.com/minio/minio-go/v7 v7.0.84/go.mod h1:57YXpvc5l3rjPdhqNrDsvVlY0qPI6UTk1bflAe+9doY=
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
@ -289,8 +269,6 @@ github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR
github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o=
github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
github.com/rs/xid v1.6.0/go.mod h1:7XoLgs4eV+QndskICGsho+ADou8ySMSjJKDIan90Nz0=
github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
@ -316,10 +294,6 @@ github.com/xuri/excelize/v2 v2.9.0/go.mod h1:uqey4QBZ9gdMeWApPLdhm9x+9o2lq4iVmji
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7 h1:hPVCafDV85blFTabnqKgNhDCkJX25eik94Si9cTER4A=
github.com/xuri/nfp v0.0.0-20240318013403-ab9948c2c4a7/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
github.com/zclconf/go-cty v1.14.4 h1:uXXczd9QDGsgu0i/QFR/hzI5NYCHLf6NQw/atrbnhq8=
github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE=
github.com/zclconf/go-cty-yaml v1.1.0 h1:nP+jp0qPHv2IhUVqmQSzjvqAWcObN0KBkUl2rWBdig0=
github.com/zclconf/go-cty-yaml v1.1.0/go.mod h1:9YLUH4g7lOhVWqUbctnVlZ5KLpg7JAprQNgxSZ1Gyxs=
go.einride.tech/aip v0.78.0 h1:nbnM/OuGt5Pyz/r2KOxB6Hp+ey2e0+MNnfIPBtY45pY=
go.einride.tech/aip v0.78.0/go.mod h1:E8+wdTApA70odnpFzJgsGogHozC2JCIhFJBKPr8bVig=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
@ -442,6 +416,8 @@ golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
golang.org/x/tools v0.17.0/go.mod h1:xsh6VxdV005rRVaS6SSAf9oiAqljS7UZUacMZ8Bnsps=
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d h1:/hmn0Ku5kWij/kjGsrcJeC1T/MrJi2iNWwgAqrihFwc=
google.golang.org/genproto v0.0.0-20240711142825-46eb208f015d/go.mod h1:FfBgJBJg9GcpPvKIuHSZ/aE1g2ecGL74upMzGZjiGEY=
@ -466,21 +442,27 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/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/datatypes v1.2.4 h1:uZmGAcK/QZ0uyfCuVg0VQY1ZmV9h1fuG0tMwKByO1z4=
gorm.io/datatypes v1.2.4/go.mod h1:f4BsLcFAX67szSv8svwLRjklArSHAvHLeE3pXAS5DZI=
gorm.io/driver/mysql v1.5.7 h1:MndhOPYOfEp2rHKgkZIhJ16eVUIRf2HmzgoPmh7FCWo=
gorm.io/driver/mysql v1.5.7/go.mod h1:sEtPWMiqiN1N1cMXoXmBbd8C6/l+TESwriotuRRpkDM=
gorm.io/driver/postgres v1.5.11 h1:ubBVAfbKEUld/twyKZ0IYn9rSQh448EdelLYk9Mv314=
gorm.io/driver/postgres v1.5.11/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI=
gorm.io/driver/sqlite v1.1.6/go.mod h1:W8LmC/6UvVbHKah0+QOC7Ja66EaZXHwUTjgXY8YNWX8=
gorm.io/driver/sqlite v1.6.0 h1:WHRRrIiulaPiPFmDcod6prc4l2VGVWHz80KspNsxSfQ=
gorm.io/driver/sqlite v1.6.0/go.mod h1:AO9V1qIQddBESngQUKWL9yoH93HIeA1X6V633rBwyT8=
gorm.io/driver/sqlserver v1.5.3 h1:rjupPS4PVw+rjJkfvr8jn2lJ8BMhT4UW5FwuJY0P3Z0=
gorm.io/driver/sqlserver v1.5.3/go.mod h1:B+CZ0/7oFJ6tAlefsKoyxdgDCXJKSgwS2bMOQZT0I00=
gorm.io/gen v0.3.27 h1:ziocAFLpE7e0g4Rum69pGfB9S6DweTxK8gAun7cU8as=
gorm.io/gen v0.3.27/go.mod h1:9zquz2xD1f3Eb/eHq4oLn2z6vDVvQlCY5S3uMBLv4EA=
gorm.io/gorm v1.21.15/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
gorm.io/gorm v1.22.2/go.mod h1:F+OptMscr0P2F2qU97WT1WimdH9GaQPoDW7AYd5i2Y0=
gorm.io/gorm v1.25.7-0.20240204074919-46816ad31dde/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
gorm.io/gorm v1.25.7/go.mod h1:hbnx/Oo0ChWMn1BIhpy1oYozzpM15i4YPuHDmfYtwg8=
gorm.io/gorm v1.25.12/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ=
gorm.io/gorm v1.30.0 h1:qbT5aPv1UH8gI99OsRlvDToLxW5zR7FzS9acZDOZcgs=
gorm.io/gorm v1.30.0/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE=
gorm.io/plugin/dbresolver v1.5.3 h1:wFwINGZZmttuu9h7XpvbDHd8Lf9bb8GNzp/NpAMV2wU=
gorm.io/plugin/dbresolver v1.5.3/go.mod h1:TSrVhaUg2DZAWP3PrHlDlITEJmNOkL0tFTjvTEsQ4XE=
gorm.io/hints v1.1.0 h1:Lp4z3rxREufSdxn4qmkK3TLDltrM10FLTHiuqwDPvXw=
gorm.io/hints v1.1.0/go.mod h1:lKQ0JjySsPBj3uslFzY3JhYDtqEwzm+G1hv8rWujB6Y=
gorm.io/plugin/dbresolver v1.6.2 h1:F4b85TenghUeITqe3+epPSUtHH7RIk3fXr5l83DF8Pc=
gorm.io/plugin/dbresolver v1.6.2/go.mod h1:tctw63jdrOezFR9HmrKnPkmig3m5Edem9fdxk9bQSzM=
gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=

View File

@ -1,6 +1,9 @@
package biz
import "github.com/google/wire"
import (
"github.com/google/wire"
"kra/internal/biz/system"
)
// ProviderSet is biz providers.
var ProviderSet = wire.NewSet(NewAdminUsecase)
var ProviderSet = wire.NewSet(system.NewUserUsecase)

233
internal/biz/system/user.go Normal file
View File

@ -0,0 +1,233 @@
package system
import (
"context"
"encoding/json"
"errors"
"time"
"github.com/google/uuid"
"golang.org/x/crypto/bcrypt"
)
var (
ErrUserNotFound = errors.New("用户不存在")
ErrUserAlreadyExists = errors.New("用户名已注册")
ErrPasswordWrong = errors.New("密码错误")
ErrOldPasswordWrong = errors.New("原密码错误")
ErrUserNoAuthority = errors.New("该用户无此角色")
ErrDefaultRouterEmpty = errors.New("找不到默认路由,无法切换本角色")
)
// User 用户实体
type User struct {
ID uint
UUID uuid.UUID
Username string
Password string
NickName string
SideMode string
HeaderImg string
BaseColor string
AuthorityId uint
Phone string
Email string
Enable int
OriginSetting json.RawMessage
Authority *Authority
Authorities []*Authority
CreatedAt time.Time
UpdatedAt time.Time
}
// Authority 角色实体
type Authority struct {
AuthorityId uint
AuthorityName string
ParentId *uint
DefaultRouter string
}
// UserRepo 用户仓储接口
type UserRepo interface {
Create(ctx context.Context, user *User) error
Update(ctx context.Context, user *User) error
UpdateSelf(ctx context.Context, user *User) error
UpdateSelfSetting(ctx context.Context, id uint, setting json.RawMessage) error
Delete(ctx context.Context, id uint) error
FindByID(ctx context.Context, id uint) (*User, error)
FindByIDWithAuthorities(ctx context.Context, id uint) (*User, error)
FindByUUID(ctx context.Context, uuid string) (*User, error)
FindByUUIDWithAuthorities(ctx context.Context, uuid string) (*User, error)
FindByUsername(ctx context.Context, username string) (*User, error)
FindByUsernameWithAuthorities(ctx context.Context, username string) (*User, error)
List(ctx context.Context, page, pageSize int, filters map[string]string) ([]*User, int64, error)
UpdatePassword(ctx context.Context, id uint, password string) error
UpdateAuthorityID(ctx context.Context, id uint, authorityId uint) error
SetUserAuthorities(ctx context.Context, adminAuthorityID, userId uint, authorityIds []uint) error
CheckUserHasAuthority(ctx context.Context, userId, authorityId uint) (bool, error)
GetAuthorityMenuRouters(ctx context.Context, authorityId uint) ([]string, error)
GetAuthorityDefaultRouter(ctx context.Context, authorityId uint) (string, error)
}
// UserUsecase 用户用例
type UserUsecase struct {
repo UserRepo
}
// NewUserUsecase 创建用户用例
func NewUserUsecase(repo UserRepo) *UserUsecase {
return &UserUsecase{repo: repo}
}
// Register 用户注册
func (uc *UserUsecase) Register(ctx context.Context, user *User) (*User, error) {
// 检查用户名是否已存在
existing, _ := uc.repo.FindByUsername(ctx, user.Username)
if existing != nil {
return nil, ErrUserAlreadyExists
}
// 密码加密
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(user.Password), bcrypt.DefaultCost)
if err != nil {
return nil, err
}
user.Password = string(hashedPassword)
user.UUID = uuid.New()
if err := uc.repo.Create(ctx, user); err != nil {
return nil, err
}
return user, nil
}
// Login 用户登录预加载Authorities
func (uc *UserUsecase) Login(ctx context.Context, username, password string) (*User, error) {
user, err := uc.repo.FindByUsernameWithAuthorities(ctx, username)
if err != nil {
return nil, ErrUserNotFound
}
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil {
return nil, ErrPasswordWrong
}
return user, nil
}
// ChangePassword 修改密码
func (uc *UserUsecase) ChangePassword(ctx context.Context, id uint, oldPassword, newPassword string) error {
user, err := uc.repo.FindByID(ctx, id)
if err != nil {
return ErrUserNotFound
}
if err := bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(oldPassword)); err != nil {
return ErrOldPasswordWrong
}
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost)
if err != nil {
return err
}
return uc.repo.UpdatePassword(ctx, id, string(hashedPassword))
}
// ResetPassword 重置密码
func (uc *UserUsecase) ResetPassword(ctx context.Context, id uint, newPassword string) error {
hashedPassword, err := bcrypt.GenerateFromPassword([]byte(newPassword), bcrypt.DefaultCost)
if err != nil {
return err
}
return uc.repo.UpdatePassword(ctx, id, string(hashedPassword))
}
// GetUserInfo 获取用户信息预加载Authorities
func (uc *UserUsecase) GetUserInfo(ctx context.Context, uuid string) (*User, error) {
return uc.repo.FindByUUIDWithAuthorities(ctx, uuid)
}
// GetUserByID 通过ID获取用户
func (uc *UserUsecase) GetUserByID(ctx context.Context, id uint) (*User, error) {
return uc.repo.FindByID(ctx, id)
}
// FindUserById 通过ID获取用户GVA兼容
func (uc *UserUsecase) FindUserById(ctx context.Context, id uint) (*User, error) {
return uc.repo.FindByID(ctx, id)
}
// FindUserByUuid 通过UUID获取用户GVA兼容
func (uc *UserUsecase) FindUserByUuid(ctx context.Context, uuid string) (*User, error) {
return uc.repo.FindByUUID(ctx, uuid)
}
// GetUserList 获取用户列表
func (uc *UserUsecase) GetUserList(ctx context.Context, page, pageSize int, filters map[string]string) ([]*User, int64, error) {
return uc.repo.List(ctx, page, pageSize, filters)
}
// SetUserInfo 设置用户信息(管理员用)
func (uc *UserUsecase) SetUserInfo(ctx context.Context, user *User) error {
return uc.repo.Update(ctx, user)
}
// SetSelfInfo 设置自己的信息(用户用)
func (uc *UserUsecase) SetSelfInfo(ctx context.Context, user *User) error {
return uc.repo.UpdateSelf(ctx, user)
}
// SetSelfSetting 设置自己的配置
func (uc *UserUsecase) SetSelfSetting(ctx context.Context, id uint, setting json.RawMessage) error {
return uc.repo.UpdateSelfSetting(ctx, id, setting)
}
// DeleteUser 删除用户
func (uc *UserUsecase) DeleteUser(ctx context.Context, id uint) error {
return uc.repo.Delete(ctx, id)
}
// SetUserAuthority 设置用户角色(切换角色)
func (uc *UserUsecase) SetUserAuthority(ctx context.Context, id uint, authorityId uint) error {
// 检查用户是否拥有该角色
hasAuthority, err := uc.repo.CheckUserHasAuthority(ctx, id, authorityId)
if err != nil {
return err
}
if !hasAuthority {
return ErrUserNoAuthority
}
// 获取角色的默认路由
defaultRouter, err := uc.repo.GetAuthorityDefaultRouter(ctx, authorityId)
if err != nil {
return err
}
// 获取角色的菜单路由列表
menuRouters, err := uc.repo.GetAuthorityMenuRouters(ctx, authorityId)
if err != nil {
return err
}
// 检查默认路由是否在菜单中
hasMenu := false
for _, router := range menuRouters {
if router == defaultRouter {
hasMenu = true
break
}
}
if !hasMenu {
return ErrDefaultRouterEmpty
}
return uc.repo.UpdateAuthorityID(ctx, id, authorityId)
}
// SetUserAuthorities 设置用户多角色
func (uc *UserUsecase) SetUserAuthorities(ctx context.Context, adminAuthorityID, userId uint, authorityIds []uint) error {
return uc.repo.SetUserAuthorities(ctx, adminAuthorityID, userId, authorityIds)
}

View File

@ -28,6 +28,8 @@ type SysUser struct {
Email *string `gorm:"column:email;type:varchar(191);comment:用户邮箱" json:"email"` // 用户邮箱
Enable *int64 `gorm:"column:enable;type:bigint(20);default:1;comment:用户是否被冻结 1正常 2冻结" json:"enable"` // 用户是否被冻结 1正常 2冻结
OriginSetting *string `gorm:"column:origin_setting;type:text;comment:配置" json:"origin_setting"` // 配置
Authority SysAuthority `gorm:"foreignKey:AuthorityID;references:AuthorityID" json:"authority"`
Authorities []SysAuthority `gorm:"joinForeignKey:SysUserID;joinReferences:SysAuthorityAuthorityID;many2many:sys_user_authority" json:"authorities"`
}
// TableName SysUser's table name

View File

@ -42,6 +42,17 @@ func newSysUser(db *gorm.DB, opts ...gen.DOOption) sysUser {
_sysUser.Email = field.NewString(tableName, "email")
_sysUser.Enable = field.NewInt64(tableName, "enable")
_sysUser.OriginSetting = field.NewString(tableName, "origin_setting")
_sysUser.Authority = sysUserHasOneAuthority{
db: db.Session(&gorm.Session{}),
RelationField: field.NewRelation("Authority", "model.SysAuthority"),
}
_sysUser.Authorities = sysUserManyToManyAuthorities{
db: db.Session(&gorm.Session{}),
RelationField: field.NewRelation("Authorities", "model.SysAuthority"),
}
_sysUser.fillFieldMap()
@ -66,6 +77,9 @@ type sysUser struct {
Email field.String // 用户邮箱
Enable field.Int64 // 用户是否被冻结 1正常 2冻结
OriginSetting field.String // 配置
Authority sysUserHasOneAuthority
Authorities sysUserManyToManyAuthorities
fieldMap map[string]field.Expr
}
@ -120,7 +134,7 @@ func (s *sysUser) GetFieldByName(fieldName string) (field.OrderExpr, bool) {
}
func (s *sysUser) fillFieldMap() {
s.fieldMap = make(map[string]field.Expr, 14)
s.fieldMap = make(map[string]field.Expr, 16)
s.fieldMap["id"] = s.ID
s.fieldMap["created_at"] = s.CreatedAt
s.fieldMap["updated_at"] = s.UpdatedAt
@ -135,18 +149,187 @@ func (s *sysUser) fillFieldMap() {
s.fieldMap["email"] = s.Email
s.fieldMap["enable"] = s.Enable
s.fieldMap["origin_setting"] = s.OriginSetting
}
func (s sysUser) clone(db *gorm.DB) sysUser {
s.sysUserDo.ReplaceConnPool(db.Statement.ConnPool)
s.Authority.db = db.Session(&gorm.Session{Initialized: true})
s.Authority.db.Statement.ConnPool = db.Statement.ConnPool
s.Authorities.db = db.Session(&gorm.Session{Initialized: true})
s.Authorities.db.Statement.ConnPool = db.Statement.ConnPool
return s
}
func (s sysUser) replaceDB(db *gorm.DB) sysUser {
s.sysUserDo.ReplaceDB(db)
s.Authority.db = db.Session(&gorm.Session{})
s.Authorities.db = db.Session(&gorm.Session{})
return s
}
type sysUserHasOneAuthority struct {
db *gorm.DB
field.RelationField
}
func (a sysUserHasOneAuthority) Where(conds ...field.Expr) *sysUserHasOneAuthority {
if len(conds) == 0 {
return &a
}
exprs := make([]clause.Expression, 0, len(conds))
for _, cond := range conds {
exprs = append(exprs, cond.BeCond().(clause.Expression))
}
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
return &a
}
func (a sysUserHasOneAuthority) WithContext(ctx context.Context) *sysUserHasOneAuthority {
a.db = a.db.WithContext(ctx)
return &a
}
func (a sysUserHasOneAuthority) Session(session *gorm.Session) *sysUserHasOneAuthority {
a.db = a.db.Session(session)
return &a
}
func (a sysUserHasOneAuthority) Model(m *model.SysUser) *sysUserHasOneAuthorityTx {
return &sysUserHasOneAuthorityTx{a.db.Model(m).Association(a.Name())}
}
func (a sysUserHasOneAuthority) Unscoped() *sysUserHasOneAuthority {
a.db = a.db.Unscoped()
return &a
}
type sysUserHasOneAuthorityTx struct{ tx *gorm.Association }
func (a sysUserHasOneAuthorityTx) Find() (result *model.SysAuthority, err error) {
return result, a.tx.Find(&result)
}
func (a sysUserHasOneAuthorityTx) Append(values ...*model.SysAuthority) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Append(targetValues...)
}
func (a sysUserHasOneAuthorityTx) Replace(values ...*model.SysAuthority) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Replace(targetValues...)
}
func (a sysUserHasOneAuthorityTx) Delete(values ...*model.SysAuthority) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Delete(targetValues...)
}
func (a sysUserHasOneAuthorityTx) Clear() error {
return a.tx.Clear()
}
func (a sysUserHasOneAuthorityTx) Count() int64 {
return a.tx.Count()
}
func (a sysUserHasOneAuthorityTx) Unscoped() *sysUserHasOneAuthorityTx {
a.tx = a.tx.Unscoped()
return &a
}
type sysUserManyToManyAuthorities struct {
db *gorm.DB
field.RelationField
}
func (a sysUserManyToManyAuthorities) Where(conds ...field.Expr) *sysUserManyToManyAuthorities {
if len(conds) == 0 {
return &a
}
exprs := make([]clause.Expression, 0, len(conds))
for _, cond := range conds {
exprs = append(exprs, cond.BeCond().(clause.Expression))
}
a.db = a.db.Clauses(clause.Where{Exprs: exprs})
return &a
}
func (a sysUserManyToManyAuthorities) WithContext(ctx context.Context) *sysUserManyToManyAuthorities {
a.db = a.db.WithContext(ctx)
return &a
}
func (a sysUserManyToManyAuthorities) Session(session *gorm.Session) *sysUserManyToManyAuthorities {
a.db = a.db.Session(session)
return &a
}
func (a sysUserManyToManyAuthorities) Model(m *model.SysUser) *sysUserManyToManyAuthoritiesTx {
return &sysUserManyToManyAuthoritiesTx{a.db.Model(m).Association(a.Name())}
}
func (a sysUserManyToManyAuthorities) Unscoped() *sysUserManyToManyAuthorities {
a.db = a.db.Unscoped()
return &a
}
type sysUserManyToManyAuthoritiesTx struct{ tx *gorm.Association }
func (a sysUserManyToManyAuthoritiesTx) Find() (result []*model.SysAuthority, err error) {
return result, a.tx.Find(&result)
}
func (a sysUserManyToManyAuthoritiesTx) Append(values ...*model.SysAuthority) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Append(targetValues...)
}
func (a sysUserManyToManyAuthoritiesTx) Replace(values ...*model.SysAuthority) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Replace(targetValues...)
}
func (a sysUserManyToManyAuthoritiesTx) Delete(values ...*model.SysAuthority) (err error) {
targetValues := make([]interface{}, len(values))
for i, v := range values {
targetValues[i] = v
}
return a.tx.Delete(targetValues...)
}
func (a sysUserManyToManyAuthoritiesTx) Clear() error {
return a.tx.Clear()
}
func (a sysUserManyToManyAuthoritiesTx) Count() int64 {
return a.tx.Count()
}
func (a sysUserManyToManyAuthoritiesTx) Unscoped() *sysUserManyToManyAuthoritiesTx {
a.tx = a.tx.Unscoped()
return &a
}
type sysUserDo struct{ gen.DO }
type ISysUserDo interface {

View File

@ -73,11 +73,9 @@ func (r *userRepo) UpdateSelfSetting(ctx context.Context, id uint, setting json.
func (r *userRepo) Delete(ctx context.Context, id uint) error {
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
// 删除用户
if err := tx.Where("id = ?", id).Delete(&model.SysUser{}).Error; err != nil {
return err
}
// 删除用户角色关联
if err := tx.Where("sys_user_id = ?", id).Delete(&model.SysUserAuthority{}).Error; err != nil {
return err
}
@ -94,16 +92,15 @@ func (r *userRepo) FindByID(ctx context.Context, id uint) (*system.User, error)
}
func (r *userRepo) FindByIDWithAuthorities(ctx context.Context, id uint) (*system.User, error) {
var m model.SysUser
err := r.db.WithContext(ctx).
Preload("Authorities").
Preload("Authority").
Where("id = ?", id).
First(&m).Error
m, err := query.SysUser.WithContext(ctx).
Preload(query.SysUser.Authority).
Preload(query.SysUser.Authorities).
Where(query.SysUser.ID.Eq(int64(id))).
First()
if err != nil {
return nil, err
}
return toModelUserWithAuthorities(&m), nil
return toModelUserWithAuthorities(m), nil
}
func (r *userRepo) FindByUUID(ctx context.Context, uuidStr string) (*system.User, error) {
@ -115,16 +112,15 @@ func (r *userRepo) FindByUUID(ctx context.Context, uuidStr string) (*system.User
}
func (r *userRepo) FindByUUIDWithAuthorities(ctx context.Context, uuidStr string) (*system.User, error) {
var m model.SysUser
err := r.db.WithContext(ctx).
Preload("Authorities").
Preload("Authority").
Where("uuid = ?", uuidStr).
First(&m).Error
m, err := query.SysUser.WithContext(ctx).
Preload(query.SysUser.Authority).
Preload(query.SysUser.Authorities).
Where(query.SysUser.UUID.Eq(uuidStr)).
First()
if err != nil {
return nil, err
}
return toModelUserWithAuthorities(&m), nil
return toModelUserWithAuthorities(m), nil
}
func (r *userRepo) FindByUsername(ctx context.Context, username string) (*system.User, error) {
@ -136,49 +132,48 @@ func (r *userRepo) FindByUsername(ctx context.Context, username string) (*system
}
func (r *userRepo) FindByUsernameWithAuthorities(ctx context.Context, username string) (*system.User, error) {
var m model.SysUser
err := r.db.WithContext(ctx).
Preload("Authorities").
Preload("Authority").
Where("username = ?", username).
First(&m).Error
m, err := query.SysUser.WithContext(ctx).
Preload(query.SysUser.Authority).
Preload(query.SysUser.Authorities).
Where(query.SysUser.Username.Eq(username)).
First()
if err != nil {
return nil, err
}
return toModelUserWithAuthorities(&m), nil
return toModelUserWithAuthorities(m), nil
}
func (r *userRepo) List(ctx context.Context, page, pageSize int, filters map[string]string) ([]*system.User, int64, error) {
db := r.db.WithContext(ctx).Model(&model.SysUser{})
u := query.SysUser
q := u.WithContext(ctx)
if v, ok := filters["username"]; ok && v != "" {
db = db.Where("username LIKE ?", "%"+v+"%")
q = q.Where(u.Username.Like("%" + v + "%"))
}
if v, ok := filters["nick_name"]; ok && v != "" {
db = db.Where("nick_name LIKE ?", "%"+v+"%")
q = q.Where(u.NickName.Like("%" + v + "%"))
}
if v, ok := filters["phone"]; ok && v != "" {
db = db.Where("phone LIKE ?", "%"+v+"%")
q = q.Where(u.Phone.Like("%" + v + "%"))
}
if v, ok := filters["email"]; ok && v != "" {
db = db.Where("email LIKE ?", "%"+v+"%")
q = q.Where(u.Email.Like("%" + v + "%"))
}
var total int64
if err := db.Count(&total).Error; err != nil {
total, err := q.Count()
if err != nil {
return nil, 0, err
}
var list []model.SysUser
offset := (page - 1) * pageSize
err := db.Preload("Authorities").Preload("Authority").Offset(offset).Limit(pageSize).Find(&list).Error
list, err := q.Preload(u.Authority).Preload(u.Authorities).Offset(offset).Limit(pageSize).Find()
if err != nil {
return nil, 0, err
}
users := make([]*system.User, len(list))
for i := range list {
users[i] = toModelUserWithAuthorities(&list[i])
users[i] = toModelUserWithAuthorities(list[i])
}
return users, total, nil
}
@ -193,20 +188,16 @@ func (r *userRepo) UpdateAuthorityID(ctx context.Context, id uint, authorityId u
func (r *userRepo) SetUserAuthorities(ctx context.Context, adminAuthorityID, userId uint, authorityIds []uint) error {
return r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
// 查询用户是否存在
var user model.SysUser
if err := tx.Where("id = ?", userId).First(&user).Error; err != nil {
return errors.New("查询用户数据失败")
}
// 删除旧的用户角色关联
if err := tx.Where("sys_user_id = ?", userId).Delete(&model.SysUserAuthority{}).Error; err != nil {
return err
}
// 检查管理员权限并创建新的用户角色关联
for _, aid := range authorityIds {
// 检查管理员是否有权限分配该角色
if err := checkAuthorityIDAuth(tx, adminAuthorityID, aid); err != nil {
return err
}
@ -219,7 +210,6 @@ func (r *userRepo) SetUserAuthorities(ctx context.Context, adminAuthorityID, use
}
}
// 更新用户默认角色
if len(authorityIds) > 0 {
if err := tx.Model(&model.SysUser{}).Where("id = ?", userId).Update("authority_id", authorityIds[0]).Error; err != nil {
return err
@ -229,13 +219,10 @@ func (r *userRepo) SetUserAuthorities(ctx context.Context, adminAuthorityID, use
})
}
// checkAuthorityIDAuth 检查管理员是否有权限分配该角色
func checkAuthorityIDAuth(tx *gorm.DB, adminAuthorityID, targetAuthorityID uint) error {
// 如果是超级管理员(888),直接通过
if adminAuthorityID == 888 {
return nil
}
// 检查目标角色是否是管理员的子角色
var authority model.SysAuthority
if err := tx.Where("authority_id = ? AND parent_id = ?", targetAuthorityID, adminAuthorityID).First(&authority).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
@ -255,7 +242,6 @@ func (r *userRepo) CheckUserHasAuthority(ctx context.Context, userId, authorityI
}
func (r *userRepo) GetAuthorityMenuRouters(ctx context.Context, authorityId uint) ([]string, error) {
// 获取角色的菜单ID列表
var authorityMenus []model.SysAuthorityMenu
if err := r.db.WithContext(ctx).Where("sys_authority_authority_id = ?", authorityId).Find(&authorityMenus).Error; err != nil {
return nil, err
@ -265,13 +251,11 @@ func (r *userRepo) GetAuthorityMenuRouters(ctx context.Context, authorityId uint
return []string{}, nil
}
// 获取菜单ID
menuIDs := make([]string, len(authorityMenus))
menuIDs := make([]int64, len(authorityMenus))
for i, am := range authorityMenus {
menuIDs[i] = am.MenuID
menuIDs[i] = am.SysBaseMenuID
}
// 获取菜单的name(路由)
var menus []model.SysBaseMenu
if err := r.db.WithContext(ctx).Where("id IN ?", menuIDs).Find(&menus).Error; err != nil {
return nil, err
@ -337,15 +321,9 @@ func toModelUser(m *model.SysUser) *system.User {
if m.NickName != nil {
u.NickName = *m.NickName
}
if m.SideMode != nil {
u.SideMode = *m.SideMode
}
if m.HeaderImg != nil {
u.HeaderImg = *m.HeaderImg
}
if m.BaseColor != nil {
u.BaseColor = *m.BaseColor
}
if m.AuthorityID != nil {
u.AuthorityId = uint(*m.AuthorityID)
}
@ -374,16 +352,14 @@ func toModelUserWithAuthorities(m *model.SysUser) *system.User {
u := toModelUser(m)
// 转换Authority
if m.Authority != nil {
u.Authority = &system.Authority{
AuthorityId: uint(m.Authority.AuthorityID),
AuthorityName: safeString(m.Authority.AuthorityName),
DefaultRouter: safeString(m.Authority.DefaultRouter),
}
if m.Authority.ParentID != nil {
pid := uint(*m.Authority.ParentID)
u.Authority.ParentId = &pid
}
u.Authority = &system.Authority{
AuthorityId: uint(m.Authority.AuthorityID),
AuthorityName: safeString(m.Authority.AuthorityName),
DefaultRouter: safeString(m.Authority.DefaultRouter),
}
if m.Authority.ParentID != nil {
pid := uint(*m.Authority.ParentID)
u.Authority.ParentId = &pid
}
// 转换Authorities

View File

@ -3,4 +3,4 @@ package service
import "github.com/google/wire"
// ProviderSet is service providers.
var ProviderSet = wire.NewSet(NewAdminService)
var ProviderSet = wire.NewSet()

View File

@ -0,0 +1,558 @@
package system
import (
"context"
"encoding/json"
"kra/internal/biz/system"
"kra/internal/server/middleware"
"kra/pkg/jwt"
"github.com/go-kratos/kratos/v2/errors"
"github.com/go-kratos/kratos/v2/transport/http"
)
// UserService 用户服务
type UserService struct {
uc *system.UserUsecase
jwtPkg *jwt.JWT
}
// NewUserService 创建用户服务
func NewUserService(uc *system.UserUsecase, jwtPkg *jwt.JWT) *UserService {
return &UserService{uc: uc, jwtPkg: jwtPkg}
}
// LoginRequest 登录请求
type LoginRequest struct {
Username string `json:"username"`
Password string `json:"password"`
Captcha string `json:"captcha"`
CaptchaId string `json:"captchaId"`
}
// LoginResponse 登录响应
type LoginResponse struct {
User *UserInfo `json:"user"`
Token string `json:"token"`
ExpiresAt int64 `json:"expiresAt"`
}
// UserInfo 用户信息
type UserInfo struct {
ID uint `json:"id"`
UUID string `json:"uuid"`
Username string `json:"username"`
NickName string `json:"nickName"`
SideMode string `json:"sideMode"`
HeaderImg string `json:"headerImg"`
BaseColor string `json:"baseColor"`
AuthorityId uint `json:"authorityId"`
Phone string `json:"phone"`
Email string `json:"email"`
Enable int `json:"enable"`
OriginSetting json.RawMessage `json:"originSetting,omitempty"`
Authority *AuthorityInfo `json:"authority,omitempty"`
Authorities []*AuthorityInfo `json:"authorities,omitempty"`
}
// AuthorityInfo 角色信息
type AuthorityInfo struct {
AuthorityId uint `json:"authorityId"`
AuthorityName string `json:"authorityName"`
ParentId *uint `json:"parentId,omitempty"`
DefaultRouter string `json:"defaultRouter"`
}
// Login 用户登录
func (s *UserService) Login(ctx context.Context, req *LoginRequest) (*LoginResponse, error) {
user, err := s.uc.Login(ctx, req.Username, req.Password)
if err != nil {
return nil, errors.Unauthorized("LOGIN_FAILED", err.Error())
}
if user.Enable != 1 {
return nil, errors.Forbidden("USER_DISABLED", "用户被禁止登录")
}
// 生成 JWT token
claims := s.jwtPkg.CreateClaims(jwt.BaseClaims{
UUID: user.UUID.String(),
ID: uint(user.ID),
Username: user.Username,
NickName: user.NickName,
AuthorityID: user.AuthorityId,
})
token, err := s.jwtPkg.CreateToken(claims.BaseClaims)
if err != nil {
return nil, errors.InternalServer("TOKEN_ERROR", "生成token失败")
}
return &LoginResponse{
User: toUserInfo(user),
Token: token,
ExpiresAt: claims.ExpiresAt.UnixMilli(),
}, nil
}
// RegisterRequest 注册请求
type RegisterRequest struct {
Username string `json:"username"`
Password string `json:"password"`
NickName string `json:"nickName"`
HeaderImg string `json:"headerImg"`
AuthorityId uint `json:"authorityId"`
AuthorityIds []uint `json:"authorityIds"`
Phone string `json:"phone"`
Email string `json:"email"`
Enable int `json:"enable"`
}
// Register 用户注册
func (s *UserService) Register(ctx context.Context, req *RegisterRequest) (*UserInfo, error) {
user := &system.User{
Username: req.Username,
Password: req.Password,
NickName: req.NickName,
HeaderImg: req.HeaderImg,
AuthorityId: req.AuthorityId,
Phone: req.Phone,
Email: req.Email,
Enable: req.Enable,
}
created, err := s.uc.Register(ctx, user)
if err != nil {
return nil, errors.BadRequest("REGISTER_FAILED", err.Error())
}
return toUserInfo(created), nil
}
// ChangePasswordRequest 修改密码请求
type ChangePasswordRequest struct {
Password string `json:"password"`
NewPassword string `json:"newPassword"`
}
// ChangePassword 修改密码
func (s *UserService) ChangePassword(ctx context.Context, userID uint, req *ChangePasswordRequest) error {
return s.uc.ChangePassword(ctx, userID, req.Password, req.NewPassword)
}
// ResetPasswordRequest 重置密码请求
type ResetPasswordRequest struct {
ID uint `json:"id"`
Password string `json:"password"`
}
// ResetPassword 重置密码
func (s *UserService) ResetPassword(ctx context.Context, req *ResetPasswordRequest) error {
return s.uc.ResetPassword(ctx, req.ID, req.Password)
}
// GetUserInfo 获取用户信息
func (s *UserService) GetUserInfo(ctx context.Context, uuid string) (*UserInfo, error) {
user, err := s.uc.GetUserInfo(ctx, uuid)
if err != nil {
return nil, errors.NotFound("USER_NOT_FOUND", err.Error())
}
return toUserInfo(user), nil
}
// GetUserListRequest 获取用户列表请求
type GetUserListRequest struct {
Page int `json:"page"`
PageSize int `json:"pageSize"`
Username string `json:"username"`
NickName string `json:"nickName"`
Phone string `json:"phone"`
Email string `json:"email"`
}
// GetUserListResponse 获取用户列表响应
type GetUserListResponse struct {
List []*UserInfo `json:"list"`
Total int64 `json:"total"`
Page int `json:"page"`
PageSize int `json:"pageSize"`
}
// GetUserList 获取用户列表
func (s *UserService) GetUserList(ctx context.Context, req *GetUserListRequest) (*GetUserListResponse, error) {
filters := make(map[string]string)
if req.Username != "" {
filters["username"] = req.Username
}
if req.NickName != "" {
filters["nick_name"] = req.NickName
}
if req.Phone != "" {
filters["phone"] = req.Phone
}
if req.Email != "" {
filters["email"] = req.Email
}
users, total, err := s.uc.GetUserList(ctx, req.Page, req.PageSize, filters)
if err != nil {
return nil, errors.InternalServer("LIST_ERROR", err.Error())
}
list := make([]*UserInfo, len(users))
for i, u := range users {
list[i] = toUserInfo(u)
}
return &GetUserListResponse{
List: list,
Total: total,
Page: req.Page,
PageSize: req.PageSize,
}, nil
}
// SetUserInfoRequest 设置用户信息请求(管理员用)
type SetUserInfoRequest struct {
ID uint `json:"id"`
NickName string `json:"nickName"`
HeaderImg string `json:"headerImg"`
Phone string `json:"phone"`
Email string `json:"email"`
Enable int `json:"enable"`
AuthorityIds []uint `json:"authorityIds"`
}
// SetUserInfo 设置用户信息
func (s *UserService) SetUserInfo(ctx context.Context, req *SetUserInfoRequest) error {
user := &system.User{
ID: req.ID,
NickName: req.NickName,
HeaderImg: req.HeaderImg,
Phone: req.Phone,
Email: req.Email,
Enable: req.Enable,
}
return s.uc.SetUserInfo(ctx, user)
}
// SetSelfInfoRequest 设置自己信息请求(用户用)
type SetSelfInfoRequest struct {
NickName string `json:"nickName"`
HeaderImg string `json:"headerImg"`
Phone string `json:"phone"`
Email string `json:"email"`
SideMode string `json:"sideMode"`
BaseColor string `json:"baseColor"`
}
// SetSelfInfo 设置自己的信息
func (s *UserService) SetSelfInfo(ctx context.Context, userID uint, req *SetSelfInfoRequest) error {
user := &system.User{
ID: userID,
NickName: req.NickName,
HeaderImg: req.HeaderImg,
Phone: req.Phone,
Email: req.Email,
SideMode: req.SideMode,
BaseColor: req.BaseColor,
}
return s.uc.SetSelfInfo(ctx, user)
}
// SetSelfSetting 设置自己的配置
func (s *UserService) SetSelfSetting(ctx context.Context, userID uint, setting json.RawMessage) error {
return s.uc.SetSelfSetting(ctx, userID, setting)
}
// DeleteUser 删除用户
func (s *UserService) DeleteUser(ctx context.Context, id uint) error {
return s.uc.DeleteUser(ctx, id)
}
// SetUserAuthorityRequest 设置用户角色请求
type SetUserAuthorityRequest struct {
AuthorityId uint `json:"authorityId"`
}
// SetUserAuthority 设置用户角色(切换角色)
func (s *UserService) SetUserAuthority(ctx context.Context, userID uint, req *SetUserAuthorityRequest) error {
return s.uc.SetUserAuthority(ctx, userID, req.AuthorityId)
}
// SetUserAuthoritiesRequest 设置用户多角色请求
type SetUserAuthoritiesRequest struct {
ID uint `json:"id"`
AuthorityIds []uint `json:"authorityIds"`
}
// SetUserAuthorities 设置用户多角色
func (s *UserService) SetUserAuthorities(ctx context.Context, adminAuthorityID uint, req *SetUserAuthoritiesRequest) error {
return s.uc.SetUserAuthorities(ctx, adminAuthorityID, req.ID, req.AuthorityIds)
}
// 转换函数
func toUserInfo(u *system.User) *UserInfo {
info := &UserInfo{
ID: u.ID,
UUID: u.UUID.String(),
Username: u.Username,
NickName: u.NickName,
SideMode: u.SideMode,
HeaderImg: u.HeaderImg,
BaseColor: u.BaseColor,
AuthorityId: u.AuthorityId,
Phone: u.Phone,
Email: u.Email,
Enable: u.Enable,
OriginSetting: u.OriginSetting,
}
if u.Authority != nil {
info.Authority = &AuthorityInfo{
AuthorityId: u.Authority.AuthorityId,
AuthorityName: u.Authority.AuthorityName,
ParentId: u.Authority.ParentId,
DefaultRouter: u.Authority.DefaultRouter,
}
}
if len(u.Authorities) > 0 {
info.Authorities = make([]*AuthorityInfo, len(u.Authorities))
for i, a := range u.Authorities {
info.Authorities[i] = &AuthorityInfo{
AuthorityId: a.AuthorityId,
AuthorityName: a.AuthorityName,
ParentId: a.ParentId,
DefaultRouter: a.DefaultRouter,
}
}
}
return info
}
// RegisterRoutes 注册路由
func (s *UserService) RegisterRoutes(srv *http.Server) {
r := srv.Route("/")
// 公开接口
r.POST("/base/login", s.handleLogin)
// 需要认证的接口
r.POST("/user/register", s.handleRegister)
r.POST("/user/changePassword", s.handleChangePassword)
r.POST("/user/resetPassword", s.handleResetPassword)
r.GET("/user/getUserInfo", s.handleGetUserInfo)
r.POST("/user/getUserList", s.handleGetUserList)
r.PUT("/user/setUserInfo", s.handleSetUserInfo)
r.PUT("/user/setSelfInfo", s.handleSetSelfInfo)
r.PUT("/user/setSelfSetting", s.handleSetSelfSetting)
r.DELETE("/user/deleteUser", s.handleDeleteUser)
r.POST("/user/setUserAuthority", s.handleSetUserAuthority)
r.POST("/user/setUserAuthorities", s.handleSetUserAuthorities)
}
// HTTP Handlers
func (s *UserService) handleLogin(ctx http.Context) error {
var req LoginRequest
if err := ctx.Bind(&req); err != nil {
return err
}
resp, err := s.Login(ctx, &req)
if err != nil {
return err
}
return ctx.Result(200, map[string]any{
"code": 0,
"msg": "登录成功",
"data": resp,
})
}
func (s *UserService) handleRegister(ctx http.Context) error {
var req RegisterRequest
if err := ctx.Bind(&req); err != nil {
return err
}
resp, err := s.Register(ctx, &req)
if err != nil {
return err
}
return ctx.Result(200, map[string]any{
"code": 0,
"msg": "注册成功",
"data": resp,
})
}
func (s *UserService) handleChangePassword(ctx http.Context) error {
var req ChangePasswordRequest
if err := ctx.Bind(&req); err != nil {
return err
}
userID := middleware.GetUserID(ctx)
if userID == 0 {
return errors.Unauthorized("UNAUTHORIZED", "请先登录")
}
if err := s.ChangePassword(ctx, userID, &req); err != nil {
return err
}
return ctx.Result(200, map[string]any{
"code": 0,
"msg": "修改成功",
})
}
func (s *UserService) handleResetPassword(ctx http.Context) error {
var req ResetPasswordRequest
if err := ctx.Bind(&req); err != nil {
return err
}
if err := s.ResetPassword(ctx, &req); err != nil {
return err
}
return ctx.Result(200, map[string]any{
"code": 0,
"msg": "重置成功",
})
}
func (s *UserService) handleGetUserInfo(ctx http.Context) error {
claims, ok := middleware.GetClaims(ctx)
if !ok {
return errors.Unauthorized("UNAUTHORIZED", "请先登录")
}
resp, err := s.GetUserInfo(ctx, claims.UUID)
if err != nil {
return err
}
return ctx.Result(200, map[string]any{
"code": 0,
"msg": "获取成功",
"data": map[string]any{"userInfo": resp},
})
}
func (s *UserService) handleGetUserList(ctx http.Context) error {
var req GetUserListRequest
if err := ctx.Bind(&req); err != nil {
return err
}
resp, err := s.GetUserList(ctx, &req)
if err != nil {
return err
}
return ctx.Result(200, map[string]any{
"code": 0,
"msg": "获取成功",
"data": resp,
})
}
func (s *UserService) handleSetUserInfo(ctx http.Context) error {
var req SetUserInfoRequest
if err := ctx.Bind(&req); err != nil {
return err
}
if err := s.SetUserInfo(ctx, &req); err != nil {
return err
}
return ctx.Result(200, map[string]any{
"code": 0,
"msg": "设置成功",
})
}
func (s *UserService) handleSetSelfInfo(ctx http.Context) error {
var req SetSelfInfoRequest
if err := ctx.Bind(&req); err != nil {
return err
}
userID := middleware.GetUserID(ctx)
if userID == 0 {
return errors.Unauthorized("UNAUTHORIZED", "请先登录")
}
if err := s.SetSelfInfo(ctx, userID, &req); err != nil {
return err
}
return ctx.Result(200, map[string]any{
"code": 0,
"msg": "设置成功",
})
}
func (s *UserService) handleSetSelfSetting(ctx http.Context) error {
var req json.RawMessage
if err := ctx.Bind(&req); err != nil {
return err
}
userID := middleware.GetUserID(ctx)
if userID == 0 {
return errors.Unauthorized("UNAUTHORIZED", "请先登录")
}
if err := s.SetSelfSetting(ctx, userID, req); err != nil {
return err
}
return ctx.Result(200, map[string]any{
"code": 0,
"msg": "设置成功",
})
}
func (s *UserService) handleDeleteUser(ctx http.Context) error {
var req struct {
ID uint `json:"id"`
}
if err := ctx.Bind(&req); err != nil {
return err
}
// 不能删除自己
userID := middleware.GetUserID(ctx)
if userID == req.ID {
return errors.BadRequest("DELETE_SELF", "删除失败, 无法删除自己")
}
if err := s.DeleteUser(ctx, req.ID); err != nil {
return err
}
return ctx.Result(200, map[string]any{
"code": 0,
"msg": "删除成功",
})
}
func (s *UserService) handleSetUserAuthority(ctx http.Context) error {
var req SetUserAuthorityRequest
if err := ctx.Bind(&req); err != nil {
return err
}
userID := middleware.GetUserID(ctx)
if userID == 0 {
return errors.Unauthorized("UNAUTHORIZED", "请先登录")
}
if err := s.SetUserAuthority(ctx, userID, &req); err != nil {
return err
}
return ctx.Result(200, map[string]any{
"code": 0,
"msg": "修改成功",
})
}
func (s *UserService) handleSetUserAuthorities(ctx http.Context) error {
var req SetUserAuthoritiesRequest
if err := ctx.Bind(&req); err != nil {
return err
}
adminAuthorityID := middleware.GetAuthorityID(ctx)
if adminAuthorityID == 0 {
return errors.Unauthorized("UNAUTHORIZED", "请先登录")
}
if err := s.SetUserAuthorities(ctx, adminAuthorityID, &req); err != nil {
return err
}
return ctx.Result(200, map[string]any{
"code": 0,
"msg": "修改成功",
})
}