diff --git a/internal/http/request/file.go b/internal/http/request/file.go index 6e76566a..16e6e126 100644 --- a/internal/http/request/file.go +++ b/internal/http/request/file.go @@ -1,5 +1,10 @@ package request +type FileList struct { + Path string `json:"path" form:"path" validate:"required"` + Sort string `json:"sort" form:"sort"` +} + type FilePath struct { Path string `json:"path" form:"path" validate:"required"` } diff --git a/internal/service/file.go b/internal/service/file.go index 8b42d61c..11d4f8a1 100644 --- a/internal/service/file.go +++ b/internal/service/file.go @@ -8,6 +8,7 @@ import ( "net/http" stdos "os" "path/filepath" + "slices" "strconv" "strings" "syscall" @@ -132,7 +133,7 @@ func (s *FileService) Upload(w http.ResponseWriter, r *http.Request) { return } if io.Exists(path) { - Error(w, http.StatusForbidden, "目标路径%s已存在", path) + Error(w, http.StatusForbidden, "目标路径 %s 已存在", path) return } @@ -168,7 +169,8 @@ func (s *FileService) Move(w http.ResponseWriter, r *http.Request) { } if io.Exists(req.Target) && !req.Force { - Error(w, http.StatusForbidden, "目标路径%s已存在", req.Target) + Error(w, http.StatusForbidden, "目标路径 %s 已存在", req.Target) + return } if err = io.Mv(req.Source, req.Target); err != nil { @@ -187,7 +189,8 @@ func (s *FileService) Copy(w http.ResponseWriter, r *http.Request) { } if io.Exists(req.Target) && !req.Force { - Error(w, http.StatusForbidden, "目标路径%s已存在", req.Target) + Error(w, http.StatusForbidden, "目标路径 %s 已存在", req.Target) + return } if err = io.Cp(req.Source, req.Target); err != nil { @@ -343,21 +346,41 @@ func (s *FileService) Search(w http.ResponseWriter, r *http.Request) { } func (s *FileService) List(w http.ResponseWriter, r *http.Request) { - req, err := Bind[request.FilePath](r) + req, err := Bind[request.FileList](r) if err != nil { Error(w, http.StatusInternalServerError, "%v", err) return } - fileInfoList, err := io.ReadDir(req.Path) + list, err := io.ReadDir(req.Path) if err != nil { Error(w, http.StatusInternalServerError, "%v", err) return } + if req.Sort == "asc" { + slices.SortFunc(list, func(a, b stdos.DirEntry) int { + return strings.Compare(strings.ToLower(b.Name()), strings.ToLower(a.Name())) + }) + } else if req.Sort == "desc" { + slices.SortFunc(list, func(a, b stdos.DirEntry) int { + return strings.Compare(strings.ToLower(a.Name()), strings.ToLower(b.Name())) + }) + } else { + slices.SortFunc(list, func(a, b stdos.DirEntry) int { + if a.IsDir() && !b.IsDir() { + return -1 + } + if !a.IsDir() && b.IsDir() { + return 1 + } + return strings.Compare(strings.ToLower(a.Name()), strings.ToLower(b.Name())) + }) + } + var paths []any - for _, fileInfo := range fileInfoList { - info, _ := fileInfo.Info() + for _, file := range list { + info, _ := file.Info() stat := info.Sys().(*syscall.Stat_t) paths = append(paths, map[string]any{ diff --git a/internal/service/file_windows.go b/internal/service/file_windows.go index 64485cf3..d6bafb70 100644 --- a/internal/service/file_windows.go +++ b/internal/service/file_windows.go @@ -10,6 +10,7 @@ import ( "net/http" stdos "os" "path/filepath" + "slices" "strconv" "strings" "time" @@ -132,7 +133,7 @@ func (s *FileService) Upload(w http.ResponseWriter, r *http.Request) { return } if io.Exists(path) { - Error(w, http.StatusForbidden, "目标路径%s已存在", path) + Error(w, http.StatusForbidden, "目标路径 %s 已存在", path) return } @@ -168,7 +169,8 @@ func (s *FileService) Move(w http.ResponseWriter, r *http.Request) { } if io.Exists(req.Target) && !req.Force { - Error(w, http.StatusForbidden, "目标路径"+req.Target+"已存在") + Error(w, http.StatusForbidden, "目标路径 %s 已存在", req.Target) + return } if err = io.Mv(req.Source, req.Target); err != nil { @@ -187,7 +189,8 @@ func (s *FileService) Copy(w http.ResponseWriter, r *http.Request) { } if io.Exists(req.Target) && !req.Force { - Error(w, http.StatusForbidden, "目标路径"+req.Target+"已存在") + Error(w, http.StatusForbidden, "目标路径 %s 已存在", req.Target) + return } if err = io.Cp(req.Source, req.Target); err != nil { @@ -330,21 +333,41 @@ func (s *FileService) Search(w http.ResponseWriter, r *http.Request) { } func (s *FileService) List(w http.ResponseWriter, r *http.Request) { - req, err := Bind[request.FilePath](r) + req, err := Bind[request.FileList](r) if err != nil { Error(w, http.StatusInternalServerError, "%v", err) return } - fileInfoList, err := io.ReadDir(req.Path) + list, err := io.ReadDir(req.Path) if err != nil { Error(w, http.StatusInternalServerError, "%v", err) return } + if req.Sort == "asc" { + slices.SortFunc(list, func(a, b stdos.DirEntry) int { + return strings.Compare(strings.ToLower(b.Name()), strings.ToLower(a.Name())) + }) + } else if req.Sort == "desc" { + slices.SortFunc(list, func(a, b stdos.DirEntry) int { + return strings.Compare(strings.ToLower(a.Name()), strings.ToLower(b.Name())) + }) + } else { + slices.SortFunc(list, func(a, b stdos.DirEntry) int { + if a.IsDir() && !b.IsDir() { + return -1 + } + if !a.IsDir() && b.IsDir() { + return 1 + } + return strings.Compare(strings.ToLower(a.Name()), strings.ToLower(b.Name())) + }) + } + var paths []any - for _, fileInfo := range fileInfoList { - info, _ := fileInfo.Info() + for _, file := range list { + info, _ := file.Info() paths = append(paths, map[string]any{ "name": info.Name(), diff --git a/web/src/api/panel/file/index.ts b/web/src/api/panel/file/index.ts index 7360961e..e2bd1673 100644 --- a/web/src/api/panel/file/index.ts +++ b/web/src/api/panel/file/index.ts @@ -53,6 +53,6 @@ export default { search: (keyword: string): Promise> => request.post('/file/search', { keyword }), // 获取文件列表 - list: (path: string, page: number, limit: number): Promise> => - request.get('/file/list', { params: { path, page, limit } }) + list: (path: string, page: number, limit: number, sort: string): Promise> => + request.get('/file/list', { params: { path, page, limit, sort } }) } diff --git a/web/src/views/file/ListTable.vue b/web/src/views/file/ListTable.vue index ebc8d829..7f677955 100644 --- a/web/src/views/file/ListTable.vue +++ b/web/src/views/file/ListTable.vue @@ -1,6 +1,7 @@