├── .babelrc ├── .gitignore ├── LICENSE ├── README.md ├── babel.config.js ├── package-lock.json ├── package.json ├── public └── index.html ├── src ├── App.vue ├── assets │ ├── images │ │ ├── common │ │ │ └── logo.png │ │ ├── error │ │ │ ├── 401.png │ │ │ ├── 404.png │ │ │ └── 500.png │ │ ├── file │ │ │ ├── dir.png │ │ │ ├── file_avi.png │ │ │ ├── file_chm.png │ │ │ ├── file_code.png │ │ │ ├── file_css.png │ │ │ ├── file_csv.png │ │ │ ├── file_dmg.png │ │ │ ├── file_excel.png │ │ │ ├── file_exe.png │ │ │ ├── file_gif.png │ │ │ ├── file_html.png │ │ │ ├── file_img.png │ │ │ ├── file_jar.png │ │ │ ├── file_js.png │ │ │ ├── file_json.png │ │ │ ├── file_md.png │ │ │ ├── file_music.png │ │ │ ├── file_oa.png │ │ │ ├── file_open.png │ │ │ ├── file_pdf.png │ │ │ ├── file_pic.png │ │ │ ├── file_ppt.png │ │ │ ├── file_rar.png │ │ │ ├── file_rtf.png │ │ │ ├── file_sql.png │ │ │ ├── file_svg.png │ │ │ ├── file_txt.png │ │ │ ├── file_unknown.png │ │ │ ├── file_video.png │ │ │ ├── file_word.png │ │ │ └── file_zip.png │ │ ├── footer │ │ │ └── wechatImg.png │ │ ├── login │ │ │ └── qqIcon.png │ │ └── settings │ │ │ └── userImg.png │ └── styles │ │ ├── css │ │ ├── base.css │ │ ├── border.css │ │ ├── element-cover.css │ │ └── mediaScreen.styl │ │ ├── mixins.styl │ │ └── varibles.styl ├── components │ ├── DdPlayer.vue │ ├── DragVerify.vue │ ├── Footer.vue │ ├── GlobalUploader.vue │ ├── Header.vue │ ├── ImgReview.vue │ └── ScpDivider.vue ├── element.js ├── filters │ └── index.js ├── global │ ├── globalConst.js │ └── globalFunction.js ├── main.js ├── request │ ├── file.js │ ├── http.js │ └── user.js ├── router │ ├── before.js │ └── router.js ├── store │ ├── index.js │ └── module │ │ ├── fileList.js │ │ ├── imgReview.js │ │ ├── player.js │ │ ├── sideMenu.js │ │ └── user.js └── views │ ├── ErrorPage │ ├── 401.vue │ ├── 404.vue │ └── 500.vue │ ├── file │ ├── File.vue │ └── components │ │ ├── AsideMenu │ │ └── AsideMenu.vue │ │ └── FileList │ │ ├── components │ │ ├── BreadCrumb.vue │ │ ├── FileGrid.vue │ │ ├── FileTable.vue │ │ ├── FileTimeLine.vue │ │ ├── MoveFileDialog.vue │ │ ├── OperationMenu.vue │ │ └── SelectColumn.vue │ │ └── index.vue │ └── user │ ├── Login.vue │ └── Register.vue └── vue.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [["@babel/preset-env", { "modules": false }]], 3 | "plugins": [ 4 | [ 5 | "component", 6 | { 7 | "libraryName": "element-ui", 8 | "styleLibraryName": "theme-chalk" 9 | } 10 | ] 11 | ] 12 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | /dist 4 | 5 | # local env files 6 | .env.local 7 | .env.*.local 8 | 9 | # Log files 10 | npm-debug.log* 11 | yarn-debug.log* 12 | yarn-error.log* 13 | 14 | # Editor directories and files 15 | .idea 16 | .vscode 17 | *.suo 18 | *.ntvs* 19 | *.njsproj 20 | *.sln 21 | *.sw? 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 MAC 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![输入图片说明](https://images.gitee.com/uploads/images/2021/0410/050022_9ec81567_2098391.png "网格视图.png") 2 | 3 | ## 在线演示 4 | 5 | 6 | [丢丢网盘演示地址](http://106.53.130.89) 7 | 8 | 9 | 10 | ## 功能介绍 11 | 12 | 1. 多文件格式分类查看 13 | 14 | 2. 支持网格、表格视图、时间线三种展示视图 15 | 16 | 3. 支持极速秒传功能,提高上传效率 17 | 18 | 4. 多人上传同一文件,可多人并行上传,共享他人上传进度,极大提高上传效率 19 | 20 | 5. 拒绝冗余,每份文件只存一份,提高硬盘使用效率 21 | 22 | 6. 上传文件前台实时显示上传文件进度,上传速率,百分比等信息 23 | 24 | 7. 安全的下载机制,断点下载,权限校验,他人拿到了下载地址也无法下载您的文件 25 | 26 | 8. 支持视频音频播放,进度条拖拽,倍速播放 27 | 28 | 9. 拥有回收站功能,妈妈再也不怕我误删数据了 29 | 30 | 10. 高效的垃圾回收机制 31 | 32 | ## 未来支持 33 | 1. 文件夹上传 34 | 2. 文件在线解压 35 | 3. 文件在线压缩 36 | 4. 文件分享 37 | 5. 拖拽上传 38 | 6. 链接下载(输入url,下载过程交予服务器) 39 | 7. ...... 40 | 41 | ## 正在进行计划 42 | 1. 文件分享功能 43 | 44 | ## 源码地址 45 | 46 | | 项目名称 | 源码地址 | 47 | | ------------ | -------------------------------------------------------------------------------------------- | 48 | | 丢丢网盘前端 | [https://gitee.com/JavaerLi/ddisk-web](https://gitee.com/JavaerLi/ddisk-web) | 49 | | 丢丢网盘后台 | [https://gitee.com/JavaerLi/ddisk-file](https://gitee.com/JavaerLi/ddisk-file) | 50 | 51 | 52 | 53 | ## 软件架构 54 | 55 | 该项目采用前后端分离的方式进行开发和部署,主要用到以下关键技术 56 | 57 | **前端**:Element UI、Vue CLI@3、Node.js、Webpack 58 | 59 | **后台**:Spring Boot、Spring Data Jpa、Spring Security 60 | 61 | **数据库** : MySQL、H2 62 | 63 | **数据结构**:递归算法,树的遍历和插入... 64 | 65 | 66 | 67 | ## 部分功能截图 68 | 69 | ### 视频播放 70 | 71 | ![视频播放](https://images.gitee.com/uploads/images/2021/0410/050042_0bc9d77a_2098391.png "视频播放.png") 72 | 73 | 74 | 75 | ### 图片预览 76 | 77 | ![图片预览](https://images.gitee.com/uploads/images/2021/0410/050152_9f2ee996_2098391.png "图片.png") 78 | 79 | 80 | 81 | ## 特别声明 82 | 83 | 感谢奇文社区、奇文网盘,本项目前端是在该项目UI上二次开发,后端自主研发。 84 | 85 | 该项目也是我毕业设计作品,也是学习以来,独立开发的第一款WEB产品,如果喜欢,请您star支持一下! 86 | 87 | 希望有热心的同学可以共享一个logo,感激不尽! 88 | 89 | ![QQ群](https://images.gitee.com/uploads/images/2021/0410/050213_584de85f_2098391.png "qq群.png") 90 | 91 | -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | '@vue/app' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webscp", 3 | "version": "1.3.1", 4 | "private": true, 5 | "scripts": { 6 | "serve": "vue-cli-service serve --open", 7 | "build": "vue-cli-service build", 8 | "lint": "vue-cli-service lint" 9 | }, 10 | "dependencies": { 11 | "canvas-nest.js": "^2.0.4", 12 | "core-js": "^2.6.5", 13 | "element-ui": "^2.13.2", 14 | "qs": "^6.8.0", 15 | "spark-md5": "^3.0.1", 16 | "vue": "^2.6.10", 17 | "vue-router": "^3.0.3", 18 | "vue-simple-uploader": "^0.7.6", 19 | "vue-video-player": "^5.0.2", 20 | "vuex": "^3.0.1" 21 | }, 22 | "devDependencies": { 23 | "@vue/cli-plugin-babel": "^3.11.0", 24 | "@vue/cli-plugin-eslint": "^3.11.0", 25 | "@vue/cli-service": "^3.11.0", 26 | "axios": "^0.18.1", 27 | "babel-eslint": "^10.0.1", 28 | "babel-plugin-component": "^1.1.1", 29 | "eslint": "^5.16.0", 30 | "eslint-plugin-vue": "^5.0.0", 31 | "style-resources-loader": "^1.2.1", 32 | "stylus": "^0.54.7", 33 | "stylus-loader": "^3.0.2", 34 | "vue-cli-plugin-axios": "0.0.4", 35 | "vue-cli-plugin-element": "^1.0.1", 36 | "vue-cli-plugin-style-resources-loader": "^0.1.3", 37 | "vue-template-compiler": "^2.6.10" 38 | }, 39 | "eslintConfig": { 40 | "root": true, 41 | "env": { 42 | "node": true 43 | }, 44 | "extends": [ 45 | "plugin:vue/essential", 46 | "eslint:recommended" 47 | ], 48 | "rules": { 49 | "no-console": "off" 50 | }, 51 | "parserOptions": { 52 | "parser": "babel-eslint" 53 | } 54 | }, 55 | "postcss": { 56 | "plugins": { 57 | "autoprefixer": {} 58 | } 59 | }, 60 | "browserslist": [ 61 | "> 1%", 62 | "last 2 versions" 63 | ] 64 | } 65 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 13 | 丢丢网盘 14 | 15 | 16 | 17 | 23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 64 | 82 | -------------------------------------------------------------------------------- /src/assets/images/common/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/common/logo.png -------------------------------------------------------------------------------- /src/assets/images/error/401.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/error/401.png -------------------------------------------------------------------------------- /src/assets/images/error/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/error/404.png -------------------------------------------------------------------------------- /src/assets/images/error/500.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/error/500.png -------------------------------------------------------------------------------- /src/assets/images/file/dir.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/dir.png -------------------------------------------------------------------------------- /src/assets/images/file/file_avi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_avi.png -------------------------------------------------------------------------------- /src/assets/images/file/file_chm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_chm.png -------------------------------------------------------------------------------- /src/assets/images/file/file_code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_code.png -------------------------------------------------------------------------------- /src/assets/images/file/file_css.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_css.png -------------------------------------------------------------------------------- /src/assets/images/file/file_csv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_csv.png -------------------------------------------------------------------------------- /src/assets/images/file/file_dmg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_dmg.png -------------------------------------------------------------------------------- /src/assets/images/file/file_excel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_excel.png -------------------------------------------------------------------------------- /src/assets/images/file/file_exe.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_exe.png -------------------------------------------------------------------------------- /src/assets/images/file/file_gif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_gif.png -------------------------------------------------------------------------------- /src/assets/images/file/file_html.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_html.png -------------------------------------------------------------------------------- /src/assets/images/file/file_img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_img.png -------------------------------------------------------------------------------- /src/assets/images/file/file_jar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_jar.png -------------------------------------------------------------------------------- /src/assets/images/file/file_js.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_js.png -------------------------------------------------------------------------------- /src/assets/images/file/file_json.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_json.png -------------------------------------------------------------------------------- /src/assets/images/file/file_md.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_md.png -------------------------------------------------------------------------------- /src/assets/images/file/file_music.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_music.png -------------------------------------------------------------------------------- /src/assets/images/file/file_oa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_oa.png -------------------------------------------------------------------------------- /src/assets/images/file/file_open.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_open.png -------------------------------------------------------------------------------- /src/assets/images/file/file_pdf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_pdf.png -------------------------------------------------------------------------------- /src/assets/images/file/file_pic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_pic.png -------------------------------------------------------------------------------- /src/assets/images/file/file_ppt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_ppt.png -------------------------------------------------------------------------------- /src/assets/images/file/file_rar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_rar.png -------------------------------------------------------------------------------- /src/assets/images/file/file_rtf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_rtf.png -------------------------------------------------------------------------------- /src/assets/images/file/file_sql.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_sql.png -------------------------------------------------------------------------------- /src/assets/images/file/file_svg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_svg.png -------------------------------------------------------------------------------- /src/assets/images/file/file_txt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_txt.png -------------------------------------------------------------------------------- /src/assets/images/file/file_unknown.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_unknown.png -------------------------------------------------------------------------------- /src/assets/images/file/file_video.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_video.png -------------------------------------------------------------------------------- /src/assets/images/file/file_word.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_word.png -------------------------------------------------------------------------------- /src/assets/images/file/file_zip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/file/file_zip.png -------------------------------------------------------------------------------- /src/assets/images/footer/wechatImg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/footer/wechatImg.png -------------------------------------------------------------------------------- /src/assets/images/login/qqIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/login/qqIcon.png -------------------------------------------------------------------------------- /src/assets/images/settings/userImg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/JavaerLQ/ddisk-web/ef1d172cf659a320772cf0d207c43d3f0e50e419/src/assets/images/settings/userImg.png -------------------------------------------------------------------------------- /src/assets/styles/css/base.css: -------------------------------------------------------------------------------- 1 | *{ margin:0; padding:0; box-sizing: border-box;} 2 | html{ height: 100%; } 3 | body{ height: 100%;font-size:16px; font-family:微软雅黑;font-style:normal;overflow-x: hidden;} 4 | a{ text-decoration:none} 5 | /*a,a:hover{ transition:background 0.5s linear;-webkit-transition:background 0.5s linear;-moz-transition:background 0.5s linear;-o-transition:background 0.5s linear;}*/ 6 | em, i{font-style: normal;} 7 | ul, ol, li{list-style: none;} 8 | img{ border:none;vertical-align:middle;} 9 | input,select,textarea{outline:none;border:none;background:none;} 10 | textarea{resize:none;} 11 | p{line-height:22px;} 12 | .fl{float: left;} 13 | .fr{float: right;} 14 | .clear{ clear:both; height:0px; width:100%; overflow:hidden;} 15 | .position{position:relative;} 16 | 17 | /*公共样式*/ 18 | .layout{ width:1100px; display:table; margin:0 auto;} 19 | .margin-bottom { margin-bottom: 15px; } -------------------------------------------------------------------------------- /src/assets/styles/css/border.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | .border, 3 | .border-top, 4 | .border-right, 5 | .border-bottom, 6 | .border-left, 7 | .border-topbottom, 8 | .border-rightleft, 9 | .border-topleft, 10 | .border-rightbottom, 11 | .border-topright, 12 | .border-bottomleft { 13 | position: relative; 14 | } 15 | .border::before, 16 | .border-top::before, 17 | .border-right::before, 18 | .border-bottom::before, 19 | .border-left::before, 20 | .border-topbottom::before, 21 | .border-topbottom::after, 22 | .border-rightleft::before, 23 | .border-rightleft::after, 24 | .border-topleft::before, 25 | .border-topleft::after, 26 | .border-rightbottom::before, 27 | .border-rightbottom::after, 28 | .border-topright::before, 29 | .border-topright::after, 30 | .border-bottomleft::before, 31 | .border-bottomleft::after { 32 | content: "\0020"; 33 | overflow: hidden; 34 | position: absolute; 35 | } 36 | /* border 37 | * 因,边框是由伪元素区域遮盖在父级 38 | * 故,子级若有交互,需要对子级设置 39 | * 定位 及 z轴 40 | */ 41 | .border::before { 42 | box-sizing: border-box; 43 | top: 0; 44 | left: 0; 45 | height: 100%; 46 | width: 100%; 47 | border: 1px solid #eaeaea; 48 | transform-origin: 0 0; 49 | } 50 | .border-top::before, 51 | .border-bottom::before, 52 | .border-topbottom::before, 53 | .border-topbottom::after, 54 | .border-topleft::before, 55 | .border-rightbottom::after, 56 | .border-topright::before, 57 | .border-bottomleft::before { 58 | left: 0; 59 | width: 100%; 60 | height: 1px; 61 | } 62 | .border-right::before, 63 | .border-left::before, 64 | .border-rightleft::before, 65 | .border-rightleft::after, 66 | .border-topleft::after, 67 | .border-rightbottom::before, 68 | .border-topright::after, 69 | .border-bottomleft::after { 70 | top: 0; 71 | width: 1px; 72 | height: 100%; 73 | } 74 | .border-top::before, 75 | .border-topbottom::before, 76 | .border-topleft::before, 77 | .border-topright::before { 78 | border-top: 1px solid #eaeaea; 79 | transform-origin: 0 0; 80 | } 81 | .border-right::before, 82 | .border-rightbottom::before, 83 | .border-rightleft::before, 84 | .border-topright::after { 85 | border-right: 1px solid #eaeaea; 86 | transform-origin: 100% 0; 87 | } 88 | .border-bottom::before, 89 | .border-topbottom::after, 90 | .border-rightbottom::after, 91 | .border-bottomleft::before { 92 | border-bottom: 1px solid #eaeaea; 93 | transform-origin: 0 100%; 94 | } 95 | .border-left::before, 96 | .border-topleft::after, 97 | .border-rightleft::after, 98 | .border-bottomleft::after { 99 | border-left: 1px solid #eaeaea; 100 | transform-origin: 0 0; 101 | } 102 | .border-top::before, 103 | .border-topbottom::before, 104 | .border-topleft::before, 105 | .border-topright::before { 106 | top: 0; 107 | } 108 | .border-right::before, 109 | .border-rightleft::after, 110 | .border-rightbottom::before, 111 | .border-topright::after { 112 | right: 0; 113 | } 114 | .border-bottom::before, 115 | .border-topbottom::after, 116 | .border-rightbottom::after, 117 | .border-bottomleft::after { 118 | bottom: 0; 119 | } 120 | .border-left::before, 121 | .border-rightleft::before, 122 | .border-topleft::after, 123 | .border-bottomleft::before { 124 | left: 0; 125 | } 126 | @media (max--moz-device-pixel-ratio: 1.49), (-webkit-max-device-pixel-ratio: 1.49), (max-device-pixel-ratio: 1.49), (max-resolution: 143dpi), (max-resolution: 1.49dppx) { 127 | /* 默认值,无需重置 */ 128 | } 129 | @media (min--moz-device-pixel-ratio: 1.5) and (max--moz-device-pixel-ratio: 2.49), (-webkit-min-device-pixel-ratio: 1.5) and (-webkit-max-device-pixel-ratio: 2.49), (min-device-pixel-ratio: 1.5) and (max-device-pixel-ratio: 2.49), (min-resolution: 144dpi) and (max-resolution: 239dpi), (min-resolution: 1.5dppx) and (max-resolution: 2.49dppx) { 130 | .border::before { 131 | width: 200%; 132 | height: 200%; 133 | transform: scale(.5); 134 | } 135 | .border-top::before, 136 | .border-bottom::before, 137 | .border-topbottom::before, 138 | .border-topbottom::after, 139 | .border-topleft::before, 140 | .border-rightbottom::after, 141 | .border-topright::before, 142 | .border-bottomleft::before { 143 | transform: scaleY(.5); 144 | } 145 | .border-right::before, 146 | .border-left::before, 147 | .border-rightleft::before, 148 | .border-rightleft::after, 149 | .border-topleft::after, 150 | .border-rightbottom::before, 151 | .border-topright::after, 152 | .border-bottomleft::after { 153 | transform: scaleX(.5); 154 | } 155 | } 156 | @media (min--moz-device-pixel-ratio: 2.5), (-webkit-min-device-pixel-ratio: 2.5), (min-device-pixel-ratio: 2.5), (min-resolution: 240dpi), (min-resolution: 2.5dppx) { 157 | .border::before { 158 | width: 300%; 159 | height: 300%; 160 | transform: scale(.33333); 161 | } 162 | .border-top::before, 163 | .border-bottom::before, 164 | .border-topbottom::before, 165 | .border-topbottom::after, 166 | .border-topleft::before, 167 | .border-rightbottom::after, 168 | .border-topright::before, 169 | .border-bottomleft::before { 170 | transform: scaleY(.33333); 171 | } 172 | .border-right::before, 173 | .border-left::before, 174 | .border-rightleft::before, 175 | .border-rightleft::after, 176 | .border-topleft::after, 177 | .border-rightbottom::before, 178 | .border-topright::after, 179 | .border-bottomleft::after { 180 | transform: scaleX(.33333); 181 | } 182 | } 183 | .border-radius { 184 | border-radius: 4px; 185 | } -------------------------------------------------------------------------------- /src/assets/styles/css/element-cover.css: -------------------------------------------------------------------------------- 1 | .el-avatar>img { 2 | width: 100%; 3 | } 4 | .el-textarea__inner { 5 | font-family: inherit; 6 | } -------------------------------------------------------------------------------- /src/assets/styles/css/mediaScreen.styl: -------------------------------------------------------------------------------- 1 | @media screen and (max-width 980px) 2 | // 顶部导航栏 3 | .headerWrapper 4 | .headerItem 5 | padding 0 10px !important 6 | .userDisplay 7 | width 110px !important 8 | .el-menu-demo 9 | .userDisplay 10 | .username-header 11 | display none !important 12 | // 底部 13 | .footer-wrapper 14 | .footer-top 15 | .info 16 | .logo 17 | height 80px !important 18 | .link-wrapper 19 | padding 6px 6px 6px 12px !important 20 | line-height 30px !important -------------------------------------------------------------------------------- /src/assets/styles/mixins.styl: -------------------------------------------------------------------------------- 1 | setScrollbar(scrollbarWidth, trackColor = #EBEEF5, thumbColor = #909399) 2 | // 修改滚动条下面的宽度 3 | &::-webkit-scrollbar 4 | width scrollbarWidth 5 | // 修改滚动条的下面的样式 6 | &::-webkit-scrollbar-track 7 | background-color trackColor 8 | -webkit-border-radius 2em 9 | -moz-border-radius 2em 10 | border-radius 2em 11 | // 修改滑块 12 | &::-webkit-scrollbar-thumb 13 | background-color thumbColor 14 | -webkit-border-radius 2em 15 | -moz-border-radius 2em 16 | border-radius 2em 17 | setEllipsis(line) 18 | display: -webkit-box; 19 | overflow: hidden; 20 | white-space: wrap; 21 | text-overflow: ellipsis; 22 | -webkit-box-orient: vertical; /* -webkit-box-orient 必须结合的属性 ,设置或检索伸缩盒对象的子元素的排列方式 */ 23 | -webkit-line-clamp: line; /* -webkit-line-clamp用来限制在一个块元素显示的文本的行数 */ -------------------------------------------------------------------------------- /src/assets/styles/varibles.styl: -------------------------------------------------------------------------------- 1 | $Primary = #409EFF 2 | $Success = #67C23A 3 | $Warning = #E6A23C 4 | $Danger = #F56C6C 5 | $Info = #909399 6 | 7 | $PrimaryHover = #ecf5ff 8 | $SuccessHover = #f0f9eb 9 | $WarningHover = #fdf6ec 10 | $DangerHover = #fdf6ec 11 | $InfoHover = #fef0f0 12 | 13 | $PrimaryText = #303133 14 | $RegularText = #606266 15 | $SecondaryText = #909399 16 | $Placeholder = #C0C4CC 17 | 18 | $BorderBase = #DCDFE6 19 | $BorderLight = #E4E7ED 20 | $BorderLighter = #EBEEF5 21 | $BorderExtralight = #F2F6FC 22 | 23 | $tabBackColor = #F5F7FA 24 | $tabBoxShadow = 0 2px 12px 0 rgba(0, 0, 0, 0.1) 25 | $tabBoxShadowMin = 0 2px 4px 0 rgba(0, 0, 0, 0.1) -------------------------------------------------------------------------------- /src/components/DdPlayer.vue: -------------------------------------------------------------------------------- 1 | 43 | 44 | 138 | 139 | 229 | -------------------------------------------------------------------------------- /src/components/DragVerify.vue: -------------------------------------------------------------------------------- 1 | 37 | 228 | 282 | -------------------------------------------------------------------------------- /src/components/Footer.vue: -------------------------------------------------------------------------------- 1 | 29 | 30 | 46 | 47 | 112 | -------------------------------------------------------------------------------- /src/components/GlobalUploader.vue: -------------------------------------------------------------------------------- 1 | 45 | 46 | 283 | 284 | 377 | -------------------------------------------------------------------------------- /src/components/Header.vue: -------------------------------------------------------------------------------- 1 | 32 | 33 | 76 | 77 | 128 | -------------------------------------------------------------------------------- /src/components/ImgReview.vue: -------------------------------------------------------------------------------- 1 | 71 | 72 | 215 | 216 | 370 | -------------------------------------------------------------------------------- /src/components/ScpDivider.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | 15 | -------------------------------------------------------------------------------- /src/element.js: -------------------------------------------------------------------------------- 1 | // 导入自己需要的组件 2 | import { 3 | Dialog, 4 | Dropdown, 5 | DropdownMenu, 6 | DropdownItem, 7 | Menu, 8 | Submenu, 9 | MenuItem, 10 | MenuItemGroup, 11 | Input, 12 | InputNumber, 13 | Radio, 14 | RadioGroup, 15 | RadioButton, 16 | Select, 17 | Option, 18 | OptionGroup, 19 | Button, 20 | ButtonGroup, 21 | Table, 22 | TableColumn, 23 | Tooltip, 24 | Form, 25 | FormItem, 26 | Icon, 27 | Upload, 28 | Image, 29 | Backtop, 30 | MessageBox, 31 | Message, 32 | Notification, 33 | Avatar, 34 | Container, 35 | Header, 36 | Aside, 37 | Main, 38 | Footer, 39 | Breadcrumb, 40 | BreadcrumbItem, 41 | Loading, 42 | Timeline, 43 | TimelineItem, 44 | Alert, 45 | Tree, 46 | Progress, 47 | Slider, 48 | Divider, 49 | Pagination, 50 | CheckboxGroup, 51 | Checkbox, 52 | Popover 53 | } from "element-ui"; 54 | const element = { 55 | install: function (Vue) { 56 | Vue.use(Dialog); 57 | Vue.use(Dropdown); 58 | Vue.use(DropdownMenu); 59 | Vue.use(DropdownItem); 60 | Vue.use(Menu); 61 | Vue.use(Submenu); 62 | Vue.use(MenuItem); 63 | Vue.use(MenuItemGroup); 64 | Vue.use(Input); 65 | Vue.use(InputNumber); 66 | Vue.use(Radio); 67 | Vue.use(RadioGroup); 68 | Vue.use(RadioButton); 69 | Vue.use(Select); 70 | Vue.use(Option); 71 | Vue.use(OptionGroup); 72 | Vue.use(Button); 73 | Vue.use(ButtonGroup); 74 | Vue.use(Table); 75 | Vue.use(TableColumn); 76 | Vue.use(Tooltip); 77 | Vue.use(Form); 78 | Vue.use(FormItem); 79 | Vue.use(Icon); 80 | Vue.use(Upload); 81 | Vue.use(Image); 82 | Vue.use(Backtop); 83 | Vue.use(Avatar); 84 | Vue.use(Container); 85 | Vue.use(Header); 86 | Vue.use(Aside); 87 | Vue.use(Main); 88 | Vue.use(Footer); 89 | Vue.use(Breadcrumb); 90 | Vue.use(BreadcrumbItem); 91 | Vue.use(Loading.directive); 92 | Vue.use(Timeline); 93 | Vue.use(TimelineItem); 94 | Vue.use(Alert); 95 | Vue.use(Tree); 96 | Vue.use(Progress); 97 | Vue.use(Slider); 98 | Vue.use(Divider); 99 | Vue.use(Pagination); 100 | Vue.use(CheckboxGroup); 101 | Vue.use(Checkbox); 102 | Vue.use(Popover); 103 | Vue.prototype.$loading = Loading.service; 104 | Vue.prototype.$msgbox = MessageBox; 105 | Vue.prototype.$alert = MessageBox.alert; 106 | Vue.prototype.$confirm = MessageBox.confirm; 107 | Vue.prototype.$prompt = MessageBox.prompt; 108 | Vue.prototype.$notify = Notification; 109 | Vue.prototype.$message = Message; 110 | }, 111 | }; 112 | export default element; 113 | -------------------------------------------------------------------------------- /src/filters/index.js: -------------------------------------------------------------------------------- 1 | // 存储容量格式化 2 | const storageTrans = (size, status) => { 3 | const B = 1024 4 | const KB = Math.pow(1024, 2) 5 | const MB = Math.pow(1024, 3) 6 | const GB = Math.pow(1024, 4) 7 | if(status) { // 截取整数部分 8 | if (!size) { 9 | return 0 + 'KB' 10 | } else if (size < KB) { 11 | return (size / B).toFixed(0) + 'KB' 12 | } else if (size < MB) { 13 | return (size / KB).toFixed(0) + 'MB' 14 | } else if (size < GB) { 15 | return (size / MB).toFixed(0) + 'GB' 16 | } else { 17 | return (size / GB).toFixed(0) + 'TB' 18 | } 19 | } else { 20 | if (!size) { 21 | return 0 + 'KB' 22 | } else if (size < KB) { 23 | return (size / B).toFixed(0) + 'KB' 24 | } else if (size < MB) { 25 | return (size / KB).toFixed(2) + 'MB' 26 | } else if (size < GB) { 27 | return (size / MB).toFixed(3) + 'GB' 28 | } else { 29 | return (size / GB).toFixed(4) + 'TB' 30 | } 31 | } 32 | } 33 | const filenameComplete = (item) => { 34 | return item.filename + (!item.isDir && item.extension !== null ? `.${item.extension}` : '') 35 | } 36 | 37 | // 分离文件名和文件扩展名 38 | const filenameSplit = (name) => { 39 | let index = name.lastIndexOf('.') 40 | let filename = name.substr(0, index) 41 | let extension = name.substring(index+1) 42 | return { 43 | filename,extension 44 | } 45 | } 46 | 47 | 48 | export { 49 | storageTrans, 50 | filenameComplete, 51 | filenameSplit, 52 | } 53 | -------------------------------------------------------------------------------- /src/global/globalConst.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | /** 3 | * 全局常量 4 | */ 5 | export const SYSTEM_NAME = "丢丢网盘" 6 | // 切片最大大小 7 | export const CHUNK_SIZE = 1024 * 1024; 8 | // 文件根目录ID 9 | export const ROOT_PATH = null; 10 | // 文件类型 11 | export const FILE_TYPE = { 12 | // 不区分文件类型,默认所有类型 13 | ALL: "ALL", 14 | // 图片文件类型 15 | IMAGE: "IMAGE", 16 | // 文档文件类型 17 | DOC: "DOC", 18 | // 视频文件类型 19 | VIDEO: "VIDEO", 20 | // 音乐文件类型 21 | MUSIC: "MUSIC", 22 | // 软件包类型 23 | APP: "APP", 24 | // 其他文件类型 25 | OTHER: "OTHER", 26 | // 共享文件类型 27 | SHARE: "SHARE", 28 | // 回收站文件类型 29 | RECYCLE: "RECYCLE", 30 | } 31 | 32 | // 操作类型,折叠,展开 33 | export const FOLD_TYPE = { 34 | // 展开 35 | UNFOLD: true, 36 | // 折叠 37 | FOLD: false, 38 | } 39 | 40 | // 文件类型对应的中文解释 41 | export const FILE_TYPE_MAP = { 42 | "ALL": '全部文件', 43 | "IMAGE": '全部图片', 44 | "DOC": '全部文档', 45 | "VIDEO": '全部视频', 46 | "MUSIC": '全部音乐', 47 | "APP": '全部应用', 48 | "OTHER": '其他', 49 | "SHARE": '共享文件', 50 | "RECYCLE": '回收站' 51 | } 52 | 53 | // 文件展示模式 54 | export const FILE_MODEL = { 55 | // 列表 56 | TABLE: 0, 57 | // 网格 58 | GRID: 1, 59 | // 时间线 60 | TIME_LINE: 2 61 | } 62 | 63 | // 可识别的图片类型 64 | export const IMG_TYPE_LIST = ["bmp", "jpg", "png", "tif", "gif", "jpeg"] 65 | export const VIDEO_TYPE_LIST = ["avi", "mp4", "mpg", "mov", "swf", "flv"] 66 | export const MUSIC_TYPE_LIST = ["wav", "aif", "au", "mp3", "ram", "wma", "mmf", "amr", "aac", "flac"] 67 | 68 | // 可以识别的文件类型 69 | export const FILE_IMG_TYPE_LIST = [ 70 | 'png', 71 | 'jpg', 72 | 'jpeg', 73 | 'docx', 74 | 'doc', 75 | 'ppt', 76 | 'pptx', 77 | 'xls', 78 | 'xlsx', 79 | 'avi', 80 | 'mp4', 81 | 'css', 82 | 'csv', 83 | 'chm', 84 | 'rar', 85 | 'zip', 86 | 'dmg', 87 | 'mp3', 88 | 'flac', 89 | 'open', 90 | 'pdf', 91 | 'rtf', 92 | 'txt', 93 | 'oa', 94 | 'js', 95 | 'html', 96 | 'img', 97 | 'sql', 98 | 'jar', 99 | 'svg', 100 | 'gif', 101 | 'json', 102 | 'exe', 103 | 'md' 104 | ]; 105 | // 文件图片Map映射 106 | export const FILE_IMG_MAP = { 107 | dir: require('@/assets/images/file/dir.png'), 108 | chm: require('@/assets/images/file/file_chm.png'), 109 | css: require('@/assets/images/file/file_css.png'), 110 | csv: require('@/assets/images/file/file_csv.png'), 111 | png: require('@/assets/images/file/file_pic.png'), 112 | jpg: require('@/assets/images/file/file_pic.png'), 113 | jpeg: require('@/assets/images/file/file_pic.png'), 114 | docx: require('@/assets/images/file/file_word.png'), 115 | doc: require('@/assets/images/file/file_word.png'), 116 | ppt: require('@/assets/images/file/file_ppt.png'), 117 | pptx: require('@/assets/images/file/file_ppt.png'), 118 | xls: require('@/assets/images/file/file_excel.png'), 119 | xlsx: require('@/assets/images/file/file_excel.png'), 120 | mp4: require('@/assets/images/file/file_video.png'), 121 | avi: require('@/assets/images/file/file_avi.png'), 122 | rar: require('@/assets/images/file/file_rar.png'), 123 | zip: require('@/assets/images/file/file_zip.png'), 124 | dmg: require('@/assets/images/file/file_dmg.png'), 125 | mp3: require('@/assets/images/file/file_music.png'), 126 | flac: require('@/assets/images/file/file_music.png'), 127 | open: require('@/assets/images/file/file_open.png'), 128 | pdf: require('@/assets/images/file/file_pdf.png'), 129 | rtf: require('@/assets/images/file/file_rtf.png'), 130 | txt: require('@/assets/images/file/file_txt.png'), 131 | oa: require('@/assets/images/file/file_oa.png'), 132 | md: require('@/assets/images/file/file_md.png'), 133 | unknown: require('@/assets/images/file/file_unknown.png'), 134 | js: require('@/assets/images/file/file_js.png'), 135 | html: require('@/assets/images/file/file_html.png'), 136 | img: require('@/assets/images/file/file_img.png'), 137 | sql: require('@/assets/images/file/file_sql.png'), 138 | jar: require('@/assets/images/file/file_jar.png'), 139 | svg: require('@/assets/images/file/file_svg.png'), 140 | gif: require('@/assets/images/file/file_gif.png'), 141 | json: require('@/assets/images/file/file_json.png'), 142 | exe: require('@/assets/images/file/file_exe.png') 143 | }; 144 | 145 | export default { 146 | install(){ 147 | Vue.prototype.SYSTEM_NAME = SYSTEM_NAME 148 | // 文件类型 149 | Vue.prototype.FILE_TYPE = FILE_TYPE; 150 | // 根目录ID 151 | Vue.prototype.ROOT_PATH = ROOT_PATH; 152 | // 文件类型对应的中文解释 153 | Vue.prototype.FILE_TYPE_MAP = FILE_TYPE_MAP; 154 | // 文件操作,折叠或展开 155 | Vue.prototype.FOLD_TYPE = FOLD_TYPE; 156 | // 文件展示模式 157 | Vue.prototype.FILE_MODEL = FILE_MODEL; 158 | Vue.prototype.FILE_IMG_TYPE_LIST = FILE_IMG_TYPE_LIST; 159 | Vue.prototype.FILE_IMG_MAP = FILE_IMG_MAP; 160 | Vue.prototype.CHUNK_SIZE = CHUNK_SIZE; 161 | Vue.prototype.IMG_TYPE_LIST = IMG_TYPE_LIST; 162 | Vue.prototype.VIDEO_TYPE_LIST = VIDEO_TYPE_LIST 163 | Vue.prototype.MUSIC_TYPE_LIST = MUSIC_TYPE_LIST 164 | } 165 | } 166 | -------------------------------------------------------------------------------- /src/global/globalFunction.js: -------------------------------------------------------------------------------- 1 | //全局函数 ,挂载到Vue实例上 2 | import {url} from "@/request/http"; 3 | 4 | export default function install(Vue) { 5 | /** 6 | * checkIsLogin(params) 页面内某些功能需要用户登录时调用,调用示例如下 7 | * let res = this.checkIsLogin(this.$route.fullPath); 8 | * if(res === true) { 9 | * // 做些什么...... 10 | * } 11 | * 其中,参数为当前页面的全部路由fullPath(即包括query等参数) 12 | */ 13 | // 检测用户登录状态并做相应的跳转 14 | Vue.prototype.checkIsLogin = function (params) { 15 | if (this.$store.getters.isLogin === false) { // 未登录时自动跳转到登录页面,并将当前页面的路由作为query传递给登陆页面 16 | this.$router.push({path: '/login', query: {Rurl: params}}); 17 | } else { 18 | return true 19 | } 20 | }; 21 | 22 | // 文件类型,图片,音乐,文档等 23 | Vue.prototype.fileType = function () { 24 | // 是回收站类型文件 25 | let that = this 26 | return { 27 | // 当前文件类型 28 | current() { 29 | return that.$route.query.fileType 30 | }, 31 | isAll() { 32 | return that.$route.query.fileType === that.FILE_TYPE.ALL 33 | }, 34 | isNotAll() { 35 | return that.$route.query.fileType !== that.FILE_TYPE.ALL 36 | }, 37 | isRecycle() { 38 | return that.$route.query.fileType === that.FILE_TYPE.RECYCLE 39 | }, 40 | isNotRecycle() { 41 | return that.$route.query.fileType !== that.FILE_TYPE.RECYCLE 42 | }, 43 | isMusic() { 44 | return that.$route.query.fileType === that.FILE_TYPE.MUSIC 45 | }, 46 | isImage() { 47 | return that.$route.query.fileType === that.FILE_TYPE.IMAGE 48 | }, 49 | isVideo() { 50 | return that.$route.query.fileType === that.FILE_TYPE.VIDEO 51 | }, 52 | isDoc() { 53 | return that.$route.query.fileType === that.FILE_TYPE.DOC 54 | }, 55 | isApp() { 56 | return that.$route.query.fileType === that.FILE_TYPE.APP 57 | }, 58 | isOther() { 59 | return that.$route.query.fileType === that.FILE_TYPE.OTHER 60 | }, 61 | isShare() { 62 | return that.$route.query.fileType === that.FILE_TYPE.SHARE 63 | } 64 | } 65 | }; 66 | 67 | // 文件查看模式 0列表模式 1网格模式 2 时间线模式 68 | Vue.prototype.fileModel = function () { 69 | // 是回收站类型文件 70 | let that = this 71 | return { 72 | current() { 73 | return that.$store.getters.currentFileModel 74 | }, 75 | isTable() { 76 | return that.FILE_MODEL.TABLE === that.$store.getters.currentFileModel 77 | }, 78 | isGrid() { 79 | return that.FILE_MODEL.GRID === that.$store.getters.currentFileModel 80 | }, 81 | isTimeLine() { 82 | return that.FILE_MODEL.TIME_LINE === that.$store.getters.currentFileModel 83 | } 84 | } 85 | }; 86 | 87 | // 文件路径,此处是id值,Long类型 88 | Vue.prototype.filePath = function () { 89 | // 是回收站类型文件 90 | let that = this 91 | return { 92 | // 文件查看模式 0列表模式 1网格模式 2 时间线模式 93 | current() { 94 | return that.$route.query.pid 95 | }, 96 | } 97 | }; 98 | 99 | // 文件下载 100 | Vue.prototype.getDownloadPath = fileId => url("/transfer/download/" + fileId) 101 | 102 | // 获取图片略缩图 103 | Vue.prototype.getThumbnailPath = fileId => url('/transfer/thumbnail/' + fileId) 104 | 105 | 106 | // 获取 office 文件在线预览路径 107 | Vue.prototype.getFileOnlineViewPathByOffice = fileId => { 108 | // 本地磁盘存储 - 在本地开发环境中,本地磁盘存储的文件是无法预览的,因为 office 要求文件可以在 Internet 访问 109 | let fileUrl = `${location.protocol}//${location.host}/` + url(`/transfer/download/${fileId}`) 110 | return `https://view.officeapps.live.com/op/embed.aspx?src=${fileUrl}` 111 | } 112 | 113 | // 是否退出登录 114 | Vue.prototype.isLoginPage = function (){ 115 | return this.$route.name == 'Login' 116 | } 117 | 118 | } 119 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './App.vue' 3 | import router from './router/router' 4 | import store from '@/store/index.js' 5 | import globalFunction from '@/./global/globalFunction' 6 | import globalConst from "@/global/globalConst"; 7 | import * as filters from '@/filters/index.js' 8 | import '@/assets/styles/css/base.css' 9 | import '@/assets/styles/css/border.css' 10 | import '@/assets/styles/css/element-cover.css' 11 | import '@/assets/styles/css/mediaScreen.styl' 12 | import '@/router/before.js' 13 | import 'element-ui/lib/theme-chalk/index.css' 14 | import element from './element.js' 15 | import uploader from 'vue-simple-uploader' 16 | 17 | Vue.config.productionTip = false; 18 | Vue.use(globalConst); 19 | Vue.use(globalFunction); 20 | Vue.use(element); 21 | Vue.use(uploader); 22 | Vue.prototype.$EventBus = new Vue() 23 | 24 | Object.keys(filters).forEach(key => { 25 | Vue.filter(key, filters[key]) 26 | }) 27 | 28 | new Vue({ 29 | router, 30 | store, 31 | render: h => h(App) 32 | }).$mount('#app') 33 | -------------------------------------------------------------------------------- /src/request/file.js: -------------------------------------------------------------------------------- 1 | // 文件模块接口 2 | import { get,post } from './http' 3 | 4 | /** 5 | * 查询文件相关api 6 | */ 7 | //获取文件的树结构 8 | export const getFileTree = p => get('/file/dir/tree', p); 9 | // 获取回收站文件列表 10 | export const getRecoveryFile = p => get('/file/list/recycle', p); 11 | // 获取路径树字典 12 | export const getPathTreeMap = p => get('/file/path/tree', p) 13 | // 通过文件类型选择文件 14 | export const selectFileByFileType = p => get('/file/list/type', p); 15 | // 搜索文件 16 | export const searchFile = p => get('/file/search', p) 17 | // 获取当前目录下的所有文件 18 | export const getFileList = p => get('/file/list', p); 19 | /** 20 | * 文件上传下载 21 | */ 22 | // 合并切片 23 | export const mergeFile = p => post('/transfer/merge', p); 24 | // 下载文件 25 | export const downloadFile = p => get("/transfer/download/"+p); 26 | // 获取略缩图 27 | export const getThumbnail = p => get('/transfer/thumbnail/' + p); 28 | 29 | /** 30 | * 创建文件 31 | */ 32 | // 创建文件夹 33 | export const makeDir = p => post('/file/mkdir', p, true); 34 | // 恢复回收站文件 35 | export const recoverRecycleFile = p => post('/file/recover', p, true) 36 | // 恢复回收站文件 37 | export const batchRecoverRecycle = p => post('/file/batch/recover', p, true) 38 | 39 | 40 | /** 41 | * 删除文件 42 | */ 43 | //删除文件 44 | export const deleteFile = p => post('/file/delete', p, true); 45 | // 回收站文件删除 46 | export const deleteRecoveryFile = p => post('/file/delete/recycle', p, true); 47 | // 批量删除回收站文件 48 | export const batchDeleteRecoveryFile = p => post('/file/batch/delete/recycle', p, true) 49 | //批量删除文件 50 | export const batchDeleteFile = p => post('/file/batch/delete', p, true); 51 | 52 | /**其他*/ 53 | //移动文件 54 | export const moveFile = p => post('/file/move', p, true); 55 | //批量移动文件 56 | export const batchMoveFile = p => post('/file/batch/move', p, true); 57 | //获取存储占用 58 | export const getStorage = p => get('/user/storage/info', p); 59 | //重命名文件 60 | export const renameFile = p => post('/file/rename', p, true); 61 | 62 | /**未实现*/ 63 | export const unzipfile = p => post('/file/unzip', p); //解压文件 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /src/request/http.js: -------------------------------------------------------------------------------- 1 | import axios from "axios" 2 | import router from '@/router/router.js' 3 | 4 | // 请求超时时间 5 | axios.defaults.timeout = 10000 * 5; 6 | 7 | // 请求基础URL 8 | axios.defaults.baseURL = "/api"; 9 | 10 | // post请求头 11 | axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; 12 | 13 | // 请求携带cookie 14 | axios.defaults.withCredentials = true; 15 | 16 | // 响应拦截器 17 | axios.interceptors.response.use( 18 | response => { 19 | if (response.status === 200) { 20 | return Promise.resolve(response); 21 | } 22 | }, 23 | // 服务器状态码不是200的情况 24 | error => { 25 | if (error.response.status) { 26 | switch (error.response.status) { 27 | case 500: 28 | router.replace({ name: 'Error_500' }) 29 | break; 30 | case 401: 31 | router.replace({ name: 'Error_401' }) 32 | break; 33 | case 404: 34 | router.replace({ name: 'Error_404' }) 35 | break; 36 | default: 37 | return Promise.reject(error.response); 38 | } 39 | } 40 | } 41 | ); 42 | /** 43 | * get方法,对应get请求 44 | */ 45 | export function get(url, params, info = '') { 46 | return new Promise((resolve, reject) => { 47 | axios.get(url + info, { 48 | params: params 49 | }) 50 | .then(res => { 51 | resolve(res.data); 52 | }) 53 | .catch(err => { 54 | reject(err.data) 55 | }) 56 | }); 57 | } 58 | /** 59 | * post方法,对应post请求 60 | * info为 true,formData格式; 61 | * info为 undefined或false,是json格式 62 | */ 63 | export function post(url, data = {}, info) { 64 | return new Promise((resolve, reject) => { 65 | let newData = data 66 | if (info) { // 转formData格式 67 | newData = new FormData(); 68 | for (let i in data) { 69 | newData.append(i, data[i]); 70 | } 71 | } 72 | axios.post(url, newData) 73 | .then(res => { 74 | resolve(res.data); 75 | }) 76 | .catch(err => { 77 | reject(err.data) 78 | }) 79 | }); 80 | } 81 | 82 | /** 83 | * 封装put请求 84 | */ 85 | 86 | export function put(url, params = {}, info = "") { 87 | return new Promise((resolve, reject) => { 88 | axios.put(url + info, params) 89 | .then(res => { 90 | resolve(res.data); 91 | }, err => { 92 | reject(err.data) 93 | }) 94 | }) 95 | } 96 | 97 | /** 98 | * 封装delete请求 99 | */ 100 | export function axiosDelete(url, params = {}, info = "") { 101 | return new Promise((resolve, reject) => { 102 | axios.delete(url + info, { 103 | params: params 104 | }) 105 | .then(res => { 106 | resolve(res.data); 107 | }) 108 | .catch(err => { 109 | reject(err.data) 110 | }) 111 | }); 112 | } 113 | 114 | export function url(uri){ 115 | 116 | if (uri.charAt(0)!=="/"){ 117 | uri = '/' + uri; 118 | } 119 | return axios.defaults.baseURL + uri; 120 | } 121 | -------------------------------------------------------------------------------- /src/request/user.js: -------------------------------------------------------------------------------- 1 | /** 2 | * post请求,formData格式,不传额外info参数,调用接口时,test({key: value}).then(res => {}) 3 | * export const test = p => post('/user/getattentionstate', p); 4 | * 5 | * post请求,非formData格式,传递额外info = true参数,调用接口时,test({key: value},true).then(res => {}) 6 | * export const test = (p, info) => post('/user/getattentionstate', p, info); 7 | * 8 | * 目前所有post接口均采用formData格式 9 | */ 10 | 11 | // 和用户信息相关的接口 12 | import { get,post } from './http' 13 | 14 | /* 用户登录 */ 15 | export const login = p => post('/user/login', p, true); 16 | //qq登录接口 17 | export const authorize = p => post('/user/authorize/qq', p); 18 | // 获取登录用户信息 19 | export const getLoginUserInfo = ()=>get("/user/info"); 20 | //退出登录 21 | export const logout = () => get('/user/logout'); 22 | // 获取注册令牌 23 | export const fetchRegisterToken = (p) => get('/user/register', p) 24 | // 用户注册 25 | export const addUser = p => post('/user/register', p); 26 | // 设置用户头像 27 | export const setAvatar = p => post('/user/avatar', p, true) 28 | 29 | // 忘记密码1,发送邮件获取令牌 30 | export const forgetPasswd1 = p=> get('/user/reset/passwd', p) 31 | // 忘记密码2,修改密码 32 | export const forgetPasswd2 = p=> post('/user/reset/passwd', p, true) 33 | 34 | -------------------------------------------------------------------------------- /src/router/before.js: -------------------------------------------------------------------------------- 1 | import router from '@/router/router' 2 | import store from '@/store/index.js' 3 | 4 | // 路由全局前置守卫, 类似于拦截器 5 | router.beforeEach((to, from, next) => { 6 | if (store.state.user.error >=3){ 7 | next() 8 | return 9 | } 10 | if (to.name.startsWith("Error_")){ 11 | next(from); 12 | return 13 | } 14 | store.dispatch("getUserInfo").then(() => { 15 | if (to.matched.some(m => m.meta.requireAuth)) { 16 | if (!store.getters.isLogin) { // 没有登录 17 | next({ 18 | path: '/login', 19 | query: { Rurl: to.fullPath } 20 | }) //将to参数中的url传递给login页面进行操作 21 | } else { 22 | next() // 正常跳转到你设置好的页面 23 | } 24 | } else { 25 | next() // 正常跳转到你设置好的页面 26 | } 27 | /* 路由发生变化修改页面title */ 28 | if (to.meta.title) { 29 | document.title = to.meta.title 30 | } 31 | /* 路由发生变化修改页面meta */ 32 | if(to.meta.content){ 33 | let head = document.getElementsByTagName('head'); 34 | let meta = document.createElement('meta'); 35 | document.querySelector('meta[name="description"]').setAttribute('content', to.meta.content.description) 36 | meta.content = to.meta.content; 37 | head[0].appendChild(meta) 38 | } 39 | }) 40 | }) 41 | -------------------------------------------------------------------------------- /src/router/router.js: -------------------------------------------------------------------------------- 1 | import Router from 'vue-router' 2 | import Vue from 'vue' 3 | import {ROOT_PATH, FILE_TYPE, SYSTEM_NAME} from "@/global/globalConst"; 4 | 5 | Vue.use(Router) 6 | export default new Router({ 7 | mode: 'history', 8 | base: process.env.BASE_URL, 9 | routes: [ 10 | { 11 | path: '/', 12 | name: 'Home', 13 | redirect: {path: '/file', query: {fileType: FILE_TYPE.ALL, pid: ROOT_PATH}} 14 | }, { 15 | path: '/login', 16 | name: 'Login', 17 | component: () => import('@/views/user/Login.vue'), 18 | meta: {title: '登录 - ' + SYSTEM_NAME}, 19 | }, { 20 | path: '/register', 21 | name: 'Register', 22 | component: () => import('@/views/user/Register.vue'), 23 | meta: {title: '注册 - ' + SYSTEM_NAME}, 24 | }, { 25 | path: '/file', 26 | name: 'File', 27 | component: () => import('@/views/file/File.vue'), 28 | meta: { 29 | requireAuth: true, 30 | title: SYSTEM_NAME, 31 | content: { 32 | description: '基于springboot + vue 框架开发的Web文件系统,旨在为用户提供一个简单、方便的文件存储方案' 33 | } 34 | } 35 | }, { 36 | path: '/500', 37 | name: 'Error_500', 38 | component: () => import('@/views/ErrorPage/500.vue'), 39 | meta: {title: '500 - ' + SYSTEM_NAME}, 40 | }, { 41 | path: '/401', 42 | name: 'Error_401', 43 | component: () => import('@/views/ErrorPage/401.vue'), 44 | meta: {title: '401 - ' + SYSTEM_NAME}, 45 | }, { 46 | path: '*', 47 | name: 'Error_404', 48 | component: () => import('@/views/ErrorPage/404.vue'), 49 | meta: {title: '404 - ' + SYSTEM_NAME}, 50 | } 51 | ] 52 | }) 53 | 54 | 55 | const originalPush = Router.prototype.push; 56 | Router.prototype.push = function push(location) { 57 | return originalPush.call(this, location).catch(err => err) 58 | }; 59 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from "vue"; 2 | import Vuex from "vuex"; 3 | 4 | import user from './module/user' 5 | import fileList from './module/fileList' 6 | import sideMenu from './module/sideMenu' 7 | import imgReview from './module/imgReview' 8 | import player from "@/store/module/player"; 9 | import {FOLD_TYPE, FILE_MODEL} from "@/global/globalConst"; 10 | 11 | Vue.use(Vuex) 12 | 13 | export default new Vuex.Store({ 14 | state: {}, 15 | getters: { 16 | isLogin: (state) => state.user.isLogin, 17 | isPlaying: (state) => state.player.isPlaying, 18 | user: (state)=>state.user.user, 19 | // 左侧栏是否折叠 20 | isFold: (state) => Number(state.sideMenu.isFold), 21 | // 文件路径,key:id, value:{id, pid, parent} 22 | getFilePath: (state) => (pid) => { 23 | let path = '/' 24 | let id = pid 25 | while (id) { 26 | path = '/' + state.fileList.pathTreeMap[id].name + path 27 | id = state.fileList.pathTreeMap[id].pid 28 | } 29 | return path 30 | }, 31 | // 传入目录id 32 | getPathTree: (state) => (pid) => { 33 | let list = [] 34 | let id = pid 35 | while (id) { 36 | list.push(state.fileList.pathTreeMap[id]) 37 | id = state.fileList.pathTreeMap[id].pid 38 | } 39 | return list.reverse(); 40 | }, 41 | 42 | // 操作列是否展开,false不展开,true展开 43 | operaColumnExpand: (state) => 44 | state.fileList.operaColumnExpand !== null 45 | ? Number(state.fileList.operaColumnExpand) 46 | : document.body.clientWidth > 1280 ? FOLD_TYPE.UNFOLD : FOLD_TYPE.FOLD, 47 | selectedColumnList: (state) => 48 | state.fileList.selectedColumnList === null 49 | ? ["extension", "fileSize", "updateTime", "deleteTime"] 50 | : state.fileList.selectedColumnList.split(","), // 列显隐 51 | currentFileModel: (state) => state.fileList.fileModel === null ? FILE_MODEL.TABLE : Number(state.fileList.fileModel), // 文件展示模式,0列表模式,1网格模式 2 时间线模式 52 | }, 53 | mutations: { 54 | // 55 | }, 56 | actions: { 57 | // 58 | }, 59 | modules: { 60 | user, 61 | fileList, 62 | sideMenu, 63 | imgReview, 64 | player 65 | } 66 | }) 67 | -------------------------------------------------------------------------------- /src/store/module/fileList.js: -------------------------------------------------------------------------------- 1 | import {getPathTreeMap} from "@/request/file"; 2 | 3 | export default { 4 | state: { 5 | operaColumnExpand: sessionStorage.getItem("operaColumnExpand"), // 操作列是否展开 6 | selectedColumnList: sessionStorage.getItem("selectedColumnList"), // 列显隐 7 | fileModel: sessionStorage.getItem("fileModel"), // 文件展示模式,0列表模式,1网格模式 2时间线模式 8 | pathTreeMap: Map 9 | }, 10 | mutations: { 11 | changeOperaColumnExpand(state, data) { 12 | sessionStorage.setItem("operaColumnExpand", data); 13 | state.operaColumnExpand = data; 14 | }, 15 | changeSelectedColumnList(state, data) { 16 | sessionStorage.setItem("selectedColumnList", data.toString()); 17 | state.selectedColumnList = data.toString(); 18 | }, 19 | changeFileModel(state, data) { 20 | sessionStorage.setItem("fileModel", data); 21 | state.fileModel = data; 22 | }, 23 | setPathTreeMap(state, data) { 24 | state.pathTreeMap = data 25 | } 26 | }, 27 | actions: { 28 | fetchPathTreeMap(context) { 29 | getPathTreeMap().then(res => 30 | context.commit("setPathTreeMap", res) 31 | ) 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/store/module/imgReview.js: -------------------------------------------------------------------------------- 1 | export default { 2 | state: { 3 | imgReviewVisible: false, // 图片查看组件显隐状态 4 | imgReviewList: [], // 图片列表 5 | defaultActiveIndex: 0 // 默认当前打开的图片的索引 6 | }, 7 | mutations: { 8 | setImgReviewData(state, data) { 9 | if(data.imgReviewVisible) { 10 | state.imgReviewVisible = data.imgReviewVisible 11 | state.imgReviewList = data.imgReviewList 12 | state.defaultActiveIndex = data.activeIndex 13 | } else { 14 | state.imgReviewVisible = data.false 15 | state.imgReviewList = [] 16 | state.defaultActiveIndex = 0 17 | } 18 | } 19 | }, 20 | actions: { 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/store/module/player.js: -------------------------------------------------------------------------------- 1 | export default { 2 | state: { 3 | videoPlayer: { 4 | visible: false, // 查看组件显隐状态 5 | url: '', 6 | filename: '', 7 | }, 8 | isPlaying: false 9 | }, 10 | mutations: { 11 | setVideoReviewData(state, data) { 12 | state.videoPlayer.visible = data.visible 13 | state.videoPlayer.url = data.url 14 | state.videoPlayer.filename = data.filename 15 | }, 16 | setVideoPlayMin(state){ 17 | state.videoPlayer.visible = false 18 | }, 19 | setVideoPlayNormal(state){ 20 | state.videoPlayer.visible = true 21 | }, 22 | closeVideoPlay(state){ 23 | state.videoPlayer = { 24 | visible: false, 25 | url: '', 26 | filename: '', 27 | } 28 | }, 29 | setPlaying(state, data){ 30 | state.isPlaying = data 31 | } 32 | }, 33 | actions: { 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/store/module/sideMenu.js: -------------------------------------------------------------------------------- 1 | import {getStorage} from '@/request/file.js' 2 | 3 | export default { 4 | state: { 5 | isFold: sessionStorage.getItem("isFold"), 6 | storageUsedValue: 0, // 已使用存储容量 7 | storageMaxValue: 0 // 最大存储容量 8 | }, 9 | mutations: { 10 | switchFold(state) { 11 | state.isFold = !state.isFold 12 | sessionStorage.setItem("isFold", state.isFold); 13 | }, 14 | setStorageInfo(state, storageInfo) { 15 | state.storageUsedValue = Number(storageInfo.usedStorage) 16 | state.storageMaxValue = Number(storageInfo.maxStorage) 17 | } 18 | }, 19 | actions: { 20 | showStorage(context) { 21 | return getStorage().then(res => { 22 | context.commit('setStorageInfo', res) 23 | }).catch(err => this.$message.error(err.msg)); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/store/module/user.js: -------------------------------------------------------------------------------- 1 | import {getLoginUserInfo} from "@/request/user.js"; 2 | import {url} from "@/request/http"; 3 | 4 | export default { 5 | state: { 6 | isLogin: false, //初始时候给一个 isLogin = false 表示用户未登录 7 | user: sessionStorage.getItem("user")||{ 8 | username: '', 9 | imgUrl: '', 10 | email: '', 11 | }, 12 | error: 0, 13 | }, 14 | mutations: { 15 | setUserLogin(state, loginUser) { 16 | let imgUrl = loginUser.imgUrl; 17 | state.isLogin = true; 18 | if (imgUrl) { 19 | imgUrl = url('/transfer/thumbnail/' + imgUrl) 20 | } else { 21 | // 没有头像,显示的默认头像 22 | imgUrl = "@/assets/images/settings/userImg.png"; 23 | } 24 | loginUser.imgUrl = imgUrl 25 | state.user = loginUser 26 | sessionStorage.setItem("user", loginUser); 27 | }, 28 | setUserLogout(state) { 29 | sessionStorage.removeItem("user") 30 | state.isLogin = false 31 | state.user = { 32 | username: '', 33 | imgUrl: '', 34 | email: '', 35 | } 36 | }, 37 | increaseError(state){ 38 | state.error += 1; 39 | }, 40 | resetError(state){ 41 | state.error = 0 42 | } 43 | }, 44 | actions: { 45 | getUserInfo(context) { 46 | // 登录成功返回LoginUser 47 | return getLoginUserInfo().then(user => { 48 | context.commit("resetError") 49 | context.commit("setUserLogin", user) 50 | }).catch(() => { 51 | context.commit("increaseError") 52 | context.commit("setUserLogout") 53 | } 54 | ) 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/views/ErrorPage/401.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 18 | 19 | 27 | -------------------------------------------------------------------------------- /src/views/ErrorPage/404.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 18 | 19 | 27 | -------------------------------------------------------------------------------- /src/views/ErrorPage/500.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 18 | 19 | 27 | -------------------------------------------------------------------------------- /src/views/file/File.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 28 | 29 | -------------------------------------------------------------------------------- /src/views/file/components/AsideMenu/AsideMenu.vue: -------------------------------------------------------------------------------- 1 | 64 | 65 | 121 | 122 | 218 | -------------------------------------------------------------------------------- /src/views/file/components/FileList/components/BreadCrumb.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 30 | 31 | 42 | -------------------------------------------------------------------------------- /src/views/file/components/FileList/components/FileGrid.vue: -------------------------------------------------------------------------------- 1 | 71 | 72 | 442 | 443 | 509 | -------------------------------------------------------------------------------- /src/views/file/components/FileList/components/FileTable.vue: -------------------------------------------------------------------------------- 1 | 160 | 161 | 489 | 490 | 568 | -------------------------------------------------------------------------------- /src/views/file/components/FileList/components/FileTimeLine.vue: -------------------------------------------------------------------------------- 1 | 39 | 40 | 89 | 90 | 126 | -------------------------------------------------------------------------------- /src/views/file/components/FileList/components/MoveFileDialog.vue: -------------------------------------------------------------------------------- 1 | 21 | 22 | 44 | 45 | 75 | -------------------------------------------------------------------------------- /src/views/file/components/FileList/components/OperationMenu.vue: -------------------------------------------------------------------------------- 1 | 78 | 79 | 247 | 248 | 283 | -------------------------------------------------------------------------------- /src/views/file/components/FileList/components/SelectColumn.vue: -------------------------------------------------------------------------------- 1 | 23 | 24 | 68 | 69 | -------------------------------------------------------------------------------- /src/views/file/components/FileList/index.vue: -------------------------------------------------------------------------------- 1 | 64 | 65 | 352 | 353 | 377 | -------------------------------------------------------------------------------- /src/views/user/Login.vue: -------------------------------------------------------------------------------- 1 | 57 | 58 | 221 | 264 | -------------------------------------------------------------------------------- /src/views/user/Register.vue: -------------------------------------------------------------------------------- 1 | 68 | 69 | 224 | 268 | -------------------------------------------------------------------------------- /vue.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | // 选项... 3 | publicPath: '/', 4 | 5 | //是否开启eslint校验 6 | lintOnSave: false, 7 | 8 | devServer: { 9 | disableHostCheck: true, 10 | host: '127.0.0.1', 11 | proxy: { //配置代理,解决跨域请求后台数据的问题 12 | '/api': { 13 | target: 'http://127.0.0.1:8848', //后台接口,连接本地服务 14 | ws: true, //是否跨域 15 | changeOrigin: true, 16 | pathRewrite: { 17 | '^/api':'/' 18 | } 19 | } 20 | 21 | } 22 | }, 23 | 24 | productionSourceMap: false, 25 | 26 | pluginOptions: { 27 | 'style-resources-loader': { 28 | preProcessor: 'stylus', 29 | patterns: [] 30 | } 31 | } 32 | } 33 | --------------------------------------------------------------------------------