diff --git a/backend/app/http/provider.gen.go b/backend/app/http/provider.gen.go index 868b553..21ec8ca 100755 --- a/backend/app/http/provider.gen.go +++ b/backend/app/http/provider.gen.go @@ -57,11 +57,13 @@ func Provide(opts ...opt.Option) error { auth *auth, pays *pays, posts *posts, + users *users, ) (contracts.HttpRoute, error) { obj := &Routes{ auth: auth, pays: pays, posts: posts, + users: users, } if err := obj.Prepare(); err != nil { return nil, err @@ -71,5 +73,12 @@ func Provide(opts ...opt.Option) error { }, atom.GroupRoutes); err != nil { return err } + if err := container.Container.Provide(func() (*users, error) { + obj := &users{} + + return obj, nil + }); err != nil { + return err + } return nil } diff --git a/backend/app/http/routes.gen.go b/backend/app/http/routes.gen.go index 19b7c99..3168d6d 100644 --- a/backend/app/http/routes.gen.go +++ b/backend/app/http/routes.gen.go @@ -18,6 +18,7 @@ type Routes struct { auth *auth pays *pays posts *posts + users *users } func (r *Routes) Prepare() error { @@ -82,4 +83,16 @@ func (r *Routes) Register(router fiber.Router) { Local[*model.Users]("user"), )) + // 注册路由组: users + router.Get("/users/profile", DataFunc1( + r.users.Profile, + Local[*model.Users]("user"), + )) + + router.Put("/users/username", Func2( + r.users.Update, + Local[*model.Users]("user"), + Body[ProfileForm]("form"), + )) + } diff --git a/backend/app/http/users.go b/backend/app/http/users.go new file mode 100644 index 0000000..17624a2 --- /dev/null +++ b/backend/app/http/users.go @@ -0,0 +1,54 @@ +package http + +import ( + "strings" + "time" + + "quyun/app/models" + "quyun/database/schemas/public/model" + + "github.com/gofiber/fiber/v3" +) + +// @provider +type users struct{} + +type UserInfo struct { + ID int64 `json:"id,omitempty"` + CreatedAt time.Time `json:"created_at,omitempty"` + Username string `json:"username,omitempty"` +} + +// @Router /users/profile [get] +// @Bind user local +func (ctl *users) Profile(ctx fiber.Ctx, user *model.Users) (*UserInfo, error) { + return &UserInfo{ + ID: user.ID, + CreatedAt: user.CreatedAt, + Username: user.Username, + }, nil +} + +type ProfileForm struct { + Username string `json:"username" validate:"required"` +} + +// Update +// @Router /users/username [put] +// @Bind user local +// @Bind form body +func (ctl *users) Update(ctx fiber.Ctx, user *model.Users, form *ProfileForm) error { + username := strings.TrimSpace(form.Username) + if len([]rune(username)) > 12 { + return fiber.NewError(fiber.StatusBadRequest, "Username exceeds maximum length of 12 characters") + } + + if username == "" { + return fiber.NewError(fiber.StatusBadRequest, "Username cannot be empty") + } + + if err := models.Users.UpdateUsername(ctx.Context(), user.ID, username); err != nil { + return err + } + return nil +} diff --git a/backend/app/models/users.go b/backend/app/models/users.go index 1648ae6..198cc51 100644 --- a/backend/app/models/users.go +++ b/backend/app/models/users.go @@ -343,3 +343,21 @@ func (m *usersModel) Count(ctx context.Context, cond BoolExpression) (int64, err return cnt.Cnt, nil } + +// UpdateUsername +func (m *usersModel) UpdateUsername(ctx context.Context, id int64, username string) error { + tbl := table.Users + stmt := tbl. + UPDATE(tbl.Username). + SET(String(username)). + WHERE( + tbl.ID.EQ(Int64(id)), + ) + m.log.Infof("sql: %s", stmt.DebugSql()) + + if _, err := stmt.ExecContext(ctx, db); err != nil { + m.log.Errorf("error updating username: %v", err) + return err + } + return nil +} diff --git a/backend/main_test.go b/backend/main_test.go index 10a8158..f63365a 100644 --- a/backend/main_test.go +++ b/backend/main_test.go @@ -27,3 +27,11 @@ func Test_hassID(t *testing.T) { }) }) } + +func Test_username(t *testing.T) { + Convey("test_username", t, func() { + Convey("step 1", func() { + t.Logf("length: %s", len("你好")) + }) + }) +} diff --git a/backend/test.http b/backend/test.http index 12fa3f9..3d2fe4c 100644 --- a/backend/test.http +++ b/backend/test.http @@ -75,4 +75,8 @@ Authorization: {{token}} ### get statistics GET {{host}}/v1/admin/statistics HTTP/1.1 +Authorization: {{token}} + +### get user profile +GET {{host}}/v1/users/profile HTTP/1.1 Authorization: {{token}} \ No newline at end of file diff --git a/frontend/wechat/src/api/userApi.js b/frontend/wechat/src/api/userApi.js new file mode 100644 index 0000000..e67037d --- /dev/null +++ b/frontend/wechat/src/api/userApi.js @@ -0,0 +1,10 @@ +import client from './client'; + +export const userApi = { + profile() { + return client.get(`/users/profile`); + }, + update(profile) { + return client.put(`/users/profile`, { username: profile.username }); + }, +} \ No newline at end of file diff --git a/frontend/wechat/src/api/user_profile.json b/frontend/wechat/src/api/user_profile.json new file mode 100644 index 0000000..95938d7 --- /dev/null +++ b/frontend/wechat/src/api/user_profile.json @@ -0,0 +1,5 @@ +{ + "id": 1, + "created_at": "2025-04-15T20:53:07.107819Z", + "username": "u_K6YDZTMc" +} \ No newline at end of file diff --git a/frontend/wechat/src/views/UserProfile.vue b/frontend/wechat/src/views/UserProfile.vue index cccd260..88ff74b 100644 --- a/frontend/wechat/src/views/UserProfile.vue +++ b/frontend/wechat/src/views/UserProfile.vue @@ -1,29 +1,74 @@ - - - - - - - {{ userInfo.name }} - - - - {{ item }} - + + + + + + {{ userInfo.username }} + ID: {{ userInfo.id }} + + + + {{ group.title }} + + + + {{ item.label }} + › + + + + +