2
0
mirror of https://github.com/acepanel/panel.git synced 2026-02-04 06:47:20 +08:00

feat: 优化容器编排列表

This commit is contained in:
2026-01-16 23:42:02 +08:00
parent e205f51197
commit 980b3674b0
7 changed files with 51 additions and 15 deletions

View File

@@ -67,6 +67,12 @@ func (r *templateRepo) Callback(slug string) error {
// CreateCompose 创建编排
func (r *templateRepo) CreateCompose(name, compose string, envs []types.KV, autoFirewall bool) (string, error) {
dir := filepath.Join(app.Root, "compose", name)
// 检查编排是否已存在
if _, err := os.Stat(dir); err == nil {
return "", errors.New(r.t.Get("compose %s already exists", name))
}
if err := os.MkdirAll(dir, 0755); err != nil {
return "", err
}

View File

@@ -26,7 +26,15 @@ func NewTemplateService(t *gotext.Locale, template biz.TemplateRepo, setting biz
// List 获取所有模版
func (s *TemplateService) List(w http.ResponseWriter, r *http.Request) {
paged, total := Paginate(r, s.templateRepo.List())
category := r.URL.Query().Get("category")
templates := s.templateRepo.List()
// 按分类过滤
if category != "" {
templates = templates.FilterByCategory(category)
}
paged, total := Paginate(r, templates)
Success(w, chix.M{
"total": total,
"items": paged,

View File

@@ -27,6 +27,20 @@ type Template struct {
type Templates []*Template
// FilterByCategory 按分类过滤模版
func (t Templates) FilterByCategory(category string) Templates {
filtered := make(Templates, 0)
for _, tpl := range t {
for _, cat := range tpl.Categories {
if cat == category {
filtered = append(filtered, tpl)
break
}
}
}
return filtered
}
// Templates 返回所有模版
func (r *API) Templates() (*Templates, error) {
resp, err := r.client.R().SetResult(&Response{}).Get("/templates")

View File

@@ -2,7 +2,8 @@ import { http } from '@/utils'
export default {
// 获取模版列表
list: (page: number, pageSize: number): any => http.Get(`/template?page=${page}&limit=${pageSize}`),
list: (page: number, pageSize: number, category?: string): any =>
http.Get(`/template`, { params: { page, limit: pageSize, category } }),
// 获取模版详情
get: (slug: string): any => http.Get(`/template/${slug}`),
// 使用模版创建编排

View File

@@ -262,7 +262,7 @@ const handlePrev = () => {
}
const resetForm = () => {
deployModel.name = ''
deployModel.name = props.template?.slug || ''
deployModel.autoStart = true
deployModel.autoFirewall = false
deployModel.envs = {}

View File

@@ -25,7 +25,7 @@ const deployModalShow = ref(false)
const selectedTemplate = ref<Template | null>(null)
const { loading, data, page, total, pageSize, pageCount, refresh } = usePagination(
(page, pageSize) => template.list(page, pageSize),
(page, pageSize) => template.list(page, pageSize, selectedCategory.value || undefined),
{
initialData: { total: 0, list: [] },
initialPageSize: 12,
@@ -39,14 +39,6 @@ const { data: categories } = useRequest(app.categories, {
initialData: []
})
// 过滤后的模版列表
const filteredTemplates = computed(() => {
if (!selectedCategory.value) {
return data.value || []
}
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
@@ -54,6 +46,8 @@ const getCategoryLabel = (catValue: string) => {
const handleCategoryChange = (category: string) => {
selectedCategory.value = category
page.value = 1
refresh()
}
const handleDeploy = (tpl: Template) => {
@@ -91,7 +85,7 @@ onMounted(() => {
<n-spin :show="loading">
<n-grid :x-gap="16" :y-gap="16" cols="1 s:2 m:3 l:4" responsive="screen">
<n-grid-item v-for="tpl in filteredTemplates" :key="tpl.slug">
<n-grid-item v-for="tpl in data" :key="tpl.slug">
<n-card hoverable style="height: 100%">
<n-flex vertical :size="12">
<n-flex justify="space-between" align="center">
@@ -138,7 +132,7 @@ onMounted(() => {
</n-grid-item>
</n-grid>
<n-empty v-if="!loading && filteredTemplates.length === 0" />
<n-empty v-if="!loading && data.length === 0" />
</n-spin>
<n-flex justify="end" v-if="total > 12">

View File

@@ -60,7 +60,20 @@ const columns: any = [
return h(
NTag,
{ type: row.status === 'active' ? 'success' : 'default' },
{ default: () => (row.status === 'active' ? $gettext('Running') : $gettext('Stopped')) }
{
default: () => {
switch (row.status) {
case 'active':
return $gettext('Running')
case 'inactive':
return $gettext('Stopped')
case 'failed':
return $gettext('Failed')
default:
return $gettext('Inactive')
}
}
}
)
}
},