// Copyright 2024 The Devstar Authors. All rights reserved. // SPDX-License-Identifier: MIT package appstore import ( "context" "fmt" "strings" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/timeutil" ) // AppStore represents an application in the app store type AppStore struct { ID int64 `xorm:"pk autoincr"` AppID string `xorm:"UNIQUE NOT NULL"` // 应用唯一标识,如 "nginx" Name string `xorm:"NOT NULL"` // 应用名称,如 "Nginx Web Server" Description string `xorm:"TEXT"` // 应用描述 Category string `xorm:"INDEX"` // 应用分类,如 "web-server" Tags string `xorm:"TEXT"` // 标签,JSON格式存储 Icon string `xorm:"VARCHAR(2048)"` // 应用图标URL Author string `xorm:"VARCHAR(128)"` // 应用作者 Website string `xorm:"VARCHAR(2048)"` // 应用官网 Repository string `xorm:"VARCHAR(2048)"` // 应用仓库地址 License string `xorm:"VARCHAR(64)"` // 许可证类型 Version string `xorm:"NOT NULL"` // 应用版本 DeploymentType string `xorm:"VARCHAR(20) NOT NULL DEFAULT 'docker' INDEX"` // 部署类型:docker, kubernetes, both JSONData string `xorm:"LONGTEXT NOT NULL"` // 完整的应用JSON描述 // 统计信息 InstallCount int64 `xorm:"NOT NULL DEFAULT 0"` // 安装次数 // 状态 IsActive bool `xorm:"INDEX NOT NULL DEFAULT true"` // 是否激活 IsOfficial bool `xorm:"NOT NULL DEFAULT false"` // 是否官方应用 IsVerified bool `xorm:"NOT NULL DEFAULT false"` // 是否已验证 // 时间戳 CreatedUnix timeutil.TimeStamp `xorm:"INDEX created"` UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"` } // TableName returns the table name for AppStore func (a *AppStore) TableName() string { return "app_store" } // BeforeUpdate is called before updating the record func (a *AppStore) BeforeUpdate() { a.UpdatedUnix = timeutil.TimeStampNow() } // BeforeInsert is called before inserting the record func (a *AppStore) BeforeInsert() { a.CreatedUnix = timeutil.TimeStampNow() a.UpdatedUnix = timeutil.TimeStampNow() } // GetTagsList returns the tags as a string slice func (a *AppStore) GetTagsList() []string { if a.Tags == "" { return []string{} } return strings.Split(a.Tags, ",") } // SetTagsList sets the tags from a string slice func (a *AppStore) SetTagsList(tags []string) { a.Tags = strings.Join(tags, ",") } // 数据库操作函数 // GetAppStoreByID 根据ID获取应用商店记录 func GetAppStoreByID(ctx context.Context, id int64) (*AppStore, error) { app := &AppStore{} has, err := db.GetEngine(ctx).ID(id).Get(app) if err != nil { return nil, err } if !has { return nil, fmt.Errorf("app store not found: %d", id) } return app, nil } // GetAppStoreByAppID 根据AppID获取应用商店记录 func GetAppStoreByAppID(ctx context.Context, appID string) (*AppStore, error) { app := &AppStore{} has, err := db.GetEngine(ctx).Where("app_id = ?", appID).Get(app) if err != nil { return nil, err } if !has { return nil, fmt.Errorf("app store not found: %s", appID) } return app, nil } // GetAppStoreByName 根据应用名称获取应用商店记录 func GetAppStoreByName(ctx context.Context, name string) (*AppStore, error) { app := &AppStore{} has, err := db.GetEngine(ctx).Where("name = ?", name).Get(app) if err != nil { return nil, err } if !has { return nil, fmt.Errorf("app store not found: %s", name) } return app, nil } // ListAppStores 列出应用商店记录 func ListAppStores(ctx context.Context, opts *db.ListOptions) ([]*AppStore, error) { var apps []*AppStore sess := db.GetEngine(ctx).Where("is_active = ?", true) if opts != nil { sess = db.SetSessionPagination(sess, opts) } err := sess.OrderBy("created_unix DESC").Find(&apps) return apps, err } // CreateAppStore 创建应用商店记录 func CreateAppStore(ctx context.Context, app *AppStore) error { // 检查AppID是否已存在 has, err := db.GetEngine(ctx).Where("app_id = ?", app.AppID).Exist(&AppStore{}) if err != nil { return err } if has { return fmt.Errorf("app store already exists: %s", app.AppID) } _, err = db.GetEngine(ctx).Insert(app) return err } // UpdateAppStore 更新应用商店记录 func UpdateAppStore(ctx context.Context, app *AppStore) error { _, err := db.GetEngine(ctx).ID(app.ID).Update(app) return err } // DeleteAppStore 删除应用商店记录 func DeleteAppStore(ctx context.Context, id int64) error { _, err := db.GetEngine(ctx).ID(id).Delete(&AppStore{}) return err } // GetCategories 获取所有应用分类 func GetCategories(ctx context.Context) ([]string, error) { var categories []string err := db.GetEngine(ctx).Table("app_store"). Where("is_active = ?", true). Distinct("category"). Cols("category"). Find(&categories) return categories, err } // GetTags 获取所有应用标签 func GetTags(ctx context.Context) ([]string, error) { var tags []string if err := db.GetEngine(ctx).Table("app_store"). Where("is_active = ? AND tags != ''", true). Cols("tags"). Find(&tags); err != nil { return nil, err } // 解析标签字符串并去重 tagSet := make(map[string]bool) for _, tagStr := range tags { tagList := strings.Split(tagStr, ",") for _, tag := range tagList { if tag != "" { tagSet[tag] = true } } } result := make([]string, 0, len(tagSet)) for tag := range tagSet { result = append(result, tag) } return result, nil } // IncrementInstallCount 增加安装次数 func IncrementInstallCount(ctx context.Context, appID string) error { _, err := db.GetEngine(ctx).Exec("UPDATE app_store SET install_count = install_count + 1 WHERE app_id = ?", appID) return err } func init() { db.RegisterModel(new(AppStore)) }