204 lines
6.0 KiB
Go
204 lines
6.0 KiB
Go
|
// 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))
|
|||
|
}
|