mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 06:47:20 +08:00
fix: 优化容器模版
This commit is contained in:
@@ -128,7 +128,7 @@ func initWeb() (*app.Web, error) {
|
||||
toolboxLogService := service.NewToolboxLogService(locale, db, containerImageRepo, settingRepo)
|
||||
webHookRepo := data.NewWebHookRepo(locale, db, logger)
|
||||
webHookService := service.NewWebHookService(webHookRepo)
|
||||
templateRepo := data.NewTemplateRepo()
|
||||
templateRepo := data.NewTemplateRepo(locale, cacheRepo)
|
||||
templateService := service.NewTemplateService(locale, templateRepo, settingRepo)
|
||||
apacheApp := apache.NewApp(locale)
|
||||
codeserverApp := codeserver.NewApp()
|
||||
|
||||
@@ -8,6 +8,7 @@ const (
|
||||
CacheKeyCategories CacheKey = "categories"
|
||||
CacheKeyApps CacheKey = "apps"
|
||||
CacheKeyEnvironment CacheKey = "environment"
|
||||
CacheKeyTemplates CacheKey = "templates"
|
||||
CacheKeyRewrites CacheKey = "rewrites"
|
||||
)
|
||||
|
||||
@@ -24,5 +25,6 @@ type CacheRepo interface {
|
||||
UpdateCategories() error
|
||||
UpdateApps() error
|
||||
UpdateEnvironments() error
|
||||
UpdateTemplates() error
|
||||
UpdateRewrites() error
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
)
|
||||
|
||||
type TemplateRepo interface {
|
||||
List() (api.Templates, error)
|
||||
List() api.Templates
|
||||
Get(slug string) (*api.Template, error)
|
||||
Callback(slug string) error
|
||||
CreateCompose(name, compose string, envs []types.KV, autoFirewall bool) error
|
||||
|
||||
@@ -97,6 +97,20 @@ func (r *cacheRepo) UpdateEnvironments() error {
|
||||
return r.Set(biz.CacheKeyEnvironment, string(encoded))
|
||||
}
|
||||
|
||||
func (r *cacheRepo) UpdateTemplates() error {
|
||||
templates, err := r.api.Templates()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
encoded, err := json.Marshal(templates)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return r.Set(biz.CacheKeyTemplates, string(encoded))
|
||||
}
|
||||
|
||||
func (r *cacheRepo) UpdateRewrites() error {
|
||||
rewrites, err := r.api.RewritesByType("nginx")
|
||||
if err != nil {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package data
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -12,43 +13,50 @@ import (
|
||||
"github.com/acepanel/panel/pkg/api"
|
||||
"github.com/acepanel/panel/pkg/firewall"
|
||||
"github.com/acepanel/panel/pkg/types"
|
||||
"github.com/leonelquinteros/gotext"
|
||||
)
|
||||
|
||||
type templateRepo struct {
|
||||
t *gotext.Locale
|
||||
cache biz.CacheRepo
|
||||
api *api.API
|
||||
firewall *firewall.Firewall
|
||||
}
|
||||
|
||||
func NewTemplateRepo() biz.TemplateRepo {
|
||||
func NewTemplateRepo(t *gotext.Locale, cache biz.CacheRepo) biz.TemplateRepo {
|
||||
return &templateRepo{
|
||||
t: t,
|
||||
cache: cache,
|
||||
api: api.NewAPI(app.Version, app.Locale),
|
||||
firewall: firewall.NewFirewall(),
|
||||
}
|
||||
}
|
||||
|
||||
// List 获取所有模版
|
||||
func (r *templateRepo) List() (api.Templates, error) {
|
||||
templates, err := r.api.Templates()
|
||||
func (r *templateRepo) List() api.Templates {
|
||||
cached, err := r.cache.Get(biz.CacheKeyTemplates)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil
|
||||
}
|
||||
return *templates, nil
|
||||
templates := make(api.Templates, 0)
|
||||
if err = json.Unmarshal([]byte(cached), &templates); err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
return templates
|
||||
}
|
||||
|
||||
// Get 获取模版详情
|
||||
func (r *templateRepo) Get(slug string) (*api.Template, error) {
|
||||
templates, err := r.api.Templates()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
templates := r.List()
|
||||
|
||||
for _, t := range *templates {
|
||||
for _, t := range templates {
|
||||
if t.Slug == slug {
|
||||
return t, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("template %s not found", slug)
|
||||
return nil, fmt.Errorf(r.t.Get("template %s not found", slug))
|
||||
}
|
||||
|
||||
// Callback 模版下载回调
|
||||
|
||||
@@ -219,6 +219,10 @@ func (s *AppService) UpdateCache(w http.ResponseWriter, r *http.Request) {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
if err := s.cacheRepo.UpdateTemplates(); err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
Success(w, nil)
|
||||
}
|
||||
|
||||
@@ -127,6 +127,9 @@ func (s *CliService) Sync(ctx context.Context, cmd *cli.Command) error {
|
||||
if err := s.cacheRepo.UpdateEnvironments(); err != nil {
|
||||
return errors.New(s.t.Get("Failed to synchronize app data: %v", err))
|
||||
}
|
||||
if err := s.cacheRepo.UpdateTemplates(); err != nil {
|
||||
return errors.New(s.t.Get("Failed to synchronize app data: %v", err))
|
||||
}
|
||||
if err := s.cacheRepo.UpdateRewrites(); err != nil {
|
||||
return errors.New(s.t.Get("Failed to synchronize rewrite rules: %v", err))
|
||||
}
|
||||
|
||||
@@ -30,13 +30,7 @@ func (s *TemplateService) List(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
templates, err := s.templateRepo.List()
|
||||
if err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
return
|
||||
}
|
||||
|
||||
Success(w, templates)
|
||||
Success(w, s.templateRepo.List())
|
||||
}
|
||||
|
||||
// Get 获取模版详情
|
||||
@@ -47,11 +41,6 @@ func (s *TemplateService) Get(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if offline, _ := s.settingRepo.GetBool(biz.SettingKeyOfflineMode); offline {
|
||||
Error(w, http.StatusForbidden, s.t.Get("Unable to get template in offline mode"))
|
||||
return
|
||||
}
|
||||
|
||||
template, err := s.templateRepo.Get(req.Slug)
|
||||
if err != nil {
|
||||
Error(w, http.StatusInternalServerError, "%v", err)
|
||||
@@ -69,11 +58,6 @@ func (s *TemplateService) Create(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if offline, _ := s.settingRepo.GetBool(biz.SettingKeyOfflineMode); offline {
|
||||
Error(w, http.StatusForbidden, s.t.Get("Unable to create compose from template in offline mode"))
|
||||
return
|
||||
}
|
||||
|
||||
// 获取模版
|
||||
template, err := s.templateRepo.Get(req.Slug)
|
||||
if err != nil {
|
||||
|
||||
@@ -61,34 +61,35 @@ const handleSubmit = async () => {
|
||||
|
||||
doSubmit.value = true
|
||||
|
||||
try {
|
||||
// 构建环境变量数组
|
||||
const envs = Object.entries(deployModel.envs).map(([key, value]) => ({
|
||||
key,
|
||||
value: String(value)
|
||||
}))
|
||||
// 构建环境变量数组
|
||||
const envs = Object.entries(deployModel.envs).map(([key, value]) => ({
|
||||
key,
|
||||
value: String(value)
|
||||
}))
|
||||
|
||||
// 创建 compose
|
||||
await templateApi.create({
|
||||
// 创建 compose
|
||||
useRequest(
|
||||
templateApi.create({
|
||||
slug: props.template.slug,
|
||||
name: deployModel.name,
|
||||
envs,
|
||||
auto_firewall: deployModel.autoFirewall
|
||||
})
|
||||
|
||||
window.$message.success($gettext('Created successfully'))
|
||||
|
||||
if (deployModel.autoStart) {
|
||||
// 自动启动
|
||||
upCommand.value = `docker compose -f /opt/ace/server/compose/${deployModel.name}/docker-compose.yml up -d`
|
||||
upModal.value = true
|
||||
} else {
|
||||
show.value = false
|
||||
emit('success')
|
||||
}
|
||||
} finally {
|
||||
doSubmit.value = false
|
||||
}
|
||||
)
|
||||
.onSuccess(() => {
|
||||
window.$message.success($gettext('Created successfully'))
|
||||
if (deployModel.autoStart) {
|
||||
// 自动启动
|
||||
upCommand.value = `docker compose -f /opt/ace/server/compose/${deployModel.name}/docker-compose.yml up -d`
|
||||
upModal.value = true
|
||||
} else {
|
||||
show.value = false
|
||||
emit('success')
|
||||
}
|
||||
})
|
||||
.onComplete(() => {
|
||||
doSubmit.value = false
|
||||
})
|
||||
}
|
||||
|
||||
// 启动完成
|
||||
@@ -180,6 +181,7 @@ watch(
|
||||
v-for="env in template.environments"
|
||||
:key="env.name"
|
||||
:label="env.description"
|
||||
:required="env.default == ''"
|
||||
>
|
||||
<!-- Select 类型 -->
|
||||
<n-select
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
import { NButton, NCard, NEllipsis, NFlex, NGrid, NGridItem, NSpin, NTag } from 'naive-ui'
|
||||
import { useGettext } from 'vue3-gettext'
|
||||
|
||||
import app from '@/api/panel/app'
|
||||
import template from '@/api/panel/template'
|
||||
import TemplateDeployModal from './TemplateDeployModal.vue'
|
||||
import type { Template } from './types'
|
||||
@@ -17,12 +18,8 @@ const { loading, data, refresh } = usePagination(template.list, {
|
||||
})
|
||||
|
||||
// 获取所有分类
|
||||
const categories = computed(() => {
|
||||
const cats = new Set<string>()
|
||||
data.value?.forEach((t: Template) => {
|
||||
t.categories?.forEach((c) => cats.add(c))
|
||||
})
|
||||
return Array.from(cats)
|
||||
const { data: categories } = useRequest(app.categories, {
|
||||
initialData: []
|
||||
})
|
||||
|
||||
// 过滤后的模版列表
|
||||
@@ -33,6 +30,11 @@ const filteredTemplates = computed(() => {
|
||||
return (data.value || []).filter((t: Template) => t.categories?.includes(selectedCategory.value))
|
||||
})
|
||||
|
||||
const getCategoryLabel = (catValue: string) => {
|
||||
const cat = categories.value.find((c: any) => c.value === catValue)
|
||||
return cat ? cat.label : catValue
|
||||
}
|
||||
|
||||
const handleCategoryChange = (category: string) => {
|
||||
selectedCategory.value = category
|
||||
}
|
||||
@@ -60,13 +62,13 @@ onMounted(() => {
|
||||
</n-tag>
|
||||
<n-tag
|
||||
v-for="cat in categories"
|
||||
:key="cat"
|
||||
:type="selectedCategory === cat ? 'primary' : 'default'"
|
||||
:bordered="selectedCategory !== cat"
|
||||
:key="cat.value"
|
||||
:type="selectedCategory === cat.value ? 'primary' : 'default'"
|
||||
:bordered="selectedCategory !== cat.value"
|
||||
style="cursor: pointer"
|
||||
@click="handleCategoryChange(cat)"
|
||||
@click="handleCategoryChange(cat.value)"
|
||||
>
|
||||
{{ cat }}
|
||||
{{ cat.label }}
|
||||
</n-tag>
|
||||
</n-flex>
|
||||
|
||||
@@ -84,7 +86,7 @@ onMounted(() => {
|
||||
</n-ellipsis>
|
||||
<n-flex :size="4" style="margin-top: auto">
|
||||
<n-tag v-for="cat in tpl.categories" :key="cat" size="small">
|
||||
{{ cat }}
|
||||
{{ getCategoryLabel(cat) }}
|
||||
</n-tag>
|
||||
</n-flex>
|
||||
</n-flex>
|
||||
|
||||
Reference in New Issue
Block a user