| @@ -147,6 +147,8 @@ func init() { | |||
| new(AiModelConvert), | |||
| new(ResourceQueue), | |||
| new(ResourceSpecification), | |||
| new(ResourceScene), | |||
| new(ResourceSceneSpec), | |||
| ) | |||
| tablesStatistic = append(tablesStatistic, | |||
| @@ -82,6 +82,10 @@ type ResourceQueueCodesRes struct { | |||
| AiCenterCode string | |||
| } | |||
| type GetQueueCodesOptions struct { | |||
| Cluster string | |||
| } | |||
| func NewResourceQueueListRes(totalSize int64, list []ResourceQueue) *ResourceQueueListRes { | |||
| resList := make([]*ResourceQueueRes, len(list)) | |||
| for i, v := range list { | |||
| @@ -143,9 +147,15 @@ func SearchResourceQueue(opts SearchResourceQueueOptions) (int64, []ResourceQueu | |||
| return n, r, nil | |||
| } | |||
| func GetResourceQueueCodes() ([]*ResourceQueueCodesRes, error) { | |||
| func GetResourceQueueCodes(opts GetQueueCodesOptions) ([]*ResourceQueueCodesRes, error) { | |||
| cond := builder.NewCond() | |||
| if opts.Cluster != "" { | |||
| cond = cond.And(builder.Eq{"cluster": opts.Cluster}) | |||
| } | |||
| cond = cond.And(builder.NotNull{"queue_code"}) | |||
| cond = cond.And(builder.Neq{"queue_code": ""}) | |||
| r := make([]*ResourceQueueCodesRes, 0) | |||
| err := x.Table("resource_queue").Where("queue_code is not null AND queue_code != '' ").Find(&r) | |||
| err := x.Table("resource_queue").Where(cond).OrderBy("id desc").Find(&r) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| @@ -1,6 +1,15 @@ | |||
| package models | |||
| import "code.gitea.io/gitea/modules/timeutil" | |||
| import ( | |||
| "code.gitea.io/gitea/modules/timeutil" | |||
| "errors" | |||
| "xorm.io/builder" | |||
| ) | |||
| const ( | |||
| Exclusive = iota + 1 | |||
| NotExclusive | |||
| ) | |||
| type ResourceScene struct { | |||
| ID int64 `xorm:"pk autoincr"` | |||
| @@ -9,9 +18,9 @@ type ResourceScene struct { | |||
| IsExclusive bool | |||
| ExclusiveOrg string | |||
| QueueId int64 | |||
| CreatedTime timeutil.TimeStamp `xorm:"INDEX created"` | |||
| CreatedTime timeutil.TimeStamp `xorm:"created"` | |||
| CreatedBy int64 | |||
| UpdatedTime timeutil.TimeStamp `xorm:"INDEX updated"` | |||
| UpdatedTime timeutil.TimeStamp `xorm:"updated"` | |||
| UpdatedBy int64 | |||
| DeleteTime timeutil.TimeStamp `xorm:"deleted"` | |||
| DeletedBy int64 | |||
| @@ -19,7 +28,285 @@ type ResourceScene struct { | |||
| type ResourceSceneSpec struct { | |||
| ID int64 `xorm:"pk autoincr"` | |||
| SceneId int64 `xorm:"INDEX"` | |||
| SpecId int64 `xorm:"INDEX"` | |||
| SceneId int64 `xorm:"unique(idx_scene_spec)"` | |||
| SpecId int64 `xorm:"unique(idx_scene_spec)"` | |||
| CreatedTime timeutil.TimeStamp `xorm:"created"` | |||
| } | |||
| type ResourceSceneReq struct { | |||
| ID int64 | |||
| SceneName string | |||
| JobType string | |||
| IsExclusive bool | |||
| ExclusiveOrg string | |||
| QueueId int64 | |||
| CreatorId int64 | |||
| SpecIds []int64 | |||
| } | |||
| type SearchResourceSceneOptions struct { | |||
| ListOptions | |||
| JobType string | |||
| IsExclusive int | |||
| AiCenterCode string | |||
| QueueId int64 | |||
| } | |||
| type ResourceSceneListRes struct { | |||
| TotalSize int64 | |||
| List []ResourceSceneRes | |||
| } | |||
| func NewResourceSceneListRes(totalSize int64, list []ResourceSceneRes) *ResourceSceneListRes { | |||
| return &ResourceSceneListRes{ | |||
| TotalSize: totalSize, | |||
| List: list, | |||
| } | |||
| } | |||
| type ResourceSceneRes struct { | |||
| ID int64 | |||
| SceneName string | |||
| JobType JobType | |||
| IsExclusive bool | |||
| ExclusiveOrg string | |||
| Cluster string | |||
| AiCenterCode string | |||
| QueueCode string | |||
| Specs []ResourceSpecWithSceneId | |||
| } | |||
| func (ResourceSceneRes) TableName() string { | |||
| return "resource_scene" | |||
| } | |||
| type ResourceSpecWithSceneId struct { | |||
| ID int64 | |||
| SourceSpecId string | |||
| AccCardsNum int | |||
| CpuCores int | |||
| MemGiB float32 | |||
| GPUMemGiB float32 | |||
| ShareMemGiB float32 | |||
| UnitPrice int | |||
| Status int | |||
| UpdatedTime timeutil.TimeStamp | |||
| SceneId int64 | |||
| } | |||
| func (ResourceSpecWithSceneId) TableName() string { | |||
| return "resource_specification" | |||
| } | |||
| func InsertResourceScene(r ResourceSceneReq) error { | |||
| sess := x.NewSession() | |||
| defer sess.Close() | |||
| //check | |||
| specs := make([]ResourceSpecification, 0) | |||
| cond := builder.In("id", r.SpecIds).And(builder.Eq{"queue_id": r.QueueId}).And(builder.Eq{"status": SpecOnShelf}) | |||
| if err := sess.Where(cond).Find(&specs); err != nil { | |||
| return err | |||
| } | |||
| if len(specs) < len(r.SpecIds) { | |||
| return errors.New("specIds not correct") | |||
| } | |||
| rs := ResourceScene{ | |||
| SceneName: r.SceneName, | |||
| JobType: r.JobType, | |||
| IsExclusive: r.IsExclusive, | |||
| ExclusiveOrg: r.ExclusiveOrg, | |||
| QueueId: r.QueueId, | |||
| CreatedBy: r.CreatorId, | |||
| UpdatedBy: r.CreatorId, | |||
| } | |||
| _, err := sess.InsertOne(&rs) | |||
| if err != nil { | |||
| sess.Rollback() | |||
| return err | |||
| } | |||
| if len(r.SpecIds) == 0 { | |||
| return sess.Commit() | |||
| } | |||
| rss := make([]ResourceSceneSpec, len(r.SpecIds)) | |||
| for i, v := range r.SpecIds { | |||
| rss[i] = ResourceSceneSpec{ | |||
| SceneId: rs.ID, | |||
| SpecId: v, | |||
| } | |||
| } | |||
| _, err = sess.Insert(&rss) | |||
| if err != nil { | |||
| sess.Rollback() | |||
| return err | |||
| } | |||
| return sess.Commit() | |||
| } | |||
| func UpdateResourceScene(r ResourceSceneReq) error { | |||
| sess := x.NewSession() | |||
| var err error | |||
| defer func() { | |||
| if err != nil { | |||
| sess.Rollback() | |||
| } | |||
| sess.Close() | |||
| }() | |||
| // find old scene | |||
| old := ResourceScene{} | |||
| if has, _ := sess.ID(r.ID).Get(&old); !has { | |||
| return errors.New("ResourceScene not exist") | |||
| } | |||
| //check specification | |||
| specs := make([]ResourceSpecification, 0) | |||
| cond := builder.In("id", r.SpecIds).And(builder.Eq{"queue_id": old.QueueId}).And(builder.Eq{"status": SpecOnShelf}) | |||
| if err := sess.Where(cond).Find(&specs); err != nil { | |||
| return err | |||
| } | |||
| if len(specs) < len(r.SpecIds) { | |||
| return errors.New("specIds not correct") | |||
| } | |||
| //update scene | |||
| rs := ResourceScene{ | |||
| SceneName: r.SceneName, | |||
| IsExclusive: r.IsExclusive, | |||
| ExclusiveOrg: r.ExclusiveOrg, | |||
| } | |||
| if _, err = sess.ID(r.ID).UseBool("is_exclusive").Update(&rs); err != nil { | |||
| return err | |||
| } | |||
| //delete scene spec relation | |||
| if _, err = sess.Where("scene_id = ? ", r.ID).Delete(&ResourceSceneSpec{}); err != nil { | |||
| sess.Rollback() | |||
| return err | |||
| } | |||
| if len(r.SpecIds) == 0 { | |||
| return sess.Commit() | |||
| } | |||
| //build new scene spec relation | |||
| rss := make([]ResourceSceneSpec, len(r.SpecIds)) | |||
| for i, v := range r.SpecIds { | |||
| rss[i] = ResourceSceneSpec{ | |||
| SceneId: r.ID, | |||
| SpecId: v, | |||
| } | |||
| } | |||
| if _, err = sess.Insert(&rss); err != nil { | |||
| sess.Rollback() | |||
| return err | |||
| } | |||
| return sess.Commit() | |||
| } | |||
| func DeleteResourceScene(sceneId int64) error { | |||
| sess := x.NewSession() | |||
| var err error | |||
| defer func() { | |||
| if err != nil { | |||
| sess.Rollback() | |||
| } | |||
| sess.Close() | |||
| }() | |||
| if _, err = sess.ID(sceneId).Delete(&ResourceScene{}); err != nil { | |||
| return err | |||
| } | |||
| if _, err = sess.Where("scene_id = ? ", sceneId).Delete(&ResourceSceneSpec{}); err != nil { | |||
| return err | |||
| } | |||
| return sess.Commit() | |||
| } | |||
| func SearchResourceScene(opts SearchResourceSceneOptions) (int64, []ResourceSceneRes, error) { | |||
| var cond = builder.NewCond() | |||
| if opts.Page <= 0 { | |||
| opts.Page = 1 | |||
| } | |||
| if opts.JobType != "" { | |||
| cond = cond.And(builder.Eq{"resource_scene.job_type": opts.JobType}) | |||
| } | |||
| if opts.IsExclusive == Exclusive { | |||
| cond = cond.And(builder.Eq{"resource_scene.is_exclusive": 1}) | |||
| } else if opts.IsExclusive == NotExclusive { | |||
| cond = cond.And(builder.Eq{"resource_scene.is_exclusive": 0}) | |||
| } | |||
| if opts.AiCenterCode != "" { | |||
| cond = cond.And(builder.Eq{"resource_queue.ai_center_code": opts.AiCenterCode}) | |||
| } | |||
| if opts.QueueId > 0 { | |||
| cond = cond.And(builder.Eq{"resource_scene.queue_id": opts.QueueId}) | |||
| } | |||
| cond = cond.And(builder.NewCond().Or(builder.Eq{"resource_scene.delete_time": 0}).Or(builder.IsNull{"resource_scene.delete_time"})) | |||
| count, err := x.Where(cond).Join("INNER", "resource_queue", "resource_queue.id = resource_scene.queue_id").Count(&ResourceSceneRes{}) | |||
| if err != nil { | |||
| return 0, nil, err | |||
| } | |||
| cols := []string{"resource_scene.id", "resource_scene.scene_name", "resource_scene.job_type", "resource_scene.is_exclusive", | |||
| "resource_scene.exclusive_org", "resource_queue.cluster", "resource_queue.ai_center_code", | |||
| "resource_queue.queue_code"} | |||
| r := make([]ResourceSceneRes, 0) | |||
| if err = x.Where(cond).Cols(cols...). | |||
| Join("INNER", "resource_queue", "resource_queue.id = resource_scene.queue_id"). | |||
| Desc("resource_scene.id"). | |||
| Limit(opts.PageSize, (opts.Page-1)*opts.PageSize). | |||
| Find(&r); err != nil { | |||
| return 0, nil, err | |||
| } | |||
| if len(r) == 0 { | |||
| return 0, r, err | |||
| } | |||
| //find related specs | |||
| sceneIds := make([]int64, 0, len(r)) | |||
| for _, v := range r { | |||
| sceneIds = append(sceneIds, v.ID) | |||
| } | |||
| specs := make([]ResourceSpecWithSceneId, 0) | |||
| if err := x.Cols("resource_specification.id", | |||
| "resource_specification.source_spec_id", | |||
| "resource_specification.acc_cards_num", | |||
| "resource_specification.cpu_cores", | |||
| "resource_specification.mem_gi_b", | |||
| "resource_specification.gpu_mem_gi_b", | |||
| "resource_specification.share_mem_gi_b", | |||
| "resource_specification.unit_price", | |||
| "resource_specification.status", | |||
| "resource_specification.updated_time", | |||
| "resource_scene_spec.scene_id", | |||
| ).In("resource_scene_spec.scene_id", sceneIds). | |||
| Join("INNER", "resource_scene_spec", "resource_scene_spec.spec_id = resource_specification.id"). | |||
| OrderBy("resource_specification.acc_cards_num"). | |||
| Find(&specs); err != nil { | |||
| return 0, nil, err | |||
| } | |||
| specsMap := make(map[int64][]ResourceSpecWithSceneId, 0) | |||
| for _, v := range specs { | |||
| if _, ok := specsMap[v.SceneId]; !ok { | |||
| specsMap[v.SceneId] = []ResourceSpecWithSceneId{v} | |||
| } else { | |||
| specsMap[v.SceneId] = append(specsMap[v.SceneId], v) | |||
| } | |||
| } | |||
| for i, v := range r { | |||
| s := specsMap[v.ID] | |||
| if s == nil { | |||
| s = make([]ResourceSpecWithSceneId, 0) | |||
| } | |||
| r[i].Specs = s | |||
| } | |||
| return count, r, nil | |||
| } | |||
| @@ -46,6 +46,7 @@ func (r ResourceSpecification) ConvertToRes() *ResourceSpecificationRes { | |||
| type ResourceSpecificationReq struct { | |||
| QueueId int64 `binding:"Required"` | |||
| SourceSpecId string | |||
| AccCardsNum int | |||
| CpuCores int | |||
| MemGiB float32 | |||
| @@ -60,6 +61,7 @@ type ResourceSpecificationReq struct { | |||
| func (r ResourceSpecificationReq) ToDTO() ResourceSpecification { | |||
| return ResourceSpecification{ | |||
| QueueId: r.QueueId, | |||
| SourceSpecId: r.SourceSpecId, | |||
| AccCardsNum: r.AccCardsNum, | |||
| CpuCores: r.CpuCores, | |||
| MemGiB: r.MemGiB, | |||
| @@ -77,6 +79,12 @@ type SearchResourceSpecificationOptions struct { | |||
| ListOptions | |||
| QueueId int64 | |||
| Status int | |||
| Cluster string | |||
| } | |||
| type SearchResourceBriefSpecificationOptions struct { | |||
| QueueId int64 | |||
| Cluster string | |||
| } | |||
| type ResourceSpecAndQueueListRes struct { | |||
| @@ -108,6 +116,10 @@ type ResourceSpecificationRes struct { | |||
| UpdatedTime timeutil.TimeStamp | |||
| } | |||
| func (ResourceSpecificationRes) TableName() string { | |||
| return "resource_specification" | |||
| } | |||
| type ResourceSpecAndQueueRes struct { | |||
| Spec *ResourceSpecificationRes | |||
| Queue *ResourceQueueRes | |||
| @@ -133,8 +145,8 @@ func InsertResourceSpecification(r ResourceSpecification) (int64, error) { | |||
| return x.Insert(&r) | |||
| } | |||
| func UpdateResourceSpecificationById(queueId int64, queue ResourceSpecification) (int64, error) { | |||
| return x.ID(queueId).Update(&queue) | |||
| func UpdateResourceSpecificationById(queueId int64, spec ResourceSpecification) (int64, error) { | |||
| return x.ID(queueId).Update(&spec) | |||
| } | |||
| func SearchResourceSpecification(opts SearchResourceSpecificationOptions) (int64, []ResourceSpecAndQueue, error) { | |||
| @@ -148,14 +160,18 @@ func SearchResourceSpecification(opts SearchResourceSpecificationOptions) (int64 | |||
| if opts.Status > 0 { | |||
| cond = cond.And(builder.Eq{"resource_specification.status": opts.Status}) | |||
| } | |||
| n, err := x.Where(cond).Count(&ResourceSpecAndQueue{}) | |||
| if opts.Cluster != "" { | |||
| cond = cond.And(builder.Eq{"resource_queue.cluster": opts.Cluster}) | |||
| } | |||
| n, err := x.Where(cond).Join("INNER", "resource_queue", "resource_queue.ID = resource_specification.queue_id"). | |||
| Count(&ResourceSpecAndQueue{}) | |||
| if err != nil { | |||
| return 0, nil, err | |||
| } | |||
| r := make([]ResourceSpecAndQueue, 0) | |||
| err = x.Where(cond). | |||
| Join("LEFT", "resource_queue", "resource_queue.ID = resource_specification.queue_id"). | |||
| Join("INNER", "resource_queue", "resource_queue.ID = resource_specification.queue_id"). | |||
| Desc("resource_specification.id"). | |||
| Limit(opts.PageSize, (opts.Page-1)*opts.PageSize). | |||
| Find(&r) | |||
| @@ -165,17 +181,32 @@ func SearchResourceSpecification(opts SearchResourceSpecificationOptions) (int64 | |||
| return n, r, nil | |||
| } | |||
| func ResourceSpecOnShelf(id int64) (int64, error) { | |||
| param := ResourceSpecification{ | |||
| Status: SpecOnShelf, | |||
| } | |||
| return x.Where("id = ? and status in (?,?)", id, SpecOffShelf, SpecNotVerified).Update(¶m) | |||
| func ResourceSpecOnShelf(id int64, spec ResourceSpecification) (int64, error) { | |||
| spec.Status = SpecOnShelf | |||
| return x.Where("id = ? and status in (?,?)", id, SpecOffShelf, SpecNotVerified).Update(&spec) | |||
| } | |||
| func ResourceSpecOffShelf(id int64) (int64, error) { | |||
| //todo delete scene | |||
| sess := x.NewSession() | |||
| var err error | |||
| defer func() { | |||
| if err != nil { | |||
| sess.Rollback() | |||
| } | |||
| sess.Close() | |||
| }() | |||
| //delete scene spec relation | |||
| if _, err = sess.Where("spec_id = ?", id).Delete(&ResourceSceneSpec{}); err != nil { | |||
| return 0, err | |||
| } | |||
| param := ResourceSpecification{ | |||
| Status: SpecOffShelf, | |||
| } | |||
| return x.Where("id = ? and status = ?", id, SpecOnShelf).Update(¶m) | |||
| n, err := sess.Where("id = ? and status = ?", id, SpecOnShelf).Update(¶m) | |||
| if err != nil { | |||
| return 0, err | |||
| } | |||
| sess.Commit() | |||
| return n, err | |||
| } | |||
| @@ -59,7 +59,8 @@ func GetResourceQueueList(ctx *context.Context) { | |||
| } | |||
| func GetResourceQueueCodes(ctx *context.Context) { | |||
| list, err := resource.GetResourceQueueCodes() | |||
| cluster := ctx.Query("cluster") | |||
| list, err := resource.GetResourceQueueCodes(models.GetQueueCodesOptions{Cluster: cluster}) | |||
| if err != nil { | |||
| log.Error("GetResourceQueueCodes error.%v", err) | |||
| ctx.JSON(http.StatusOK, response.ServerError(err.Error())) | |||
| @@ -96,10 +97,12 @@ func GetResourceSpecificationList(ctx *context.Context) { | |||
| page := ctx.QueryInt("page") | |||
| queue := ctx.QueryInt64("queue") | |||
| status := ctx.QueryInt("status") | |||
| cluster := ctx.Query("cluster") | |||
| list, err := resource.GetResourceSpecificationList(models.SearchResourceSpecificationOptions{ | |||
| ListOptions: models.ListOptions{Page: page, PageSize: 20}, | |||
| QueueId: queue, | |||
| Status: status, | |||
| Cluster: cluster, | |||
| }) | |||
| if err != nil { | |||
| log.Error("GetResourceSpecificationList error.%v", err) | |||
| @@ -135,7 +138,7 @@ func UpdateResourceSpecification(ctx *context.Context, req models.ResourceSpecif | |||
| //only UnitPrice and permitted to change | |||
| err = resource.UpdateResourceSpecification(id, req) | |||
| case "on-shelf": | |||
| err = resource.ResourceSpecOnShelf(id) | |||
| err = resource.ResourceSpecOnShelf(id, req) | |||
| case "off-shelf": | |||
| err = resource.ResourceSpecOffShelf(id) | |||
| } | |||
| @@ -147,3 +150,56 @@ func UpdateResourceSpecification(ctx *context.Context, req models.ResourceSpecif | |||
| } | |||
| ctx.JSON(http.StatusOK, response.Success()) | |||
| } | |||
| func GetResourceSceneList(ctx *context.Context) { | |||
| page := ctx.QueryInt("page") | |||
| jobType := ctx.Query("jobType") | |||
| aiCenterCode := ctx.Query("center") | |||
| queueId := ctx.QueryInt64("queue") | |||
| isExclusive := ctx.QueryInt("IsExclusive") | |||
| list, err := resource.GetResourceSceneList(models.SearchResourceSceneOptions{ | |||
| ListOptions: models.ListOptions{Page: page, PageSize: 20}, | |||
| JobType: jobType, | |||
| IsExclusive: isExclusive, | |||
| AiCenterCode: aiCenterCode, | |||
| QueueId: queueId, | |||
| }) | |||
| if err != nil { | |||
| log.Error("GetResourceSceneList error.%v", err) | |||
| ctx.JSON(http.StatusOK, response.ServerError(err.Error())) | |||
| return | |||
| } | |||
| ctx.JSON(http.StatusOK, response.SuccessWithData(list)) | |||
| } | |||
| func AddResourceScene(ctx *context.Context, req models.ResourceSceneReq) { | |||
| req.CreatorId = ctx.User.ID | |||
| err := resource.AddResourceScene(req) | |||
| if err != nil { | |||
| log.Error("AddResourceScene error. %v", err) | |||
| ctx.JSON(http.StatusOK, response.ServerError(err.Error())) | |||
| return | |||
| } | |||
| ctx.JSON(http.StatusOK, response.Success()) | |||
| } | |||
| func UpdateResourceScene(ctx *context.Context, req models.ResourceSceneReq) { | |||
| id := ctx.ParamsInt64(":id") | |||
| action := ctx.Query("action") | |||
| req.ID = id | |||
| var err error | |||
| switch action { | |||
| case "edit": | |||
| err = resource.UpdateResourceScene(req) | |||
| case "delete": | |||
| err = resource.DeleteResourceScene(id) | |||
| } | |||
| if err != nil { | |||
| log.Error("UpdateResourceScene error. %v", err) | |||
| ctx.JSON(http.StatusOK, response.ServerError(err.Error())) | |||
| return | |||
| } | |||
| ctx.JSON(http.StatusOK, response.Success()) | |||
| } | |||
| @@ -622,6 +622,9 @@ func RegisterRoutes(m *macaron.Macaron) { | |||
| }) | |||
| m.Group("/scene", func() { | |||
| m.Get("", admin.GetScenePage) | |||
| m.Get("/list", admin.GetResourceSceneList) | |||
| m.Post("/add", binding.Bind(models.ResourceSceneReq{}), admin.AddResourceScene) | |||
| m.Post("/update/:id", binding.BindIgnErr(models.ResourceSceneReq{}), admin.UpdateResourceScene) | |||
| }) | |||
| }) | |||
| }, adminReq) | |||
| @@ -30,8 +30,8 @@ func GetResourceQueueList(opts models.SearchResourceQueueOptions) (*models.Resou | |||
| return models.NewResourceQueueListRes(n, r), nil | |||
| } | |||
| func GetResourceQueueCodes() ([]*models.ResourceQueueCodesRes, error) { | |||
| r, err := models.GetResourceQueueCodes() | |||
| func GetResourceQueueCodes(opts models.GetQueueCodesOptions) ([]*models.ResourceQueueCodesRes, error) { | |||
| r, err := models.GetResourceQueueCodes(opts) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| @@ -0,0 +1,35 @@ | |||
| package resource | |||
| import ( | |||
| "code.gitea.io/gitea/models" | |||
| ) | |||
| func AddResourceScene(req models.ResourceSceneReq) error { | |||
| if err := models.InsertResourceScene(req); err != nil { | |||
| return err | |||
| } | |||
| return nil | |||
| } | |||
| func UpdateResourceScene(req models.ResourceSceneReq) error { | |||
| if err := models.UpdateResourceScene(req); err != nil { | |||
| return err | |||
| } | |||
| return nil | |||
| } | |||
| func DeleteResourceScene(id int64) error { | |||
| if err := models.DeleteResourceScene(id); err != nil { | |||
| return err | |||
| } | |||
| return nil | |||
| } | |||
| func GetResourceSceneList(opts models.SearchResourceSceneOptions) (*models.ResourceSceneListRes, error) { | |||
| n, r, err := models.SearchResourceScene(opts) | |||
| if err != nil { | |||
| return nil, err | |||
| } | |||
| return models.NewResourceSceneListRes(n, r), nil | |||
| } | |||
| @@ -23,6 +23,7 @@ func UpdateResourceSpecification(specId int64, req models.ResourceSpecificationR | |||
| return nil | |||
| } | |||
| //GetResourceSpecificationList returns specification and queue | |||
| func GetResourceSpecificationList(opts models.SearchResourceSpecificationOptions) (*models.ResourceSpecAndQueueListRes, error) { | |||
| n, r, err := models.SearchResourceSpecification(opts) | |||
| if err != nil { | |||
| @@ -32,8 +33,10 @@ func GetResourceSpecificationList(opts models.SearchResourceSpecificationOptions | |||
| return models.NewResourceSpecAndQueueListRes(n, r), nil | |||
| } | |||
| func ResourceSpecOnShelf(id int64) error { | |||
| _, err := models.ResourceSpecOnShelf(id) | |||
| func ResourceSpecOnShelf(id int64, req models.ResourceSpecificationReq) error { | |||
| _, err := models.ResourceSpecOnShelf(id, models.ResourceSpecification{ | |||
| UnitPrice: req.UnitPrice, | |||
| }) | |||
| if err != nil { | |||
| return err | |||
| } | |||