From 58c5af686cd7785712eaa0b202416c479c6769b0 Mon Sep 17 00:00:00 2001 From: zhengkunwang223 <31820853+zhengkunwang223@users.noreply.github.com> Date: Wed, 24 Aug 2022 11:10:50 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=87=E4=BB=B6=E7=AE=A1=E7=90=86?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/api/v1/entry.go | 1 + backend/app/api/v1/file.go | 22 ++++ backend/app/dto/file.go | 11 ++ backend/app/service/entry.go | 1 + backend/app/service/file.go | 27 ++++ backend/init/router/router.go | 1 + backend/router/entry.go | 1 + backend/router/ro_file.go | 21 ++++ backend/utils/files/fileinfo.go | 123 +++++++++++++++++++ backend/utils/files/utils.go | 27 ++++ frontend/src/api/interface/file.ts | 22 ++-- frontend/src/api/modules/files.ts | 10 +- frontend/src/lang/modules/zh.ts | 2 + frontend/src/views/file-management/index.vue | 84 +++++++++---- 14 files changed, 315 insertions(+), 38 deletions(-) create mode 100644 backend/app/api/v1/file.go create mode 100644 backend/app/dto/file.go create mode 100644 backend/app/service/file.go create mode 100644 backend/router/ro_file.go create mode 100644 backend/utils/files/fileinfo.go create mode 100644 backend/utils/files/utils.go diff --git a/backend/app/api/v1/entry.go b/backend/app/api/v1/entry.go index 60b75b664..70c2a30b8 100644 --- a/backend/app/api/v1/entry.go +++ b/backend/app/api/v1/entry.go @@ -14,4 +14,5 @@ var ( groupService = service.ServiceGroupApp.GroupService commandService = service.ServiceGroupApp.CommandService operationService = service.ServiceGroupApp.OperationService + fileService = service.ServiceGroupApp.FileService ) diff --git a/backend/app/api/v1/file.go b/backend/app/api/v1/file.go new file mode 100644 index 000000000..136605c02 --- /dev/null +++ b/backend/app/api/v1/file.go @@ -0,0 +1,22 @@ +package v1 + +import ( + "github.com/1Panel-dev/1Panel/app/api/v1/helper" + "github.com/1Panel-dev/1Panel/app/dto" + "github.com/1Panel-dev/1Panel/constant" + "github.com/gin-gonic/gin" +) + +func (b *BaseApi) ListFiles(c *gin.Context) { + var req dto.FileOption + if err := c.ShouldBindJSON(&req); err != nil { + helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err) + return + } + files, err := fileService.GetFileList(req) + if err != nil { + helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err) + return + } + helper.SuccessWithData(c, files) +} diff --git a/backend/app/dto/file.go b/backend/app/dto/file.go new file mode 100644 index 000000000..b6312764d --- /dev/null +++ b/backend/app/dto/file.go @@ -0,0 +1,11 @@ +package dto + +import "github.com/1Panel-dev/1Panel/utils/files" + +type FileOption struct { + files.FileOption +} + +type FileInfo struct { + files.FileInfo +} diff --git a/backend/app/service/entry.go b/backend/app/service/entry.go index b1ba8e5b4..742388ac0 100644 --- a/backend/app/service/entry.go +++ b/backend/app/service/entry.go @@ -8,6 +8,7 @@ type ServiceGroup struct { GroupService CommandService OperationService + FileService } var ServiceGroupApp = new(ServiceGroup) diff --git a/backend/app/service/file.go b/backend/app/service/file.go new file mode 100644 index 000000000..cc9b5d0fb --- /dev/null +++ b/backend/app/service/file.go @@ -0,0 +1,27 @@ +package service + +import ( + "github.com/1Panel-dev/1Panel/app/dto" + "github.com/1Panel-dev/1Panel/utils/files" +) + +type FileService struct { +} + +type IFileService interface { + GetFileList(op dto.FileOption) (dto.FileInfo, error) +} + +func NewFileService() IFileService { + return FileService{} +} + +func (f FileService) GetFileList(op dto.FileOption) (dto.FileInfo, error) { + var fileInfo dto.FileInfo + info, err := files.NewFileInfo(op.FileOption) + if err != nil { + return fileInfo, err + } + fileInfo.FileInfo = *info + return fileInfo, nil +} diff --git a/backend/init/router/router.go b/backend/init/router/router.go index a3f75b973..3a4c010ba 100644 --- a/backend/init/router/router.go +++ b/backend/init/router/router.go @@ -44,6 +44,7 @@ func Routers() *gin.Engine { systemRouter.InitCommandRouter(PrivateGroup) systemRouter.InitTerminalRouter(PrivateGroup) systemRouter.InitOperationLogRouter(PrivateGroup) + systemRouter.InitFileRouter(PrivateGroup) } return Router diff --git a/backend/router/entry.go b/backend/router/entry.go index 1865a1bd8..ed7444635 100644 --- a/backend/router/entry.go +++ b/backend/router/entry.go @@ -7,6 +7,7 @@ type RouterGroup struct { GroupRouter CommandRouter OperationLogRouter + FileRouter } var RouterGroupApp = new(RouterGroup) diff --git a/backend/router/ro_file.go b/backend/router/ro_file.go new file mode 100644 index 000000000..71fe5b51d --- /dev/null +++ b/backend/router/ro_file.go @@ -0,0 +1,21 @@ +package router + +import ( + v1 "github.com/1Panel-dev/1Panel/app/api/v1" + "github.com/1Panel-dev/1Panel/middleware" + "github.com/gin-gonic/gin" +) + +type FileRouter struct { +} + +func (f *FileRouter) InitFileRouter(Router *gin.RouterGroup) { + fileRouter := Router.Group("files") + fileRouter.Use(middleware.JwtAuth()).Use(middleware.SessionAuth()) + //withRecordRouter := fileRouter.Use(middleware.OperationRecord()) + baseApi := v1.ApiGroupApp.BaseApi + { + fileRouter.POST("/search", baseApi.ListFiles) + } + +} diff --git a/backend/utils/files/fileinfo.go b/backend/utils/files/fileinfo.go new file mode 100644 index 000000000..3e7617ef9 --- /dev/null +++ b/backend/utils/files/fileinfo.go @@ -0,0 +1,123 @@ +package files + +import ( + "fmt" + "github.com/spf13/afero" + "os" + "path" + "path/filepath" + "syscall" + "time" +) + +type FileInfo struct { + Fs afero.Fs `json:"-"` + Path string `json:"path"` + Name string `json:"name"` + User string `json:"user"` + Group string `json:"group"` + Extension string `json:"extension"` + Content string `json:"content"` + Size int64 `json:"size"` + IsDir bool `json:"isDir"` + IsSymlink bool `json:"isSymlink"` + Type string `json:"type"` + Mode string `json:"mode"` + UpdateTime time.Time `json:"updateTime"` + ModTime time.Time `json:"modTime"` + FileMode os.FileMode `json:"-"` + Items []*FileInfo `json:"items"` +} + +type FileOption struct { + Path string `json:"path"` + Search string `json:"search"` + Expand bool `json:"expand"` +} + +func NewFileInfo(op FileOption) (*FileInfo, error) { + var appFs = afero.NewOsFs() + + info, err := appFs.Stat(op.Path) + if err != nil { + return nil, err + } + + file := &FileInfo{ + Fs: appFs, + Path: op.Path, + Name: info.Name(), + IsDir: info.IsDir(), + FileMode: info.Mode(), + ModTime: info.ModTime(), + Size: info.Size(), + IsSymlink: IsSymlink(info.Mode()), + Extension: filepath.Ext(info.Name()), + Mode: fmt.Sprintf("%04o", info.Mode().Perm()), + User: GetUsername(info.Sys().(*syscall.Stat_t).Uid), + Group: GetGroup(info.Sys().(*syscall.Stat_t).Gid), + } + if op.Expand { + if file.IsDir { + if err := file.listChildren(); err != nil { + return nil, err + } + return file, nil + } else { + if err := file.getContent(); err != nil { + return nil, err + } + } + } + return file, nil +} + +func (f *FileInfo) listChildren() error { + afs := &afero.Afero{Fs: f.Fs} + dir, err := afs.ReadDir(f.Path) + if err != nil { + return err + } + var items []*FileInfo + for _, df := range dir { + name := df.Name() + fPath := path.Join(f.Path, df.Name()) + + isSymlink, isInvalidLink := false, false + if IsSymlink(df.Mode()) { + isSymlink = true + info, err := f.Fs.Stat(fPath) + if err == nil { + df = info + } else { + isInvalidLink = true + } + } + + file := &FileInfo{ + Fs: f.Fs, + Name: name, + Size: df.Size(), + ModTime: df.ModTime(), + FileMode: df.Mode(), + IsDir: df.IsDir(), + IsSymlink: isSymlink, + Extension: filepath.Ext(name), + Path: fPath, + Mode: fmt.Sprintf("%04o", df.Mode().Perm()), + User: GetUsername(df.Sys().(*syscall.Stat_t).Uid), + Group: GetGroup(df.Sys().(*syscall.Stat_t).Gid), + } + + if isInvalidLink { + file.Type = "invalid_link" + } + items = append(items, file) + } + f.Items = items + return nil +} + +func (f *FileInfo) getContent() error { + return nil +} diff --git a/backend/utils/files/utils.go b/backend/utils/files/utils.go new file mode 100644 index 000000000..a647eb403 --- /dev/null +++ b/backend/utils/files/utils.go @@ -0,0 +1,27 @@ +package files + +import ( + "os" + "os/user" + "strconv" +) + +func IsSymlink(mode os.FileMode) bool { + return mode&os.ModeSymlink != 0 +} + +func GetUsername(uid uint32) string { + usr, err := user.LookupId(strconv.Itoa(int(uid))) + if err != nil { + return "" + } + return usr.Username +} + +func GetGroup(gid uint32) string { + usr, err := user.LookupGroupId(strconv.Itoa(int(gid))) + if err != nil { + return "" + } + return usr.Name +} diff --git a/frontend/src/api/interface/file.ts b/frontend/src/api/interface/file.ts index 4b50d6836..40ef77a6a 100644 --- a/frontend/src/api/interface/file.ts +++ b/frontend/src/api/interface/file.ts @@ -1,16 +1,24 @@ import { CommonModel } from '.'; export namespace File { export interface File extends CommonModel { + path: string; name: string; - mode: number; user: string; group: string; - updateDate: string; - isDir: boolean; - isLink: boolean; - path: string; + content: string; size: number; - accessTime: string; - changeTime: string; + isDir: boolean; + isSymlink: boolean; + type: string; + updateTime: string; + modTime: string; + mode: number; + items: File[]; + } + + export interface ReqFile { + path: string; + search?: string; + expand: boolean; } } diff --git a/frontend/src/api/modules/files.ts b/frontend/src/api/modules/files.ts index c77b5b9f1..dd4b7c1c3 100644 --- a/frontend/src/api/modules/files.ts +++ b/frontend/src/api/modules/files.ts @@ -1,7 +1,7 @@ -// import { File } from '@/api/interface/file'; -import files from '@/api/interface/files.json'; +import { File } from '@/api/interface/file'; +import http from '@/api'; +import { ResultData } from '@/api/interface'; -export const GetFilesList = () => { - // return http.post(`/auth/login`, params); - return files; +export const GetFilesList = (params: File.ReqFile) => { + return http.post>('files/search', params); }; diff --git a/frontend/src/lang/modules/zh.ts b/frontend/src/lang/modules/zh.ts index 427672b19..9d82f921d 100644 --- a/frontend/src/lang/modules/zh.ts +++ b/frontend/src/lang/modules/zh.ts @@ -174,5 +174,7 @@ export default { terminal: '终端', shareList: '分享列表', zip: '压缩', + user: '用户', + group: '组', }, }; diff --git a/frontend/src/views/file-management/index.vue b/frontend/src/views/file-management/index.vue index 007152fb6..14dca1799 100644 --- a/frontend/src/views/file-management/index.vue +++ b/frontend/src/views/file-management/index.vue @@ -2,7 +2,7 @@ - +