From 48b06b25dabe24dc51043251da68533f61aa7038 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=80=97=E5=AD=90?= Date: Fri, 11 Oct 2024 01:39:47 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=A1=A5=E5=85=A8=E9=83=A8=E5=88=86?= =?UTF-8?q?=E9=9D=A2=E6=9D=BF=E5=91=BD=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/biz/app.go | 2 +- internal/data/app.go | 2 +- internal/route/http.go | 5 +- internal/service/app.go | 6 +- internal/service/cli.go | 102 ++++++++++++++++++++++++++++--- pkg/types/app.go | 4 +- web/src/api/panel/task/index.ts | 8 +-- web/src/router/index.ts | 4 +- web/src/views/task/IndexView.vue | 4 +- 9 files changed, 110 insertions(+), 27 deletions(-) diff --git a/internal/biz/app.go b/internal/biz/app.go index b27db9fa..fa227bdc 100644 --- a/internal/biz/app.go +++ b/internal/biz/app.go @@ -27,7 +27,7 @@ type AppRepo interface { GetHomeShow() ([]map[string]string, error) IsInstalled(query string, cond ...string) (bool, error) Install(channel, slug string) error - Uninstall(slug string) error + UnInstall(slug string) error Update(slug string) error UpdateShow(slug string, show bool) error UpdateCache() error diff --git a/internal/data/app.go b/internal/data/app.go index cfcaa782..2268b818 100644 --- a/internal/data/app.go +++ b/internal/data/app.go @@ -191,7 +191,7 @@ func (r *appRepo) Install(channel, slug string) error { return err } -func (r *appRepo) Uninstall(slug string) error { +func (r *appRepo) UnInstall(slug string) error { item, err := r.Get(slug) if err != nil { return err diff --git a/internal/route/http.go b/internal/route/http.go index 9a20265c..98e9dd52 100644 --- a/internal/route/http.go +++ b/internal/route/http.go @@ -38,13 +38,12 @@ func Http(r chi.Router) { }) r.Route("/task", func(r chi.Router) { - // TODO 修改前端 r.Use(middleware.MustLogin) task := service.NewTaskService() r.Get("/status", task.Status) r.Get("/", task.List) - r.Get("/{id}", task.Get) // TODO 修改前端 - r.Delete("/{id}", task.Delete) // TODO 修改前端 + r.Get("/{id}", task.Get) + r.Delete("/{id}", task.Delete) }) r.Route("/website", func(r chi.Router) { diff --git a/internal/service/app.go b/internal/service/app.go index 983e19db..493f48bd 100644 --- a/internal/service/app.go +++ b/internal/service/app.go @@ -34,7 +34,7 @@ func (s *AppService) List(w http.ResponseWriter, r *http.Request) { installedAppMap[p.Slug] = p } - var apps []types.StoreApp + var apps []types.AppCenter for _, item := range all { installed, installedChannel, installedVersion, updateExist, show := false, "", "", false, false if _, ok := installedAppMap[item.Slug]; ok { @@ -44,7 +44,7 @@ func (s *AppService) List(w http.ResponseWriter, r *http.Request) { updateExist = s.appRepo.UpdateExist(item.Slug) show = installedAppMap[item.Slug].Show } - apps = append(apps, types.StoreApp{ + apps = append(apps, types.AppCenter{ Name: item.Name, Description: item.Description, Slug: item.Slug, @@ -98,7 +98,7 @@ func (s *AppService) Uninstall(w http.ResponseWriter, r *http.Request) { return } - if err = s.appRepo.Uninstall(req.Slug); err != nil { + if err = s.appRepo.UnInstall(req.Slug); err != nil { Error(w, http.StatusInternalServerError, err.Error()) return } diff --git a/internal/service/cli.go b/internal/service/cli.go index 4691b4ec..272cedc9 100644 --- a/internal/service/cli.go +++ b/internal/service/cli.go @@ -23,13 +23,15 @@ import ( ) type CliService struct { - repo biz.UserRepo + app biz.AppRepo + user biz.UserRepo hash hash.Hasher } func NewCliService() *CliService { return &CliService{ - repo: data.NewUserRepo(), + app: data.NewAppRepo(), + user: data.NewUserRepo(), hash: hash.NewArgon2id(), } } @@ -236,37 +238,116 @@ func (s *CliService) CutoffWebsite(ctx context.Context, cmd *cli.Command) error } func (s *CliService) AppInstall(ctx context.Context, cmd *cli.Command) error { - println("Hello, World!") + channel := cmd.Args().Get(0) + slug := cmd.Args().Get(1) + if channel == "" || slug == "" { + return fmt.Errorf("参数不能为空") + } + + if err := s.app.Install(channel, slug); err != nil { + return fmt.Errorf("应用安装失败:%v", err) + } + + color.Greenln(fmt.Sprintf("已创建应用 %s 安装任务", slug)) + return nil } func (s *CliService) AppUnInstall(ctx context.Context, cmd *cli.Command) error { - println("Hello, World!") + slug := cmd.Args().First() + if slug == "" { + return fmt.Errorf("参数不能为空") + } + + if err := s.app.UnInstall(slug); err != nil { + return fmt.Errorf("应用卸载失败:%v", err) + } + + color.Greenln(fmt.Sprintf("已创建应用 %s 卸载任务", slug)) + return nil } func (s *CliService) AppWrite(ctx context.Context, cmd *cli.Command) error { - println("Hello, World!") + slug := cmd.Args().Get(0) + channel := cmd.Args().Get(1) + version := cmd.Args().Get(2) + if slug == "" || channel == "" || version == "" { + return fmt.Errorf("参数不能为空") + } + + newApp := new(biz.App) + if err := app.Orm.Where("slug", slug).First(newApp).Error; err != nil { + if !errors.Is(err, gorm.ErrRecordNotFound) { + return fmt.Errorf("获取应用失败:%v", err) + } + } + newApp.Slug = slug + newApp.Channel = channel + newApp.Version = version + if err := app.Orm.Save(newApp).Error; err != nil { + return fmt.Errorf("应用保存失败:%v", err) + } + return nil } func (s *CliService) AppRemove(ctx context.Context, cmd *cli.Command) error { - println("Hello, World!") + slug := cmd.Args().First() + if slug == "" { + return fmt.Errorf("参数不能为空") + } + + if err := app.Orm.Where("slug", slug).Delete(&biz.App{}).Error; err != nil { + return fmt.Errorf("应用删除失败:%v", err) + } + return nil } func (s *CliService) ClearTask(ctx context.Context, cmd *cli.Command) error { - println("Hello, World!") + if err := app.Orm.Model(&biz.Task{}). + Where("status", biz.TaskStatusRunning).Or("status", biz.TaskStatusWaiting). + Update("status", biz.TaskStatusFailed). + Error; err != nil { + return fmt.Errorf("任务清理失败:%v", err) + } + return nil } func (s *CliService) WriteSetting(ctx context.Context, cmd *cli.Command) error { - println("Hello, World!") + key := cmd.Args().Get(0) + value := cmd.Args().Get(1) + if key == "" || value == "" { + return fmt.Errorf("参数不能为空") + } + + setting := new(biz.Setting) + if err := app.Orm.Where("key", key).First(setting).Error; err != nil { + if !errors.Is(err, gorm.ErrRecordNotFound) { + return fmt.Errorf("获取设置失败:%v", err) + } + } + setting.Key = biz.SettingKey(key) + setting.Value = value + if err := app.Orm.Save(setting).Error; err != nil { + return fmt.Errorf("设置保存失败:%v", err) + } + return nil } func (s *CliService) RemoveSetting(ctx context.Context, cmd *cli.Command) error { - println("Hello, World!") + key := cmd.Args().First() + if key == "" { + return fmt.Errorf("参数不能为空") + } + + if err := app.Orm.Where("key", key).Delete(&biz.Setting{}).Error; err != nil { + return fmt.Errorf("设置删除失败:%v", err) + } + return nil } @@ -313,5 +394,6 @@ func (s *CliService) Init(ctx context.Context, cmd *cli.Command) error { return err } - return nil + // 初始化应用中心缓存 + return s.app.UpdateCache() } diff --git a/pkg/types/app.go b/pkg/types/app.go index fba070c3..a6e33985 100644 --- a/pkg/types/app.go +++ b/pkg/types/app.go @@ -8,8 +8,8 @@ type App struct { Route func(r chi.Router) `json:"-"` // 路由 } -// StoreApp 商店应用结构 -type StoreApp struct { +// AppCenter 应用中心结构 +type AppCenter struct { Name string `json:"name"` Description string `json:"description"` Slug string `json:"slug"` diff --git a/web/src/api/panel/task/index.ts b/web/src/api/panel/task/index.ts index cd5ae332..1e70d98c 100644 --- a/web/src/api/panel/task/index.ts +++ b/web/src/api/panel/task/index.ts @@ -7,9 +7,9 @@ export default { status: (): Promise> => request.get('/task/status'), // 获取任务列表 list: (page: number, limit: number): Promise> => - request.get('/task/list', { params: { page, limit } }), - // 获取任务日志 - log: (id: number): Promise> => request.get('/task/log', { params: { id } }), + request.get('/task', { params: { page, limit } }), + // 获取任务 + get: (id: number): Promise> => request.get('/task/' + id), // 删除任务 - delete: (id: number): Promise> => request.post('/task/delete', { id }) + delete: (id: number): Promise> => request.delete('/task/' + id) } diff --git a/web/src/router/index.ts b/web/src/router/index.ts index 1aaa3b1b..28389d50 100644 --- a/web/src/router/index.ts +++ b/web/src/router/index.ts @@ -1,4 +1,4 @@ -import { usePermissionStore } from '@/store' +import { usePermissionStore, useUserStore } from '@/store' import type { App } from 'vue' import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router' import type { RoutesType, RouteType } from '~/types/router' @@ -22,6 +22,8 @@ export async function setupRouter(app: App) { export async function addDynamicRoutes() { try { + const userStore = useUserStore() + await userStore.getUserInfo() const permissionStore = usePermissionStore() const accessRoutes = permissionStore.generateRoutes(['admin']) accessRoutes.forEach((route: RouteType) => { diff --git a/web/src/views/task/IndexView.vue b/web/src/views/task/IndexView.vue index 8e603e3e..64d4b69e 100644 --- a/web/src/views/task/IndexView.vue +++ b/web/src/views/task/IndexView.vue @@ -136,9 +136,9 @@ const handleDelete = (id: number) => { const handleShowLog = (id: number) => { task - .log(id) + .get(id) .then((res) => { - taskLog.value = res.data + taskLog.value = res.data.log }) .catch(() => { autoRefresh.value = false