fix: 上传备份文件名限制
This commit is contained in:
@@ -323,6 +323,34 @@ func (b *BaseApi) UploadFiles(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @Tags File
|
||||||
|
// @Summary Check file exist
|
||||||
|
// @Description 检测文件是否存在
|
||||||
|
// @Accept json
|
||||||
|
// @Param request body request.FilePathCheck true "request"
|
||||||
|
// @Success 200
|
||||||
|
// @Security ApiKeyAuth
|
||||||
|
// @Router /files/check [post]
|
||||||
|
// @x-panel-log {"bodyKeys":["path"],"paramKeys":[],"BeforeFuntions":[],"formatZH":"检测文件 [path] 是否存在","formatEN":"Check whether file [path] exists"}
|
||||||
|
func (b *BaseApi) CheckFile(c *gin.Context) {
|
||||||
|
var req request.FilePathCheck
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := os.Stat(req.Path); err != nil && os.IsNotExist(err) {
|
||||||
|
helper.SuccessWithData(c, true)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
helper.SuccessWithData(c, false)
|
||||||
|
}
|
||||||
|
|
||||||
// @Tags File
|
// @Tags File
|
||||||
// @Summary Change file name
|
// @Summary Change file name
|
||||||
// @Description 修改文件名称
|
// @Description 修改文件名称
|
||||||
|
|||||||
@@ -58,6 +58,10 @@ type FileRename struct {
|
|||||||
NewName string `json:"newName" validate:"required"`
|
NewName string `json:"newName" validate:"required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type FilePathCheck struct {
|
||||||
|
Path string `json:"path" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
type FileWget struct {
|
type FileWget struct {
|
||||||
Url string `json:"url" validate:"required"`
|
Url string `json:"url" validate:"required"`
|
||||||
Path string `json:"path" validate:"required"`
|
Path string `json:"path" validate:"required"`
|
||||||
|
|||||||
@@ -99,7 +99,7 @@ func (u *BackupService) MysqlRecoverByUpload(req dto.CommonRecover) error {
|
|||||||
})
|
})
|
||||||
if !hasTestSql {
|
if !hasTestSql {
|
||||||
_ = os.RemoveAll(dstDir)
|
_ = os.RemoveAll(dstDir)
|
||||||
return fmt.Errorf("no such file named test.sql in %s, err: %v", fileName, err)
|
return fmt.Errorf("no such file named test.sql in %s", fileName)
|
||||||
}
|
}
|
||||||
defer func() {
|
defer func() {
|
||||||
_ = os.RemoveAll(dstDir)
|
_ = os.RemoveAll(dstDir)
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ func (f *FileRouter) InitFileRouter(Router *gin.RouterGroup) {
|
|||||||
fileRouter.POST("/decompress", baseApi.DeCompressFile)
|
fileRouter.POST("/decompress", baseApi.DeCompressFile)
|
||||||
fileRouter.POST("/content", baseApi.GetContent)
|
fileRouter.POST("/content", baseApi.GetContent)
|
||||||
fileRouter.POST("/save", baseApi.SaveContent)
|
fileRouter.POST("/save", baseApi.SaveContent)
|
||||||
|
fileRouter.POST("/check", baseApi.CheckFile)
|
||||||
fileRouter.POST("/upload", baseApi.UploadFiles)
|
fileRouter.POST("/upload", baseApi.UploadFiles)
|
||||||
fileRouter.POST("/rename", baseApi.ChangeFileName)
|
fileRouter.POST("/rename", baseApi.ChangeFileName)
|
||||||
fileRouter.POST("/wget", baseApi.WgetFile)
|
fileRouter.POST("/wget", baseApi.WgetFile)
|
||||||
|
|||||||
@@ -3857,6 +3857,48 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/files/check": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "检测文件是否存在",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"File"
|
||||||
|
],
|
||||||
|
"summary": "Check file exist",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/request.FilePathCheck"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-panel-log": {
|
||||||
|
"BeforeFuntions": [],
|
||||||
|
"bodyKeys": [
|
||||||
|
"path"
|
||||||
|
],
|
||||||
|
"formatEN": "Check whether file [path] exists",
|
||||||
|
"formatZH": "检测文件 [path] 是否存在",
|
||||||
|
"paramKeys": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/files/compress": {
|
"/files/compress": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -9603,10 +9645,6 @@ var doc = `{
|
|||||||
},
|
},
|
||||||
"dto.Login": {
|
"dto.Login": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"name",
|
|
||||||
"password"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"authMethod": {
|
"authMethod": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -9627,11 +9665,6 @@ var doc = `{
|
|||||||
},
|
},
|
||||||
"dto.MFALogin": {
|
"dto.MFALogin": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"name",
|
|
||||||
"password",
|
|
||||||
"secret"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"authMethod": {
|
"authMethod": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -10959,6 +10992,9 @@ var doc = `{
|
|||||||
"deleteBackup": {
|
"deleteBackup": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
"deleteDB": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"detailId": {
|
"detailId": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
@@ -11159,11 +11195,15 @@ var doc = `{
|
|||||||
"request.FileDownload": {
|
"request.FileDownload": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
|
"compress",
|
||||||
"name",
|
"name",
|
||||||
"paths",
|
"paths",
|
||||||
"type"
|
"type"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"compress": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -11244,6 +11284,17 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"request.FilePathCheck": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"path"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"path": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"request.FileRename": {
|
"request.FileRename": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
|
|||||||
@@ -3843,6 +3843,48 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/files/check": {
|
||||||
|
"post": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"ApiKeyAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "检测文件是否存在",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"File"
|
||||||
|
],
|
||||||
|
"summary": "Check file exist",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"description": "request",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/request.FilePathCheck"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"x-panel-log": {
|
||||||
|
"BeforeFuntions": [],
|
||||||
|
"bodyKeys": [
|
||||||
|
"path"
|
||||||
|
],
|
||||||
|
"formatEN": "Check whether file [path] exists",
|
||||||
|
"formatZH": "检测文件 [path] 是否存在",
|
||||||
|
"paramKeys": []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/files/compress": {
|
"/files/compress": {
|
||||||
"post": {
|
"post": {
|
||||||
"security": [
|
"security": [
|
||||||
@@ -9589,10 +9631,6 @@
|
|||||||
},
|
},
|
||||||
"dto.Login": {
|
"dto.Login": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"name",
|
|
||||||
"password"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"authMethod": {
|
"authMethod": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -9613,11 +9651,6 @@
|
|||||||
},
|
},
|
||||||
"dto.MFALogin": {
|
"dto.MFALogin": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
|
||||||
"name",
|
|
||||||
"password",
|
|
||||||
"secret"
|
|
||||||
],
|
|
||||||
"properties": {
|
"properties": {
|
||||||
"authMethod": {
|
"authMethod": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -10945,6 +10978,9 @@
|
|||||||
"deleteBackup": {
|
"deleteBackup": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
|
"deleteDB": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"detailId": {
|
"detailId": {
|
||||||
"type": "integer"
|
"type": "integer"
|
||||||
},
|
},
|
||||||
@@ -11145,11 +11181,15 @@
|
|||||||
"request.FileDownload": {
|
"request.FileDownload": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
|
"compress",
|
||||||
"name",
|
"name",
|
||||||
"paths",
|
"paths",
|
||||||
"type"
|
"type"
|
||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
|
"compress": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"name": {
|
"name": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@@ -11230,6 +11270,17 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"request.FilePathCheck": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"path"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"path": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"request.FileRename": {
|
"request.FileRename": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": [
|
"required": [
|
||||||
|
|||||||
@@ -839,9 +839,6 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
password:
|
password:
|
||||||
type: string
|
type: string
|
||||||
required:
|
|
||||||
- name
|
|
||||||
- password
|
|
||||||
type: object
|
type: object
|
||||||
dto.MFALogin:
|
dto.MFALogin:
|
||||||
properties:
|
properties:
|
||||||
@@ -855,10 +852,6 @@ definitions:
|
|||||||
type: string
|
type: string
|
||||||
secret:
|
secret:
|
||||||
type: string
|
type: string
|
||||||
required:
|
|
||||||
- name
|
|
||||||
- password
|
|
||||||
- secret
|
|
||||||
type: object
|
type: object
|
||||||
dto.MfaCredential:
|
dto.MfaCredential:
|
||||||
properties:
|
properties:
|
||||||
@@ -1723,6 +1716,8 @@ definitions:
|
|||||||
type: integer
|
type: integer
|
||||||
deleteBackup:
|
deleteBackup:
|
||||||
type: boolean
|
type: boolean
|
||||||
|
deleteDB:
|
||||||
|
type: boolean
|
||||||
detailId:
|
detailId:
|
||||||
type: integer
|
type: integer
|
||||||
forceDelete:
|
forceDelete:
|
||||||
@@ -1859,6 +1854,8 @@ definitions:
|
|||||||
type: object
|
type: object
|
||||||
request.FileDownload:
|
request.FileDownload:
|
||||||
properties:
|
properties:
|
||||||
|
compress:
|
||||||
|
type: boolean
|
||||||
name:
|
name:
|
||||||
type: string
|
type: string
|
||||||
paths:
|
paths:
|
||||||
@@ -1868,6 +1865,7 @@ definitions:
|
|||||||
type:
|
type:
|
||||||
type: string
|
type: string
|
||||||
required:
|
required:
|
||||||
|
- compress
|
||||||
- name
|
- name
|
||||||
- paths
|
- paths
|
||||||
- type
|
- type
|
||||||
@@ -1916,6 +1914,13 @@ definitions:
|
|||||||
showHidden:
|
showHidden:
|
||||||
type: boolean
|
type: boolean
|
||||||
type: object
|
type: object
|
||||||
|
request.FilePathCheck:
|
||||||
|
properties:
|
||||||
|
path:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- path
|
||||||
|
type: object
|
||||||
request.FileRename:
|
request.FileRename:
|
||||||
properties:
|
properties:
|
||||||
newName:
|
newName:
|
||||||
@@ -5033,6 +5038,33 @@ paths:
|
|||||||
formatEN: Batch delete dir or file [paths]
|
formatEN: Batch delete dir or file [paths]
|
||||||
formatZH: 批量删除文件/文件夹 [paths]
|
formatZH: 批量删除文件/文件夹 [paths]
|
||||||
paramKeys: []
|
paramKeys: []
|
||||||
|
/files/check:
|
||||||
|
post:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 检测文件是否存在
|
||||||
|
parameters:
|
||||||
|
- description: request
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/request.FilePathCheck'
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: ""
|
||||||
|
security:
|
||||||
|
- ApiKeyAuth: []
|
||||||
|
summary: Check file exist
|
||||||
|
tags:
|
||||||
|
- File
|
||||||
|
x-panel-log:
|
||||||
|
BeforeFuntions: []
|
||||||
|
bodyKeys:
|
||||||
|
- path
|
||||||
|
formatEN: Check whether file [path] exists
|
||||||
|
formatZH: 检测文件 [path] 是否存在
|
||||||
|
paramKeys: []
|
||||||
/files/compress:
|
/files/compress:
|
||||||
post:
|
post:
|
||||||
consumes:
|
consumes:
|
||||||
|
|||||||
@@ -51,6 +51,10 @@ export const SaveFileContent = (params: File.FileEdit) => {
|
|||||||
return http.post<File.File>('files/save', params);
|
return http.post<File.File>('files/save', params);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const CheckFile = (path: string) => {
|
||||||
|
return http.post<boolean>('files/check', { path: path });
|
||||||
|
};
|
||||||
|
|
||||||
export const UploadFileData = (params: FormData, config: AxiosRequestConfig) => {
|
export const UploadFileData = (params: FormData, config: AxiosRequestConfig) => {
|
||||||
return http.upload<File.File>('files/upload', params, config);
|
return http.upload<File.File>('files/upload', params, config);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ import i18n from '@/lang';
|
|||||||
import { UploadFile, UploadFiles, UploadInstance } from 'element-plus';
|
import { UploadFile, UploadFiles, UploadInstance } from 'element-plus';
|
||||||
import { File } from '@/api/interface/file';
|
import { File } from '@/api/interface/file';
|
||||||
import DrawerHeader from '@/components/drawer-header/index.vue';
|
import DrawerHeader from '@/components/drawer-header/index.vue';
|
||||||
import { BatchDeleteFile, GetUploadList, UploadFileData } from '@/api/modules/files';
|
import { BatchDeleteFile, CheckFile, GetUploadList, UploadFileData } from '@/api/modules/files';
|
||||||
import { loadBaseDir } from '@/api/modules/setting';
|
import { loadBaseDir } from '@/api/modules/setting';
|
||||||
import { MsgError, MsgSuccess } from '@/utils/message';
|
import { MsgError, MsgSuccess } from '@/utils/message';
|
||||||
|
|
||||||
@@ -190,14 +190,26 @@ const handleClose = () => {
|
|||||||
upVisiable.value = false;
|
upVisiable.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
const onSubmit = () => {
|
const onSubmit = async () => {
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
if (uploaderFiles.value.length !== 1) {
|
if (uploaderFiles.value.length !== 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (uploaderFiles.value[0]!.raw != undefined) {
|
if (!uploaderFiles.value[0]!.raw.name) {
|
||||||
formData.append('file', uploaderFiles.value[0]!.raw);
|
MsgError(i18n.global.t('commons.msg.fileNameErr'));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
let reg = /^[a-zA-Z0-9\u4e00-\u9fa5]{1}[a-z:A-Z0-9_.\u4e00-\u9fa5-]{0,50}$/;
|
||||||
|
if (!reg.test(uploaderFiles.value[0]!.raw.name)) {
|
||||||
|
MsgError(i18n.global.t('commons.msg.fileNameErr'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const res = await CheckFile(baseDir.value + '/' + uploaderFiles.value[0]!.raw.name);
|
||||||
|
if (!res.data) {
|
||||||
|
MsgError(i18n.global.t('commons.msg.fileExist'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
formData.append('file', uploaderFiles.value[0]!.raw);
|
||||||
let isOk = beforeAvatarUpload(uploaderFiles.value[0]!.raw);
|
let isOk = beforeAvatarUpload(uploaderFiles.value[0]!.raw);
|
||||||
if (!isOk) {
|
if (!isOk) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -93,6 +93,9 @@ export default {
|
|||||||
backupSuccess: 'Backup Success',
|
backupSuccess: 'Backup Success',
|
||||||
unSupportType: 'Current file type is not supported!',
|
unSupportType: 'Current file type is not supported!',
|
||||||
unSupportSize: 'The uploaded file exceeds {0}M, please confirm!',
|
unSupportSize: 'The uploaded file exceeds {0}M, please confirm!',
|
||||||
|
fileExist: 'The file already exists in the current folder. Repeat uploading is not supported!',
|
||||||
|
fileNameErr:
|
||||||
|
'You can upload only files whose name contains 1 to 50 characters, including English, Chinese, digits, or periods (.-_)',
|
||||||
},
|
},
|
||||||
login: {
|
login: {
|
||||||
firstLogin: 'First login, please create an initial administrator user!',
|
firstLogin: 'First login, please create an initial administrator user!',
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ export default {
|
|||||||
notFound: '抱歉,您访问的页面不存在',
|
notFound: '抱歉,您访问的页面不存在',
|
||||||
unSupportType: '不支持当前文件类型!',
|
unSupportType: '不支持当前文件类型!',
|
||||||
unSupportSize: '上传文件超过 {0}M,请确认!',
|
unSupportSize: '上传文件超过 {0}M,请确认!',
|
||||||
|
fileExist: '当前文件夹已存在该文件,不支持重复上传!',
|
||||||
|
fileNameErr: '仅支持上传名称包含英文、中文、数字或者 .-_ ,长度 1-50 位的文件',
|
||||||
},
|
},
|
||||||
login: {
|
login: {
|
||||||
firstLogin: '首次登录,请创建初始管理员用户!',
|
firstLogin: '首次登录,请创建初始管理员用户!',
|
||||||
|
|||||||
Reference in New Issue
Block a user