mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2025-03-17 03:04:46 +08:00
feat: 增加文件上传功能
This commit is contained in:
parent
b172a5124e
commit
89b95e0d45
@ -1,10 +1,13 @@
|
|||||||
package v1
|
package v1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"github.com/1Panel-dev/1Panel/app/api/v1/helper"
|
"github.com/1Panel-dev/1Panel/app/api/v1/helper"
|
||||||
"github.com/1Panel-dev/1Panel/app/dto"
|
"github.com/1Panel-dev/1Panel/app/dto"
|
||||||
"github.com/1Panel-dev/1Panel/constant"
|
"github.com/1Panel-dev/1Panel/constant"
|
||||||
|
"github.com/1Panel-dev/1Panel/global"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
"path"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (b *BaseApi) ListFiles(c *gin.Context) {
|
func (b *BaseApi) ListFiles(c *gin.Context) {
|
||||||
@ -131,3 +134,23 @@ func (b *BaseApi) SaveContent(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
helper.SuccessWithData(c, nil)
|
helper.SuccessWithData(c, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *BaseApi) UploadFiles(c *gin.Context) {
|
||||||
|
form, err := c.MultipartForm()
|
||||||
|
if err != nil {
|
||||||
|
helper.ErrorWithDetail(c, constant.CodeErrBadRequest, constant.ErrTypeInvalidParams, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
files := form.File["file"]
|
||||||
|
paths := form.Value["path"]
|
||||||
|
success := 0
|
||||||
|
for _, file := range files {
|
||||||
|
err := c.SaveUploadedFile(file, path.Join(paths[0], file.Filename))
|
||||||
|
if err != nil {
|
||||||
|
global.LOG.Errorf("upload [%s] file failed, err: %v", file.Filename, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
success++
|
||||||
|
}
|
||||||
|
helper.SuccessWithMsg(c, fmt.Sprintf("%d files upload success", success))
|
||||||
|
}
|
||||||
|
@ -68,6 +68,15 @@ func SuccessWithData(ctx *gin.Context, data interface{}) {
|
|||||||
ctx.Abort()
|
ctx.Abort()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SuccessWithMsg(ctx *gin.Context, msg string) {
|
||||||
|
res := dto.Response{
|
||||||
|
Code: constant.CodeSuccess,
|
||||||
|
Msg: msg,
|
||||||
|
}
|
||||||
|
ctx.JSON(http.StatusOK, res)
|
||||||
|
ctx.Abort()
|
||||||
|
}
|
||||||
|
|
||||||
func GetParamID(c *gin.Context) (uint, error) {
|
func GetParamID(c *gin.Context) (uint, error) {
|
||||||
idParam, ok := c.Params.Get("id")
|
idParam, ok := c.Params.Get("id")
|
||||||
if !ok {
|
if !ok {
|
||||||
|
@ -24,6 +24,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("/upload", baseApi.UploadFiles)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
68
frontend/package-lock.json
generated
68
frontend/package-lock.json
generated
@ -15,6 +15,7 @@
|
|||||||
"echarts-liquidfill": "^3.1.0",
|
"echarts-liquidfill": "^3.1.0",
|
||||||
"element-plus": "^2.2.13",
|
"element-plus": "^2.2.13",
|
||||||
"fit2cloud-ui-plus": "^0.0.1-beta.15",
|
"fit2cloud-ui-plus": "^0.0.1-beta.15",
|
||||||
|
"js-base64": "^3.7.2",
|
||||||
"js-md5": "^0.7.3",
|
"js-md5": "^0.7.3",
|
||||||
"monaco-editor": "^0.34.0",
|
"monaco-editor": "^0.34.0",
|
||||||
"nprogress": "^0.2.0",
|
"nprogress": "^0.2.0",
|
||||||
@ -22,12 +23,16 @@
|
|||||||
"pinia-plugin-persistedstate": "^1.6.1",
|
"pinia-plugin-persistedstate": "^1.6.1",
|
||||||
"qs": "^6.10.3",
|
"qs": "^6.10.3",
|
||||||
"sass-loader": "^13.0.2",
|
"sass-loader": "^13.0.2",
|
||||||
|
"screenfull": "^6.0.2",
|
||||||
"unplugin-vue-define-options": "^0.7.3",
|
"unplugin-vue-define-options": "^0.7.3",
|
||||||
"vite-plugin-monaco-editor": "^1.1.0",
|
"vite-plugin-monaco-editor": "^1.1.0",
|
||||||
"vue": "^3.2.25",
|
"vue": "^3.2.25",
|
||||||
"vue-i18n": "^9.1.9",
|
"vue-i18n": "^9.1.9",
|
||||||
"vue-router": "^4.0.12",
|
"vue-router": "^4.0.12",
|
||||||
"vue3-seamless-scroll": "^1.2.0"
|
"vue3-seamless-scroll": "^1.2.0",
|
||||||
|
"xterm": "^4.19.0",
|
||||||
|
"xterm-addon-attach": "^0.6.0",
|
||||||
|
"xterm-addon-fit": "^0.5.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@commitlint/cli": "^17.0.1",
|
"@commitlint/cli": "^17.0.1",
|
||||||
@ -5863,6 +5868,11 @@
|
|||||||
"node": ">=10"
|
"node": ">=10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/js-base64": {
|
||||||
|
"version": "3.7.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/js-base64/-/js-base64-3.7.2.tgz",
|
||||||
|
"integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ=="
|
||||||
|
},
|
||||||
"node_modules/js-md5": {
|
"node_modules/js-md5": {
|
||||||
"version": "0.7.3",
|
"version": "0.7.3",
|
||||||
"resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.7.3.tgz",
|
"resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.7.3.tgz",
|
||||||
@ -7806,6 +7816,14 @@
|
|||||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||||
"peer": true
|
"peer": true
|
||||||
},
|
},
|
||||||
|
"node_modules/screenfull": {
|
||||||
|
"version": "6.0.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/screenfull/-/screenfull-6.0.2.tgz",
|
||||||
|
"integrity": "sha512-AQdy8s4WhNvUZ6P8F6PB21tSPIYKniic+Ogx0AacBMjKP1GUHN2E9URxQHtCusiwxudnCKkdy4GrHXPPJSkCCw==",
|
||||||
|
"engines": {
|
||||||
|
"node": "^14.13.1 || >=16.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/select": {
|
"node_modules/select": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
|
||||||
@ -9774,6 +9792,27 @@
|
|||||||
"node": ">=0.4"
|
"node": ">=0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/xterm": {
|
||||||
|
"version": "4.19.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/xterm/-/xterm-4.19.0.tgz",
|
||||||
|
"integrity": "sha512-c3Cp4eOVsYY5Q839dR5IejghRPpxciGmLWWaP9g+ppfMeBChMeLa1DCA+pmX/jyDZ+zxFOmlJL/82qVdayVoGQ=="
|
||||||
|
},
|
||||||
|
"node_modules/xterm-addon-attach": {
|
||||||
|
"version": "0.6.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/xterm-addon-attach/-/xterm-addon-attach-0.6.0.tgz",
|
||||||
|
"integrity": "sha512-Mo8r3HTjI/EZfczVCwRU6jh438B4WLXxdFO86OB7bx0jGhwh2GdF4ifx/rP+OB+Cb2vmLhhVIZ00/7x3YSP3dg==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"xterm": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/xterm-addon-fit": {
|
||||||
|
"version": "0.5.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/xterm-addon-fit/-/xterm-addon-fit-0.5.0.tgz",
|
||||||
|
"integrity": "sha512-DsS9fqhXHacEmsPxBJZvfj2la30Iz9xk+UKjhQgnYNkrUIN5CYLbw7WEfz117c7+S86S/tpHPfvNxJsF5/G8wQ==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"xterm": "^4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/y18n": {
|
"node_modules/y18n": {
|
||||||
"version": "5.0.8",
|
"version": "5.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||||
@ -14390,6 +14429,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"js-base64": {
|
||||||
|
"version": "3.7.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/js-base64/-/js-base64-3.7.2.tgz",
|
||||||
|
"integrity": "sha512-NnRs6dsyqUXejqk/yv2aiXlAvOs56sLkX6nUdeaNezI5LFFLlsZjOThmwnrcwh5ZZRwZlCMnVAY3CvhIhoVEKQ=="
|
||||||
|
},
|
||||||
"js-md5": {
|
"js-md5": {
|
||||||
"version": "0.7.3",
|
"version": "0.7.3",
|
||||||
"resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.7.3.tgz",
|
"resolved": "https://registry.npmjs.org/js-md5/-/js-md5-0.7.3.tgz",
|
||||||
@ -15942,6 +15986,11 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"screenfull": {
|
||||||
|
"version": "6.0.2",
|
||||||
|
"resolved": "https://registry.npmmirror.com/screenfull/-/screenfull-6.0.2.tgz",
|
||||||
|
"integrity": "sha512-AQdy8s4WhNvUZ6P8F6PB21tSPIYKniic+Ogx0AacBMjKP1GUHN2E9URxQHtCusiwxudnCKkdy4GrHXPPJSkCCw=="
|
||||||
|
},
|
||||||
"select": {
|
"select": {
|
||||||
"version": "1.1.2",
|
"version": "1.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz",
|
||||||
@ -17428,6 +17477,23 @@
|
|||||||
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"xterm": {
|
||||||
|
"version": "4.19.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/xterm/-/xterm-4.19.0.tgz",
|
||||||
|
"integrity": "sha512-c3Cp4eOVsYY5Q839dR5IejghRPpxciGmLWWaP9g+ppfMeBChMeLa1DCA+pmX/jyDZ+zxFOmlJL/82qVdayVoGQ=="
|
||||||
|
},
|
||||||
|
"xterm-addon-attach": {
|
||||||
|
"version": "0.6.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/xterm-addon-attach/-/xterm-addon-attach-0.6.0.tgz",
|
||||||
|
"integrity": "sha512-Mo8r3HTjI/EZfczVCwRU6jh438B4WLXxdFO86OB7bx0jGhwh2GdF4ifx/rP+OB+Cb2vmLhhVIZ00/7x3YSP3dg==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
|
"xterm-addon-fit": {
|
||||||
|
"version": "0.5.0",
|
||||||
|
"resolved": "https://registry.npmmirror.com/xterm-addon-fit/-/xterm-addon-fit-0.5.0.tgz",
|
||||||
|
"integrity": "sha512-DsS9fqhXHacEmsPxBJZvfj2la30Iz9xk+UKjhQgnYNkrUIN5CYLbw7WEfz117c7+S86S/tpHPfvNxJsF5/G8wQ==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
"y18n": {
|
"y18n": {
|
||||||
"version": "5.0.8",
|
"version": "5.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
|
||||||
|
@ -36,3 +36,7 @@ export const GetFileContent = (params: File.ReqFile) => {
|
|||||||
export const SaveFileContent = (params: File.FileEdit) => {
|
export const SaveFileContent = (params: File.FileEdit) => {
|
||||||
return http.post<File.File>('files/save', params);
|
return http.post<File.File>('files/save', params);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const UploadFileData = (params: FormData) => {
|
||||||
|
return http.post<File.File>('files/upload', params);
|
||||||
|
};
|
||||||
|
@ -2,14 +2,12 @@ export default {
|
|||||||
commons: {
|
commons: {
|
||||||
button: {
|
button: {
|
||||||
create: '新建',
|
create: '新建',
|
||||||
create: '创建',
|
|
||||||
add: '添加',
|
add: '添加',
|
||||||
delete: '删除',
|
delete: '删除',
|
||||||
edit: '编辑',
|
edit: '编辑',
|
||||||
confirm: '确认',
|
confirm: '确认',
|
||||||
cancel: '取消',
|
cancel: '取消',
|
||||||
reset: '重置',
|
reset: '重置',
|
||||||
login: '登陆',
|
|
||||||
conn: '连接',
|
conn: '连接',
|
||||||
login: '登录',
|
login: '登录',
|
||||||
},
|
},
|
||||||
@ -197,5 +195,6 @@ export default {
|
|||||||
softLink: '软链接',
|
softLink: '软链接',
|
||||||
hardLink: '硬链接',
|
hardLink: '硬链接',
|
||||||
linkPath: '链接路径',
|
linkPath: '链接路径',
|
||||||
|
selectFile: '选择文件',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -1,12 +1,22 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-dialog v-model="open" :title="'code editor'" @opened="onOpen" :before-close="handleClose">
|
<el-dialog
|
||||||
|
v-model="open"
|
||||||
|
:title="$t('commons.button.edit')"
|
||||||
|
@opened="onOpen"
|
||||||
|
:before-close="handleClose"
|
||||||
|
destroy-on-close
|
||||||
|
width="70%"
|
||||||
|
draggable
|
||||||
|
>
|
||||||
<div>
|
<div>
|
||||||
<div id="codeBox" style="height: 600px"></div>
|
<div v-loading="loading">
|
||||||
|
<div id="codeBox" style="height: 60vh"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<span class="dialog-footer">
|
<span class="dialog-footer">
|
||||||
<el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button>
|
<el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button>
|
||||||
<el-button type="primary" @click="saveContent">{{ $t('commons.button.confirm') }}</el-button>
|
<el-button type="primary" @click="save()">{{ $t('commons.button.confirm') }}</el-button>
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
</el-dialog>
|
</el-dialog>
|
||||||
@ -31,6 +41,10 @@ const props = defineProps({
|
|||||||
type: String,
|
type: String,
|
||||||
default: '',
|
default: '',
|
||||||
},
|
},
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
let data = reactive({
|
let data = reactive({
|
||||||
@ -38,7 +52,7 @@ let data = reactive({
|
|||||||
language: '',
|
language: '',
|
||||||
});
|
});
|
||||||
|
|
||||||
const em = defineEmits(['close', 'save']);
|
const em = defineEmits(['close', 'qsave', 'save']);
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
if (editor) {
|
if (editor) {
|
||||||
@ -47,6 +61,14 @@ const handleClose = () => {
|
|||||||
em('close', false);
|
em('close', false);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const save = () => {
|
||||||
|
em('save', data.content);
|
||||||
|
};
|
||||||
|
|
||||||
|
const saveNotClose = () => {
|
||||||
|
em('qsave', data.content);
|
||||||
|
};
|
||||||
|
|
||||||
const initEditor = () => {
|
const initEditor = () => {
|
||||||
if (editor) {
|
if (editor) {
|
||||||
editor.dispose();
|
editor.dispose();
|
||||||
@ -67,10 +89,8 @@ const initEditor = () => {
|
|||||||
data.content = editor.getValue();
|
data.content = editor.getValue();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
|
||||||
const saveContent = () => {
|
editor.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, saveNotClose);
|
||||||
em('save', data.content);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onOpen = () => {
|
const onOpen = () => {
|
||||||
|
@ -65,9 +65,9 @@ const props = defineProps({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const rules = reactive<FormRules>({
|
const rules = reactive<FormRules>({
|
||||||
type: [Rules.required],
|
type: [Rules.requiredSelect],
|
||||||
dst: [Rules.required],
|
dst: [Rules.requiredInput],
|
||||||
name: [Rules.required],
|
name: [Rules.requiredInput],
|
||||||
});
|
});
|
||||||
|
|
||||||
const { open, files, type, dst, name } = toRefs(props);
|
const { open, files, type, dst, name } = toRefs(props);
|
||||||
|
@ -71,10 +71,10 @@ const handleClose = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const rules = reactive<FormRules>({
|
const rules = reactive<FormRules>({
|
||||||
name: [Rules.required],
|
name: [Rules.requiredInput],
|
||||||
path: [Rules.required],
|
path: [Rules.requiredInput],
|
||||||
isSymlink: [Rules.required],
|
isSymlink: [Rules.requiredInput],
|
||||||
linkPath: [Rules.required],
|
linkPath: [Rules.requiredInput],
|
||||||
});
|
});
|
||||||
|
|
||||||
const getMode = (val: number) => {
|
const getMode = (val: number) => {
|
||||||
|
@ -60,7 +60,7 @@ const props = defineProps({
|
|||||||
});
|
});
|
||||||
|
|
||||||
const rules = reactive<FormRules>({
|
const rules = reactive<FormRules>({
|
||||||
dst: [Rules.required],
|
dst: [Rules.requiredInput],
|
||||||
});
|
});
|
||||||
|
|
||||||
const { open, dst, path, name, mimeType } = toRefs(props);
|
const { open, dst, path, name, mimeType } = toRefs(props);
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<LayoutContent>
|
<LayoutContent>
|
||||||
<el-row :gutter="20">
|
<el-row :gutter="20">
|
||||||
<el-col :span="5">
|
<el-col :span="5">
|
||||||
<el-scrollbar height="800px">
|
<el-scrollbar height="80vh">
|
||||||
<el-tree
|
<el-tree
|
||||||
:data="fileTree"
|
:data="fileTree"
|
||||||
:props="defaultProps"
|
:props="defaultProps"
|
||||||
@ -57,7 +57,7 @@
|
|||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</template>
|
</template>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
<el-button type="primary" plain> {{ $t('file.upload') }}</el-button>
|
<el-button type="primary" plain @click="openUpload"> {{ $t('file.upload') }}</el-button>
|
||||||
<el-button type="primary" plain> {{ $t('file.search') }}</el-button>
|
<el-button type="primary" plain> {{ $t('file.search') }}</el-button>
|
||||||
<el-button type="primary" plain> {{ $t('file.remoteFile') }}</el-button>
|
<el-button type="primary" plain> {{ $t('file.remoteFile') }}</el-button>
|
||||||
<!-- <el-button type="primary" plain> {{ $t('file.sync') }}</el-button>
|
<!-- <el-button type="primary" plain> {{ $t('file.sync') }}</el-button>
|
||||||
@ -85,6 +85,7 @@
|
|||||||
prop="modTime"
|
prop="modTime"
|
||||||
:formatter="dateFromat"
|
:formatter="dateFromat"
|
||||||
min-width="100"
|
min-width="100"
|
||||||
|
show-overflow-tooltip
|
||||||
>
|
>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
|
|
||||||
@ -118,9 +119,12 @@
|
|||||||
:open="editorPage.open"
|
:open="editorPage.open"
|
||||||
:language="'json'"
|
:language="'json'"
|
||||||
:content="editorPage.content"
|
:content="editorPage.content"
|
||||||
|
:loading="editorPage.loading"
|
||||||
@close="closeCodeEditor"
|
@close="closeCodeEditor"
|
||||||
|
@qsave="quickSave"
|
||||||
@save="saveContent"
|
@save="saveContent"
|
||||||
></CodeEditor>
|
></CodeEditor>
|
||||||
|
<Upload :open="uploadPage.open" :path="uploadPage.path" @close="closeUpload"></Upload>
|
||||||
</el-row>
|
</el-row>
|
||||||
</LayoutContent>
|
</LayoutContent>
|
||||||
</template>
|
</template>
|
||||||
@ -139,8 +143,10 @@ import CreateFile from './create/index.vue';
|
|||||||
import ChangeRole from './change-role/index.vue';
|
import ChangeRole from './change-role/index.vue';
|
||||||
import Compress from './compress/index.vue';
|
import Compress from './compress/index.vue';
|
||||||
import Decompress from './decompress/index.vue';
|
import Decompress from './decompress/index.vue';
|
||||||
|
import Upload from './upload/index.vue';
|
||||||
import { useDeleteData } from '@/hooks/use-delete-data';
|
import { useDeleteData } from '@/hooks/use-delete-data';
|
||||||
import CodeEditor from './code-editor/index.vue';
|
import CodeEditor from './code-editor/index.vue';
|
||||||
|
import { ElMessage } from 'element-plus';
|
||||||
|
|
||||||
let data = ref();
|
let data = ref();
|
||||||
let selects = ref<any>([]);
|
let selects = ref<any>([]);
|
||||||
@ -155,8 +161,9 @@ let filePage = reactive({ open: false, createForm: { path: '/', isDir: false, mo
|
|||||||
let modePage = reactive({ open: false, modeForm: { path: '/', isDir: false, mode: 0o755 } });
|
let modePage = reactive({ open: false, modeForm: { path: '/', isDir: false, mode: 0o755 } });
|
||||||
let compressPage = reactive({ open: false, files: [''], name: '', dst: '' });
|
let compressPage = reactive({ open: false, files: [''], name: '', dst: '' });
|
||||||
let deCompressPage = reactive({ open: false, path: '', name: '', dst: '', mimeType: '' });
|
let deCompressPage = reactive({ open: false, path: '', name: '', dst: '', mimeType: '' });
|
||||||
let editorPage = reactive({ open: false, content: '' });
|
let editorPage = reactive({ open: false, content: '', loading: false });
|
||||||
let codeReq = reactive({ path: '', expand: false });
|
let codeReq = reactive({ path: '', expand: false });
|
||||||
|
const uploadPage = reactive({ open: false, path: '' });
|
||||||
|
|
||||||
const defaultProps = {
|
const defaultProps = {
|
||||||
children: 'children',
|
children: 'children',
|
||||||
@ -321,9 +328,30 @@ const closeCodeEditor = () => {
|
|||||||
editorPage.open = false;
|
editorPage.open = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const openUpload = () => {
|
||||||
|
uploadPage.open = true;
|
||||||
|
uploadPage.path = req.path;
|
||||||
|
};
|
||||||
|
|
||||||
|
const closeUpload = () => {
|
||||||
|
uploadPage.open = false;
|
||||||
|
search(req);
|
||||||
|
};
|
||||||
|
|
||||||
const saveContent = (content: string) => {
|
const saveContent = (content: string) => {
|
||||||
SaveFileContent({ path: codeReq.path, content: content }).then(() => {
|
editorPage.loading = true;
|
||||||
|
SaveFileContent({ path: codeReq.path, content: content }).finally(() => {
|
||||||
|
editorPage.loading = false;
|
||||||
editorPage.open = false;
|
editorPage.open = false;
|
||||||
|
ElMessage.success(i18n.global.t('commons.msg.updateSuccess'));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const quickSave = (content: string) => {
|
||||||
|
editorPage.loading = true;
|
||||||
|
SaveFileContent({ path: codeReq.path, content: content }).finally(() => {
|
||||||
|
editorPage.loading = false;
|
||||||
|
ElMessage.success(i18n.global.t('commons.msg.updateSuccess'));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
64
frontend/src/views/file-management/upload/index.vue
Normal file
64
frontend/src/views/file-management/upload/index.vue
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<template>
|
||||||
|
<el-dialog v-model="open" :title="$t('file.upload')" @open="onOpen" :before-close="handleClose">
|
||||||
|
<el-upload action="#" :auto-upload="false" ref="uploadRef" :multiple="true" :on-change="fileOnChange">
|
||||||
|
<template #trigger>
|
||||||
|
<el-button type="primary">{{ $t('file.selectFile') }}</el-button>
|
||||||
|
</template>
|
||||||
|
</el-upload>
|
||||||
|
|
||||||
|
<template #footer>
|
||||||
|
<span class="dialog-footer">
|
||||||
|
<el-button @click="handleClose">{{ $t('commons.button.cancel') }}</el-button>
|
||||||
|
<el-button type="primary" @click="submit()">{{ $t('commons.button.confirm') }}</el-button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { ElMessage, UploadFile, UploadFiles, UploadInstance } from 'element-plus';
|
||||||
|
import { UploadFileData } from '@/api/modules/files';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
open: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
path: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const uploadRef = ref<UploadInstance>();
|
||||||
|
// let loading = ref<Boolean>(false);
|
||||||
|
|
||||||
|
const em = defineEmits(['close']);
|
||||||
|
const handleClose = () => {
|
||||||
|
em('close', false);
|
||||||
|
};
|
||||||
|
|
||||||
|
const uploaderFiles = ref<UploadFiles>([]);
|
||||||
|
|
||||||
|
const fileOnChange = (_uploadFile: UploadFile, uploadFiles: UploadFiles) => {
|
||||||
|
uploaderFiles.value = uploadFiles;
|
||||||
|
};
|
||||||
|
|
||||||
|
const submit = () => {
|
||||||
|
const formData = new FormData();
|
||||||
|
for (const file of uploaderFiles.value) {
|
||||||
|
if (file.raw != undefined) {
|
||||||
|
formData.append('file', file.raw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
formData.append('path', props.path);
|
||||||
|
|
||||||
|
UploadFileData(formData).then(() => {
|
||||||
|
ElMessage('upload success');
|
||||||
|
handleClose();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
const onOpen = () => {};
|
||||||
|
</script>
|
Loading…
x
Reference in New Issue
Block a user