Bladeren bron

upload

master
zhaodengke 1 jaar geleden
bovenliggende
commit
1362b37c59
8 gewijzigde bestanden met toevoegingen van 333 en 3 verwijderingen
  1. +19
    -0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/file/FileSystemController.java
  2. +1
    -1
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/open/OpenFileController.java
  3. +1
    -1
      ruoyi-common/src/main/java/com/ruoyi/common/utils/file/PathUtils.java
  4. +13
    -1
      ruoyi-file/src/main/java/com/ruoyi/file/model/FileModel.java
  5. +23
    -0
      ruoyi-file/src/main/java/com/ruoyi/file/request/PutFileReq.java
  6. +61
    -0
      ruoyi-file/src/main/java/com/ruoyi/file/service/FileSystemService.java
  7. +11
    -0
      ruoyi-ui/src/components/ServerFileChooser.vue
  8. +204
    -0
      ruoyi-ui/src/views/file/fs/index.vue

+ 19
- 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/file/FileSystemController.java Bestand weergeven

@@ -4,15 +4,22 @@ import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.file.model.FileModel;
import com.ruoyi.file.model.FileSystemFilter;
import com.ruoyi.file.object.UploadResp;
import com.ruoyi.file.request.PutFileReq;
import com.ruoyi.file.service.FileSystemService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import java.util.List;

/**
@@ -42,4 +49,16 @@ public class FileSystemController extends BaseController
return AjaxResult.success(list);
}

/**
* 上传文件
*/
@ApiOperation("上传文件")
@PreAuthorize("@ss.hasPermi('admin:fs:put')")
@PostMapping("/put")
public AjaxResult put(@Valid PutFileReq req, MultipartFile file)
{
FileModel upload = fileSystemService.put(req, file);
return AjaxResult.success(upload);
}

}

+ 1
- 1
ruoyi-admin/src/main/java/com/ruoyi/web/controller/open/OpenFileController.java Bestand weergeven

@@ -48,7 +48,7 @@ public class OpenFileController
* @param fileName 文件名称
* @param delete 是否删除
*/
@GetMapping("/download")
//@GetMapping("/download")
public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
{
try


+ 1
- 1
ruoyi-common/src/main/java/com/ruoyi/common/utils/file/PathUtils.java Bestand weergeven

@@ -95,7 +95,7 @@ public final class PathUtils
else if(i == part.length() - 1)
return part;
else
return part.substring(0, i);
return part.substring(0, i + 1);
}

private PathUtils() {}


+ 13
- 1
ruoyi-file/src/main/java/com/ruoyi/file/model/FileModel.java Bestand weergeven

@@ -6,10 +6,12 @@ import com.ruoyi.file.enums.FileType;
import lombok.Data;

import java.io.File;
import java.util.Comparator;
import java.util.List;
import java.util.Objects;

@Data
public final class FileModel
public final class FileModel implements Comparator
{
private String fileName;
private String filePath;
@@ -42,4 +44,14 @@ public final class FileModel
filePath = PathUtils.normalizeSlash(filePath);
type = FileType.FileType(file);
}

@Override
public int compare(Object o1, Object o2)
{
FileModel a = (FileModel)o1;
FileModel b = (FileModel)o2;
if(Objects.equals(a.type, b.type))
return a.fileName.compareToIgnoreCase(b.fileName);
return -(a.type - b.type);
}
}

+ 23
- 0
ruoyi-file/src/main/java/com/ruoyi/file/request/PutFileReq.java Bestand weergeven

@@ -0,0 +1,23 @@
package com.ruoyi.file.request;

import lombok.Data;

import javax.validation.constraints.NotEmpty;

@Data
public final class PutFileReq
{
@NotEmpty(message = "上传路径不能为空")
private String path;
private Integer ifExists;

public boolean allowOverride()
{
return null != ifExists && ifExists == 2;
}

public boolean allowRename()
{
return null != ifExists && ifExists == 1;
}
}

+ 61
- 0
ruoyi-file/src/main/java/com/ruoyi/file/service/FileSystemService.java Bestand weergeven

@@ -1,13 +1,19 @@
package com.ruoyi.file.service;

import cn.hutool.core.io.FileUtil;
import com.ruoyi.common.exception.ASSERT;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.PathUtils;
import com.ruoyi.file.model.FileSystemFilter;
import com.ruoyi.file.model.FileModel;
import com.ruoyi.file.request.PutFileReq;
import org.apache.commons.io.FilenameUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

@Service
@@ -36,6 +42,61 @@ public class FileSystemService
list.add(new FileModel(f));
}
}
list.sort(new FileModel());
return list;
}

public FileModel put(PutFileReq req, MultipartFile file)
{
String dst = PathUtils.appendPaths(req.getPath(), file.getOriginalFilename());
File dstFile = new File(dst);
if(dstFile.exists())
{
if(dstFile.isDirectory())
throw new RuntimeException("目标文件是目录: " + dst);
if(req.allowRename())
{
int i = 1;
do
{
String originalFilename = file.getOriginalFilename();
String extension = FilenameUtils.getExtension(originalFilename);
originalFilename = PathUtils.removeExtension(originalFilename);
originalFilename += "(" + i++ + ")";
if(StringUtils.isNotEmpty(extension))
originalFilename += "." + extension;
dst = PathUtils.appendPaths(req.getPath(), originalFilename);
dstFile = new File(dst);
} while(dstFile.exists());
}
else if(req.allowOverride())
{
// override
}
else
throw new RuntimeException("目标文件已存在: " + dst);
}

File parentFile = dstFile.getParentFile();
if(null == parentFile)
throw new RuntimeException("必须指定存储目录: " + dst);
if(parentFile.exists() && !parentFile.isDirectory())
throw new RuntimeException("存储目录必须是文件夹: " + dst);
if(!parentFile.exists())
{
if(!parentFile.mkdirs())
throw new RuntimeException("存储目录不存在且创建失败: " + dst);
}
try
{
byte[] bytes = file.getBytes();
FileUtil.writeBytes(bytes, dstFile);
return new FileModel(dstFile);
}
catch(Exception e)
{
e.printStackTrace();
throw new RuntimeException(e);
}
}
}

