mirror of
https://github.com/acepanel/panel.git
synced 2026-02-04 06:47:20 +08:00
feat: 优化容器编排列表
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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}`),
|
||||
// 使用模版创建编排
|
||||
|
||||
@@ -262,7 +262,7 @@ const handlePrev = () => {
|
||||
}
|
||||
|
||||
const resetForm = () => {
|
||||
deployModel.name = ''
|
||||
deployModel.name = props.template?.slug || ''
|
||||
deployModel.autoStart = true
|
||||
deployModel.autoFirewall = false
|
||||
deployModel.envs = {}
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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')
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user