技术栈:前端vue2.x全家桶。服务端:.net Core3.1 ORM:xcode 数据库:mysql.
先上效果图:
文件管理操作页面代码:
<template>
<div id="v_ywArrivalRecord">
<el-container style="height: calc(100vh - 102px); border: 1px solid #eee">
<el-container>
<el-header>
<div class="search">
<el-form :inline="true" class="demo-form-inline" >
<el-form-item label="日期:">
<el-date-picker v-model="queryparam.startDate" type="date" placeholder="选择开始日期" format="yyyy 年 MM 月 dd 日" value-format="yyyy-MM-dd"></el-date-picker>
</el-form-item>
<el-form-item label="-">
<el-date-picker v-model="queryparam.endDate" type="date" placeholder="选择结束日期" format="yyyy 年 MM 月 dd 日" value-format="yyyy-MM-dd"></el-date-picker>
</el-form-item>
<el-form-item class="btn">
<el-button type="primary" icon="el-icon-search" @click="getList();">查询</el-button>
<el-button size="small" class="el-button-iconButton" icon="el-icon-upload" style="text-overflow: initial;" @click="handleUpload">上传</el-button>
<el-button size="small" class="el-button-iconButton" icon="el-icon-plus" style="text-overflow: initial;" @click="handleAddFolder">新建文件夹</el-button>
</el-form-item>
</el-form>
</div>
<div>
<span v-show="false">当前路径:{{BusinessType}} </span>
<el-button size="small" class="el-button-iconButton" icon="el-icon-upload" v-has="'fileMgr_handelUpload'" style="text-overflow: initial;" @click="handleUpload">上传</el-button>
<el-button size="small" class="el-button-iconButton" icon="el-icon-plus" v-has="'fileMgr_handleAdd'" style="text-overflow: initial;" @click="handleAddFolder">新建文件夹</el-button>
</div>
</el-header>
<el-main>
<el-table
v-loading="listLoading"
:data="list"
:element-loading-text="elementLoadingText"
@selection-change="setSelectRows"
@row-click="handleRowdblclick"
>
<el-table-column show-overflow-tooltip type="selection"></el-table-column>
<el-table-column
show-overflow-tooltip
label="序号"
type="index"
width="50"
align="center"
></el-table-column>
<el-table-column
show-overflow-tooltip
prop="id"
label=""
align="center"
v-if="false"
></el-table-column>
<el-table-column
show-overflow-tooltip
prop="fileName"
label="文档名称"
align="center"
>
<template show-overflow-tooltip #default="{ row }">
<i v-if="row.fileCType == 1" class="el-icon-files">{{row.fileName}}</i>
<i v-else class="el-icon-folder-opened">{{row.fileName}}</i>
</template>
</el-table-column>
<el-table-column
show-overflow-tooltip
prop="uploadTime"
label="上传时间"
align="center"
></el-table-column>
<el-table-column
show-overflow-tooltip
prop="downloadCount"
label="下载次数"
align="center"
></el-table-column>
<el-table-column
show-overflow-tooltip
prop="creator"
label="录入人"
align="center"
></el-table-column>
<el-table-column
show-overflow-tooltip
align="center"
label="操作"
width="250"
>
<template show-overflow-tooltip #default="{ row }">
<!-- <el-tooltip v-show="false" class="item" effect="dark" content="重命名" placement="top">
<el-button
size="mini"
class="btnStyle"
type="primary"
icon="el-icon-edit"
@click="handleEdit(row)"
></el-button>
</el-tooltip> -->
<el-tooltip class="item" effect="dark" content="删除" placement="top">
<el-button
v-has="'fileMgr_handleMultiplDel'"
size="mini"
class="btnStyle"
type="danger"
icon="el-icon-delete"
v-show="row.fileName != '根目录' && row.fileName != '上一层'"
@click="Singelmultipl(row)"
></el-button>
</el-tooltip>
<el-tooltip class="item" effect="dark" content="下载" placement="top">
<el-button
v-has="'fileMgr_handleDownLoad'"
class="btnStyle"
type="success"
size="mini"
icon="el-icon-download"
v-show="row.fileCType == 1"
@click="commonDownLoad(row)"
></el-button>
</el-tooltip>
</template>
</el-table-column>
</el-table>
<el-pagination
background
:current-page="page.pageNo"
:page-size="page.pageSize"
:layout="layout"
:total="page.total"
@size-change="getSizeChange"
@current-change="getCurrentPage"
></el-pagination>
</el-main>
</el-container>
</el-container>
<div>
<el-dialog title="新建文件夹" :visible.sync="isFolder" width="30%">
<el-input v-model="FileName" autocomplete="off"></el-input>
<el-button type="primary" @click="submitForm()">提交</el-button>
</el-dialog>
</div>
<div>
<el-dialog title="上传文件" :visible.sync="isUpload" width="50%">
<RateUpload :BusinessType='BusinessType' :BusinessId='BusinessId' :Ismultiple='Ismultiple' :limit="limit" @uploadSuccess='uploadSuccess'></RateUpload>
</el-dialog>
</div>
</div>
</template>
<script>
import RateUpload from '@/components/VabUpload/rateUploadFileMgr'
import base from '@/api/base'
export default {
data(){
return{
queryparam:{
startDate:'',
endDate:'',
},
BusinessType:"0",
BusinessId:1,//0:文件夹 1:文件
limit:1,
Ismultiple:false,
isFolder:false,
isUpload:false,
selectRows:[],
list: null,
listLoading: true,
layout: 'total, sizes, prev, pager, next, jumper',
elementLoadingText: '正在加载...',
page: {
//关于页码的相关参数
pageShow: true, //是否显示
total: 0, //总条数
pageSize: 10, //每页条数
pageNo: 1, //第几页
},
FileName:'',//wenjianjia
}
},
components:{
RateUpload
},
created(){},
mounted() {
this.getList();//调用获取列表页的方法
},
methods:{
//查询
getList(){
var self = this;
this.$http({
method: 'GET',
url: base.env+'/api/CommonBusineess/GetFileManagePageBySearch?pageSize=' + self.page.pageSize + '&pageIndex=' + self.page.pageNo+'&id='+self.BusinessType+'&startDate='+self.queryparam.startDate+'&endDate='+self.queryparam.endDate
}).then(res => {
if(res.status==200){
self.list=res.data.data;
self.page.total = res.data.total;
self.listLoading=false;
}
}).catch(error => {
console.log(error);
});
},
handleAddFolder(){
this.isFolder=true;
},
handleUpload(){
this.isUpload=true;
},
setSelectRows(val) {
this.selectRows = val;
},
handleRowdblclick(row, column, event) {//双击行
var self = this;
if(row.fileCType==0){//文件夹
this.BusinessType=row.id;
this.$http({
method: 'GET',
url: base.env+'/api/CommonBusineess/GetFileManagePageBySearch?pageSize=10000&pageIndex=1&id='+row.id
}).then(res => {
debugger
if(res.status==200){
self.list=res.data.data;
self.page.total = res.data.total;
self.$http({
method: 'GET',
url: base.env+'/api/CommonBusineess/GetParentIdById?id='+row.id
}).then(res => {
debugger
if(res.status==200){
self.list.unshift({ "id": 0, "keyId": 0, "fileCategory": null, "fileType": null, "fileCType": 0, "docType": "9", "usrId": 1, "creator": "", "uploadTime": "", "fileCode": null, "fileName": "根目录", "fileGuid": "", "fileUrl": "", "downloadCount": 0, "version": null, "keyWords": null, "backup": null, "status": null },
{ "id": res.data.data, "keyId": res.data.data, "fileCategory": null, "fileType": null, "fileCType": 0, "docType": "9", "usrId": 1, "creator": "", "uploadTime": "", "fileCode": null, "fileName": "上一层", "fileGuid": "", "fileUrl": "", "downloadCount": 0, "version": null, "keyWords": null, "backup": null, "status": null });
self.listLoading=false;
}
}).catch(error => {
console.log(error);
});
}
}).catch(error => {
console.log(error);
});
}
},
getSizeChange(val) {
//table组件发射的方法 用于改变每页数据量
this.page.pageSize = val
//这下面需要重新调用 获取列表页的函数
this.getList()
},
getCurrentPage(val) {
//table组件发射的方法 用于改变当前所在页码
this.page.pageNo = val
//这下面需要重新调用 获取列表页的函数
this.getList()
},
handleEdit(){},
Singelmultipl(row){
var self = this;
this.$confirm('确认删除?').then(function () {
self.handleMultiplDel(row);
}).catch(function () {
});
},
handleMultiplDel(row){
var self = this;
this.$http({
method: 'GET',
url: base.env+'/api/CommonBusineess/handleRemoveFile?id='+row.id
}).then(res => {
if(res.data.code==200){
self.$message({
message: res.data.message,
type: 'info' //warning,success,info,error
});
}
if(res.data.code==300){
self.$message({
message: res.data.message,
type: 'warning' //warning,success,info,error
});
}
self.getList();
self.handleRowdblclick({id:self.BusinessType,fileCType:0},{},{});
}).catch(error => {
console.log(error);
});
},
commonDownLoad(row){
var self = this;
this.$http({
method: 'GET',
url: base.env+'/api/CommonS/commonGetDownLoadPath?partialPath='+row.fileUrl
}).then(res => {
debugger
if(res.data.code==200){
location.href = base.env + '/api/CommonS/commonDownLoad?fileName='+row.fileName+'&path='+res.data.data;
self.$http({
method: 'GET',
url: base.env+'/api/CommonBusineess/downLoadFile?id='+row.id
}).then(res => {
self.getList();
self.handleRowdblclick({id:self.BusinessType,fileCType:0},{},{});
}).catch(error => {
console.log(error);
});
}
}).catch(error => {
console.log(error);
});
},
uploadSuccess(obj){
if(obj.fileName!=undefined){
this.$message({
message: '上传成功!',
type: 'success' //warning,success,info,error
});
}else{
this.$message({
message: '文件格式错误,上传失败!',
type: 'error' //warning,success,info,error
});
}
this.isUpload=false;
this.getList();
this.handleRowdblclick({id:this.BusinessType,fileCType:0},{},{});
},
submitForm(){
var self = this;
this.$http({
method: 'GET',
url: base.env+'/api/CommonBusineess/UploadFolder?BusinessType='+self.BusinessType+'&FileName='+self.FileName
}).then(res => {
if(res.data.code==200){
self.isFolder=false;
self.getList();
self.handleRowdblclick({id:self.BusinessType,fileCType:0},{},{});
}
}).catch(error => {
console.log(error);
});
},
}
}
</script>
<style scoped>
::-webkit-scrollbar{width: 7px;height: 7px;background-color: #F5F5F5;}
/*定义滚动条轨道 内阴影+圆角*/
::-webkit-scrollbar-track {box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);border-radius: 10px;background-color: #F5F5F5;}
/*定义滑块 内阴影+圆角*/
::-webkit-scrollbar-thumb{border-radius: 10px;box-shadow: inset 0 0 6px rgba(0, 0, 0, .1);-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, .1);background-color: #c8c8c8;}
.el-aside {color: #333;}
.el-header{height: 100px !important;}
.el-header .search{box-sizing: border-box;border-bottom: 1px solid #eee;text-align: left;}
.el-header .search .btn{position: absolute;right: 12px;top: 2px;}
.el-header .tools{height: 40px;border: 1px solid #ccc;background: #F5F5F5;line-height: 35px;text-align: right;padding: 0px 5px;}
.el-main{height: calc(100vh - 336px);}
.el-cascader,.el-cascader--medium{width: 100%;height: 28px;line-height: 28px;}
.el-date-editor,.el-input {width: 100%;}
.el-icon-folder-opened:before {
content: "\E784";
font-size: 20px !important;
background: yellow !important;
}
.el-icon-files:before {
content: "\E75B";
font-size: 20px !important;
background: #51ff09 !important;
}
</style>
文件上传组件:
<template>
<div id="v_upload">
<el-upload
class="upload-demo"
drag
:limit='limit'
:action="action+'?BusinessId='+BusinessId+'&BusinessType='+BusinessType"
:headers='headers'
:before-upload='beforeUpload'
:on-success='uploadSuccess'
:on-exceed="handleExceed"
:multiple='Ismultiple'>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">上传不超过30M的文件</div>
</el-upload>
<div v-show='false'>
<el-input v-model="fileName" autocomplete="off"></el-input>
<el-input v-model="fileURL" autocomplete="off"></el-input>
</div>
</div>
</template>
<script>
import base from '@/api/base'
export default {
props:['BusinessId','BusinessType','Ismultiple','limit'],
data() {
return {
Base64:'',
fileName:'',
fileURL:'',
headers:{},
// headers:{token:sessionStorage.getItem('Authorization')},
action: base.env+'/api/CommonBusineess/UploadFilesFileMgr',
};
},
created(){
},
watch: {
fileName() {
this.uploadEmit();
}
},
mounted() {
},
methods: {
beforeUpload (file) {
var self = this;
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(e) {
// 图片base64化
var newUrl = this.result; //图片路径
self.Base64 = newUrl;
};
var ext=file.name.substring(file.name.lastIndexOf(".")+1,file.name.length).toLowerCase();
// var msg=/^image\/(jpeg|png|jpg|gif|txt|doc|docx|document|xls|xlsx|pdf)$/.test(file.type)
const isLt4M = file.size / 1024/1024 <=30 //大小不超过30MB
if(!(ext!="xls"||ext!="xlsx"||ext!="pdf"||ext!="docx"||ext!="doc"||ext!="txt"||ext!="gif"||ext!="jpg"||ext!="jpeg"||ext!="png")){
this.$message.error('上传文件格式不对!');
return false;
}
if(!isLt4M) {
this.$message.error('上传文件大小不能超过 30M!');
return false;
}
return isLt4M
},
handleExceed(files, fileList){
if(files.length>this.limit){
this.$message.warning(`此次上传数量为:${files.length},超出文件最大(${this.limit})限制个数。`);
}
},
uploadSuccess(response, file, fileList){
this.fileName=response.fileName;
this.fileURL=response.fileURL;
},
uploadEmit(){
this.$emit('uploadSuccess', {fileName:this.fileName,fileUrl:this.fileURL,Base64:this.Base64});
}
}
}
</script>
<style scoped>
</style>
base:后端接口基地址。
axios封装:
import axios from 'axios'
Vue.prototype.$http = axios
服务端代码:
public class CommonBusineessController : BaseController
{
#region
/// <summary>
/// 查询文件管理带分页
/// </summary>
/// <param name="id">查询内容</param>
/// <param name="pageIndex">页索引</param>
/// <param name="pageSize">页大小</param>
/// <returns></returns>
[HttpPost, HttpGet]
public ActionResult<ZyFileinfos> GetFileManagePageBySearch(string id, int pageIndex, int pageSize, string startDate, string endDate)
{
var data = XCode.Entity<ZyFileinfos>.FindAll().ToList();
if (!string.IsNullOrEmpty(id))
{
data = data.Where(p => p.keyId == id).ToList();
}
if (!string.IsNullOrEmpty(startDate))
{
data = data.Where(p => p.uploadTime >= Convert.ToDateTime(startDate)).ToList();
}
if (!string.IsNullOrEmpty(endDate))
{
data = data.Where(p => p.uploadTime <= Convert.ToDateTime(endDate)).ToList();
}
var list = data.Skip((pageIndex - 1) * pageSize).Take(pageSize);
return Ok(new { code = 200, total = data.Count, data = list });
}
/// <summary>
/// 查询文件管理
/// </summary>
/// <param name="id">查询内容</param>
/// <returns></returns>
[HttpPost, HttpGet]
public ActionResult<ZyFileinfos> GetParentIdById(Int32? id)
{
ZyFileinfos data = XCode.Entity<ZyFileinfos>.Find("id", id);
return Ok(new { code = 200, data = data.keyId });
}
/// <summary>
/// 文件管理删除
/// </summary>
/// <returns></returns>
[HttpPost, HttpGet]
public ActionResult<ZyFileinfos> handleRemoveFile(string id)
{
if (XCode.Entity<ZyFileinfos>.FindAll("keyId", id).ToList<ZyFileinfos>() != null && XCode.Entity<ZyFileinfos>.FindAll("keyId", id).ToList<ZyFileinfos>().Count > 0)
{
return Ok(new { code = 300, message = "该文件夹存在文件,不允许删除!" });
}
else
{
string message=XCode.Entity<ZyFileinfos>.Find("id", id).Delete() > 0 ? "操作成功!" : "操作失败!";
return Ok(new { code = 200, message });
}
}
/// <summary>
/// 下载
/// </summary>
/// <returns></returns>
[HttpPost, HttpGet]
public ActionResult<ZyFileinfos> downLoadFile(string id)
{
ZyFileinfos model = XCode.Entity<ZyFileinfos>.Find("id", id);
model.downloadCount += 1;
XCode.Entity<ZyFileinfos>.Update(model);
return Ok(new { code = 200 });
}
/// <summary>
/// 文件管理附件上传
/// </summary>
/// <param name="sfi"></param>
/// <returns></returns>
[HttpPost, HttpGet]
[AllowAnonymous]
public IActionResult UploadFolder(ZyFileinfos sfi)
{
//UserModel CurUser = JsonConvert.DeserializeObject<UserModel>(this.User.FindFirstValue(ClaimTypes.UserData));
bool isSucc = false;
string fPath = "";
string shortTime = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
string CurDate = DateTime.Now.ToString("yyyyMMddHHmmssff");
string filePhysicalPath = Directory.GetCurrentDirectory() + "/Upload/FileMgr/" + CurDate;
ZyFileinfos model = new ZyFileinfos();
var filePath = Path.Combine(Directory.GetCurrentDirectory(), "Upload/FileMgr/" + CurDate, sfi.FileName);
fPath = filePath;
var linkNameHTML = "Upload/FileMgr/" + CurDate + "/" + sfi.FileName + "";
var fileName = Path.GetFileName(linkNameHTML);//带后缀
model.keyId = sfi.BusinessType.ToString(); //上级目录
model.fileCType = 0;//0:文件夹 1:文件
model.docType = "9";//暂定9文件管理
//model.usrId = Convert.ToInt32(CurUser.UserId);
//model.Creator = CurUser.UserName;
model.uploadTime = DateTime.Now;
model.fileName = sfi.FileName;
model.fileUrl = linkNameHTML;
model.fileGuid = Guid.NewGuid().ToString();
model.downloadCount = 0;
isSucc=XCode.Entity<ZyFileinfos>.Insert(model) > 0 ? true : false;
return Ok(new { code = 200, IsSuccess = true, model.fileUrl, model.fileName });
}
/// <summary>
/// 文件管理添加文件夹
/// </summary>
/// <param name="sfi"></param>
/// <returns></returns>
[HttpPost, HttpGet]
public IActionResult UploadFilesFileMgr(ZyFileinfos sfi)
{
//UserModel CurUser = JsonConvert.DeserializeObject<UserModel>(this.User.FindFirstValue(ClaimTypes.UserData));
bool isSucc = false;
var file = Request;
var files = Request.Form.Files;
string fPath = "";
string shortTime = DateTime.Now.ToString("yyyy-MM-dd hh:mm:ss");
string CurDate = DateTime.Now.ToString("yyyyMMddHHmmssff");
string filePhysicalPath = Directory.GetCurrentDirectory() + "/Upload/FileMgr/" + CurDate;
Console.WriteLine(filePhysicalPath);
//如果目标文件夹不存在,则创建
if (!Directory.Exists(filePhysicalPath))
{
Directory.CreateDirectory(filePhysicalPath);
}
string allowExtension = ".jpg,.jpeg,.png,.gif,.txt,.doc,.docx,.xls,.xlsx,.pdf";// System.Configuration.ConfigurationManager.AppSettings["excelExtension"].ToString();
//Sys_FileInfo model = new Sys_FileInfo();
ZyFileinfos model = new ZyFileinfos();
foreach (var file1 in files)
{
if (file1.Length > 0)
{
string extension = Path.GetExtension(file1.FileName).ToLower();
if (allowExtension.IndexOf(extension) == -1)
{
return Ok(new { IsSuccess = false });
}
var filePath = Path.Combine(Directory.GetCurrentDirectory(), "Upload/FileMgr/" + CurDate, file1.FileName);
fPath = filePath;
using (var stream = new FileStream(filePath, FileMode.Create))
{
file1.CopyTo(stream);
}
}
var linkNameHTML = "Upload/FileMgr/" + CurDate + "/" + file1.FileName + "";
var fileName = Path.GetFileName(linkNameHTML);//带后缀
model.keyId = sfi.BusinessType.ToString(); //上级目录
model.fileCType = Convert.ToInt32(sfi.BusinessId);//0:文件夹 1:文件
model.docType = "9";//暂定9文件管理
//model.usrId = Convert.ToInt32(CurUser.UserId);
//model.Creator = CurUser.UserName;
model.uploadTime = DateTime.Now;
model.fileName = fileName;
model.fileUrl = linkNameHTML;
model.fileGuid = Guid.NewGuid().ToString();
model.downloadCount = 0;
isSucc = XCode.Entity<ZyFileinfos>.Insert(model) > 0 ? true : false;
}
return Ok(new { code = 200, IsSuccess = true, model.fileUrl, model.fileName });
}
#endregion
}
下载文件通用代码:
public class CommonS : BaseController
{
private readonly IHostingEnvironment _hostingEnvironment;
string _webRootPath = string.Empty;
string _contentRootPath = string.Empty;
/// <summary>
/// 构造函数相关
/// </summary>
/// <param name="hostingEnvironment">参数</param>
public CommonS(IHostingEnvironment hostingEnvironment)
{
_hostingEnvironment = hostingEnvironment;
_webRootPath = _hostingEnvironment.WebRootPath;
_contentRootPath = _hostingEnvironment.ContentRootPath;
}
/// <summary>
/// 获取下载文件路径
/// </summary>
/// <param name="partialPath">文件部分路径</param>
/// <returns></returns>
[HttpPost, HttpGet]
public ActionResult commonGetDownLoadPath(string partialPath)
{
if (!string.IsNullOrEmpty(partialPath))
{
_contentRootPath += "/"+partialPath;
FileInfo fileInfo = new FileInfo(_contentRootPath);
if (fileInfo.Exists == true)
{
return Ok(new { code = 200, data = _contentRootPath });
}
else
{
return Ok(new { code = 404, data = "下载文件已经被删除,无法下载!" });
}
}
else
{
return Ok(new { code = 201, msg = "参数不能为空!" });
}
}
/// <summary>
/// 下载通用[文件名称带后缀,比如.doc,.xls]
/// </summary>
/// <param name="fileName">文件名称</param>
/// <param name="path">路径</param>
/// <returns></returns>
[HttpPost, HttpGet]
public ActionResult commonDownLoad(string fileName, string path)
{
if (!string.IsNullOrEmpty(fileName) && !string.IsNullOrEmpty(path))
{
var stream = System.IO.File.OpenRead(path);
return File(stream, "application/oct-stream", fileName.Trim());//输出到浏览器
}
else
{
return Ok(new { code = 201, msg = "参数不能为空!" });
}
}
}
数据库设计:
扩展字段: