From 6277ab0c4c7ea61c0b7fb82509ba6eee576c065f Mon Sep 17 00:00:00 2001 From: veypi Date: Tue, 13 May 2025 17:19:11 +0800 Subject: [PATCH] feat: update app resouce --- api/app/app.go | 94 ++++++++++++++++++------------- api/app/app_user.go | 100 --------------------------------- api/app/app_user/create.go | 34 ++++++++++++ api/app/app_user/del.go | 36 ++++++++++++ api/app/app_user/get.go | 26 +++++++++ api/app/app_user/init.go | 14 +++++ api/app/app_user/list.go | 52 ++++++++++++++++++ api/app/app_user/patch.go | 40 ++++++++++++++ api/app/init.go | 17 +++--- api/app/resource.go | 91 ------------------------------ api/app/resource/create.go | 37 +++++++++++++ api/app/resource/del.go | 37 +++++++++++++ api/app/resource/get.go | 26 +++++++++ api/app/resource/init.go | 14 +++++ api/app/resource/list.go | 56 +++++++++++++++++++ api/app/resource/patch.go | 47 ++++++++++++++++ api/app/role.go | 96 -------------------------------- api/app/role/create.go | 37 +++++++++++++ api/app/role/del.go | 38 +++++++++++++ api/app/role/get.go | 26 +++++++++ api/app/role/init.go | 14 +++++ api/app/role/list.go | 62 +++++++++++++++++++++ api/app/role/patch.go | 57 +++++++++++++++++++ models/app.gen.go | 110 ------------------------------------- 24 files changed, 718 insertions(+), 443 deletions(-) delete mode 100644 api/app/app_user.go create mode 100644 api/app/app_user/create.go create mode 100644 api/app/app_user/del.go create mode 100644 api/app/app_user/get.go create mode 100644 api/app/app_user/init.go create mode 100644 api/app/app_user/list.go create mode 100644 api/app/app_user/patch.go delete mode 100644 api/app/resource.go create mode 100644 api/app/resource/create.go create mode 100644 api/app/resource/del.go create mode 100644 api/app/resource/get.go create mode 100644 api/app/resource/init.go create mode 100644 api/app/resource/list.go create mode 100644 api/app/resource/patch.go delete mode 100644 api/app/role.go create mode 100644 api/app/role/create.go create mode 100644 api/app/role/del.go create mode 100644 api/app/role/get.go create mode 100644 api/app/role/init.go create mode 100644 api/app/role/list.go create mode 100644 api/app/role/patch.go delete mode 100644 models/app.gen.go diff --git a/api/app/app.go b/api/app/app.go index fe5f39c..7b2fdb8 100644 --- a/api/app/app.go +++ b/api/app/app.go @@ -6,7 +6,7 @@ import ( "oa/cfg" "oa/errs" "oa/libs/auth" - M "oa/models" + "oa/models" "time" "github.com/veypi/OneBD/rest" @@ -14,20 +14,14 @@ import ( "gorm.io/gorm" ) -func useApp(r rest.Router) { - r.Delete("/:app_id", auth.Check("app", "app_id", auth.DoDelete), appDelete) - r.Get("/:app_id", auth.Check("app", "app_id", auth.DoRead), appGet) - r.Get("/:app_id/key", auth.Check("app", "app_id", auth.DoDelete), appKey) - r.Get("/", appList) - r.Patch("/:app_id", auth.Check("app", "app_id", auth.DoUpdate), appPatch) - r.Post("/", auth.Check("app", "", auth.DoCreate), appPost) -} +var _ = Router.Get("/:app_id/key", auth.Check("app", "app_id", auth.DoDelete), appKey) + func appKey(x *rest.X) (any, error) { id := x.Params.Get("app_id") if id == "" { return nil, errs.ArgsInvalid.WithStr("missing app_id") } - data := &M.App{} + data := &models.App{} data.ID = id key := utils.RandSeq(32) // err := cfg.DB().Where("id = ?", x.Params.GetStr("app_id")).First(data).Error @@ -35,38 +29,40 @@ func appKey(x *rest.X) (any, error) { return key, err } + +var _ = Router.Delete("/:app_id", auth.Check("app", "app_id", auth.DoDelete), appDelete) + func appDelete(x *rest.X) (any, error) { - opts := &M.AppDelete{} - err := x.Parse(opts) - if err != nil { - return nil, err - } - data := &M.App{} + data := &models.App{} - err = cfg.DB().Where("id = ?", opts.ID).Delete(data).Error + err := cfg.DB().Where("id = ?", x.Params.Get("app_id")).Delete(data).Error return data, err } -func appGet(x *rest.X) (any, error) { - opts := &M.AppGet{} - err := x.Parse(opts) - if err != nil { - return nil, err - } - data := &M.App{} - err = cfg.DB().Where("id = ?", opts.ID).First(data).Error +var _ = Router.Get("/:app_id", auth.Check("app", "app_id", auth.DoRead), appGet) + +func appGet(x *rest.X) (any, error) { + data := &models.App{} + err := cfg.DB().Where("id = ?", x.Params.Get("app_id")).First(data).Error return data, err } + +type listOpts struct { + Name *string `json:"name" parse:"query"` +} + +var _ = Router.Get("/", appList) + func appList(x *rest.X) (any, error) { - opts := &M.AppList{} + opts := &listOpts{} err := x.Parse(opts) if err != nil { return nil, err } data := make([]*struct { - M.App + models.App UserStatus string `json:"user_status"` }, 0, 10) token, err := auth.CheckJWT(x) @@ -82,21 +78,27 @@ func appList(x *rest.X) (any, error) { } else { err = cfg.DB().Table("apps").Select("id", "name", "icon").Find(&data).Error } - - // logv.AssertError(cfg.DB().Table("accesses a"). - // Select("a.name, a.t_id, a.level"). - // Joins("INNER JOIN user_roles ur ON ur.role_id = a.role_id AND ur.user_id = ?", refresh.UID). - // Scan(&acList).Error) - return data, err } + +type postOpts struct { + Name string `json:"name" parse:"json"` + Icon string `json:"icon" parse:"json"` + Des *string `json:"des" parse:"json"` + Typ string `json:"typ" parse:"json"` + Status string `json:"status" parse:"json"` + InitUrl string `json:"init_url" parse:"json"` +} + +var _ = Router.Post("/", auth.Check("app", "", auth.DoCreate), appPost) + func appPost(x *rest.X) (any, error) { - opts := &M.AppPost{} + opts := &postOpts{} err := x.Parse(opts) if err != nil { return nil, err } - data := &M.App{} + data := &models.App{} data.Name = opts.Name data.Icon = opts.Icon @@ -113,23 +115,37 @@ func appPost(x *rest.X) (any, error) { if err != nil { return err } - au := &M.AppUser{ + au := &models.AppUser{ AppID: data.ID, UserID: x.Request.Context().Value("uid").(string), - Status: M.AUSTATUS_OK, + Status: models.AUSTATUS_OK, } return tx.Create(au).Error }) return data, err } + +type patchOpts struct { + ID string `json:"id" gorm:"primaryKey;type:varchar(32)" parse:"path@app_id"` + Name *string `json:"name" parse:"json"` + Icon *string `json:"icon" parse:"json"` + Des *string `json:"des" parse:"json"` + Typ *string `json:"typ" gorm:"default:auto" parse:"json"` + InitRoleID *string `json:"init_role_id" gorm:"index;type:varchar(32)" parse:"json"` + Status *string `json:"status" gorm:"default:ok" parse:"json"` + InitUrl *string `json:"init_url" parse:"json"` +} + +var _ = Router.Patch("/:app_id", auth.Check("app", "app_id", auth.DoUpdate), appPatch) + func appPatch(x *rest.X) (any, error) { - opts := &M.AppPatch{} + opts := &patchOpts{} err := x.Parse(opts) if err != nil { return nil, err } - data := &M.App{} + data := &models.App{} err = cfg.DB().Where("id = ?", opts.ID).First(data).Error if err != nil { diff --git a/api/app/app_user.go b/api/app/app_user.go deleted file mode 100644 index 01cc675..0000000 --- a/api/app/app_user.go +++ /dev/null @@ -1,100 +0,0 @@ -package app - -import ( - "oa/cfg" - M "oa/models" - "strings" - - "github.com/google/uuid" - "github.com/veypi/OneBD/rest" -) - -func useAppUser(r rest.Router) { - r.Post("/", appUserPost) - r.Delete("/:user_id", appUserDelete) - r.Get("/:user_id", appUserGet) - r.Get("/", appUserList) - r.Patch("/:user_id", appUserPatch) -} -func appUserPost(x *rest.X) (any, error) { - opts := &M.AppUserPost{} - err := x.Parse(opts) - if err != nil { - return nil, err - } - data := &M.AppUser{} - - data.ID = strings.ReplaceAll(uuid.New().String(), "-", "") - data.AppID = opts.AppID - data.UserID = opts.UserID - data.Status = opts.Status - err = cfg.DB().Create(data).Error - - return data, err -} -func appUserDelete(x *rest.X) (any, error) { - opts := &M.AppUserDelete{} - err := x.Parse(opts) - if err != nil { - return nil, err - } - data := &M.AppUser{} - - err = cfg.DB().Where("id = ?", opts.ID).Delete(data).Error - - return data, err -} -func appUserGet(x *rest.X) (any, error) { - opts := &M.AppUserGet{} - err := x.Parse(opts) - if err != nil { - return nil, err - } - data := &M.AppUser{} - - err = cfg.DB().Where("id = ?", opts.ID).First(data).Error - - return data, err -} -func appUserList(x *rest.X) (any, error) { - opts := &M.AppUserList{} - err := x.Parse(opts) - if err != nil { - return nil, err - } - data := make([]*M.AppUser, 0, 10) - - query := cfg.DB() - if opts.AppID != nil { - query = query.Where("app_id LIKE ?", opts.AppID) - } - if opts.UserID != nil { - query = query.Where("user_id LIKE ?", opts.UserID) - } - if opts.Status != nil { - query = query.Where("status LIKE ?", opts.Status) - } - err = query.Find(&data).Error - - return data, err -} -func appUserPatch(x *rest.X) (any, error) { - opts := &M.AppUserPatch{} - err := x.Parse(opts) - if err != nil { - return nil, err - } - data := &M.AppUser{} - - err = cfg.DB().Where("id = ?", opts.ID).First(data).Error - if err != nil { - return nil, err - } - optsMap := make(map[string]interface{}) - if opts.Status != nil { - optsMap["status"] = opts.Status - } - err = cfg.DB().Model(data).Updates(optsMap).Error - - return data, err -} diff --git a/api/app/app_user/create.go b/api/app/app_user/create.go new file mode 100644 index 0000000..31e66b0 --- /dev/null +++ b/api/app/app_user/create.go @@ -0,0 +1,34 @@ +package app_user + +import ( + "github.com/veypi/OneBD/rest" + "oa/models" + "oa/cfg" +) + +type createOpts struct { + AppID string `parse:"path"` + UserID string `json:"user_id"` + Status string `json:"status" default:"ok"` +} + +var _ = Router.Post("/", createAppUser) + +func createAppUser(x *rest.X) (any, error) { + opts := &createOpts{} + if err := x.Parse(opts); err != nil { + return nil, err + } + + appUser := &models.AppUser{ + AppID: opts.AppID, + UserID: opts.UserID, + Status: opts.Status, + } + + if err := cfg.DB().Create(appUser).Error; err != nil { + return nil, err + } + + return appUser, nil +} diff --git a/api/app/app_user/del.go b/api/app/app_user/del.go new file mode 100644 index 0000000..70f33aa --- /dev/null +++ b/api/app/app_user/del.go @@ -0,0 +1,36 @@ +package app_user + +import ( + "github.com/veypi/OneBD/rest" + "oa/models" + "oa/cfg" +) + +type deleteOpts struct { + AppID string `parse:"path"` + UserID string `parse:"path"` +} + +var _ = Router.Delete("/:user_id", deleteAppUser) + +func deleteAppUser(x *rest.X) (any, error) { + opts := &deleteOpts{} + if err := x.Parse(opts); err != nil { + return nil, err + } + + appUser := &models.AppUser{} + if err := cfg.DB().Where("app_id = ? AND user_id = ?", opts.AppID, opts.UserID).First(appUser).Error; err != nil { + return nil, rest.NewError("app_user not found").WithCode(404) + } + + if err := cfg.DB().Delete(appUser).Error; err != nil { + return nil, err + } + + return map[string]interface{}{ + "message": "app_user deleted successfully", + "app_id": opts.AppID, + "user_id": opts.UserID, + }, nil +} diff --git a/api/app/app_user/get.go b/api/app/app_user/get.go new file mode 100644 index 0000000..4dd6eef --- /dev/null +++ b/api/app/app_user/get.go @@ -0,0 +1,26 @@ +package app_user + +import ( + "github.com/veypi/OneBD/rest" + "oa/models" + "oa/cfg" +) + +var _ = Router.Get("/:user_id", getAppUser) + +func getAppUser(x *rest.X) (any, error) { + appID := x.Params.Get("app_id") + userID := x.Params.Get("user_id") + + if appID == "" || userID == "" { + return nil, rest.NewError("app_id or user_id is empty").WithCode(400) + } + + appUser := &models.AppUser{} + err := cfg.DB().Where("app_id = ? AND user_id = ?", appID, userID).First(appUser).Error + if err != nil { + return nil, rest.NewError("app_user not found").WithCode(404) + } + + return appUser, nil +} diff --git a/api/app/app_user/init.go b/api/app/app_user/init.go new file mode 100644 index 0000000..38900fa --- /dev/null +++ b/api/app/app_user/init.go @@ -0,0 +1,14 @@ +// +// init.go +// Copyright (C) 2025 veypi +// 2025-05-13 16:47 +// Distributed under terms of the MIT license. +// + +package app_user + +import ( + "github.com/veypi/OneBD/rest" +) + +var Router = rest.NewRouter() diff --git a/api/app/app_user/list.go b/api/app/app_user/list.go new file mode 100644 index 0000000..7156622 --- /dev/null +++ b/api/app/app_user/list.go @@ -0,0 +1,52 @@ +package app_user + +import ( + "github.com/veypi/OneBD/rest" + "oa/models" + "oa/cfg" +) + +type listOpts struct { + AppID string `parse:"path"` + Page int `parse:"query" default:"1"` + PageSize int `parse:"query" default:"20"` + Status string `parse:"query" default:""` +} + +type listResponse struct { + Total int64 `json:"total"` + Items []*models.AppUser `json:"items"` +} + +var _ = Router.Get("/", listAppUsers) + +func listAppUsers(x *rest.X) (any, error) { + opts := &listOpts{} + if err := x.Parse(opts); err != nil { + return nil, err + } + + query := cfg.DB().Model(&models.AppUser{}).Where("app_id = ?", opts.AppID) + + if opts.Status != "" { + query = query.Where("status = ?", opts.Status) + } + + var total int64 + if err := query.Count(&total).Error; err != nil { + return nil, err + } + + offset := (opts.Page - 1) * opts.PageSize + query = query.Offset(offset).Limit(opts.PageSize) + + var users []*models.AppUser + if err := query.Find(&users).Error; err != nil { + return nil, err + } + + return &listResponse{ + Total: total, + Items: users, + }, nil +} diff --git a/api/app/app_user/patch.go b/api/app/app_user/patch.go new file mode 100644 index 0000000..6c3198f --- /dev/null +++ b/api/app/app_user/patch.go @@ -0,0 +1,40 @@ +package app_user + +import ( + "github.com/veypi/OneBD/rest" + "oa/models" + "oa/cfg" +) + +type updateOpts struct { + AppID string `parse:"path"` + UserID string `parse:"path"` + Status *string `json:"status"` +} + +var _ = Router.Patch("/:user_id", updateAppUser) + +func updateAppUser(x *rest.X) (any, error) { + opts := &updateOpts{} + if err := x.Parse(opts); err != nil { + return nil, err + } + + appUser := &models.AppUser{} + if err := cfg.DB().Where("app_id = ? AND user_id = ?", opts.AppID, opts.UserID).First(appUser).Error; err != nil { + return nil, rest.NewError("app_user not found").WithCode(404) + } + + updates := map[string]interface{}{} + if opts.Status != nil { + updates["status"] = *opts.Status + } + + if len(updates) > 0 { + if err := cfg.DB().Model(appUser).Updates(updates).Error; err != nil { + return nil, err + } + } + + return appUser, nil +} diff --git a/api/app/init.go b/api/app/init.go index f171bde..4078265 100644 --- a/api/app/init.go +++ b/api/app/init.go @@ -8,14 +8,17 @@ package app import ( + "oa/api/app/app_user" + "oa/api/app/resource" + "oa/api/user/role" + "github.com/veypi/OneBD/rest" ) var Router = rest.NewRouter() -func init() { - r := Router - useApp(r) - useAppUser(r.SubRouter(":app_id/user")) - useResource(r.SubRouter(":app_id/resource")) - useRole(r.SubRouter(":app_id/role")) -} +var appRouter = Router.SubRouter(":app_id") +var ( + _ = appRouter.Extend("resource",resource.Router) + _ = appRouter.Extend("user", app_user.Router) + _ = appRouter.Extend("role", role.Router) +) diff --git a/api/app/resource.go b/api/app/resource.go deleted file mode 100644 index d9c59a3..0000000 --- a/api/app/resource.go +++ /dev/null @@ -1,91 +0,0 @@ -package app - -import ( - "github.com/veypi/OneBD/rest" - "oa/cfg" - M "oa/models" -) - -func useResource(r rest.Router) { - r.Post("/", resourcePost) - r.Delete("/", resourceDelete) - r.Get("/", resourceList) - r.Delete("/:resource_id", resourceDelete) - r.Get("/:resource_id", resourceGet) - r.Patch("/:resource_id", resourcePatch) -} -func resourceGet(x *rest.X) (any, error) { - opts := &M.ResourceGet{} - err := x.Parse(opts) - if err != nil { - return nil, err - } - data := &M.Resource{} - - err = cfg.DB().Where("id = ?", opts.ID).First(data).Error - - return data, err -} -func resourcePatch(x *rest.X) (any, error) { - opts := &M.ResourcePatch{} - err := x.Parse(opts) - if err != nil { - return nil, err - } - data := &M.Resource{} - - err = cfg.DB().Where("id = ?", opts.ID).First(data).Error - if err != nil { - return nil, err - } - optsMap := make(map[string]interface{}) - if opts.Des != nil { - optsMap["des"] = opts.Des - } - err = cfg.DB().Model(data).Updates(optsMap).Error - - return data, err -} -func resourceDelete(x *rest.X) (any, error) { - opts := &M.ResourceDelete{} - err := x.Parse(opts) - if err != nil { - return nil, err - } - data := &M.Resource{} - - err = cfg.DB().Where("id = ?", opts.ID).Delete(data).Error - - return data, err -} -func resourceList(x *rest.X) (any, error) { - opts := &M.ResourceList{} - err := x.Parse(opts) - if err != nil { - return nil, err - } - data := make([]*M.Resource, 0, 10) - - query := cfg.DB() - if opts.AppID != nil { - query = query.Where("app_id LIKE ?", opts.AppID) - } - err = query.Find(&data).Error - - return data, err -} -func resourcePost(x *rest.X) (any, error) { - opts := &M.ResourcePost{} - err := x.Parse(opts) - if err != nil { - return nil, err - } - data := &M.Resource{} - - data.AppID = opts.AppID - data.Name = opts.Name - data.Des = opts.Des - err = cfg.DB().Create(data).Error - - return data, err -} diff --git a/api/app/resource/create.go b/api/app/resource/create.go new file mode 100644 index 0000000..c4c7a62 --- /dev/null +++ b/api/app/resource/create.go @@ -0,0 +1,37 @@ +package resource + +import ( + "github.com/veypi/OneBD/rest" + "oa/models" + "oa/cfg" +) + +var _ = Router.Post("/", createResource) + +type createOpts struct { + AppID string `json:"app_id" parse:"path"` + Name string `json:"name" parse:"json"` + Des string `json:"des" parse:"json"` +} + +func createResource(x *rest.X) (any, error) { + // 解析参数 + opts := &createOpts{} + if err := x.Parse(opts); err != nil { + return nil, err + } + + // 创建资源对象 + resource := &models.Resource{ + AppID: opts.AppID, + Name: opts.Name, + Des: opts.Des, + } + + // 保存到数据库 + if err := cfg.DB().Create(resource).Error; err != nil { + return nil, rest.NewError("failed to create resource").WithCode(500) + } + + return resource, nil +} diff --git a/api/app/resource/del.go b/api/app/resource/del.go new file mode 100644 index 0000000..5f15cfa --- /dev/null +++ b/api/app/resource/del.go @@ -0,0 +1,37 @@ +package resource + +import ( + "github.com/veypi/OneBD/rest" + "oa/models" + "oa/cfg" +) + +var _ = Router.Delete("/:resource_id", deleteResource) + +type deleteOpts struct { + ResourceID string `parse:"path"` +} + +func deleteResource(x *rest.X) (any, error) { + // 解析参数 + opts := &deleteOpts{} + if err := x.Parse(opts); err != nil { + return nil, err + } + + // 查找资源 + resource := &models.Resource{} + if err := cfg.DB().Where("id = ?", opts.ResourceID).First(resource).Error; err != nil { + return nil, rest.NewError("resource not found").WithCode(404) + } + + // 删除资源 + if err := cfg.DB().Delete(resource).Error; err != nil { + return nil, rest.NewError("failed to delete resource").WithCode(500) + } + + return map[string]interface{}{ + "message": "resource deleted successfully", + "id": opts.ResourceID, + }, nil +} diff --git a/api/app/resource/get.go b/api/app/resource/get.go new file mode 100644 index 0000000..70991fa --- /dev/null +++ b/api/app/resource/get.go @@ -0,0 +1,26 @@ +package resource + +import ( + "github.com/veypi/OneBD/rest" + "oa/models" + "oa/cfg" +) + +var _ = Router.Get("/:resource_id", getResource) + +func getResource(x *rest.X) (any, error) { + // 获取路径参数 + resourceID := x.Params.Get("resource_id") + if resourceID == "" { + return nil, rest.NewError("resource_id is required").WithCode(400) + } + + // 查询数据库 + resource := &models.Resource{} + err := cfg.DB().Where("id = ?", resourceID).First(resource).Error + if err != nil { + return nil, rest.NewError("resource not found").WithCode(404) + } + + return resource, nil +} diff --git a/api/app/resource/init.go b/api/app/resource/init.go new file mode 100644 index 0000000..77e9e8a --- /dev/null +++ b/api/app/resource/init.go @@ -0,0 +1,14 @@ +// +// init.go +// Copyright (C) 2025 veypi +// 2025-05-13 16:45 +// Distributed under terms of the MIT license. +// + +package resource + +import ( + "github.com/veypi/OneBD/rest" +) + +var Router = rest.NewRouter() diff --git a/api/app/resource/list.go b/api/app/resource/list.go new file mode 100644 index 0000000..b5a29c1 --- /dev/null +++ b/api/app/resource/list.go @@ -0,0 +1,56 @@ +package resource + +import ( + "github.com/veypi/OneBD/rest" + "oa/models" + "oa/cfg" +) + +type listOpts struct { + Page int `parse:"query" default:"1"` + PageSize int `parse:"query" default:"20"` + AppID string `parse:"query"` + Name string `parse:"query"` +} + +type listResponse struct { + Total int64 `json:"total"` + Items []*models.Resource `json:"items"` +} + +var _ = Router.Get("/", listResources) + +func listResources(x *rest.X) (any, error) { + // 解析参数 + opts := &listOpts{} + if err := x.Parse(opts); err != nil { + return nil, err + } + + // 构建查询 + db := cfg.DB().Model(&models.Resource{}) + if opts.AppID != "" { + db = db.Where("app_id = ?", opts.AppID) + } + if opts.Name != "" { + db = db.Where("name LIKE ?", "%"+opts.Name+"%") + } + + // 计算总数 + var total int64 + if err := db.Count(&total).Error; err != nil { + return nil, err + } + + // 分页查询 + offset := (opts.Page - 1) * opts.PageSize + var resources []*models.Resource + if err := db.Offset(offset).Limit(opts.PageSize).Find(&resources).Error; err != nil { + return nil, err + } + + return &listResponse{ + Total: total, + Items: resources, + }, nil +} diff --git a/api/app/resource/patch.go b/api/app/resource/patch.go new file mode 100644 index 0000000..8c03258 --- /dev/null +++ b/api/app/resource/patch.go @@ -0,0 +1,47 @@ +package resource + +import ( + "github.com/veypi/OneBD/rest" + "oa/cfg" + "oa/models" +) + +var _ = Router.Patch("/:resource_id", updateResource) + +type updateOpts struct { + ResourceID string `parse:"path"` + Name *string `json:"name" parse:"json"` + Des *string `json:"des" parse:"json"` +} + +func updateResource(x *rest.X) (any, error) { + // 解析参数 + opts := &updateOpts{} + if err := x.Parse(opts); err != nil { + return nil, err + } + + // 查找资源 + resource := &models.Resource{} + if err := cfg.DB().Where("id = ?", opts.ResourceID).First(resource).Error; err != nil { + return nil, rest.NewError("resource not found").WithCode(404) + } + + // 更新字段 + updates := map[string]interface{}{} + if opts.Name != nil { + updates["name"] = *opts.Name + } + if opts.Des != nil { + updates["des"] = *opts.Des + } + + // 执行更新 + if len(updates) > 0 { + if err := cfg.DB().Model(resource).Updates(updates).Error; err != nil { + return nil, rest.NewError("failed to update resource").WithCode(500) + } + } + return resource, nil + +} diff --git a/api/app/role.go b/api/app/role.go deleted file mode 100644 index d60ee2d..0000000 --- a/api/app/role.go +++ /dev/null @@ -1,96 +0,0 @@ -package app - -import ( - "github.com/veypi/OneBD/rest" - "oa/cfg" - M "oa/models" -) - -func useRole(r rest.Router) { - r.Delete("/:role_id", roleDelete) - r.Get("/", roleList) - r.Post("/", rolePost) - r.Get("/:role_id", roleGet) - r.Patch("/:role_id", rolePatch) -} -func roleDelete(x *rest.X) (any, error) { - opts := &M.RoleDelete{} - err := x.Parse(opts) - if err != nil { - return nil, err - } - data := &M.Role{} - - err = cfg.DB().Where("id = ?", opts.ID).Delete(data).Error - - return data, err -} -func roleList(x *rest.X) (any, error) { - opts := &M.RoleList{} - err := x.Parse(opts) - if err != nil { - return nil, err - } - data := make([]*M.Role, 0, 10) - - query := cfg.DB() - if opts.AppID != nil { - query = query.Where("app_id LIKE ?", opts.AppID) - } - if opts.Name != nil { - query = query.Where("name LIKE ?", opts.Name) - } - err = query.Find(&data).Error - - return data, err -} -func rolePost(x *rest.X) (any, error) { - opts := &M.RolePost{} - err := x.Parse(opts) - if err != nil { - return nil, err - } - data := &M.Role{} - - data.AppID = opts.AppID - data.Name = opts.Name - data.Des = opts.Des - err = cfg.DB().Create(data).Error - - return data, err -} -func roleGet(x *rest.X) (any, error) { - opts := &M.RoleGet{} - err := x.Parse(opts) - if err != nil { - return nil, err - } - data := &M.Role{} - - err = cfg.DB().Where("id = ?", opts.ID).First(data).Error - - return data, err -} -func rolePatch(x *rest.X) (any, error) { - opts := &M.RolePatch{} - err := x.Parse(opts) - if err != nil { - return nil, err - } - data := &M.Role{} - - err = cfg.DB().Where("id = ?", opts.ID).First(data).Error - if err != nil { - return nil, err - } - optsMap := make(map[string]interface{}) - if opts.Name != nil { - optsMap["name"] = opts.Name - } - if opts.Des != nil { - optsMap["des"] = opts.Des - } - err = cfg.DB().Model(data).Updates(optsMap).Error - - return data, err -} diff --git a/api/app/role/create.go b/api/app/role/create.go new file mode 100644 index 0000000..89ff618 --- /dev/null +++ b/api/app/role/create.go @@ -0,0 +1,37 @@ +package role + +import ( + "github.com/veypi/OneBD/rest" + "oa/models" + "oa/cfg" +) + +var _ = Router.Post("/", createRole) + +type createOpts struct { + AppID string `parse:"path"` // 应用 ID + Name string `json:"name"` // 角色名称 + Des string `json:"des"` // 角色描述 +} + +func createRole(x *rest.X) (any, error) { + // 解析参数 + opts := &createOpts{} + if err := x.Parse(opts); err != nil { + return nil, err + } + + // 创建角色 + role := &models.Role{ + AppID: opts.AppID, + Name: opts.Name, + Des: opts.Des, + } + + // 保存到数据库 + if err := cfg.DB().Create(role).Error; err != nil { + return nil, err + } + + return role, nil +} diff --git a/api/app/role/del.go b/api/app/role/del.go new file mode 100644 index 0000000..01a2945 --- /dev/null +++ b/api/app/role/del.go @@ -0,0 +1,38 @@ +package role + +import ( + "github.com/veypi/OneBD/rest" + "oa/models" + "oa/cfg" +) + +var _ = Router.Delete("/:role_id", deleteRole) + +type deleteOpts struct { + RoleID string `parse:"path"` // 角色 ID +} + +func deleteRole(x *rest.X) (any, error) { + // 解析参数 + opts := &deleteOpts{} + if err := x.Parse(opts); err != nil { + return nil, err + } + + // 查找角色 + role := &models.Role{} + if err := cfg.DB().Where("id = ?", opts.RoleID).First(role).Error; err != nil { + return nil, rest.NewError("role not found").WithCode(404) + } + + // 执行删除操作 + if err := cfg.DB().Delete(role).Error; err != nil { + return nil, err + } + + // 返回成功消息 + return map[string]interface{}{ + "message": "role deleted successfully", + "id": opts.RoleID, + }, nil +} diff --git a/api/app/role/get.go b/api/app/role/get.go new file mode 100644 index 0000000..6d62c0d --- /dev/null +++ b/api/app/role/get.go @@ -0,0 +1,26 @@ +package role + +import ( + "github.com/veypi/OneBD/rest" + "oa/models" + "oa/cfg" +) + +var _ = Router.Get("/:role_id", getRole) + +func getRole(x *rest.X) (any, error) { + // 获取角色 ID + roleID := x.Params.Get("role_id") + if roleID == "" { + return nil, rest.NewError("role_id is required").WithCode(400) + } + + // 查询数据库 + role := &models.Role{} + err := cfg.DB().Where("id = ?", roleID).First(role).Error + if err != nil { + return nil, rest.NewError("role not found").WithCode(404) + } + + return role, nil +} diff --git a/api/app/role/init.go b/api/app/role/init.go new file mode 100644 index 0000000..6dc7ad0 --- /dev/null +++ b/api/app/role/init.go @@ -0,0 +1,14 @@ +// +// init.go +// Copyright (C) 2025 veypi +// 2025-05-13 16:49 +// Distributed under terms of the MIT license. +// + +package role + +import ( + "github.com/veypi/OneBD/rest" +) + +var Router = rest.NewRouter() diff --git a/api/app/role/list.go b/api/app/role/list.go new file mode 100644 index 0000000..3a7b067 --- /dev/null +++ b/api/app/role/list.go @@ -0,0 +1,62 @@ +package role + +import ( + "github.com/veypi/OneBD/rest" + "oa/models" + "oa/cfg" +) + +var _ = Router.Get("/", listRoles) + +type listOpts struct { + Page int `parse:"query" default:"1"` + PageSize int `parse:"query" default:"20"` + Keyword string `parse:"query" default:""` + SortBy string `parse:"query" default:"created_at"` + Order string `parse:"query" default:"desc"` +} + +type listResponse struct { + Total int64 `json:"total"` + Items []*models.Role `json:"items"` +} + +func listRoles(x *rest.X) (any, error) { + // 解析参数 + opts := &listOpts{} + if err := x.Parse(opts); err != nil { + return nil, err + } + + // 构建查询 + db := cfg.DB().Model(&models.Role{}) + query := db + + // 应用关键词搜索 + if opts.Keyword != "" { + query = query.Where("name LIKE ? OR des LIKE ?", "%"+opts.Keyword+"%", "%"+opts.Keyword+"%") + } + + // 计算总数 + var total int64 + if err := query.Count(&total).Error; err != nil { + return nil, err + } + + // 分页和排序 + offset := (opts.Page - 1) * opts.PageSize + query = query.Order(opts.SortBy + " " + opts.Order) + query = query.Offset(offset).Limit(opts.PageSize) + + // 查询数据 + var roles []*models.Role + if err := query.Find(&roles).Error; err != nil { + return nil, err + } + + // 返回结果 + return &listResponse{ + Total: total, + Items: roles, + }, nil +} diff --git a/api/app/role/patch.go b/api/app/role/patch.go new file mode 100644 index 0000000..bc731f7 --- /dev/null +++ b/api/app/role/patch.go @@ -0,0 +1,57 @@ +package role + +import ( + "github.com/veypi/OneBD/rest" + "oa/models" + "oa/cfg" +) + +var _ = Router.Patch("/:role_id", updateRole) + +type updateOpts struct { + RoleID string `parse:"path"` // 角色 ID + Name *string `json:"name"` // 可选,角色名称 + Des *string `json:"des"` // 可选,角色描述 +} + +func updateRole(x *rest.X) (any, error) { + // 解析参数 + opts := &updateOpts{} + if err := x.Parse(opts); err != nil { + return nil, err + } + + // 查找角色 + role := &models.Role{} + if err := cfg.DB().Where("id = ?", opts.RoleID).First(role).Error; err != nil { + return nil, rest.NewError("role not found").WithCode(404) + } + + // 准备更新字段 + updates := map[string]interface{}{} + + if opts.Name != nil { + updates["name"] = *opts.Name + } + + if opts.Des != nil { + updates["des"] = *opts.Des + } + + // 如果没有更新字段,直接返回 + if len(updates) == 0 { + return role, nil + } + + // 执行更新 + if err := cfg.DB().Model(role).Updates(updates).Error; err != nil { + return nil, err + } + + // 重新查询以获取最新数据 + if err := cfg.DB().Where("id = ?", opts.RoleID).First(role).Error; err != nil { + return nil, err + } + + return role, nil +} diff --git a/models/app.gen.go b/models/app.gen.go deleted file mode 100644 index ba616bf..0000000 --- a/models/app.gen.go +++ /dev/null @@ -1,110 +0,0 @@ -package models - -type AppGet struct { - ID string `json:"id" gorm:"primaryKey;type:varchar(32)" parse:"path@app_id"` -} - -type AppPatch struct { - ID string `json:"id" gorm:"primaryKey;type:varchar(32)" parse:"path@app_id"` - Name *string `json:"name" parse:"json"` - Icon *string `json:"icon" parse:"json"` - Des *string `json:"des" parse:"json"` - Typ *string `json:"typ" gorm:"default:auto" parse:"json"` - InitRoleID *string `json:"init_role_id" gorm:"index;type:varchar(32)" parse:"json"` - Status *string `json:"status" gorm:"default:ok" parse:"json"` - InitUrl *string `json:"init_url" parse:"json"` -} - -type AppDelete struct { - ID string `json:"id" gorm:"primaryKey;type:varchar(32)" parse:"path@app_id"` -} - -type AppPost struct { - Name string `json:"name" parse:"json"` - Icon string `json:"icon" parse:"json"` - Des *string `json:"des" parse:"json"` - Typ string `json:"typ" gorm:"default:auto" parse:"json"` - Status string `json:"status" gorm:"default:ok" parse:"json"` - InitUrl string `json:"init_url" methods:"*patch" parse:"json"` -} - -type AppList struct { - Name *string `json:"name" parse:"query"` -} - -type AppUserGet struct { - ID string `json:"id" gorm:"primaryKey;type:varchar(32)" parse:"path@app_user_id"` - AppID string `json:"app_id" parse:"path"` - UserID string `json:"user_id" parse:"query"` -} - -type AppUserPatch struct { - ID string `json:"id" gorm:"primaryKey;type:varchar(32)" parse:"path@app_user_id"` - Status *string `json:"status" parse:"json"` - AppID string `json:"app_id" parse:"path"` -} - -type AppUserDelete struct { - ID string `json:"id" gorm:"primaryKey;type:varchar(32)" parse:"path@app_user_id"` - AppID string `json:"app_id" parse:"path"` -} - -type AppUserList struct { - AppID *string `json:"app_id" parse:"path"` - UserID *string `json:"user_id" parse:"query"` - Status *string `json:"status" parse:"query"` -} - -type AppUserPost struct { - Status string `json:"status" parse:"json"` - UserID string `json:"user_id" parse:"json"` - AppID string `json:"app_id" parse:"path"` -} - -type ResourceGet struct { - ID string `json:"id" gorm:"primaryKey;type:varchar(32)" parse:"path@resource_id"` -} - -type ResourcePatch struct { - ID string `json:"id" gorm:"primaryKey;type:varchar(32)" parse:"path@resource_id"` - Des *string `json:"des" parse:"json"` -} - -type ResourceDelete struct { - ID string `json:"id" gorm:"primaryKey;type:varchar(32)" parse:"path@resource_id"` -} - -type ResourceList struct { - AppID *string `json:"app_id" parse:"path"` -} - -type ResourcePost struct { - AppID string `json:"app_id" parse:"path"` - Name string `json:"name" parse:"json"` - Des string `json:"des" parse:"json"` -} - -type RoleGet struct { - ID string `json:"id" gorm:"primaryKey;type:varchar(32)" parse:"path@role_id"` -} - -type RolePatch struct { - ID string `json:"id" gorm:"primaryKey;type:varchar(32)" parse:"path@role_id"` - Name *string `json:"name" parse:"json"` - Des *string `json:"des" parse:"json"` -} - -type RoleDelete struct { - ID string `json:"id" gorm:"primaryKey;type:varchar(32)" parse:"path@role_id"` -} - -type RoleList struct { - AppID *string `json:"app_id" parse:"path"` - Name *string `json:"name" parse:"query"` -} - -type RolePost struct { - AppID string `json:"app_id" parse:"path"` - Name string `json:"name" parse:"json"` - Des string `json:"des" parse:"json"` -}