1
0
mirror of https://github.com/1Panel-dev/1Panel.git synced 2025-03-13 17:24:44 +08:00

fix: 统一文件上传、删除接口

This commit is contained in:
ssongliu 2022-12-01 10:36:49 +08:00 committed by ssongliu
parent c11c3be0de
commit e66ce1a9f2
17 changed files with 304 additions and 195 deletions

View File

@ -1,8 +1,6 @@
package v1
import (
"errors"
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/constant"
@ -44,50 +42,6 @@ func (b *BaseApi) UpdateMysql(c *gin.Context) {
helper.SuccessWithData(c, nil)
}
func (b *BaseApi) UploadMysqlFiles(c *gin.Context) {
form, err := c.MultipartForm()
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
files := form.File["file"]
mysqlName, ok := c.Params.Get("mysqlName")
if !ok {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error mysqlName in path"))
return
}
if err := mysqlService.UpFile(mysqlName, files); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
func (b *BaseApi) MysqlUpList(c *gin.Context) {
var req dto.SearchDBWithPage
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
if err := global.VALID.Struct(req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
total, list, err := mysqlService.SearchUpListWithPage(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, dto.PageResult{
Items: list,
Total: total,
})
}
func (b *BaseApi) UpdateMysqlVariables(c *gin.Context) {
var req []dto.MysqlVariablesUpdate
if err := c.ShouldBindJSON(&req); err != nil {

View File

@ -128,24 +128,6 @@ func (b *BaseApi) RedisBackupList(c *gin.Context) {
})
}
func (b *BaseApi) RedisBackupDelete(c *gin.Context) {
var req dto.RedisBackupDelete
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
for _, name := range req.Names {
fullPath := fmt.Sprintf("%s/%s", req.FileDir, name)
if err := os.Remove(fullPath); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
}
helper.SuccessWithData(c, nil)
}
func (b *BaseApi) UpdateRedisConfByFile(c *gin.Context) {
var req dto.RedisConfUpdateByFile
if err := c.ShouldBindJSON(&req); err != nil {

View File

@ -1,10 +1,13 @@
package v1
import (
"errors"
"fmt"
"io/ioutil"
"net/http"
"os"
"path"
"strings"
"github.com/1Panel-dev/1Panel/backend/app/api/v1/helper"
"github.com/1Panel-dev/1Panel/backend/app/dto"
@ -71,6 +74,20 @@ func (b *BaseApi) DeleteFile(c *gin.Context) {
helper.SuccessWithData(c, nil)
}
func (b *BaseApi) BatchDeleteFile(c *gin.Context) {
var req dto.FileBatchDelete
if err := c.ShouldBindJSON(&req); err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
return
}
err := fileService.BatchDelete(req)
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrInternalServer, constant.ErrTypeInternalServer, err)
return
}
helper.SuccessWithData(c, nil)
}
func (b *BaseApi) ChangeFileMode(c *gin.Context) {
var req dto.FileCreate
if err := c.ShouldBindJSON(&req); err != nil {
@ -148,6 +165,19 @@ func (b *BaseApi) UploadFiles(c *gin.Context) {
}
files := form.File["file"]
paths := form.Value["path"]
if len(paths) == 0 || !strings.Contains(paths[0], "/") {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, errors.New("error paths in request"))
return
}
dir := paths[0][:strings.LastIndex(paths[0], "/")]
if _, err := os.Stat(dir); err != nil && os.IsNotExist(err) {
if err = os.MkdirAll(dir, os.ModePerm); err != nil {
if err != nil {
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, fmt.Errorf("mkdir %s failed, err: %v", dir, err))
return
}
}
}
success := 0
for _, file := range files {
err := c.SaveUploadedFile(file, path.Join(paths[0], file.Filename))

View File

@ -190,7 +190,3 @@ type RedisBackupRecover struct {
FileName string `json:"fileName"`
FileDir string `json:"fileDir"`
}
type RedisBackupDelete struct {
FileDir string `json:"fileDir"`
Names []string `json:"names"`
}

View File

@ -34,6 +34,11 @@ type FileDelete struct {
IsDir bool
}
type FileBatchDelete struct {
IsDir bool
Paths []string
}
type FileCompress struct {
Files []string
Dst string

View File

@ -6,9 +6,7 @@ import (
"context"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"mime/multipart"
"os"
"os/exec"
"path/filepath"
@ -38,9 +36,7 @@ type IMysqlService interface {
UpdateVariables(updatas []dto.MysqlVariablesUpdate) error
UpdateConfByFile(info dto.MysqlConfUpdateByFile) error
UpFile(mysqlName string, files []*multipart.FileHeader) error
RecoverByUpload(req dto.UploadRecover) error
SearchUpListWithPage(req dto.SearchDBWithPage) (int64, interface{}, error)
Backup(db dto.BackupDB) error
Recover(db dto.RecoverDB) error
@ -67,74 +63,6 @@ func (u *MysqlService) SearchWithPage(search dto.PageInfo) (int64, interface{},
return total, dtoMysqls, err
}
func (u *MysqlService) SearchUpListWithPage(req dto.SearchDBWithPage) (int64, interface{}, error) {
var (
list []dto.DatabaseFileRecords
backDatas []dto.DatabaseFileRecords
)
localDir, err := loadLocalDir()
if err != nil {
return 0, list, nil
}
uploadDir := fmt.Sprintf("%s/database/mysql/%s/upload", localDir, req.MysqlName)
if _, err := os.Stat(uploadDir); err != nil {
return 0, list, nil
}
_ = filepath.Walk(uploadDir, func(path string, info os.FileInfo, err error) error {
if err != nil {
return nil
}
if !info.IsDir() {
list = append(list, dto.DatabaseFileRecords{
CreatedAt: info.ModTime().Format("2006-01-02 15:04:05"),
Size: int(info.Size()),
FileDir: uploadDir,
FileName: info.Name(),
})
}
return nil
})
total, start, end := len(list), (req.Page-1)*req.PageSize, req.Page*req.PageSize
if start > total {
backDatas = make([]dto.DatabaseFileRecords, 0)
} else {
if end >= total {
end = total
}
backDatas = list[start:end]
}
return int64(total), backDatas, nil
}
func (u *MysqlService) UpFile(mysqlName string, files []*multipart.FileHeader) error {
localDir, err := loadLocalDir()
if err != nil {
return err
}
dstDir := fmt.Sprintf("%s/database/mysql/%s/upload", localDir, mysqlName)
if _, err := os.Stat(dstDir); err != nil && os.IsNotExist(err) {
if err = os.MkdirAll(dstDir, os.ModePerm); err != nil {
if err != nil {
return fmt.Errorf("mkdir %s failed, err: %v", dstDir, err)
}
}
}
for _, file := range files {
src, err := file.Open()
if err != nil {
return err
}
defer src.Close()
out, err := os.Create(dstDir + "/" + file.Filename)
if err != nil {
return err
}
defer out.Close()
_, _ = io.Copy(out, src)
}
return nil
}
func (u *MysqlService) RecoverByUpload(req dto.UploadRecover) error {
app, err := appInstallRepo.LoadBaseInfoByKey("mysql")
if err != nil {

View File

@ -2,17 +2,18 @@ package service
import (
"fmt"
"io/fs"
"os"
"path/filepath"
"strings"
"time"
"github.com/1Panel-dev/1Panel/backend/app/dto"
"github.com/1Panel-dev/1Panel/backend/global"
"github.com/1Panel-dev/1Panel/backend/utils/common"
"github.com/1Panel-dev/1Panel/backend/utils/files"
"github.com/pkg/errors"
uuid "github.com/satori/go.uuid"
"io/fs"
"os"
"path/filepath"
"strings"
"time"
)
type FileService struct {
@ -20,6 +21,9 @@ type FileService struct {
func (f FileService) GetFileList(op dto.FileOption) (dto.FileInfo, error) {
var fileInfo dto.FileInfo
if _, err := os.Stat(op.Path); err != nil && os.IsNotExist(err) {
return fileInfo, nil
}
info, err := files.NewFileInfo(op.FileOption)
if err != nil {
return fileInfo, err
@ -77,6 +81,24 @@ func (f FileService) Delete(op dto.FileDelete) error {
}
}
func (f FileService) BatchDelete(op dto.FileBatchDelete) error {
fo := files.NewFileOp()
if op.IsDir {
for _, file := range op.Paths {
if err := fo.DeleteDir(file); err != nil {
return err
}
}
} else {
for _, file := range op.Paths {
if err := fo.DeleteFile(file); err != nil {
return err
}
}
}
return nil
}
func (f FileService) ChangeMode(op dto.FileCreate) error {
fo := files.NewFileOp()
return fo.Chmod(op.Path, fs.FileMode(op.Mode))

View File

@ -24,8 +24,6 @@ func (s *DatabaseRouter) InitDatabaseRouter(Router *gin.RouterGroup) {
withRecordRouter.POST("", baseApi.CreateMysql)
withRecordRouter.PUT("/:id", baseApi.UpdateMysql)
withRecordRouter.POST("/backup", baseApi.BackupMysql)
cmdRouter.POST("/uplist", baseApi.MysqlUpList)
cmdRouter.POST("/uplist/upload/:mysqlName", baseApi.UploadMysqlFiles)
withRecordRouter.POST("/recover/byupload", baseApi.RecoverMysqlByUpload)
withRecordRouter.POST("/recover", baseApi.RecoverMysql)
withRecordRouter.POST("/del", baseApi.DeleteMysql)
@ -44,7 +42,6 @@ func (s *DatabaseRouter) InitDatabaseRouter(Router *gin.RouterGroup) {
cmdRouter.POST("/redis/backup", baseApi.RedisBackup)
cmdRouter.POST("/redis/recover", baseApi.RedisRecover)
cmdRouter.POST("/redis/backup/records", baseApi.RedisBackupList)
cmdRouter.POST("/redis/backup/del", baseApi.RedisBackupDelete)
cmdRouter.POST("/redis/conf/update", baseApi.UpdateRedisConf)
cmdRouter.POST("/redis/conf/update/byfile", baseApi.UpdateRedisConfByFile)
cmdRouter.POST("/redis/conf/update/persistence", baseApi.UpdateRedisPersistenceConf)

View File

@ -19,6 +19,7 @@ func (f *FileRouter) InitFileRouter(Router *gin.RouterGroup) {
fileRouter.POST("/tree", baseApi.GetFileTree)
fileRouter.POST("", baseApi.CreateFile)
fileRouter.POST("/del", baseApi.DeleteFile)
fileRouter.POST("/batch/del", baseApi.BatchDeleteFile)
fileRouter.POST("/mode", baseApi.ChangeFileMode)
fileRouter.POST("/compress", baseApi.CompressFile)
fileRouter.POST("/decompress", baseApi.DeCompressFile)

View File

@ -169,10 +169,6 @@ export namespace Database {
createdAt: string;
size: string;
}
export interface FileRecordDelete {
fileDir: string;
names: Array<string>;
}
export interface RedisRecover {
fileName: string;
fileDir: string;

View File

@ -51,6 +51,11 @@ export namespace File {
isDir: boolean;
}
export interface FileBatchDelete {
isDir: boolean;
paths: Array<string>;
}
export interface FileCompress {
files: string[];
type: string;

View File

@ -1,18 +1,11 @@
import http from '@/api';
import { ReqPage, ResPage } from '../interface';
import { Database } from '../interface/database';
import { File } from '@/api/interface/file';
export const searchMysqlDBs = (params: ReqPage) => {
return http.post<ResPage<Database.MysqlDBInfo>>(`/databases/search`, params);
};
export const searchUpList = (params: ReqPage) => {
return http.post<ResPage<Database.FileRecord>>(`/databases/uplist`, params);
};
export const uploadFile = (mysqlName: string, params: FormData) => {
return http.upload<File.File>(`/databases/uplist/upload/${mysqlName}`, params);
};
export const backup = (params: Database.Backup) => {
return http.post(`/databases/backup`, params);
};
@ -80,6 +73,3 @@ export const recoverRedis = (param: Database.RedisRecover) => {
export const redisBackupRedisRecords = (param: ReqPage) => {
return http.post<ResPage<Database.FileRecord>>(`/databases/redis/backup/records`, param);
};
export const deleteDatabaseFile = (param: Database.FileRecordDelete) => {
return http.post(`/databases/redis/backup/del`, param);
};

View File

@ -18,6 +18,10 @@ export const DeleteFile = (form: File.FileDelete) => {
return http.post<File.File>('files/del', form);
};
export const BatchDeleteFile = (form: File.FileBatchDelete) => {
return http.post('files/batch/del', form);
};
export const ChangeFileMode = (form: File.FileCreate) => {
return http.post<File.File>('files/mode', form);
};

View File

@ -40,14 +40,17 @@
</el-button>
</template>
<el-table-column type="selection" fix />
<el-table-column :label="$t('commons.table.name')" show-overflow-tooltip prop="fileName" />
<el-table-column :label="$t('file.dir')" show-overflow-tooltip prop="fileDir" />
<el-table-column :label="$t('commons.table.name')" show-overflow-tooltip prop="name" />
<el-table-column :label="$t('file.size')" prop="size">
<template #default="{ row }">
{{ computeSize(row.size) }}
</template>
</el-table-column>
<el-table-column :label="$t('commons.table.createdAt')" prop="createdAt" />
<el-table-column :label="$t('commons.table.createdAt')" min-width="80" fix>
<template #default="{ row }">
{{ dateFromat(0, 0, row.modTime) }}
</template>
</el-table-column>
<fu-table-operations
width="300px"
:buttons="buttons"
@ -63,14 +66,16 @@
<script lang="ts" setup>
import ComplexTable from '@/components/complex-table/index.vue';
import { reactive, ref } from 'vue';
import { computeSize } from '@/utils/util';
import { computeSize, dateFromat } from '@/utils/util';
import { useDeleteData } from '@/hooks/use-delete-data';
import { deleteDatabaseFile, recoverByUpload, searchUpList, uploadFile } from '@/api/modules/database';
import { recoverByUpload } from '@/api/modules/database';
import i18n from '@/lang';
import { ElMessage, UploadFile, UploadFiles, UploadInstance, UploadProps } from 'element-plus';
import { Database } from '@/api/interface/database';
import { File } from '@/api/interface/file';
import { BatchDeleteFile, GetFilesList, UploadFileData } from '@/api/modules/files';
const selects = ref<any>([]);
const baseDir = '/opt/1Panel/data/uploads/database/';
const data = ref();
const paginationConfig = reactive({
@ -97,19 +102,20 @@ const search = async () => {
let params = {
page: paginationConfig.currentPage,
pageSize: paginationConfig.pageSize,
mysqlName: mysqlName.value,
path: baseDir,
expand: true,
};
const res = await searchUpList(params);
const res = await GetFilesList(params);
data.value = res.data.items || [];
paginationConfig.total = res.data.total;
paginationConfig.total = res.data.itemTotal;
};
const onRecover = async (row: Database.FileRecord) => {
const onRecover = async (row: File.File) => {
let params = {
mysqlName: mysqlName.value,
dbName: dbName.value,
fileDir: row.fileDir,
fileName: row.fileName,
fileDir: baseDir,
fileName: row.name,
};
await recoverByUpload(params);
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
@ -150,39 +156,37 @@ const onSubmit = () => {
if (uploaderFiles.value[0]!.raw != undefined) {
formData.append('file', uploaderFiles.value[0]!.raw);
}
uploadFile(mysqlName.value, formData).then(() => {
formData.append('path', baseDir);
UploadFileData(formData, {}).then(() => {
ElMessage.success(i18n.global.t('file.uploadSuccess'));
handleClose();
search();
});
};
const onBatchDelete = async (row: Database.FileRecord | null) => {
let names: Array<string> = [];
let fileDir: string = '';
const onBatchDelete = async (row: File.File | null) => {
let files: Array<string> = [];
if (row) {
fileDir = row.fileDir;
names.push(row.fileName);
files.push(baseDir + row.name);
} else {
selects.value.forEach((item: Database.FileRecord) => {
fileDir = item.fileDir;
names.push(item.fileName);
selects.value.forEach((item: File.File) => {
files.push(baseDir + item.name);
});
}
await useDeleteData(deleteDatabaseFile, { fileDir: fileDir, names: names }, 'commons.msg.delete', true);
await useDeleteData(BatchDeleteFile, { paths: files, isDir: false }, 'commons.msg.delete', true);
search();
};
const buttons = [
{
label: i18n.global.t('commons.button.recover'),
click: (row: Database.FileRecord) => {
click: (row: File.File) => {
onRecover(row);
},
},
{
label: i18n.global.t('commons.button.delete'),
click: (row: Database.FileRecord) => {
click: (row: File.File) => {
onBatchDelete(row);
},
},

View File

@ -124,7 +124,6 @@ import ConfirmDialog from '@/components/confirm-dialog/index.vue';
import { Database } from '@/api/interface/database';
import {
backupRedis,
deleteDatabaseFile,
recoverRedis,
redisBackupRedisRecords,
RedisPersistenceConf,
@ -136,6 +135,7 @@ import { ElMessage, FormInstance } from 'element-plus';
import { reactive, ref } from 'vue';
import { useDeleteData } from '@/hooks/use-delete-data';
import { computeSize } from '@/utils/util';
import { BatchDeleteFile } from '@/api/modules/files';
interface saveStruct {
second: number;
@ -207,18 +207,15 @@ const onRecover = async () => {
};
const onBatchDelete = async (row: Database.FileRecord | null) => {
let names: Array<string> = [];
let fileDir: string = '';
let files: Array<string> = [];
if (row) {
fileDir = row.fileDir;
names.push(row.fileName);
files.push(row.fileDir + '/' + row.fileName);
} else {
selects.value.forEach((item: Database.FileRecord) => {
fileDir = item.fileDir;
names.push(item.fileName);
files.push(item.fileDir + '/' + item.fileName);
});
}
await useDeleteData(deleteDatabaseFile, { fileDir: fileDir, names: names }, 'commons.msg.delete', true);
await useDeleteData(BatchDeleteFile, { isDir: false, paths: files }, 'commons.msg.delete', true);
loadBackupRecords();
};
const buttons = [

View File

@ -63,7 +63,7 @@
<script lang="ts" setup>
import LayoutContent from '@/layout/layout-content.vue';
import BackupRecords from '@/views/website/website/backup/index.vue';
import UploadDialog from '@/views/database/mysql/upload/index.vue';
import UploadDialog from '@/views/website/website/upload/index.vue';
import ComplexTable from '@/components/complex-table/index.vue';
import { onMounted, reactive, ref } from '@vue/runtime-core';
import CreateWebSite from './create/index.vue';

View File

@ -0,0 +1,198 @@
<template>
<div>
<el-dialog v-model="upVisiable" :destroy-on-close="true" :close-on-click-modal="false" width="70%">
<template #header>
<div class="card-header">
<span>{{ $t('commons.button.import') }}</span>
</div>
</template>
<el-upload
ref="uploadRef"
:on-change="fileOnChange"
:before-upload="beforeAvatarUpload"
class="upload-demo"
:auto-upload="false"
>
<template #trigger>
<el-button type="primary" plain>{{ $t('database.selectFile') }}</el-button>
</template>
<el-button style="margin-left: 10px" icon="Upload" @click="onSubmit">
{{ $t('commons.button.upload') }}
</el-button>
</el-upload>
<div style="margin-left: 10px">
<span class="input-help">{{ $t('database.supportUpType') }}</span>
<span class="input-help">
{{ $t('database.zipFormat') }}
</span>
</div>
<el-divider />
<ComplexTable :pagination-config="paginationConfig" v-model:selects="selects" :data="data">
<template #toolbar>
<el-button
style="margin-left: 10px"
type="danger"
plain
:disabled="selects.length === 0"
@click="onBatchDelete(null)"
>
{{ $t('commons.button.delete') }}
</el-button>
</template>
<el-table-column type="selection" fix />
<el-table-column :label="$t('commons.table.name')" show-overflow-tooltip prop="name" />
<el-table-column :label="$t('file.size')" prop="size">
<template #default="{ row }">
{{ computeSize(row.size) }}
</template>
</el-table-column>
<el-table-column :label="$t('commons.table.createdAt')" min-width="80" fix>
<template #default="{ row }">
{{ dateFromat(0, 0, row.modTime) }}
</template>
</el-table-column>
<fu-table-operations
width="300px"
:buttons="buttons"
:ellipsis="10"
:label="$t('commons.table.operate')"
fix
/>
</ComplexTable>
</el-dialog>
</div>
</template>
<script lang="ts" setup>
import ComplexTable from '@/components/complex-table/index.vue';
import { reactive, ref } from 'vue';
import { computeSize, dateFromat } from '@/utils/util';
import { useDeleteData } from '@/hooks/use-delete-data';
import { recoverByUpload } from '@/api/modules/database';
import i18n from '@/lang';
import { ElMessage, UploadFile, UploadFiles, UploadInstance, UploadProps } from 'element-plus';
import { File } from '@/api/interface/file';
import { BatchDeleteFile, GetFilesList, UploadFileData } from '@/api/modules/files';
const selects = ref<any>([]);
const baseDir = '/opt/1Panel/data/uploads/website/';
const data = ref();
const paginationConfig = reactive({
currentPage: 1,
pageSize: 10,
total: 0,
});
const upVisiable = ref(false);
const mysqlName = ref();
const dbName = ref();
interface DialogProps {
mysqlName: string;
dbName: string;
}
const acceptParams = (params: DialogProps): void => {
mysqlName.value = params.mysqlName;
dbName.value = params.dbName;
upVisiable.value = true;
search();
};
const search = async () => {
let params = {
page: paginationConfig.currentPage,
pageSize: paginationConfig.pageSize,
path: baseDir,
expand: true,
};
const res = await GetFilesList(params);
data.value = res.data.items || [];
paginationConfig.total = res.data.itemTotal;
};
const onRecover = async (row: File.File) => {
let params = {
mysqlName: mysqlName.value,
dbName: dbName.value,
fileDir: baseDir,
fileName: row.name,
};
await recoverByUpload(params);
ElMessage.success(i18n.global.t('commons.msg.operationSuccess'));
};
const uploaderFiles = ref<UploadFiles>([]);
const uploadRef = ref<UploadInstance>();
const beforeAvatarUpload: UploadProps['beforeUpload'] = (rawFile) => {
if (
rawFile.name.endsWith('.sql') ||
rawFile.name.endsWith('.gz') ||
rawFile.name.endsWith('.zip') ||
rawFile.name.endsWith('.tgz')
) {
ElMessage.error(i18n.global.t('database.unSupportType'));
return false;
} else if (rawFile.size / 1024 / 1024 > 10) {
ElMessage.error(i18n.global.t('database.unSupportSize'));
return false;
}
return true;
};
const fileOnChange = (_uploadFile: UploadFile, uploadFiles: UploadFiles) => {
uploaderFiles.value = uploadFiles;
};
const handleClose = () => {
uploadRef.value!.clearFiles();
};
const onSubmit = () => {
const formData = new FormData();
if (uploaderFiles.value.length !== 1) {
return;
}
if (uploaderFiles.value[0]!.raw != undefined) {
formData.append('file', uploaderFiles.value[0]!.raw);
}
formData.append('path', baseDir);
UploadFileData(formData, {}).then(() => {
ElMessage.success(i18n.global.t('file.uploadSuccess'));
handleClose();
search();
});
};
const onBatchDelete = async (row: File.File | null) => {
let files: Array<string> = [];
if (row) {
files.push(baseDir + row.name);
} else {
selects.value.forEach((item: File.File) => {
files.push(baseDir + item.name);
});
}
await useDeleteData(BatchDeleteFile, { isDir: false, paths: files }, 'commons.msg.delete', true);
search();
};
const buttons = [
{
label: i18n.global.t('commons.button.recover'),
click: (row: File.File) => {
onRecover(row);
},
},
{
label: i18n.global.t('commons.button.delete'),
click: (row: File.File) => {
onBatchDelete(row);
},
},
];
defineExpose({
acceptParams,
});
</script>