+ 11
- 0
ruoyi-ui/src/components/ServerFileChooser.vue Bestand weergeven

@@ -60,6 +60,17 @@ export default {
this.$emit('input', data.filePath);
this.$emit('selected', data);
},
reload() {
this.files = [];
let query = {
filePath: null,
fileType: this.fileType,
showHidden: this.showHidden,
};
ls(query).then((resp) => {
this.files = resp.data;
});
},
}
};
</script>


+ 204
- 0
ruoyi-ui/src/views/file/fs/index.vue Bestand weergeven

@@ -0,0 +1,204 @@
<template>
<div class="app-container">
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain icon="el-icon-plus" size="mini" @click="upload" v-hasPermi="['admin:fs:put']">Put</el-button>
</el-col>
<right-toolbar :showSearch.sync="showSearch" @queryTable="refresh"></right-toolbar>
</el-row>

<el-row>
<el-col :span="8">
<ServerFileChooser ref="fileBrowser" v-model="form.path" :file-type="2" @selected="getFiles"/>
</el-col>
<el-col :span="16">
<el-table :data="files">
<el-table-column type="index" label="序号" width="50" align="center" />
<el-table-column label="文件名" align="left" header-align="center" prop="fileName" sortable/>
</el-table>
</el-col>
</el-row>

<el-dialog title="上传文件" :visible.sync="open" width="700px" append-to-body>
<el-form ref="form" :model="form" label-width="100px" :rules="rules">
<el-form-item label="上传至">
<div>{{form.path}}</div>
</el-form-item>
<el-form-item label="如果已存在" prop="ifExists">
<el-select v-model="form.ifExists" placeholder="请选择如果已存在行为">
<el-option
v-for="dict in ifExistsDict"
:key="dict.value"
:label="dict.label"
:value="dict.value"
></el-option>
</el-select>
</el-form-item>
<el-form-item label="文件" prop="file">
<el-upload
ref="upload"
drag
:action="uploadUrl"
:auto-upload="false"
:data="form"
:limit="1"
:multiple="false"
:headers="header"
:on-success="onUploadSuccess"
:on-error="onUploadError"
:before-upload="startUpload"
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
</el-upload>
</el-form-item>
</el-form>

<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="put" :loading="uploading">上 传</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</el-dialog>
</div>
</template>

<script>
import DeptSelect from "@/components/common/DeptSelect.vue";
import ServerFileChooser from "@/components/ServerFileChooser.vue";
import FullscreenDialog from "@/components/FullscreenDialog.vue";
import ProjectState from "@/views/file/state/ProjectState.vue";
import {stateList, gc, stateMachine, dump, runtimeState} from "@/api/file/state";
import Descriptions from "@/components/common/Descriptions.vue";
import {formatFileSize} from "@/utils/file";
import {ls} from "@/api/file/filesystem";
import {getToken} from "@/utils/auth";


export default {
name: "State",
components: {
Descriptions,
ProjectState,
FullscreenDialog,
ServerFileChooser,
DeptSelect
},
dicts: ['sys_bool'],
data() {
return {
loading: false,
uploading: false,
showSearch: false,
// 总条数
total: 0,
uploadUrl: '/api/filesystem/put',
open: false,
queryParams: {
// 分页
pageNum: 1,
pageSize: 10,
// 查询排序
//orderByColumn: "id",
//isAsc: "desc",
// 翻译字典
//translate_dict: "1",
},
form: {
path: '',
ifExists: 0,
},
files: [],
ifExistsDict: [
{label: '中止', value: 0,},
{label: '重命名', value: 1,},
{label: '覆盖', value: 2,},
],
rules: {
ifExists: [
{ required: true, message: "如果已存在行为不能为空", trigger: "change" }
],
},
header: {
Authorization: "Bearer " + getToken(),
},
};
},
created() {
},
methods: {
// 取消按钮
cancel() {
this.open = false;
},
// 表单重置
reset() {
this.form = {
path: '',
ifExists: 0,
};
this.$refs.form.resetField();
},
refresh() {
this.$refs.fileBrowser.reload();
this.files = [];
},
getFiles() {
this.files = [];
if(this.form.path)
{
let query = {
filePath: this.form.path,
showHidden: true,
};
this.loading = true;
ls(query).then((resp) => {
this.files = resp.data;
}).finally(() => this.loading = false);
}
},
resetQuery() {
this.resetForm("queryForm");
this.handleQuery();
},
fileSizeFormatter(row, col, val) {
return formatFileSize(val);
},
upload() {
if(!this.form.path)
{
this.$message.error('请先选择存储目录');
return;
}
this.uploading = false;
this.open = true;
this.$nextTick(() => {
this.$refs.upload.clearFiles();
});
},
put() {
this.$refs.upload.submit();
},
onUploadSuccess(response, file, fileList) {
this.uploading = false;
if(response.code == 200)
{
this.$message.success('上传成功! 路径为: ' + response.data.filePath);
this.cancel();
this.getFiles();
}
else
this.$message.error('上传失败: ' + response.msg);
},
onUploadError(err, file, fileList) {
this.uploading = false;
this.$message.error('上传失败: ' + err);
},
startUpload(file) {
this.uploading = true;
},
},
filters: {
formatFileSize,
},
};
</script>

Laden…
Annuleren
Opslaan