From 6ea1295f86af5e3a04e629dfe5186a10197cbb39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=97=E5=AD=90?= Date: Sun, 11 Jan 2026 00:34:20 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E9=A1=B9=E7=9B=AE=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E9=98=B6=E6=AE=B52?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/biz/project.go | 2 +- internal/data/project.go | 23 +-- internal/service/project.go | 4 +- web/src/api/panel/project/index.ts | 15 ++ web/src/views/project/CreateModal.vue | 8 + web/src/views/project/IndexView.vue | 12 +- web/src/views/project/ListView.vue | 211 ++++++++++++++++++++++++++ 7 files changed, 261 insertions(+), 14 deletions(-) create mode 100644 web/src/api/panel/project/index.ts create mode 100644 web/src/views/project/CreateModal.vue create mode 100644 web/src/views/project/ListView.vue diff --git a/internal/biz/project.go b/internal/biz/project.go index 54910147..dce55e7a 100644 --- a/internal/biz/project.go +++ b/internal/biz/project.go @@ -17,7 +17,7 @@ type Project struct { } type ProjectRepo interface { - List(page, limit uint) ([]*types.ProjectDetail, int64, error) + List(typ types.ProjectType, page, limit uint) ([]*types.ProjectDetail, int64, error) Get(id uint) (*types.ProjectDetail, error) Create(req *request.ProjectCreate) (*types.ProjectDetail, error) Update(req *request.ProjectUpdate) error diff --git a/internal/data/project.go b/internal/data/project.go index 47928336..8ed40055 100644 --- a/internal/data/project.go +++ b/internal/data/project.go @@ -21,27 +21,30 @@ import ( ) type projectRepo struct { - systemdDir string - t *gotext.Locale - db *gorm.DB + t *gotext.Locale + db *gorm.DB } func NewProjectRepo(t *gotext.Locale, db *gorm.DB) biz.ProjectRepo { return &projectRepo{ - systemdDir: "/etc/systemd/system", - t: t, - db: db, + t: t, + db: db, } } -func (r *projectRepo) List(page, limit uint) ([]*types.ProjectDetail, int64, error) { +func (r *projectRepo) List(typ types.ProjectType, page, limit uint) ([]*types.ProjectDetail, int64, error) { var projects []*biz.Project var total int64 - if err := r.db.Model(&biz.Project{}).Count(&total).Error; err != nil { + query := r.db.Model(&biz.Project{}) + if typ != "" { + query = query.Where("type = ?", typ) + } + + if err := query.Count(&total).Error; err != nil { return nil, 0, err } - if err := r.db.Offset(int((page - 1) * limit)).Limit(int(limit)).Order("id desc").Find(&projects).Error; err != nil { + if err := query.Offset(int((page - 1) * limit)).Limit(int(limit)).Order("id desc").Find(&projects).Error; err != nil { return nil, 0, err } @@ -148,7 +151,7 @@ func (r *projectRepo) Delete(id uint) error { // unitFilePath 返回 systemd unit 文件路径 func (r *projectRepo) unitFilePath(name string) string { - return filepath.Join(r.systemdDir, fmt.Sprintf("acepanel-project-%s.service", name)) + return filepath.Join("/etc/systemd/system", fmt.Sprintf("%s.service", name)) } // parseProjectDetail 从数据库记录和 systemd unit 文件解析项目详情 diff --git a/internal/service/project.go b/internal/service/project.go index f069b743..fa9af6ef 100644 --- a/internal/service/project.go +++ b/internal/service/project.go @@ -7,6 +7,7 @@ import ( "github.com/acepanel/panel/internal/biz" "github.com/acepanel/panel/internal/http/request" + "github.com/acepanel/panel/pkg/types" ) type ProjectService struct { @@ -26,7 +27,8 @@ func (s *ProjectService) List(w http.ResponseWriter, r *http.Request) { return } - projects, total, err := s.projectRepo.List(req.Page, req.Limit) + typ := types.ProjectType(r.URL.Query().Get("type")) + projects, total, err := s.projectRepo.List(typ, req.Page, req.Limit) if err != nil { Error(w, http.StatusInternalServerError, "%v", err) return diff --git a/web/src/api/panel/project/index.ts b/web/src/api/panel/project/index.ts new file mode 100644 index 00000000..31d8e338 --- /dev/null +++ b/web/src/api/panel/project/index.ts @@ -0,0 +1,15 @@ +import { http } from '@/utils' + +export default { + // 获取项目列表 + list: (type: string, page: number, limit: number): any => + http.Get('/project', { params: { type, page, limit } }), + // 获取项目详情 + get: (id: number): any => http.Get(`/project/${id}`), + // 创建项目 + create: (data: any): any => http.Post('/project', data), + // 更新项目 + update: (id: number, data: any): any => http.Put(`/project/${id}`, data), + // 删除项目 + delete: (id: number): any => http.Delete(`/project/${id}`) +} diff --git a/web/src/views/project/CreateModal.vue b/web/src/views/project/CreateModal.vue new file mode 100644 index 00000000..a8bcdb55 --- /dev/null +++ b/web/src/views/project/CreateModal.vue @@ -0,0 +1,8 @@ + + + + + diff --git a/web/src/views/project/IndexView.vue b/web/src/views/project/IndexView.vue index 75a8e50f..07165b89 100644 --- a/web/src/views/project/IndexView.vue +++ b/web/src/views/project/IndexView.vue @@ -3,20 +3,28 @@ defineOptions({ name: 'project-index' }) -const currentTab = ref('general') +import CreateModal from '@/views/project/CreateModal.vue' +import ListView from '@/views/project/ListView.vue' + +const currentTab = ref('all') + +const createModal = ref(false) diff --git a/web/src/views/project/ListView.vue b/web/src/views/project/ListView.vue new file mode 100644 index 00000000..738c5a93 --- /dev/null +++ b/web/src/views/project/ListView.vue @@ -0,0 +1,211 @@ + + +