├── src ├── main │ ├── bin │ │ ├── start.bat │ │ └── goFastDfsWeb.sh │ ├── resources │ │ ├── static │ │ │ ├── images │ │ │ │ ├── logo.png │ │ │ │ ├── user.png │ │ │ │ ├── alipay.jpg │ │ │ │ ├── favicon.ico │ │ │ │ └── wechat.jpg │ │ │ ├── lib │ │ │ │ ├── iconfont │ │ │ │ │ ├── iconfont.eot │ │ │ │ │ ├── iconfont.ttf │ │ │ │ │ ├── iconfont.woff │ │ │ │ │ └── iconfont.woff2 │ │ │ │ ├── layui-v2.5.6 │ │ │ │ │ └── layui │ │ │ │ │ │ ├── font │ │ │ │ │ │ ├── iconfont.eot │ │ │ │ │ │ ├── iconfont.ttf │ │ │ │ │ │ ├── iconfont.woff │ │ │ │ │ │ └── iconfont.woff2 │ │ │ │ │ │ ├── images │ │ │ │ │ │ └── face │ │ │ │ │ │ │ ├── 0.gif │ │ │ │ │ │ │ ├── 1.gif │ │ │ │ │ │ │ ├── 10.gif │ │ │ │ │ │ │ ├── 11.gif │ │ │ │ │ │ │ ├── 12.gif │ │ │ │ │ │ │ ├── 13.gif │ │ │ │ │ │ │ ├── 14.gif │ │ │ │ │ │ │ ├── 15.gif │ │ │ │ │ │ │ ├── 16.gif │ │ │ │ │ │ │ ├── 17.gif │ │ │ │ │ │ │ ├── 18.gif │ │ │ │ │ │ │ ├── 19.gif │ │ │ │ │ │ │ ├── 2.gif │ │ │ │ │ │ │ ├── 20.gif │ │ │ │ │ │ │ ├── 21.gif │ │ │ │ │ │ │ ├── 22.gif │ │ │ │ │ │ │ ├── 23.gif │ │ │ │ │ │ │ ├── 24.gif │ │ │ │ │ │ │ ├── 25.gif │ │ │ │ │ │ │ ├── 26.gif │ │ │ │ │ │ │ ├── 27.gif │ │ │ │ │ │ │ ├── 28.gif │ │ │ │ │ │ │ ├── 29.gif │ │ │ │ │ │ │ ├── 3.gif │ │ │ │ │ │ │ ├── 30.gif │ │ │ │ │ │ │ ├── 31.gif │ │ │ │ │ │ │ ├── 32.gif │ │ │ │ │ │ │ ├── 33.gif │ │ │ │ │ │ │ ├── 34.gif │ │ │ │ │ │ │ ├── 35.gif │ │ │ │ │ │ │ ├── 36.gif │ │ │ │ │ │ │ ├── 37.gif │ │ │ │ │ │ │ ├── 38.gif │ │ │ │ │ │ │ ├── 39.gif │ │ │ │ │ │ │ ├── 4.gif │ │ │ │ │ │ │ ├── 40.gif │ │ │ │ │ │ │ ├── 41.gif │ │ │ │ │ │ │ ├── 42.gif │ │ │ │ │ │ │ ├── 43.gif │ │ │ │ │ │ │ ├── 44.gif │ │ │ │ │ │ │ ├── 45.gif │ │ │ │ │ │ │ ├── 46.gif │ │ │ │ │ │ │ ├── 47.gif │ │ │ │ │ │ │ ├── 48.gif │ │ │ │ │ │ │ ├── 49.gif │ │ │ │ │ │ │ ├── 5.gif │ │ │ │ │ │ │ ├── 50.gif │ │ │ │ │ │ │ ├── 51.gif │ │ │ │ │ │ │ ├── 52.gif │ │ │ │ │ │ │ ├── 53.gif │ │ │ │ │ │ │ ├── 54.gif │ │ │ │ │ │ │ ├── 55.gif │ │ │ │ │ │ │ ├── 56.gif │ │ │ │ │ │ │ ├── 57.gif │ │ │ │ │ │ │ ├── 58.gif │ │ │ │ │ │ │ ├── 59.gif │ │ │ │ │ │ │ ├── 6.gif │ │ │ │ │ │ │ ├── 60.gif │ │ │ │ │ │ │ ├── 61.gif │ │ │ │ │ │ │ ├── 62.gif │ │ │ │ │ │ │ ├── 63.gif │ │ │ │ │ │ │ ├── 64.gif │ │ │ │ │ │ │ ├── 65.gif │ │ │ │ │ │ │ ├── 66.gif │ │ │ │ │ │ │ ├── 67.gif │ │ │ │ │ │ │ ├── 68.gif │ │ │ │ │ │ │ ├── 69.gif │ │ │ │ │ │ │ ├── 7.gif │ │ │ │ │ │ │ ├── 70.gif │ │ │ │ │ │ │ ├── 71.gif │ │ │ │ │ │ │ ├── 8.gif │ │ │ │ │ │ │ └── 9.gif │ │ │ │ │ │ ├── css │ │ │ │ │ │ └── modules │ │ │ │ │ │ │ ├── layer │ │ │ │ │ │ │ └── default │ │ │ │ │ │ │ │ ├── icon.png │ │ │ │ │ │ │ │ ├── icon-ext.png │ │ │ │ │ │ │ │ ├── loading-0.gif │ │ │ │ │ │ │ │ ├── loading-1.gif │ │ │ │ │ │ │ │ └── loading-2.gif │ │ │ │ │ │ │ └── code.css │ │ │ │ │ │ └── lay │ │ │ │ │ │ └── modules │ │ │ │ │ │ ├── code.js │ │ │ │ │ │ ├── laytpl.js │ │ │ │ │ │ ├── flow.js │ │ │ │ │ │ ├── rate.js │ │ │ │ │ │ ├── util.js │ │ │ │ │ │ ├── carousel.js │ │ │ │ │ │ └── laypage.js │ │ │ │ ├── font-awesome-4.7.0 │ │ │ │ │ ├── fonts │ │ │ │ │ │ ├── FontAwesome.otf │ │ │ │ │ │ ├── fontawesome-webfont.eot │ │ │ │ │ │ ├── fontawesome-webfont.ttf │ │ │ │ │ │ ├── fontawesome-webfont.woff │ │ │ │ │ │ └── fontawesome-webfont.woff2 │ │ │ │ │ ├── less │ │ │ │ │ │ ├── fixed-width.less │ │ │ │ │ │ ├── screen-reader.less │ │ │ │ │ │ ├── larger.less │ │ │ │ │ │ ├── list.less │ │ │ │ │ │ ├── core.less │ │ │ │ │ │ ├── stacked.less │ │ │ │ │ │ ├── font-awesome.less │ │ │ │ │ │ ├── bordered-pulled.less │ │ │ │ │ │ ├── rotated-flipped.less │ │ │ │ │ │ ├── path.less │ │ │ │ │ │ ├── animated.less │ │ │ │ │ │ └── mixins.less │ │ │ │ │ ├── scss │ │ │ │ │ │ ├── _fixed-width.scss │ │ │ │ │ │ ├── _screen-reader.scss │ │ │ │ │ │ ├── _larger.scss │ │ │ │ │ │ ├── _list.scss │ │ │ │ │ │ ├── _core.scss │ │ │ │ │ │ ├── font-awesome.scss │ │ │ │ │ │ ├── _stacked.scss │ │ │ │ │ │ ├── _bordered-pulled.scss │ │ │ │ │ │ ├── _rotated-flipped.scss │ │ │ │ │ │ ├── _path.scss │ │ │ │ │ │ ├── _animated.scss │ │ │ │ │ │ └── _mixins.scss │ │ │ │ │ └── HELP-US-OUT.txt │ │ │ │ ├── step-lay │ │ │ │ │ ├── step.css │ │ │ │ │ └── step.js │ │ │ │ └── template-web │ │ │ │ │ └── template-web.js │ │ │ ├── css │ │ │ │ ├── home.css │ │ │ │ ├── login.css │ │ │ │ ├── install.css │ │ │ │ └── file.css │ │ │ └── js │ │ │ │ ├── common.js │ │ │ │ ├── kit.js │ │ │ │ └── upload.js │ │ ├── application.yml │ │ ├── assembly.xml │ │ └── templates │ │ │ ├── index.html │ │ │ ├── layout │ │ │ ├── header.html │ │ │ └── sider.html │ │ │ ├── login.html │ │ │ ├── peers │ │ │ ├── add.html │ │ │ ├── edit.html │ │ │ └── list.html │ │ │ ├── file │ │ │ ├── upload.html │ │ │ └── file.html │ │ │ └── settings │ │ │ └── user.html │ └── java │ │ └── com │ │ └── perfree │ │ ├── mapper │ │ ├── UserMapper.java │ │ └── PeersMapper.java │ │ ├── service │ │ ├── SettingService.java │ │ ├── UserService.java │ │ ├── PeersService.java │ │ ├── FileService.java │ │ └── IndexService.java │ │ ├── GoFastdfsWebApplication.java │ │ ├── common │ │ ├── RegexUtill.java │ │ ├── PageResult.java │ │ ├── Constant.java │ │ ├── FileSizeUtil.java │ │ ├── GetFileUtil.java │ │ ├── ResponseBean.java │ │ └── UploadUtils.java │ │ ├── form │ │ ├── ApiStatResult.java │ │ ├── ApiResult.java │ │ ├── FileResult.java │ │ ├── FileDetails.java │ │ ├── GoFastDfsUploadResult.java │ │ └── InstallForm.java │ │ ├── config │ │ ├── WebConfig.java │ │ ├── SQLiteConfiguration.java │ │ ├── ShiroRealm.java │ │ └── ShiroConfig.java │ │ ├── controller │ │ ├── UploadController.java │ │ ├── SettingController.java │ │ ├── SystemController.java │ │ ├── BaseController.java │ │ └── FileController.java │ │ ├── interceptor │ │ └── InstallInterceptor.java │ │ └── model │ │ ├── User.java │ │ └── Peers.java └── test │ └── java │ └── com │ └── perfree │ └── GoFastdfsWebApplicationTests.java ├── screen ├── 01.png ├── 02.png ├── 03.png ├── 04.png ├── alipay.jpg └── wechat.jpg ├── db └── go-fastdfs.db ├── .mvn └── wrapper │ ├── maven-wrapper.jar │ ├── maven-wrapper.properties │ └── MavenWrapperDownloader.java ├── Dockerfile ├── .gitignore ├── LICENSE.md ├── HELP.md └── README.md /src/main/bin/start.bat: -------------------------------------------------------------------------------- 1 | start java -jar go-fastdfs-web.jar -------------------------------------------------------------------------------- /screen/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/screen/01.png -------------------------------------------------------------------------------- /screen/02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/screen/02.png -------------------------------------------------------------------------------- /screen/03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/screen/03.png -------------------------------------------------------------------------------- /screen/04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/screen/04.png -------------------------------------------------------------------------------- /db/go-fastdfs.db: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/db/go-fastdfs.db -------------------------------------------------------------------------------- /screen/alipay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/screen/alipay.jpg -------------------------------------------------------------------------------- /screen/wechat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/screen/wechat.jpg -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /src/main/resources/static/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/images/logo.png -------------------------------------------------------------------------------- /src/main/resources/static/images/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/images/user.png -------------------------------------------------------------------------------- /src/main/resources/static/images/alipay.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/images/alipay.jpg -------------------------------------------------------------------------------- /src/main/resources/static/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/images/favicon.ico -------------------------------------------------------------------------------- /src/main/resources/static/images/wechat.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/images/wechat.jpg -------------------------------------------------------------------------------- /src/main/resources/static/lib/iconfont/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/iconfont/iconfont.eot -------------------------------------------------------------------------------- /src/main/resources/static/lib/iconfont/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/iconfont/iconfont.ttf -------------------------------------------------------------------------------- /src/main/resources/static/lib/iconfont/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/iconfont/iconfont.woff -------------------------------------------------------------------------------- /src/main/resources/static/lib/iconfont/iconfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/iconfont/iconfont.woff2 -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/font/iconfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/font/iconfont.eot -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/font/iconfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/font/iconfont.ttf -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/font/iconfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/font/iconfont.woff -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/0.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/0.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/1.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/10.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/10.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/11.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/11.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/12.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/12.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/13.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/13.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/14.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/14.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/15.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/15.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/16.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/16.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/17.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/17.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/18.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/18.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/19.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/19.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/2.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/20.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/20.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/21.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/21.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/22.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/22.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/23.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/23.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/24.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/24.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/25.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/25.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/26.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/26.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/27.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/27.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/28.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/28.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/29.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/29.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/3.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/3.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/30.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/30.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/31.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/31.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/32.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/32.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/33.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/33.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/34.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/34.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/35.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/35.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/36.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/36.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/37.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/37.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/38.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/38.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/39.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/39.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/4.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/4.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/40.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/40.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/41.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/41.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/42.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/42.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/43.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/43.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/44.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/44.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/45.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/45.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/46.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/46.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/47.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/47.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/48.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/48.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/49.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/49.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/5.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/5.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/50.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/50.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/51.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/51.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/52.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/52.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/53.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/53.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/54.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/54.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/55.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/55.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/56.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/56.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/57.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/57.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/58.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/58.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/59.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/59.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/6.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/6.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/60.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/60.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/61.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/61.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/62.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/62.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/63.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/63.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/64.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/64.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/65.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/65.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/66.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/66.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/67.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/67.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/68.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/68.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/69.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/69.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/7.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/7.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/70.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/70.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/71.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/71.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/8.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/8.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/images/face/9.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/images/face/9.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/font-awesome-4.7.0/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/font/iconfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/font/iconfont.woff2 -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/less/fixed-width.less: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .@{fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/less/screen-reader.less: -------------------------------------------------------------------------------- 1 | // Screen Readers 2 | // ------------------------- 3 | 4 | .sr-only { .sr-only(); } 5 | .sr-only-focusable { .sr-only-focusable(); } 6 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/font-awesome-4.7.0/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/font-awesome-4.7.0/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/font-awesome-4.7.0/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/font-awesome-4.7.0/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/scss/_fixed-width.scss: -------------------------------------------------------------------------------- 1 | // Fixed Width Icons 2 | // ------------------------- 3 | .#{$fa-css-prefix}-fw { 4 | width: (18em / 14); 5 | text-align: center; 6 | } 7 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/scss/_screen-reader.scss: -------------------------------------------------------------------------------- 1 | // Screen Readers 2 | // ------------------------- 3 | 4 | .sr-only { @include sr-only(); } 5 | .sr-only-focusable { @include sr-only-focusable(); } 6 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/css/modules/layer/default/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/css/modules/layer/default/icon.png -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/css/modules/layer/default/icon-ext.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/css/modules/layer/default/icon-ext.png -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/css/modules/layer/default/loading-0.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/css/modules/layer/default/loading-0.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/css/modules/layer/default/loading-1.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/css/modules/layer/default/loading-1.gif -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/css/modules/layer/default/loading-2.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/perfree/go-fastdfs-web/HEAD/src/main/resources/static/lib/layui-v2.5.6/layui/css/modules/layer/default/loading-2.gif -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar 3 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM openjdk:8-jre-alpine 2 | VOLUME /tmp 3 | ARG PACKAGE_FILE 4 | COPY ${PACKAGE_FILE} app.tar.gz 5 | RUN tar -zxvf app.tar.gz 6 | RUN mv go-fastdfs-web/* / 7 | RUN rm -rf go-fastdfs-web 8 | ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/go-fastdfs-web.jar"] -------------------------------------------------------------------------------- /src/test/java/com/perfree/GoFastdfsWebApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.perfree; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class GoFastdfsWebApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/HELP-US-OUT.txt: -------------------------------------------------------------------------------- 1 | I hope you love Font Awesome. If you've found it useful, please do me a favor and check out my latest project, 2 | Fort Awesome (https://fortawesome.com). It makes it easy to put the perfect icons on your website. Choose from our awesome, 3 | comprehensive icon sets or copy and paste your own. 4 | 5 | Please. Check it out. 6 | 7 | -Dave Gandy 8 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/mapper/UserMapper.java: -------------------------------------------------------------------------------- 1 | package com.perfree.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.perfree.model.User; 5 | import org.apache.ibatis.annotations.Mapper; 6 | import org.springframework.stereotype.Component; 7 | 8 | /** 9 | * @description user用户表,Mapper接口 10 | * @author Perfree 11 | * @date 2021/3/22 14:59 12 | */ 13 | @Mapper 14 | @Component 15 | public interface UserMapper extends BaseMapper { 16 | } 17 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/less/larger.less: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .@{fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .@{fa-css-prefix}-2x { font-size: 2em; } 11 | .@{fa-css-prefix}-3x { font-size: 3em; } 12 | .@{fa-css-prefix}-4x { font-size: 4em; } 13 | .@{fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/mapper/PeersMapper.java: -------------------------------------------------------------------------------- 1 | package com.perfree.mapper; 2 | 3 | import com.baomidou.mybatisplus.core.mapper.BaseMapper; 4 | import com.perfree.model.Peers; 5 | import org.apache.ibatis.annotations.Mapper; 6 | import org.springframework.stereotype.Component; 7 | 8 | /** 9 | * @description Peers集群表,Mapper接口 10 | * @author Perfree 11 | * @date 2021/3/22 14:58 12 | */ 13 | @Mapper 14 | @Component 15 | public interface PeersMapper extends BaseMapper { 16 | } 17 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/scss/_larger.scss: -------------------------------------------------------------------------------- 1 | // Icon Sizes 2 | // ------------------------- 3 | 4 | /* makes the font 33% larger relative to the icon container */ 5 | .#{$fa-css-prefix}-lg { 6 | font-size: (4em / 3); 7 | line-height: (3em / 4); 8 | vertical-align: -15%; 9 | } 10 | .#{$fa-css-prefix}-2x { font-size: 2em; } 11 | .#{$fa-css-prefix}-3x { font-size: 3em; } 12 | .#{$fa-css-prefix}-4x { font-size: 4em; } 13 | .#{$fa-css-prefix}-5x { font-size: 5em; } 14 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/service/SettingService.java: -------------------------------------------------------------------------------- 1 | package com.perfree.service; 2 | 3 | import com.perfree.mapper.UserMapper; 4 | import com.perfree.model.User; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Service; 7 | 8 | @Service 9 | public class SettingService { 10 | 11 | @Autowired 12 | private UserMapper userMapper; 13 | 14 | public boolean editUser(User user) { 15 | return userMapper.updateById(user) > 0; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/less/list.less: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: @fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .@{fa-css-prefix}-li { 11 | position: absolute; 12 | left: -@fa-li-width; 13 | width: @fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.@{fa-css-prefix}-lg { 17 | left: (-@fa-li-width + (4em / 14)); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/scss/_list.scss: -------------------------------------------------------------------------------- 1 | // List Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-ul { 5 | padding-left: 0; 6 | margin-left: $fa-li-width; 7 | list-style-type: none; 8 | > li { position: relative; } 9 | } 10 | .#{$fa-css-prefix}-li { 11 | position: absolute; 12 | left: -$fa-li-width; 13 | width: $fa-li-width; 14 | top: (2em / 14); 15 | text-align: center; 16 | &.#{$fa-css-prefix}-lg { 17 | left: -$fa-li-width + (4em / 14); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/GoFastdfsWebApplication.java: -------------------------------------------------------------------------------- 1 | package com.perfree; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * @description 启动类 8 | * @author Perfree 9 | * @date 2021/3/22 13:44 10 | */ 11 | @SpringBootApplication 12 | public class GoFastdfsWebApplication { 13 | 14 | public static void main(String[] args) { 15 | SpringApplication.run(GoFastdfsWebApplication.class, args); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/**/target/ 5 | !**/src/test/**/target/ 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | !**/src/main/**/build/ 30 | !**/src/test/**/build/ 31 | 32 | ### VS Code ### 33 | .vscode/ 34 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/less/core.less: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix} { 5 | display: inline-block; 6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/scss/_core.scss: -------------------------------------------------------------------------------- 1 | // Base Class Definition 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix} { 5 | display: inline-block; 6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/scss/font-awesome.scss: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables"; 7 | @import "mixins"; 8 | @import "path"; 9 | @import "core"; 10 | @import "larger"; 11 | @import "fixed-width"; 12 | @import "list"; 13 | @import "bordered-pulled"; 14 | @import "animated"; 15 | @import "rotated-flipped"; 16 | @import "stacked"; 17 | @import "icons"; 18 | @import "screen-reader"; 19 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/common/RegexUtill.java: -------------------------------------------------------------------------------- 1 | package com.perfree.common; 2 | 3 | import java.util.regex.Matcher; 4 | import java.util.regex.Pattern; 5 | 6 | /** 7 | * 正则校验工具 8 | */ 9 | public class RegexUtill { 10 | /** 11 | * 验证是否是URL 12 | * 13 | * @param url url 14 | * @return boolean 15 | */ 16 | public static boolean verifyUrl(String url) { 17 | String regEx = "[a-zA-z]+://[^\\s]*"; 18 | Pattern pattern = Pattern.compile(regEx); 19 | Matcher matcher = pattern.matcher(url); 20 | return matcher.matches(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/less/stacked.less: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .@{fa-css-prefix}-stack-1x, .@{fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .@{fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .@{fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .@{fa-css-prefix}-inverse { color: @fa-inverse; } 21 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/scss/_stacked.scss: -------------------------------------------------------------------------------- 1 | // Stacked Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-stack { 5 | position: relative; 6 | display: inline-block; 7 | width: 2em; 8 | height: 2em; 9 | line-height: 2em; 10 | vertical-align: middle; 11 | } 12 | .#{$fa-css-prefix}-stack-1x, .#{$fa-css-prefix}-stack-2x { 13 | position: absolute; 14 | left: 0; 15 | width: 100%; 16 | text-align: center; 17 | } 18 | .#{$fa-css-prefix}-stack-1x { line-height: inherit; } 19 | .#{$fa-css-prefix}-stack-2x { font-size: 2em; } 20 | .#{$fa-css-prefix}-inverse { color: $fa-inverse; } 21 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/less/font-awesome.less: -------------------------------------------------------------------------------- 1 | /*! 2 | * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome 3 | * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) 4 | */ 5 | 6 | @import "variables.less"; 7 | @import "mixins.less"; 8 | @import "path.less"; 9 | @import "core.less"; 10 | @import "larger.less"; 11 | @import "fixed-width.less"; 12 | @import "list.less"; 13 | @import "bordered-pulled.less"; 14 | @import "animated.less"; 15 | @import "rotated-flipped.less"; 16 | @import "stacked.less"; 17 | @import "icons.less"; 18 | @import "screen-reader.less"; 19 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/less/bordered-pulled.less: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em @fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .@{fa-css-prefix}-pull-left { float: left; } 11 | .@{fa-css-prefix}-pull-right { float: right; } 12 | 13 | .@{fa-css-prefix} { 14 | &.@{fa-css-prefix}-pull-left { margin-right: .3em; } 15 | &.@{fa-css-prefix}-pull-right { margin-left: .3em; } 16 | } 17 | 18 | /* Deprecated as of 4.4.0 */ 19 | .pull-right { float: right; } 20 | .pull-left { float: left; } 21 | 22 | .@{fa-css-prefix} { 23 | &.pull-left { margin-right: .3em; } 24 | &.pull-right { margin-left: .3em; } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/scss/_bordered-pulled.scss: -------------------------------------------------------------------------------- 1 | // Bordered & Pulled 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-border { 5 | padding: .2em .25em .15em; 6 | border: solid .08em $fa-border-color; 7 | border-radius: .1em; 8 | } 9 | 10 | .#{$fa-css-prefix}-pull-left { float: left; } 11 | .#{$fa-css-prefix}-pull-right { float: right; } 12 | 13 | .#{$fa-css-prefix} { 14 | &.#{$fa-css-prefix}-pull-left { margin-right: .3em; } 15 | &.#{$fa-css-prefix}-pull-right { margin-left: .3em; } 16 | } 17 | 18 | /* Deprecated as of 4.4.0 */ 19 | .pull-right { float: right; } 20 | .pull-left { float: left; } 21 | 22 | .#{$fa-css-prefix} { 23 | &.pull-left { margin-right: .3em; } 24 | &.pull-right { margin-left: .3em; } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/less/rotated-flipped.less: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .@{fa-css-prefix}-rotate-90 { .fa-icon-rotate(90deg, 1); } 5 | .@{fa-css-prefix}-rotate-180 { .fa-icon-rotate(180deg, 2); } 6 | .@{fa-css-prefix}-rotate-270 { .fa-icon-rotate(270deg, 3); } 7 | 8 | .@{fa-css-prefix}-flip-horizontal { .fa-icon-flip(-1, 1, 0); } 9 | .@{fa-css-prefix}-flip-vertical { .fa-icon-flip(1, -1, 2); } 10 | 11 | // Hook for IE8-9 12 | // ------------------------- 13 | 14 | :root .@{fa-css-prefix}-rotate-90, 15 | :root .@{fa-css-prefix}-rotate-180, 16 | :root .@{fa-css-prefix}-rotate-270, 17 | :root .@{fa-css-prefix}-flip-horizontal, 18 | :root .@{fa-css-prefix}-flip-vertical { 19 | filter: none; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/resources/static/css/home.css: -------------------------------------------------------------------------------- 1 | .page-view-totla { 2 | font-size: 36px; 3 | color: #666; 4 | line-height: 36px; 5 | padding: 5px 0 10px; 6 | overflow: hidden; 7 | text-overflow: ellipsis; 8 | word-break: break-all; 9 | white-space: nowrap; 10 | } 11 | .shortcut-button{ 12 | width: 100px; 13 | height: 80px; 14 | display: block; 15 | float: left; 16 | margin-left: 10px; 17 | margin-top: 10px; 18 | cursor: pointer; 19 | text-align: center; 20 | } 21 | .shortcut-button-icon{ 22 | display: block; 23 | height: 55px; 24 | text-align: center; 25 | line-height: 55px; 26 | background: #F8F8F8; 27 | } 28 | .shortcut-button:hover{ 29 | color: #2F4056; 30 | } 31 | .layui-layer-page .layui-layer-content{ 32 | overflow: initial!important; 33 | } -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/scss/_rotated-flipped.scss: -------------------------------------------------------------------------------- 1 | // Rotated & Flipped Icons 2 | // ------------------------- 3 | 4 | .#{$fa-css-prefix}-rotate-90 { @include fa-icon-rotate(90deg, 1); } 5 | .#{$fa-css-prefix}-rotate-180 { @include fa-icon-rotate(180deg, 2); } 6 | .#{$fa-css-prefix}-rotate-270 { @include fa-icon-rotate(270deg, 3); } 7 | 8 | .#{$fa-css-prefix}-flip-horizontal { @include fa-icon-flip(-1, 1, 0); } 9 | .#{$fa-css-prefix}-flip-vertical { @include fa-icon-flip(1, -1, 2); } 10 | 11 | // Hook for IE8-9 12 | // ------------------------- 13 | 14 | :root .#{$fa-css-prefix}-rotate-90, 15 | :root .#{$fa-css-prefix}-rotate-180, 16 | :root .#{$fa-css-prefix}-rotate-270, 17 | :root .#{$fa-css-prefix}-flip-horizontal, 18 | :root .#{$fa-css-prefix}-flip-vertical { 19 | filter: none; 20 | } 21 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/less/path.less: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('@{fa-font-path}/fontawesome-webfont.eot?v=@{fa-version}'); 7 | src: url('@{fa-font-path}/fontawesome-webfont.eot?#iefix&v=@{fa-version}') format('embedded-opentype'), 8 | url('@{fa-font-path}/fontawesome-webfont.woff2?v=@{fa-version}') format('woff2'), 9 | url('@{fa-font-path}/fontawesome-webfont.woff?v=@{fa-version}') format('woff'), 10 | url('@{fa-font-path}/fontawesome-webfont.ttf?v=@{fa-version}') format('truetype'), 11 | url('@{fa-font-path}/fontawesome-webfont.svg?v=@{fa-version}#fontawesomeregular') format('svg'); 12 | // src: url('@{fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/scss/_path.scss: -------------------------------------------------------------------------------- 1 | /* FONT PATH 2 | * -------------------------- */ 3 | 4 | @font-face { 5 | font-family: 'FontAwesome'; 6 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?v=#{$fa-version}'); 7 | src: url('#{$fa-font-path}/fontawesome-webfont.eot?#iefix&v=#{$fa-version}') format('embedded-opentype'), 8 | url('#{$fa-font-path}/fontawesome-webfont.woff2?v=#{$fa-version}') format('woff2'), 9 | url('#{$fa-font-path}/fontawesome-webfont.woff?v=#{$fa-version}') format('woff'), 10 | url('#{$fa-font-path}/fontawesome-webfont.ttf?v=#{$fa-version}') format('truetype'), 11 | url('#{$fa-font-path}/fontawesome-webfont.svg?v=#{$fa-version}#fontawesomeregular') format('svg'); 12 | // src: url('#{$fa-font-path}/FontAwesome.otf') format('opentype'); // used when developing fonts 13 | font-weight: normal; 14 | font-style: normal; 15 | } 16 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/less/animated.less: -------------------------------------------------------------------------------- 1 | // Animated Icons 2 | // -------------------------- 3 | 4 | .@{fa-css-prefix}-spin { 5 | -webkit-animation: fa-spin 2s infinite linear; 6 | animation: fa-spin 2s infinite linear; 7 | } 8 | 9 | .@{fa-css-prefix}-pulse { 10 | -webkit-animation: fa-spin 1s infinite steps(8); 11 | animation: fa-spin 1s infinite steps(8); 12 | } 13 | 14 | @-webkit-keyframes fa-spin { 15 | 0% { 16 | -webkit-transform: rotate(0deg); 17 | transform: rotate(0deg); 18 | } 19 | 100% { 20 | -webkit-transform: rotate(359deg); 21 | transform: rotate(359deg); 22 | } 23 | } 24 | 25 | @keyframes fa-spin { 26 | 0% { 27 | -webkit-transform: rotate(0deg); 28 | transform: rotate(0deg); 29 | } 30 | 100% { 31 | -webkit-transform: rotate(359deg); 32 | transform: rotate(359deg); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/scss/_animated.scss: -------------------------------------------------------------------------------- 1 | // Spinning Icons 2 | // -------------------------- 3 | 4 | .#{$fa-css-prefix}-spin { 5 | -webkit-animation: fa-spin 2s infinite linear; 6 | animation: fa-spin 2s infinite linear; 7 | } 8 | 9 | .#{$fa-css-prefix}-pulse { 10 | -webkit-animation: fa-spin 1s infinite steps(8); 11 | animation: fa-spin 1s infinite steps(8); 12 | } 13 | 14 | @-webkit-keyframes fa-spin { 15 | 0% { 16 | -webkit-transform: rotate(0deg); 17 | transform: rotate(0deg); 18 | } 19 | 100% { 20 | -webkit-transform: rotate(359deg); 21 | transform: rotate(359deg); 22 | } 23 | } 24 | 25 | @keyframes fa-spin { 26 | 0% { 27 | -webkit-transform: rotate(0deg); 28 | transform: rotate(0deg); 29 | } 30 | 100% { 31 | -webkit-transform: rotate(359deg); 32 | transform: rotate(359deg); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/form/ApiStatResult.java: -------------------------------------------------------------------------------- 1 | package com.perfree.form; 2 | 3 | import java.io.Serializable; 4 | 5 | /** 6 | * @description GoFastDfs stat API接口响应格式 7 | * @author Perfree 8 | * @date 2021/3/23 10:55 9 | */ 10 | public class ApiStatResult implements Serializable { 11 | private static final long serialVersionUID = -2561810964452277221L; 12 | 13 | private String date; 14 | private String totalSize; 15 | private Long fileCount; 16 | 17 | public String getDate() { 18 | return date; 19 | } 20 | 21 | public void setDate(String date) { 22 | this.date = date; 23 | } 24 | 25 | public String getTotalSize() { 26 | return totalSize; 27 | } 28 | 29 | public void setTotalSize(String totalSize) { 30 | this.totalSize = totalSize; 31 | } 32 | 33 | public Long getFileCount() { 34 | return fileCount; 35 | } 36 | 37 | public void setFileCount(Long fileCount) { 38 | this.fileCount = fileCount; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/common/PageResult.java: -------------------------------------------------------------------------------- 1 | package com.perfree.common; 2 | 3 | import java.io.Serializable; 4 | import java.util.List; 5 | 6 | public class PageResult implements Serializable { 7 | private static final long serialVersionUID = 1L; 8 | private int state; 9 | private String msg; 10 | private Long total; 11 | private List data; 12 | 13 | public int getState() { 14 | return state; 15 | } 16 | 17 | public void setState(int state) { 18 | this.state = state; 19 | } 20 | 21 | public String getMsg() { 22 | return msg; 23 | } 24 | 25 | public void setMsg(String msg) { 26 | this.msg = msg; 27 | } 28 | 29 | public Long getTotal() { 30 | return total; 31 | } 32 | 33 | public void setTotal(Long total) { 34 | this.total = total; 35 | } 36 | 37 | public List getData() { 38 | return data; 39 | } 40 | 41 | public void setData(List data) { 42 | this.data = data; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/form/ApiResult.java: -------------------------------------------------------------------------------- 1 | package com.perfree.form; 2 | 3 | import cn.hutool.json.JSONObject; 4 | 5 | import java.io.Serializable; 6 | 7 | /** 8 | * @description GoFastDfs API接口响应格式 9 | * @author Perfree 10 | * @date 2021/3/23 10:55 11 | */ 12 | public class ApiResult implements Serializable { 13 | private static final long serialVersionUID = -2561810964453277221L; 14 | private String status; 15 | private String message; 16 | private JSONObject data; 17 | 18 | public JSONObject getData() { 19 | return data; 20 | } 21 | 22 | public void setData(JSONObject data) { 23 | this.data = data; 24 | } 25 | 26 | public String getStatus() { 27 | return status; 28 | } 29 | 30 | public void setStatus(String status) { 31 | this.status = status; 32 | } 33 | 34 | public String getMessage() { 35 | return message; 36 | } 37 | 38 | public void setMessage(String message) { 39 | this.message = message; 40 | } 41 | 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/resources/static/js/common.js: -------------------------------------------------------------------------------- 1 | (function($) { 2 | let common = function () { 3 | } 4 | common.prototype = { 5 | formatDate: function (time, format) { 6 | let t = new Date(time); 7 | let tf = function(i){return (i < 10 ? '0' : '') + i}; 8 | return format.replace(/yyyy|MM|dd|HH|mm|ss/g, function(a){ 9 | switch(a){ 10 | case 'yyyy': 11 | return tf(t.getFullYear()); 12 | case 'MM': 13 | return tf(t.getMonth() + 1); 14 | case 'mm': 15 | return tf(t.getMinutes()); 16 | case 'dd': 17 | return tf(t.getDate()); 18 | case 'HH': 19 | return tf(t.getHours()); 20 | case 'ss': 21 | return tf(t.getSeconds()); 22 | } 23 | }) 24 | } 25 | } 26 | window.common = new common(); 27 | })(window.jQuery); -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/css/modules/code.css: -------------------------------------------------------------------------------- 1 | /** layui-v2.5.7 MIT License */ 2 | html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-h3,.layui-code-view{position:relative;font-size:12px}.layui-code-view{display:block;margin:10px 0;padding:0;border:1px solid #e2e2e2;border-left-width:6px;background-color:#F2F2F2;color:#333;font-family:Courier New}.layui-code-h3{padding:0 10px;height:32px;line-height:32px;border-bottom:1px solid #e2e2e2}.layui-code-h3 a{position:absolute;right:10px;top:0;color:#999}.layui-code-view .layui-code-ol{position:relative;overflow:auto}.layui-code-view .layui-code-ol li{position:relative;margin-left:45px;line-height:20px;padding:0 5px;border-left:1px solid #e2e2e2;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view pre{margin:0}.layui-code-notepad{border:1px solid #0C0C0C;border-left-color:#3F3F3F;background-color:#0C0C0C;color:#C2BE9E}.layui-code-notepad .layui-code-h3{border-bottom:none}.layui-code-notepad .layui-code-ol li{background-color:#3F3F3F;border-left:none} -------------------------------------------------------------------------------- /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8088 3 | servlet: 4 | session: 5 | cookie: 6 | http-only: false 7 | version: v1.3.7 8 | version.date: 2021/04/12 9 | upload.temp.path: /temp/ 10 | spring: 11 | thymeleaf: 12 | mode: HTML 13 | encoding: UTF-8 14 | cache: false 15 | devtools: 16 | restart: 17 | enabled: true 18 | servlet: 19 | multipart: 20 | max-file-size: -1 21 | max-request-size: -1 22 | datasource: 23 | driver-class-name: org.sqlite.JDBC 24 | 25 | logging: 26 | level: 27 | com.perfree: debug 28 | file: 29 | name: ./logs/gofastdfs.log 30 | 31 | mybatis-plus: 32 | configuration: 33 | log-impl: org.apache.ibatis.logging.stdout.StdOutImpl 34 | # log-impl: org.apache.ibatis.logging.nologging.NoLoggingImpl 35 | map-underscore-to-camel-case: false 36 | global-config: 37 | db-config: 38 | table-prefix: t_ 39 | mapper-locations: classpath*:mapper/*.xml 40 | 41 | 42 | pagehelper: 43 | helperDialect: mysql 44 | reasonable: true 45 | supportMethodsArguments: true 46 | params: count=countSql -------------------------------------------------------------------------------- /src/main/java/com/perfree/service/UserService.java: -------------------------------------------------------------------------------- 1 | package com.perfree.service; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 4 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 5 | import com.perfree.mapper.UserMapper; 6 | import com.perfree.model.User; 7 | import org.springframework.beans.factory.annotation.Autowired; 8 | import org.springframework.stereotype.Service; 9 | 10 | /** 11 | * @description user用户表,逻辑处理 12 | * @author Perfree 13 | * @date 2021/3/22 15:01 14 | */ 15 | @Service 16 | public class UserService extends ServiceImpl { 17 | 18 | @Autowired 19 | private UserMapper userMapper; 20 | 21 | /** 22 | * @description 根据 account获取用户信息 23 | * @param account account 24 | * @return com.perfree.model.User 25 | * @author Perfree 26 | */ 27 | public User getUserByAccount(String account) { 28 | QueryWrapper queryWrapper = new QueryWrapper<>(); 29 | queryWrapper.eq("account", account); 30 | return userMapper.selectOne(queryWrapper); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Perfree 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. -------------------------------------------------------------------------------- /src/main/resources/static/css/login.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | margin: 0; 3 | min-height: 100%; 4 | line-height: 1.42857143; 5 | color: #58666e; 6 | font-size: 14px; 7 | -webkit-font-smoothing: antialiased; 8 | font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, 9 | Microsoft YaHei, Arial, sans-serif; 10 | background: #f1f1f1; 11 | height: 100%; 12 | } 13 | .full{ 14 | height: 100%; 15 | overflow: auto; 16 | width: 100%; 17 | } 18 | .login-top-box{ 19 | height: 50%; 20 | width: 100%; 21 | background: #627aad; 22 | } 23 | .login-box{ 24 | width: 350px; 25 | height: 216px; 26 | background: white; 27 | position: absolute; 28 | left: calc(50% - 175px); 29 | top: calc(50% - 108px); 30 | border-radius: 5px; 31 | box-shadow: 1px 1px 4px #b3b1b1; 32 | padding: 15px; 33 | } 34 | .layui-input-block{ 35 | margin: 0; 36 | } 37 | .login-title{ 38 | text-align: center; 39 | font-size: 22px; 40 | font-weight: 800; 41 | margin-bottom: 10px; 42 | } 43 | .login-btn{ 44 | width: 100%; 45 | background: #627aad; 46 | } -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/lay/modules/code.js: -------------------------------------------------------------------------------- 1 | /** layui-v2.5.7 MIT License */ 2 | ;layui.define("jquery",function(e){"use strict";var a=layui.$,l="http://www.layui.com/doc/modules/code.html";e("code",function(e){var t=[];e=e||{},e.elem=a(e.elem||".layui-code"),e.about=!("about"in e)||e.about,e.elem.each(function(){t.push(this)}),layui.each(t.reverse(),function(t,i){var c=a(i),o=c.html();(c.attr("lay-encode")||e.encode)&&(o=o.replace(/&(?!#?[a-zA-Z0-9]+;)/g,"&").replace(//g,">").replace(/'/g,"'").replace(/"/g,""")),c.html('
  1. '+o.replace(/[\r\t\n]+/g,"
  2. ")+"
"),c.find(">.layui-code-h3")[0]||c.prepend('

'+(c.attr("lay-title")||e.title||"code")+(e.about?'layui.code':"")+"

");var d=c.find(">.layui-code-ol");c.addClass("layui-box layui-code-view"),(c.attr("lay-skin")||e.skin)&&c.addClass("layui-code-"+(c.attr("lay-skin")||e.skin)),(d.find("li").length/100|0)>0&&d.css("margin-left",(d.find("li").length/100|0)+"px"),(c.attr("lay-height")||e.height)&&d.css("max-height",c.attr("lay-height")||e.height)})})}).addcss("modules/code.css","skincodecss"); -------------------------------------------------------------------------------- /src/main/resources/static/css/install.css: -------------------------------------------------------------------------------- 1 | html, body { 2 | margin: 0; 3 | min-height: 100%; 4 | line-height: 1.42857143; 5 | color: #58666e; 6 | font-size: 14px; 7 | -webkit-font-smoothing: antialiased; 8 | font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, 9 | Microsoft YaHei, Arial, sans-serif; 10 | background: #f1f1f1; 11 | height: 100%; 12 | } 13 | .layui-fluid{ 14 | padding: 0; 15 | } 16 | .install-title{ 17 | position: relative; 18 | height: 260px; 19 | line-height: 200px; 20 | color: #fff; 21 | border-radius: 2px 2px 0 0; 22 | background-color: #627aad; 23 | text-align: center; 24 | font-weight: bold; 25 | font-size: 18px; 26 | padding-right: 50px; 27 | padding-left: 56px; 28 | } 29 | #stepForm{ 30 | margin: 0 auto; 31 | width: 800px!important; 32 | height: 500px; 33 | background-color: white!important; 34 | padding-top: 50px; 35 | position: absolute; 36 | top: 130px; 37 | left: calc(50% - 400px); 38 | border-radius: 5px; 39 | box-shadow: 0 1px 2px 0 rgba(0,0,0,.1); 40 | } 41 | .layui-card-body{ 42 | padding-top: 40px; 43 | background: #ddd; 44 | } 45 | .layui-card { 46 | box-shadow: none; 47 | } -------------------------------------------------------------------------------- /src/main/java/com/perfree/config/WebConfig.java: -------------------------------------------------------------------------------- 1 | package com.perfree.config; 2 | 3 | import com.perfree.interceptor.InstallInterceptor; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 7 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 8 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 9 | 10 | /** 11 | * @description Web配置-静态资源配置 12 | * @author Perfree 13 | * @date 2021/3/22 13:41 14 | */ 15 | @Configuration 16 | public class WebConfig implements WebMvcConfigurer { 17 | @Bean 18 | public InstallInterceptor installInterceptor() { 19 | return new InstallInterceptor(); 20 | } 21 | 22 | @Override 23 | public void addResourceHandlers(ResourceHandlerRegistry registry) { 24 | registry.addResourceHandler("/static/**").addResourceLocations("classpath:/static/"); 25 | } 26 | 27 | @Override 28 | public void addInterceptors(InterceptorRegistry registry) { 29 | registry.addInterceptor(installInterceptor()).excludePathPatterns("/install","/install/**","/static/**").addPathPatterns("/**"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /HELP.md: -------------------------------------------------------------------------------- 1 | # Getting Started 2 | 3 | ### Reference Documentation 4 | For further reference, please consider the following sections: 5 | 6 | * [Official Apache Maven documentation](https://maven.apache.org/guides/index.html) 7 | * [Spring Boot Maven Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.4.4/maven-plugin/reference/html/) 8 | * [Create an OCI image](https://docs.spring.io/spring-boot/docs/2.4.4/maven-plugin/reference/html/#build-image) 9 | * [Spring Web](https://docs.spring.io/spring-boot/docs/2.4.4/reference/htmlsingle/#boot-features-developing-web-applications) 10 | * [Spring Boot DevTools](https://docs.spring.io/spring-boot/docs/2.4.4/reference/htmlsingle/#using-boot-devtools) 11 | * [Thymeleaf](https://docs.spring.io/spring-boot/docs/2.4.4/reference/htmlsingle/#boot-features-spring-mvc-template-engines) 12 | 13 | ### Guides 14 | The following guides illustrate how to use some features concretely: 15 | 16 | * [Building a RESTful Web Service](https://spring.io/guides/gs/rest-service/) 17 | * [Serving Web Content with Spring MVC](https://spring.io/guides/gs/serving-web-content/) 18 | * [Building REST services with Spring](https://spring.io/guides/tutorials/bookmarks/) 19 | * [Handling Form Submission](https://spring.io/guides/gs/handling-form-submission/) 20 | 21 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/common/Constant.java: -------------------------------------------------------------------------------- 1 | package com.perfree.common; 2 | 3 | /** 4 | * @description 常量 5 | * @author Perfree 6 | * @date 2021/3/23 10:58 7 | */ 8 | public class Constant { 9 | /** API 响应成功 */ 10 | public static final String API_STATUS_SUCCESS = "ok"; 11 | 12 | /** 配置管理API */ 13 | public static final String API_RELOAD = "/reload"; 14 | 15 | /** 文件统计信息API */ 16 | public static final String API_STAT = "/stat"; 17 | 18 | /** 文件上传API */ 19 | public static final String API_UPLOAD = "/upload"; 20 | 21 | /** 文件删除API */ 22 | public static final String API_DELETE = "/delete"; 23 | 24 | /** 文件信息API */ 25 | public static final String API_GET_FILE_INFO = "/get_file_info"; 26 | 27 | /** 文件列表API */ 28 | public static final String API_LIST_DIR = "/list_dir"; 29 | 30 | /** 修复统计信息API */ 31 | public static final String API_REPAIR_STAT = "/repair_stat"; 32 | public static final String API_REMOVE_EMPTY_DIR = "/remove_empty_dir"; 33 | public static final String API_BACKUP = "/backup"; 34 | 35 | /** 同步失败修复API */ 36 | public static final String API_REPAIR = "/repair"; 37 | 38 | /** 从文件目录中修复元数据API */ 39 | public static final String API_REPAIR_FILE_INFO = "/repair_fileinfo"; 40 | public static final String API_STATUS = "/status"; 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/common/FileSizeUtil.java: -------------------------------------------------------------------------------- 1 | package com.perfree.common; 2 | 3 | import java.text.DecimalFormat; 4 | 5 | /** 6 | * 文件大小转换工具类 7 | * @author Perfree 8 | * 9 | */ 10 | public class FileSizeUtil { 11 | 12 | /** 13 | * 根据文件大小转换为B、KB、MB、GB单位字符串显示 14 | * @param filesize 文件的大小(long型) 15 | * @return 返回 转换后带有单位的字符串 16 | */ 17 | public static String GetLength(long filesize){ 18 | String strFileSize = null; 19 | if(filesize < 1024){ 20 | strFileSize = filesize+"B"; 21 | return strFileSize; 22 | } 23 | DecimalFormat df = new DecimalFormat("######0.00"); 24 | if ((filesize >= 1024) && (filesize < 1024*1024)){ 25 | strFileSize = df.format(((double)filesize)/1024)+"KB"; 26 | }else if((filesize >= 1024*1024)&&(filesize < 1024*1024*1024)){ 27 | strFileSize = df.format(((double)filesize)/(1024*1024))+"MB"; 28 | }else{ 29 | strFileSize = df.format(((double)filesize)/(1024*1024*1024))+"GB"; 30 | } 31 | return strFileSize; 32 | } 33 | 34 | /** 35 | * @param filesize 文件的大小(long型) 36 | * @return 返回 转换后不带单位的字符串 37 | */ 38 | public static String GetMBLength(long filesize){ 39 | DecimalFormat df = new DecimalFormat("######0.00"); 40 | return df.format(((double)filesize)/(1024*1024)); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/config/SQLiteConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.perfree.config; 2 | 3 | import org.slf4j.Logger; 4 | import org.slf4j.LoggerFactory; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.beans.factory.annotation.Value; 7 | import org.springframework.boot.jdbc.DataSourceBuilder; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | import org.springframework.core.io.ResourceLoader; 11 | 12 | import javax.sql.DataSource; 13 | import java.io.IOException; 14 | 15 | /** 16 | * @description SQLite的配置 17 | * @author Perfree 18 | * @date 2021/3/22 15:07 19 | */ 20 | @Configuration 21 | public class SQLiteConfiguration { 22 | 23 | private static final Logger logger = LoggerFactory.getLogger(SQLiteConfiguration.class); 24 | 25 | @Value("${SQLite.dbPath:/db/go-fastdfs.db}") 26 | private String SQLiteDbPath; 27 | 28 | @Bean 29 | public DataSource dataSource() { 30 | DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create(); 31 | dataSourceBuilder.driverClassName("org.sqlite.JDBC"); 32 | String projectPath = System.getProperty("user.dir"); 33 | final String url = "jdbc:sqlite:" + projectPath + SQLiteDbPath; 34 | dataSourceBuilder.url(url); 35 | return dataSourceBuilder.build(); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/form/FileResult.java: -------------------------------------------------------------------------------- 1 | package com.perfree.form; 2 | 3 | public class FileResult { 4 | private Boolean is_dir; 5 | private String md5; 6 | private String mTime; 7 | private String name; 8 | private String path; 9 | private String size; 10 | private String peerAddr; 11 | 12 | public Boolean getIs_dir() { 13 | return is_dir; 14 | } 15 | 16 | public void setIs_dir(Boolean is_dir) { 17 | this.is_dir = is_dir; 18 | } 19 | 20 | public String getMd5() { 21 | return md5; 22 | } 23 | 24 | public void setMd5(String md5) { 25 | this.md5 = md5; 26 | } 27 | 28 | public String getmTime() { 29 | return mTime; 30 | } 31 | 32 | public void setmTime(String mTime) { 33 | this.mTime = mTime; 34 | } 35 | 36 | public String getName() { 37 | return name; 38 | } 39 | 40 | public void setName(String name) { 41 | this.name = name; 42 | } 43 | 44 | public String getPath() { 45 | return path; 46 | } 47 | 48 | public void setPath(String path) { 49 | this.path = path; 50 | } 51 | 52 | public String getSize() { 53 | return size; 54 | } 55 | 56 | public void setSize(String size) { 57 | this.size = size; 58 | } 59 | 60 | public String getPeerAddr() { 61 | return peerAddr; 62 | } 63 | 64 | public void setPeerAddr(String peerAddr) { 65 | this.peerAddr = peerAddr; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Go-Fastdfs web管理平台 2 | > go-fastdfs 是一个简单的分布式文件存储,具有高性能,高可靠,免维护等优点,支持断点续传,分块上传,小文件合并,自动同步,自动修复。本项目为go-fastdfs的web管理端 3 | 4 | [前往 Go-Fastdfs](https://github.com/sjqzhang/go-fastdfs) 5 | 6 | [Go-Fastdfs web管理平台 - Golang版本](https://github.com/perfree/go-fastdfs-web-go) 7 | 8 | ## 简单预览图 9 | ![控制台](./screen/01.png) 10 | 11 | ![文件上传](./screen/02.png) 12 | 13 | ![文件列表](./screen/03.png) 14 | 15 | ![集群列表](./screen/04.png) 16 | 17 | ## 注意事项 18 | 1. 默认端口8088,修改默认端口号更改config/application.yml即可 19 | 2. 如go-fastdfs开启了按组管理,则需要填写组名,反之不用填写 20 | 3. 进入安装页填写集群地址时,该地址需要在go-fastdfs配置文件配置管理ip白名单,否则获取不到数据! 21 | 4. 文件列表功能需要go-fastdfs服务版本在v1.2.8以上 22 | 5. 遇到获取不到信息的功能,先试一下本地调用go-fastdfs接口看是否能获取到 23 | 24 | ## 运行步骤 25 | 首先需要安装java运行环境 26 | [下载地址](https://github.com/perfree/go-fastdfs-web/releases) 27 | 28 | ### Docker安装运行 29 | ```shell script 30 | docker run --name fastdfsweb -d -p 8088:8088 perfree/fastdfsweb 31 | ``` 32 | 33 | ### Windows运行 34 | 解压压缩包后,直接运行start.bat 35 | ### Linux运行 36 | 解压压缩包后,运行脚本,命令如下: 37 | ``` 38 | 1.运行 39 | ./goFastDfsWeb.sh start 40 | 2.查看运行状态 41 | ./goFastDfsWeb.sh status 42 | 3.重新启动 43 | ./goFastDfsWeb.sh restart 44 | 4.停止 45 | ./goFastDfsWeb.sh stop 46 | ``` 47 | 如遇到-bash: ./goFastDfsWeb.sh: /bin/bash^M: 坏的解释器: 没有那个文件或目录错误,则执行以下命令再运行 48 | ```bash 49 | sed -i 's/\r//' ./goFastDfsWeb.sh 50 | ``` 51 | 52 | ## 开发说明 53 | 项目使用SpringBoot,Mybatis-Plus,Shiro进行开发,为方便后期用户安装,数据库采用Sqlite. 54 | 55 | ## 打包方式 56 | 1. maven运行mvn clean package 57 | 2. 完成之后得到jar,zip,tar.gz三种格式文件 58 | ## 支持 59 | ![微信](./screen/wechat.jpg) 60 | 61 | ![支付宝](./screen/alipay.jpg) 62 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/controller/UploadController.java: -------------------------------------------------------------------------------- 1 | package com.perfree.controller; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import com.perfree.common.Constant; 5 | import com.perfree.common.ResponseBean; 6 | import com.perfree.common.UploadUtils; 7 | import org.apache.commons.lang3.StringUtils; 8 | import org.springframework.beans.factory.annotation.Value; 9 | import org.springframework.stereotype.Controller; 10 | import org.springframework.ui.Model; 11 | import org.springframework.web.bind.annotation.RequestMapping; 12 | import org.springframework.web.bind.annotation.RequestParam; 13 | import org.springframework.web.bind.annotation.ResponseBody; 14 | import org.springframework.web.multipart.MultipartFile; 15 | 16 | /** 17 | * 文件上传Controller 18 | */ 19 | @Controller 20 | public class UploadController extends BaseController { 21 | 22 | @Value("${upload.temp.path}") 23 | private String tempPath; 24 | 25 | @RequestMapping("/file/upload") 26 | public String index(Model model) { 27 | model.addAttribute("showAddress", getUploadShowUrl()); 28 | return "file/upload"; 29 | } 30 | 31 | @RequestMapping("/file/upload/moreFileUpload") 32 | @ResponseBody 33 | public ResponseBean moreFileUpload(@RequestParam("file") MultipartFile file, String scene, String path, String showUrl) { 34 | if (file.isEmpty()) { 35 | return ResponseBean.fail("请选择文件"); 36 | } 37 | if (StringUtils.isBlank(scene)) { 38 | return ResponseBean.fail("请填写上传场景"); 39 | } 40 | if (StrUtil.isBlank(showUrl)) { 41 | showUrl = getUploadShowUrl(); 42 | } 43 | return UploadUtils.upload(file, getPeersUrl() + Constant.API_UPLOAD, showUrl); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/bin/goFastDfsWeb.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SpringBoot=go-fastdfs-web.jar 4 | 5 | if [ "$1" = "" ]; 6 | then 7 | echo -e "\033[0;31m 未输入操作名 \033[0m \033[0;34m {start|stop|restart|status} \033[0m" 8 | exit 1 9 | fi 10 | 11 | if [ "$SpringBoot" = "" ]; 12 | then 13 | echo -e "\033[0;31m 未输入应用名 \033[0m" 14 | exit 1 15 | fi 16 | 17 | function start() 18 | { 19 | count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l` 20 | if [ $count != 0 ];then 21 | echo "$SpringBoot is running..." 22 | else 23 | echo "Start $SpringBoot success..." 24 | nohup java -jar $SpringBoot > /dev/null 2>&1 & 25 | fi 26 | } 27 | 28 | function stop() 29 | { 30 | echo "Stop $SpringBoot" 31 | boot_id=`ps -ef |grep java|grep $SpringBoot|grep -v grep|awk '{print $2}'` 32 | count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l` 33 | 34 | if [ $count != 0 ];then 35 | kill $boot_id 36 | count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l` 37 | 38 | boot_id=`ps -ef |grep java|grep $SpringBoot|grep -v grep|awk '{print $2}'` 39 | kill -9 $boot_id 40 | fi 41 | } 42 | 43 | function restart() 44 | { 45 | stop 46 | sleep 2 47 | start 48 | } 49 | 50 | function status() 51 | { 52 | count=`ps -ef |grep java|grep $SpringBoot|grep -v grep|wc -l` 53 | if [ $count != 0 ];then 54 | echo "$SpringBoot is running..." 55 | else 56 | echo "$SpringBoot is not running..." 57 | fi 58 | } 59 | 60 | case $1 in 61 | start) 62 | start;; 63 | stop) 64 | stop;; 65 | restart) 66 | restart;; 67 | status) 68 | status;; 69 | *) 70 | 71 | echo -e "\033[0;31m Usage: \033[0m \033[0;34m sh $0 {start|stop|restart|status} {SpringBootJarName} \033[0m 72 | \033[0;31m Example: \033[0m 73 | \033[0;33m sh $0 start esmart-test.jar \033[0m" 74 | esac -------------------------------------------------------------------------------- /src/main/java/com/perfree/form/FileDetails.java: -------------------------------------------------------------------------------- 1 | package com.perfree.form; 2 | 3 | import java.util.List; 4 | 5 | /** 6 | * @Author Perfree 7 | * @Date 2019/5/11 11:13 8 | */ 9 | public class FileDetails { 10 | private String url; 11 | private String path; 12 | private String size; 13 | private String name; 14 | private String md5; 15 | private String scene; 16 | private String timeStamp; 17 | private List peers; 18 | 19 | public String getUrl() { 20 | return url; 21 | } 22 | 23 | public void setUrl(String url) { 24 | this.url = url; 25 | } 26 | 27 | public String getPath() { 28 | return path; 29 | } 30 | 31 | public void setPath(String path) { 32 | this.path = path; 33 | } 34 | 35 | public String getSize() { 36 | return size; 37 | } 38 | 39 | public void setSize(String size) { 40 | this.size = size; 41 | } 42 | 43 | public String getName() { 44 | return name; 45 | } 46 | 47 | public void setName(String name) { 48 | this.name = name; 49 | } 50 | 51 | public String getMd5() { 52 | return md5; 53 | } 54 | 55 | public void setMd5(String md5) { 56 | this.md5 = md5; 57 | } 58 | 59 | public String getScene() { 60 | return scene; 61 | } 62 | 63 | public void setScene(String scene) { 64 | this.scene = scene; 65 | } 66 | 67 | public String getTimeStamp() { 68 | return timeStamp; 69 | } 70 | 71 | public void setTimeStamp(String timeStamp) { 72 | this.timeStamp = timeStamp; 73 | } 74 | 75 | public List getPeers() { 76 | return peers; 77 | } 78 | 79 | public void setPeers(List peers) { 80 | this.peers = peers; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/lay/modules/laytpl.js: -------------------------------------------------------------------------------- 1 | /** layui-v2.5.7 MIT License */ 2 | ;layui.define(function(e){"use strict";var r={open:"{{",close:"}}"},c={exp:function(e){return new RegExp(e,"g")},query:function(e,c,t){var o=["#([\\s\\S])+?","([^{#}])*?"][e||0];return n((c||"")+r.open+o+r.close+(t||""))},escape:function(e){return String(e||"").replace(/&(?!#?[a-zA-Z0-9]+;)/g,"&").replace(//g,">").replace(/'/g,"'").replace(/"/g,""")},error:function(e,r){var c="Laytpl Error:";return"object"==typeof console&&console.error(c+e+"\n"+(r||"")),c+e}},n=c.exp,t=function(e){this.tpl=e};t.pt=t.prototype,window.errors=0,t.pt.parse=function(e,t){var o=this,p=e,a=n("^"+r.open+"#",""),l=n(r.close+"$","");e=e.replace(/\s+|\r|\t|\n/g," ").replace(n(r.open+"#"),r.open+"# ").replace(n(r.close+"}"),"} "+r.close).replace(/\\/g,"\\\\").replace(n(r.open+"!(.+?)!"+r.close),function(e){return e=e.replace(n("^"+r.open+"!"),"").replace(n("!"+r.close),"").replace(n(r.open+"|"+r.close),function(e){return e.replace(/(.)/g,"\\$1")})}).replace(/(?="|')/g,"\\").replace(c.query(),function(e){return e=e.replace(a,"").replace(l,""),'";'+e.replace(/\\/g,"")+';view+="'}).replace(c.query(1),function(e){var c='"+(';return e.replace(/\s/g,"")===r.open+r.close?"":(e=e.replace(n(r.open+"|"+r.close),""),/^=/.test(e)&&(e=e.replace(/^=/,""),c='"+_escape_('),c+e.replace(/\\/g,"")+')+"')}),e='"use strict";var view = "'+e+'";return view;';try{return o.cache=e=new Function("d, _escape_",e),e(t,c.escape)}catch(u){return delete o.cache,c.error(u,p)}},t.pt.render=function(e,r){var n,t=this;return e?(n=t.cache?t.cache(e,c.escape):t.parse(t.tpl,e),r?void r(n):n):c.error("no data")};var o=function(e){return"string"!=typeof e?c.error("Template not found"):new t(e)};o.config=function(e){e=e||{};for(var c in e)r[c]=e[c]},o.v="1.2.0",e("laytpl",o)}); -------------------------------------------------------------------------------- /src/main/java/com/perfree/interceptor/InstallInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.perfree.interceptor; 2 | 3 | import com.perfree.service.UserService; 4 | import org.springframework.beans.factory.annotation.Autowired; 5 | import org.springframework.web.servlet.HandlerInterceptor; 6 | import org.springframework.web.servlet.ModelAndView; 7 | 8 | import javax.servlet.http.HttpServletRequest; 9 | import javax.servlet.http.HttpServletResponse; 10 | import javax.servlet.http.HttpSession; 11 | 12 | /** 13 | * @description 安装拦截器,如用户未安装,则执行安装操作 14 | * @author Perfree 15 | * @date 2021/3/23 14:58 16 | */ 17 | public class InstallInterceptor implements HandlerInterceptor { 18 | 19 | @Autowired 20 | private UserService userService; 21 | 22 | @Override 23 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 24 | throws Exception { 25 | HttpSession session = request.getSession(); 26 | Boolean isInstall = (Boolean) session.getAttribute("isInstall"); 27 | if(isInstall == null) { 28 | if(userService.list().size() < 1){ 29 | response.sendRedirect("/install"); 30 | return false; 31 | }else{ 32 | session.setAttribute("isInstall",true); 33 | } 34 | } 35 | return true; 36 | } 37 | 38 | @Override 39 | public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, 40 | ModelAndView modelAndView) throws Exception { 41 | HandlerInterceptor.super.postHandle(request, response, handler, modelAndView); 42 | } 43 | 44 | @Override 45 | public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) 46 | throws Exception { 47 | HandlerInterceptor.super.afterCompletion(request, response, handler, ex); 48 | } 49 | 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/resources/assembly.xml: -------------------------------------------------------------------------------- 1 | 2 | ${version} 3 | 4 | zip 5 | tar.gz 6 | 7 | true 8 | 9 | 10 | ${basedir}/src/main/bin 11 | 12 | 0755 13 | 14 | 15 | ${basedir} 16 | 17 | README.md 18 | 19 | 20 | 21 | 22 | ${basedir}/db 23 | 24 | *.db 25 | 26 | db 27 | 0644 28 | 29 | 30 | ${basedir}/src/main/resources 31 | 32 | *.yml 33 | 34 | config 35 | 0644 36 | 37 | 38 | ${project.build.directory} 39 | 40 | ${project.artifactId}.jar 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/less/mixins.less: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | .fa-icon() { 5 | display: inline-block; 6 | font: normal normal normal @fa-font-size-base/@fa-line-height-base FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | 12 | } 13 | 14 | .fa-icon-rotate(@degrees, @rotation) { 15 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation})"; 16 | -webkit-transform: rotate(@degrees); 17 | -ms-transform: rotate(@degrees); 18 | transform: rotate(@degrees); 19 | } 20 | 21 | .fa-icon-flip(@horiz, @vert, @rotation) { 22 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=@{rotation}, mirror=1)"; 23 | -webkit-transform: scale(@horiz, @vert); 24 | -ms-transform: scale(@horiz, @vert); 25 | transform: scale(@horiz, @vert); 26 | } 27 | 28 | 29 | // Only display content to screen readers. A la Bootstrap 4. 30 | // 31 | // See: http://a11yproject.com/posts/how-to-hide-content/ 32 | 33 | .sr-only() { 34 | position: absolute; 35 | width: 1px; 36 | height: 1px; 37 | padding: 0; 38 | margin: -1px; 39 | overflow: hidden; 40 | clip: rect(0,0,0,0); 41 | border: 0; 42 | } 43 | 44 | // Use in conjunction with .sr-only to only display content when it's focused. 45 | // 46 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 47 | // 48 | // Credit: HTML5 Boilerplate 49 | 50 | .sr-only-focusable() { 51 | &:active, 52 | &:focus { 53 | position: static; 54 | width: auto; 55 | height: auto; 56 | margin: 0; 57 | overflow: visible; 58 | clip: auto; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/form/GoFastDfsUploadResult.java: -------------------------------------------------------------------------------- 1 | package com.perfree.form; 2 | 3 | public class GoFastDfsUploadResult { 4 | 5 | private String url; 6 | private String md5; 7 | private String path; 8 | private String domain; 9 | private String scene; 10 | private String scenes; 11 | private String retmsg; 12 | private int retcode; 13 | private String src; 14 | 15 | public String getUrl() { 16 | return url; 17 | } 18 | 19 | public void setUrl(String url) { 20 | this.url = url; 21 | } 22 | 23 | public String getMd5() { 24 | return md5; 25 | } 26 | 27 | public void setMd5(String md5) { 28 | this.md5 = md5; 29 | } 30 | 31 | public String getPath() { 32 | return path; 33 | } 34 | 35 | public void setPath(String path) { 36 | this.path = path; 37 | } 38 | 39 | public String getDomain() { 40 | return domain; 41 | } 42 | 43 | public void setDomain(String domain) { 44 | this.domain = domain; 45 | } 46 | 47 | public String getScene() { 48 | return scene; 49 | } 50 | 51 | public void setScene(String scene) { 52 | this.scene = scene; 53 | } 54 | 55 | public String getScenes() { 56 | return scenes; 57 | } 58 | 59 | public void setScenes(String scenes) { 60 | this.scenes = scenes; 61 | } 62 | 63 | public String getRetmsg() { 64 | return retmsg; 65 | } 66 | 67 | public void setRetmsg(String retmsg) { 68 | this.retmsg = retmsg; 69 | } 70 | 71 | public int getRetcode() { 72 | return retcode; 73 | } 74 | 75 | public void setRetcode(int retcode) { 76 | this.retcode = retcode; 77 | } 78 | 79 | public String getSrc() { 80 | return src; 81 | } 82 | 83 | public void setSrc(String src) { 84 | this.src = src; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/font-awesome-4.7.0/scss/_mixins.scss: -------------------------------------------------------------------------------- 1 | // Mixins 2 | // -------------------------- 3 | 4 | @mixin fa-icon() { 5 | display: inline-block; 6 | font: normal normal normal #{$fa-font-size-base}/#{$fa-line-height-base} FontAwesome; // shortening font declaration 7 | font-size: inherit; // can't have font-size inherit on line above, so need to override 8 | text-rendering: auto; // optimizelegibility throws things off #1094 9 | -webkit-font-smoothing: antialiased; 10 | -moz-osx-font-smoothing: grayscale; 11 | 12 | } 13 | 14 | @mixin fa-icon-rotate($degrees, $rotation) { 15 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation})"; 16 | -webkit-transform: rotate($degrees); 17 | -ms-transform: rotate($degrees); 18 | transform: rotate($degrees); 19 | } 20 | 21 | @mixin fa-icon-flip($horiz, $vert, $rotation) { 22 | -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=#{$rotation}, mirror=1)"; 23 | -webkit-transform: scale($horiz, $vert); 24 | -ms-transform: scale($horiz, $vert); 25 | transform: scale($horiz, $vert); 26 | } 27 | 28 | 29 | // Only display content to screen readers. A la Bootstrap 4. 30 | // 31 | // See: http://a11yproject.com/posts/how-to-hide-content/ 32 | 33 | @mixin sr-only { 34 | position: absolute; 35 | width: 1px; 36 | height: 1px; 37 | padding: 0; 38 | margin: -1px; 39 | overflow: hidden; 40 | clip: rect(0,0,0,0); 41 | border: 0; 42 | } 43 | 44 | // Use in conjunction with .sr-only to only display content when it's focused. 45 | // 46 | // Useful for "Skip to main content" links; see http://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1 47 | // 48 | // Credit: HTML5 Boilerplate 49 | 50 | @mixin sr-only-focusable { 51 | &:active, 52 | &:focus { 53 | position: static; 54 | width: auto; 55 | height: auto; 56 | margin: 0; 57 | overflow: visible; 58 | clip: auto; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/lay/modules/flow.js: -------------------------------------------------------------------------------- 1 | /** layui-v2.5.7 MIT License */ 2 | ;layui.define("jquery",function(e){"use strict";var l=layui.$,o=function(e){},t='';o.prototype.load=function(e){var o,i,n,r,a=this,c=0;e=e||{};var f=l(e.elem);if(f[0]){var m=l(e.scrollElem||document),u=e.mb||50,s=!("isAuto"in e)||e.isAuto,v=e.end||"没有更多了",y=e.scrollElem&&e.scrollElem!==document,d="加载更多",h=l('");f.find(".layui-flow-more")[0]||f.append(h);var p=function(e,t){e=l(e),h.before(e),t=0==t||null,t?h.html(v):h.find("a").html(d),i=t,o=null,n&&n()},g=function(){o=!0,h.find("a").html(t),"function"==typeof e.done&&e.done(++c,p)};if(g(),h.find("a").on("click",function(){l(this);i||o||g()}),e.isLazyimg)var n=a.lazyimg({elem:e.elem+" img",scrollElem:e.scrollElem});return s?(m.on("scroll",function(){var e=l(this),t=e.scrollTop();r&&clearTimeout(r),!i&&f.width()&&(r=setTimeout(function(){var i=y?e.height():l(window).height(),n=y?e.prop("scrollHeight"):document.documentElement.scrollHeight;n-t-i<=u&&(o||g())},100))}),a):a}},o.prototype.lazyimg=function(e){var o,t=this,i=0;e=e||{};var n=l(e.scrollElem||document),r=e.elem||"img",a=e.scrollElem&&e.scrollElem!==document,c=function(e,l){var o=n.scrollTop(),r=o+l,c=a?function(){return e.offset().top-n.offset().top+o}():e.offset().top;if(c>=o&&c<=r&&!e.attr("src")){var m=e.attr("lay-src");layui.img(m,function(){var l=t.lazyimg.elem.eq(i);e.attr("src",m).removeAttr("lay-src"),l[0]&&f(l),i++})}},f=function(e,o){var f=a?(o||n).height():l(window).height(),m=n.scrollTop(),u=m+f;if(t.lazyimg.elem=l(r),e)c(e,f);else for(var s=0;su)break}};if(f(),!o){var m;n.on("scroll",function(){var e=l(this);m&&clearTimeout(m),m=setTimeout(function(){f(null,e)},50)}),o=!0}return f},e("flow",new o)}); -------------------------------------------------------------------------------- /src/main/resources/static/lib/step-lay/step.css: -------------------------------------------------------------------------------- 1 | .lay-step { 2 | font-size: 0; 3 | width: 400px; 4 | margin: 0 auto; 5 | max-width: 100%; 6 | padding-left: 140px; 7 | } 8 | 9 | .step-item { 10 | display: inline-block; 11 | line-height: 26px; 12 | position: relative; 13 | font-size: 14px; 14 | } 15 | 16 | .step-item-tail { 17 | width: 100%; 18 | padding: 0 10px; 19 | position: absolute; 20 | left: 0; 21 | top: 13px; 22 | } 23 | .step-item-tail i { 24 | display: inline-block; 25 | width: 100%; 26 | height: 1px; 27 | vertical-align: top; 28 | background: #c2c2c2; 29 | position: relative; 30 | } 31 | 32 | .step-item-tail .step-item-tail-done { 33 | background: #627aad; 34 | } 35 | .layui-btn { 36 | display: inline-block; 37 | height: 33px; 38 | line-height: 33px; 39 | padding: 0 10px; 40 | background-color: #627aad; 41 | color: #fff; 42 | white-space: nowrap; 43 | text-align: center; 44 | font-size: 14px; 45 | border: none; 46 | border-radius: 2px; 47 | cursor: pointer; 48 | } 49 | 50 | .step-item-head { 51 | position: relative; 52 | display: inline-block; 53 | height: 26px; 54 | width: 26px; 55 | text-align: center; 56 | vertical-align: top; 57 | color: #627aad; 58 | border: 1px solid #627aad; 59 | border-radius: 50%; 60 | background: #ffffff; 61 | } 62 | 63 | .step-item-head.step-item-head-active { 64 | background: #627aad; 65 | color: #ffffff; 66 | } 67 | 68 | .step-item-main { 69 | display: block; 70 | position: relative; 71 | margin-left: -50%; 72 | margin-right: 50%; 73 | padding-left: 26px; 74 | text-align: center; 75 | } 76 | 77 | .step-item-main-title { 78 | font-weight: bolder; 79 | color: #555555; 80 | } 81 | 82 | .step-item-main-desc { 83 | color: #aaaaaa; 84 | } 85 | 86 | .lay-step + [carousel-item]:before { 87 | display: none; 88 | } 89 | 90 | .lay-step + [carousel-item] > * { 91 | background-color: transparent; 92 | } -------------------------------------------------------------------------------- /src/main/resources/static/css/file.css: -------------------------------------------------------------------------------- 1 | html,body,.layui-container,.layui-row,.layui-col-md12{ 2 | height: 100%; 3 | } 4 | .layui-container{ 5 | padding: 0; 6 | } 7 | .layui-card{ 8 | min-height: 100%; 9 | } 10 | .icon { 11 | width: 1.3em; 12 | height: 1.3em; 13 | vertical-align: -0.5em; 14 | fill: currentColor; 15 | overflow: hidden; 16 | margin-right: 5px; 17 | } 18 | #fileUpload { 19 | display: inline-block; 20 | height: 33px; 21 | line-height: 33px; 22 | padding: 0 18px; 23 | background-color: #627aad; 24 | color: #fff; 25 | white-space: nowrap; 26 | text-align: center; 27 | font-size: 14px; 28 | border: none; 29 | border-radius: 2px; 30 | cursor: pointer; 31 | } 32 | .file-list-header-ul{ 33 | display: table; 34 | width: 100%; 35 | line-height: 30px; 36 | border-bottom: 1px solid #eee; 37 | } 38 | .layui-card-body{ 39 | overflow: auto; 40 | } 41 | .file-list{ 42 | min-width: 950px; 43 | } 44 | .file-list-header-li{ 45 | display: table-cell; 46 | } 47 | .file-list-name{ 48 | width: 55%; 49 | } 50 | .file-list-size{ 51 | width: 15%; 52 | } 53 | .file-list-date{ 54 | width: 15%; 55 | } 56 | .file-list-handle{ 57 | width: 15%; 58 | } 59 | .file-list-file{ 60 | float: left; 61 | } 62 | .file-list-file-box{ 63 | border-bottom: 1px solid #eee; 64 | line-height: 50px; 65 | padding-left: 8px; 66 | } 67 | .file-list-file-box:hover{ 68 | background: #eeeeee; 69 | } 70 | .file-list-file-name{ 71 | width: 55%; 72 | } 73 | .file-list-file-size{ 74 | width: 15%; 75 | } 76 | .file-list-file-date{ 77 | width: 15%; 78 | } 79 | .file-list-file-handle{ 80 | width: 15%; 81 | } 82 | .path-side-btn{ 83 | cursor: pointer; 84 | } 85 | .clear{ clear:both} 86 | .file-details-box{ 87 | padding: 15px; 88 | } 89 | .file-details-box li{ 90 | line-height: 40px; 91 | font-size: 1.1em; 92 | border-bottom: 1px solid #f3f3f3; 93 | word-wrap: break-word; 94 | word-break: normal; 95 | } 96 | .file-details-box li span{ 97 | float: left; 98 | font-weight: 600; 99 | } -------------------------------------------------------------------------------- /src/main/resources/templates/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Go-FastDfs管理 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 |
19 | 20 |
21 |
22 |
    23 |
  • 24 |
25 |
26 |
27 | 28 | 31 |
32 |
33 |
34 |
35 | 36 |
37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/service/PeersService.java: -------------------------------------------------------------------------------- 1 | package com.perfree.service; 2 | 3 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 4 | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; 5 | import com.github.pagehelper.PageHelper; 6 | import com.github.pagehelper.PageInfo; 7 | import com.perfree.common.PageResult; 8 | import com.perfree.mapper.PeersMapper; 9 | import com.perfree.model.Peers; 10 | import org.springframework.beans.factory.annotation.Autowired; 11 | import org.springframework.stereotype.Service; 12 | 13 | import java.util.Date; 14 | import java.util.List; 15 | 16 | /** 17 | * @author Perfree 18 | * @description Peers集群表, 逻辑处理 19 | * @date 2021/3/22 15:00 20 | */ 21 | @Service 22 | public class PeersService extends ServiceImpl { 23 | @Autowired 24 | private PeersMapper peersMapper; 25 | 26 | public PageResult listPage(int page, int limit) { 27 | PageResult result = new PageResult<>(); 28 | PageHelper.startPage(page, limit); 29 | List allPeers = list(); 30 | PageInfo pageInfo = new PageInfo<>(allPeers); 31 | result.setTotal(pageInfo.getTotal()); 32 | result.setState(200); 33 | result.setData(pageInfo.getList()); 34 | return result; 35 | } 36 | 37 | /** 38 | * 检查集群是否已存在 39 | * 40 | * @param serverAddress serverAddress 41 | * @return boolean 42 | */ 43 | public boolean checkPeers(String serverAddress) { 44 | QueryWrapper queryWrapper = new QueryWrapper<>(); 45 | queryWrapper.eq("serverAddress", serverAddress); 46 | return peersMapper.selectCount(queryWrapper) > 0; 47 | } 48 | 49 | /** 50 | * 新增集群 51 | * 52 | * @param peers peers 53 | * @return boolean 54 | */ 55 | public boolean addPeers(Peers peers) { 56 | peers.setCreateTime(new Date()); 57 | return peersMapper.insert(peers) > 0; 58 | } 59 | 60 | /** 61 | * 根据id删除集群 62 | * 63 | * @param id id 64 | * @return boolean 65 | */ 66 | public boolean delPeersById(int id) { 67 | return peersMapper.deleteById(id) > 0; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/common/GetFileUtil.java: -------------------------------------------------------------------------------- 1 | package com.perfree.common; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import cn.hutool.http.HttpUtil; 5 | import cn.hutool.json.JSONArray; 6 | import cn.hutool.json.JSONObject; 7 | import cn.hutool.json.JSONUtil; 8 | import com.perfree.form.FileResult; 9 | 10 | import java.util.ArrayList; 11 | import java.util.HashMap; 12 | import java.util.List; 13 | 14 | /** 15 | * 获取文件列表工具类 16 | */ 17 | public class GetFileUtil { 18 | 19 | /** 20 | * 获取文件列表 21 | * @param serverAddress 服务地址 22 | * @param dir 要获取的目录(根目录为null) 23 | * @return List 24 | */ 25 | public static List getDirOrFileList(String showUrl, String serverAddress, String dir){ 26 | HashMap param = new HashMap<>(10); 27 | if(StrUtil.isNotBlank(dir)){ 28 | param.put("dir",dir); 29 | } 30 | String result = HttpUtil.post(serverAddress + Constant.API_LIST_DIR, param); 31 | JSONObject parseObj = JSONUtil.parseObj(result); 32 | List files = new ArrayList<>(); 33 | if(parseObj.getStr("message").equals("") && StrUtil.isNotBlank(parseObj.getStr("data"))) { 34 | JSONArray parseArray = parseObj.getJSONArray("data"); 35 | for (int i = 0;i < parseArray.size();i++) { 36 | FileResult fileResult = new FileResult(); 37 | JSONObject file = parseArray.getJSONObject(i); 38 | if(file.getStr("name").equals("_big")){ 39 | continue; 40 | } 41 | fileResult.setMd5(file.getStr("md5")); 42 | fileResult.setPath(file.getStr("path")); 43 | fileResult.setName(file.getStr("name")); 44 | fileResult.setIs_dir(file.getBool("is_dir")); 45 | fileResult.setPeerAddr(showUrl); 46 | if(file.getBool("is_dir")){ 47 | fileResult.setSize("0"); 48 | }else{ 49 | fileResult.setSize(FileSizeUtil.GetLength(Long.valueOf(file.getStr("size")))); 50 | } 51 | fileResult.setmTime(DateUtil.timeStamp2Date(file.getStr("mtime"),null)); 52 | files.add(fileResult); 53 | } 54 | } 55 | return files; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/model/User.java: -------------------------------------------------------------------------------- 1 | package com.perfree.model; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | 6 | import java.io.Serializable; 7 | import java.util.Date; 8 | 9 | /** 10 | * @description user用户表实体类 11 | * @author Perfree 12 | * @date 2021/3/22 14:39 13 | */ 14 | public class User implements Serializable { 15 | private static final long serialVersionUID = -6352683091628304520L; 16 | @TableId(type = IdType.AUTO) 17 | private Integer id; 18 | private String account; 19 | private String password; 20 | private String name; 21 | private String credentialsSalt; 22 | private String email; 23 | private Date createTime; 24 | private Date updateTime; 25 | private Integer peersId; 26 | 27 | public Integer getId() { 28 | return id; 29 | } 30 | 31 | public void setId(Integer id) { 32 | this.id = id; 33 | } 34 | 35 | public String getAccount() { 36 | return account; 37 | } 38 | 39 | public void setAccount(String account) { 40 | this.account = account; 41 | } 42 | 43 | public String getPassword() { 44 | return password; 45 | } 46 | 47 | public void setPassword(String password) { 48 | this.password = password; 49 | } 50 | 51 | public String getName() { 52 | return name; 53 | } 54 | 55 | public void setName(String name) { 56 | this.name = name; 57 | } 58 | 59 | public String getCredentialsSalt() { 60 | return credentialsSalt; 61 | } 62 | 63 | public void setCredentialsSalt(String credentialsSalt) { 64 | this.credentialsSalt = credentialsSalt; 65 | } 66 | 67 | public String getEmail() { 68 | return email; 69 | } 70 | 71 | public void setEmail(String email) { 72 | this.email = email; 73 | } 74 | 75 | public Date getCreateTime() { 76 | return createTime; 77 | } 78 | 79 | public void setCreateTime(Date createTime) { 80 | this.createTime = createTime; 81 | } 82 | 83 | public Date getUpdateTime() { 84 | return updateTime; 85 | } 86 | 87 | public void setUpdateTime(Date updateTime) { 88 | this.updateTime = updateTime; 89 | } 90 | 91 | public Integer getPeersId() { 92 | return peersId; 93 | } 94 | 95 | public void setPeersId(Integer peersId) { 96 | this.peersId = peersId; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/model/Peers.java: -------------------------------------------------------------------------------- 1 | package com.perfree.model; 2 | 3 | import com.baomidou.mybatisplus.annotation.IdType; 4 | import com.baomidou.mybatisplus.annotation.TableId; 5 | 6 | import javax.validation.constraints.NotBlank; 7 | import javax.validation.constraints.Size; 8 | import java.io.Serializable; 9 | import java.util.Date; 10 | 11 | /** 12 | * @description peers集群表实体类 13 | * @author Perfree 14 | * @date 2021/3/22 14:35 15 | */ 16 | public class Peers implements Serializable { 17 | 18 | private static final long serialVersionUID = -554407295275500627L; 19 | @TableId(type = IdType.AUTO) 20 | private Integer id; 21 | @NotBlank(message = "集群名称不能为空且在50字以内") 22 | @Size(max = 50, message = "集群名称不能为空且在50字以内") 23 | private String name; 24 | @Size(max =50, message = "组名称应在50字以内") 25 | private String groupName; 26 | @NotBlank(message = "集群服务地址不能为空且在100字以内") 27 | @Size(max = 100, message = "集群服务地址不能为空且在100字以内") 28 | private String serverAddress; 29 | @Size(max = 100, message = "访问域名应在50字以内") 30 | private String showAddress; 31 | private Date createTime; 32 | private Date updateTime; 33 | 34 | public Integer getId() { 35 | return id; 36 | } 37 | 38 | public void setId(Integer id) { 39 | this.id = id; 40 | } 41 | 42 | public String getName() { 43 | return name; 44 | } 45 | 46 | public void setName(String name) { 47 | this.name = name; 48 | } 49 | 50 | public String getGroupName() { 51 | return groupName; 52 | } 53 | 54 | public void setGroupName(String groupName) { 55 | this.groupName = groupName; 56 | } 57 | 58 | public String getServerAddress() { 59 | return serverAddress; 60 | } 61 | 62 | public void setServerAddress(String serverAddress) { 63 | this.serverAddress = serverAddress; 64 | } 65 | 66 | public String getShowAddress() { 67 | return showAddress; 68 | } 69 | 70 | public void setShowAddress(String showAddress) { 71 | this.showAddress = showAddress; 72 | } 73 | 74 | public Date getCreateTime() { 75 | return createTime; 76 | } 77 | 78 | public void setCreateTime(Date createTime) { 79 | this.createTime = createTime; 80 | } 81 | 82 | public Date getUpdateTime() { 83 | return updateTime; 84 | } 85 | 86 | public void setUpdateTime(Date updateTime) { 87 | this.updateTime = updateTime; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/resources/templates/layout/header.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 26 | 27 | 46 |
47 | 48 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/config/ShiroRealm.java: -------------------------------------------------------------------------------- 1 | package com.perfree.config; 2 | 3 | import com.perfree.model.User; 4 | import com.perfree.service.PeersService; 5 | import com.perfree.service.UserService; 6 | import org.apache.shiro.authc.*; 7 | import org.apache.shiro.authz.AuthorizationInfo; 8 | import org.apache.shiro.authz.SimpleAuthorizationInfo; 9 | import org.apache.shiro.crypto.hash.Md5Hash; 10 | import org.apache.shiro.realm.AuthorizingRealm; 11 | import org.apache.shiro.subject.PrincipalCollection; 12 | import org.springframework.beans.BeanUtils; 13 | import org.springframework.beans.factory.annotation.Autowired; 14 | import org.springframework.web.context.request.RequestContextHolder; 15 | import org.springframework.web.context.request.ServletRequestAttributes; 16 | 17 | import javax.servlet.http.HttpServletRequest; 18 | import java.util.Objects; 19 | 20 | /** 21 | * @description 自定义ShiroRealm 22 | * @author Perfree 23 | * @date 2021/3/23 14:48 24 | */ 25 | public class ShiroRealm extends AuthorizingRealm{ 26 | 27 | @Autowired 28 | private UserService userService; 29 | 30 | @Autowired 31 | private PeersService peersService; 32 | 33 | @Override 34 | protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) { 35 | //得到用户名称 36 | User user = new User(); 37 | try { 38 | BeanUtils.copyProperties(principals.getPrimaryPrincipal(), user); 39 | } catch (Exception e) { 40 | e.printStackTrace(); 41 | } 42 | return new SimpleAuthorizationInfo(); 43 | } 44 | 45 | @Override 46 | protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException { 47 | UsernamePasswordToken userToken = (UsernamePasswordToken) token; 48 | String account = userToken.getUsername(); 49 | User user = userService.getUserByAccount(account); 50 | if(user == null) { 51 | throw new UnknownAccountException("账户不存在"); 52 | } 53 | if(user.getPassword() == null) { 54 | throw new IncorrectCredentialsException("密码为空"); 55 | }else { 56 | String md5Hash = new Md5Hash(userToken.getPassword(), user.getCredentialsSalt()).toString(); 57 | userToken.setPassword(md5Hash.toCharArray()); 58 | } 59 | String password = user.getPassword(); 60 | user.setPassword(null); 61 | HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest(); 62 | request.getSession().setAttribute("peers", peersService.getById(user.getPeersId())); 63 | return new SimpleAuthenticationInfo(user,password,getName()); 64 | } 65 | 66 | } -------------------------------------------------------------------------------- /src/main/java/com/perfree/common/ResponseBean.java: -------------------------------------------------------------------------------- 1 | package com.perfree.common; 2 | 3 | /** 4 | * @description 接口响应 5 | * @author Perfree 6 | * @date 2021/3/23 10:33 7 | */ 8 | public class ResponseBean { 9 | public static final int SUCCESS_CODE = 200; 10 | public static final int ERROR_CODE = 500; 11 | 12 | private int code; 13 | 14 | private String msg; 15 | 16 | private Object data; 17 | 18 | public ResponseBean(int code, String msg, Object data) { 19 | this.code = code; 20 | this.msg = msg; 21 | this.data = data; 22 | } 23 | 24 | /** 25 | * @description 成功 26 | * @return com.perfree.common.ResponseBean 27 | * @author Perfree 28 | */ 29 | public static ResponseBean success() { 30 | return new ResponseBean(SUCCESS_CODE, "success", ""); 31 | } 32 | 33 | /** 34 | * @description 成功,附加数据 35 | * @param data data 36 | * @return com.perfree.common.ResponseBean 37 | * @author Perfree 38 | */ 39 | public static ResponseBean success(Object data) { 40 | return new ResponseBean(SUCCESS_CODE, "success", data); 41 | } 42 | 43 | /** 44 | * @description 成功,附加信息及数据 45 | * @param msg msg 46 | * @param data data 47 | * @return com.perfree.common.ResponseBean 48 | * @author Perfree 49 | */ 50 | public static ResponseBean success(String msg, Object data) { 51 | return new ResponseBean(SUCCESS_CODE, msg, data); 52 | } 53 | 54 | /** 55 | * @description 失败,附加信息及数据 56 | * @param msg msg 57 | * @param data data 58 | * @return com.perfree.common.ResponseBean 59 | * @author Perfree 60 | */ 61 | public static ResponseBean fail(String msg, Object data) { 62 | return new ResponseBean(ERROR_CODE, msg, data); 63 | } 64 | 65 | /** 66 | * @description 失败,附加信息 67 | * @param msg msg 68 | * @return com.perfree.common.ResponseBean 69 | * @author Perfree 70 | */ 71 | public static ResponseBean fail(String msg) { 72 | return new ResponseBean(ERROR_CODE, msg,""); 73 | } 74 | 75 | public int getCode() { 76 | return code; 77 | } 78 | 79 | public void setCode(int code) { 80 | this.code = code; 81 | } 82 | 83 | public String getMsg() { 84 | return msg; 85 | } 86 | 87 | public void setMsg(String msg) { 88 | this.msg = msg; 89 | } 90 | 91 | public Object getData() { 92 | return data; 93 | } 94 | 95 | public void setData(Object data) { 96 | this.data = data; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/main/resources/templates/login.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Go-FastDfs管理-登录 7 | 8 | 9 | 10 | 14 | 15 | 16 |
17 | 18 | 38 |
39 | 40 | 41 | 42 | 61 | 62 | -------------------------------------------------------------------------------- /src/main/resources/templates/peers/add.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 添加集群 6 | 7 | 8 | 9 | 10 |
11 |
12 |
13 | 14 |
15 | 16 |
17 |
18 |
19 | 20 |
21 | 22 |
23 |
如未在GoFastDfs开启按组管理,请不要填写
24 |
25 |
26 | 27 |
28 | 29 |
30 |
31 |
32 | 33 |
34 | 35 |
36 |
37 |
38 |
39 | 40 | 41 |
42 |
43 |
44 |
45 | 46 | 47 | 67 | 68 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/lay/modules/rate.js: -------------------------------------------------------------------------------- 1 | /** layui-v2.5.7 MIT License */ 2 | ;layui.define("jquery",function(e){"use strict";var a=layui.jquery,l={config:{},index:layui.rate?layui.rate.index+1e4:0,set:function(e){var l=this;return l.config=a.extend({},l.config,e),l},on:function(e,a){return layui.onevent.call(this,n,e,a)}},i=function(){var e=this,a=e.config;return{setvalue:function(a){e.setvalue.call(e,a)},config:a}},n="rate",t="layui-rate",o="layui-icon-rate",u="layui-icon-rate-solid",s="layui-icon-rate-half",r="layui-icon-rate-solid layui-icon-rate-half",c="layui-icon-rate-solid layui-icon-rate",f="layui-icon-rate layui-icon-rate-half",v=function(e){var i=this;i.index=++l.index,i.config=a.extend({},i.config,l.config,e),i.render()};v.prototype.config={length:5,text:!1,readonly:!1,half:!1,value:0,theme:""},v.prototype.render=function(){var e=this,l=e.config,i=l.theme?'style="color: '+l.theme+';"':"";l.elem=a(l.elem),l.value>l.length&&(l.value=l.length),parseInt(l.value)!==l.value&&(l.half||(l.value=Math.ceil(l.value)-l.value<.5?Math.ceil(l.value):Math.floor(l.value)));for(var n='
    ",s=1;s<=l.length;s++){var r='
  • ";l.half&&parseInt(l.value)!==l.value&&s==Math.ceil(l.value)?n=n+'
  • ":n+=r}n+="
"+(l.text?''+l.value+"星":"")+"";var c=l.elem,f=c.next("."+t);f[0]&&f.remove(),e.elemTemp=a(n),l.span=e.elemTemp.next("span"),l.setText&&l.setText(l.value),c.html(e.elemTemp),c.addClass("layui-inline"),l.readonly||e.action()},v.prototype.setvalue=function(e){var a=this,l=a.config;l.value=e,a.render()},v.prototype.action=function(){var e=this,l=e.config,i=e.elemTemp,n=i.find("i").width();i.children("li").each(function(e){var t=e+1,v=a(this);v.on("click",function(e){if(l.value=t,l.half){var o=e.pageX-a(this).offset().left;o<=n/2&&(l.value=l.value-.5)}l.text&&i.next("span").text(l.value+"星"),l.choose&&l.choose(l.value),l.setText&&l.setText(l.value)}),v.on("mousemove",function(e){if(i.find("i").each(function(){a(this).addClass(o).removeClass(r)}),i.find("i:lt("+t+")").each(function(){a(this).addClass(u).removeClass(f)}),l.half){var c=e.pageX-a(this).offset().left;c<=n/2&&v.children("i").addClass(s).removeClass(u)}}),v.on("mouseleave",function(){i.find("i").each(function(){a(this).addClass(o).removeClass(r)}),i.find("i:lt("+Math.floor(l.value)+")").each(function(){a(this).addClass(u).removeClass(f)}),l.half&&parseInt(l.value)!==l.value&&i.children("li:eq("+Math.floor(l.value)+")").children("i").addClass(s).removeClass(c)})})},v.prototype.events=function(){var e=this;e.config},l.render=function(e){var a=new v(e);return i.call(a)},e(n,l)}); -------------------------------------------------------------------------------- /src/main/java/com/perfree/controller/SettingController.java: -------------------------------------------------------------------------------- 1 | package com.perfree.controller; 2 | 3 | import cn.hutool.core.util.StrUtil; 4 | import com.perfree.common.ResponseBean; 5 | import com.perfree.model.User; 6 | import com.perfree.service.SettingService; 7 | import com.perfree.service.UserService; 8 | import org.apache.shiro.crypto.hash.Md5Hash; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.stereotype.Controller; 11 | import org.springframework.ui.Model; 12 | import org.springframework.web.bind.annotation.RequestMapping; 13 | import org.springframework.web.bind.annotation.ResponseBody; 14 | 15 | import java.util.regex.Pattern; 16 | 17 | /** 18 | * 系统设置Controller 19 | */ 20 | @Controller 21 | public class SettingController extends BaseController { 22 | 23 | @Autowired 24 | private SettingService settingService; 25 | @Autowired 26 | private UserService userService; 27 | 28 | /** 29 | * 个人资料 30 | * 31 | * @return String 32 | */ 33 | @RequestMapping("/settings/user") 34 | public String user(Model model) { 35 | model.addAttribute("user", userService.getById(getUser().getId())); 36 | return "settings/user"; 37 | } 38 | 39 | /** 40 | * 修改个人资料(垃圾代码/有空再改~) 41 | * 42 | * @return AjaxResult 43 | */ 44 | @RequestMapping("/settings/editUser") 45 | @ResponseBody 46 | public ResponseBean editUser(User user, String oldPassword, String newPassword) { 47 | if (StrUtil.isBlank(user.getName()) || user.getName().length() > 100) { 48 | return ResponseBean.fail("昵称不能为空且在100字符以内"); 49 | } 50 | String check = "^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$"; 51 | Pattern regex = Pattern.compile(check); 52 | if (StrUtil.isBlank(user.getEmail()) || !regex.matcher(user.getEmail()).matches()) { 53 | return ResponseBean.fail("邮箱不能为空且格式必须正确"); 54 | } 55 | if (StrUtil.isNotBlank(newPassword)) { 56 | if (StrUtil.isBlank(oldPassword) || oldPassword.length() > 16) { 57 | return ResponseBean.fail("请输入原密码"); 58 | } 59 | if (newPassword.length() > 16 || newPassword.length() < 6) { 60 | return ResponseBean.fail("新密码必须在6-16字符之间"); 61 | } 62 | User userResult = userService.getById(user.getId()); 63 | if (userResult.getPassword().equals(new Md5Hash(oldPassword, userResult.getCredentialsSalt()).toString())) { 64 | user.setPassword(new Md5Hash(newPassword, userResult.getCredentialsSalt()).toString()); 65 | } else { 66 | return ResponseBean.fail("原密码错误"); 67 | } 68 | } 69 | if (settingService.editUser(user)) { 70 | return ResponseBean.success(); 71 | } 72 | return ResponseBean.fail("修改失败"); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/resources/templates/peers/edit.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 添加集群 6 | 7 | 8 | 9 | 10 | 11 |
12 |
13 |
14 | 15 |
16 | 17 |
18 |
19 |
20 | 21 |
22 | 23 |
24 |
如未在GoFastDfs开启按组管理,请不要填写
25 |
26 |
27 | 28 |
29 | 30 | 31 |
32 |
33 |
34 | 35 |
36 | 37 |
38 |
39 |
40 |
41 | 42 | 43 |
44 |
45 |
46 |
47 | 48 | 49 | 69 | 70 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/controller/SystemController.java: -------------------------------------------------------------------------------- 1 | package com.perfree.controller; 2 | 3 | import com.perfree.common.ResponseBean; 4 | import com.perfree.model.User; 5 | import com.perfree.service.UserService; 6 | import org.apache.shiro.SecurityUtils; 7 | import org.apache.shiro.authc.IncorrectCredentialsException; 8 | import org.apache.shiro.authc.UnknownAccountException; 9 | import org.apache.shiro.authc.UsernamePasswordToken; 10 | import org.apache.shiro.subject.Subject; 11 | import org.slf4j.Logger; 12 | import org.slf4j.LoggerFactory; 13 | import org.springframework.beans.BeanUtils; 14 | import org.springframework.beans.factory.annotation.Autowired; 15 | import org.springframework.stereotype.Controller; 16 | import org.springframework.web.bind.annotation.RequestMapping; 17 | import org.springframework.web.bind.annotation.ResponseBody; 18 | 19 | /** 20 | * @description 常用Controller,包含首页,登录,退出等 21 | * @author Perfree 22 | * @date 2021/3/22 13:44 23 | */ 24 | @Controller 25 | public class SystemController extends BaseController { 26 | private final static Logger LOGGER = LoggerFactory.getLogger(SystemController.class); 27 | 28 | @Autowired 29 | private UserService userService; 30 | 31 | /** 32 | * @description 登录页 33 | * @return java.lang.String 34 | * @author Perfree 35 | */ 36 | @RequestMapping("/login") 37 | public String login() { 38 | return "login"; 39 | } 40 | 41 | /** 42 | * @description 登录 43 | * @param user user 44 | * @return com.perfree.common.ResponseBean 45 | * @author Perfree 46 | */ 47 | @RequestMapping("/doLogin") 48 | @ResponseBody 49 | public ResponseBean doLogin(User user) { 50 | try { 51 | UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(user.getAccount(),user.getPassword(), false); 52 | Subject subject = SecurityUtils.getSubject(); 53 | subject.login(usernamePasswordToken); 54 | LOGGER.info("{} >>>login", user.getAccount()); 55 | return ResponseBean.success(); 56 | }catch (IncorrectCredentialsException e) { 57 | LOGGER.info(user.getAccount() + e.getMessage()); 58 | return ResponseBean.fail("密码错误"); 59 | }catch (UnknownAccountException e) { 60 | LOGGER.info(user.getAccount() + e.getMessage()); 61 | return ResponseBean.fail("用户不存在"); 62 | }catch (Exception e) { 63 | LOGGER.info(user.getAccount() + e.getMessage()); 64 | return ResponseBean.fail("系统异常"); 65 | } 66 | } 67 | 68 | /** 69 | * @description 退出登录 70 | * @return java.lang.String 71 | * @author Perfree 72 | */ 73 | @RequestMapping("/logout") 74 | public String logout(){ 75 | Subject subject = SecurityUtils.getSubject(); 76 | User user = new User(); 77 | BeanUtils.copyProperties(subject.getPrincipals().getPrimaryPrincipal(), user); 78 | LOGGER.info("{} >>>logout", user.getAccount()); 79 | subject.logout(); 80 | return "redirect:/login"; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/service/FileService.java: -------------------------------------------------------------------------------- 1 | package com.perfree.service; 2 | 3 | import cn.hutool.http.HttpUtil; 4 | import cn.hutool.json.JSONObject; 5 | import cn.hutool.json.JSONUtil; 6 | import com.perfree.common.*; 7 | import com.perfree.form.FileDetails; 8 | import com.perfree.form.FileResult; 9 | import org.springframework.stereotype.Service; 10 | 11 | import java.util.Date; 12 | import java.util.HashMap; 13 | import java.util.List; 14 | 15 | /** 16 | * @description 文件列表相关逻辑处理 17 | * @author Perfree 18 | * @date 2021/4/7 11:50 19 | */ 20 | @Service 21 | public class FileService { 22 | 23 | /** 24 | * @description 获取一级目录 25 | * @param peersGroupName peersGroupName 26 | * @param serverAddress serverAddress 27 | * @return java.util.List 28 | * @author Perfree 29 | */ 30 | public List getParentFile(String peersGroupName, String serverAddress) { 31 | return GetFileUtil.getDirOrFileList(peersGroupName,serverAddress,null); 32 | } 33 | 34 | /** 35 | * @description 获取指定目录 36 | * @param showUrl showUrl 37 | * @param serverAddress serverAddress 38 | * @param dir dir 39 | * @return java.util.List 40 | * @author Perfree 41 | */ 42 | public List getDirFile(String showUrl, String serverAddress, String dir) { 43 | return GetFileUtil.getDirOrFileList(showUrl,serverAddress,dir); 44 | } 45 | 46 | /** 47 | * @description 删除文件 48 | * @param peersUrl peersUrl 49 | * @param md5 md5 50 | * @return boolean 51 | * @author Perfree 52 | */ 53 | public boolean deleteFile(String peersUrl, String md5) { 54 | HashMap param = new HashMap<>(10); 55 | param.put("md5",md5); 56 | JSONObject parseObj = JSONUtil.parseObj(HttpUtil.post(peersUrl + Constant.API_DELETE, param)); 57 | return parseObj.getStr("status").equals(Constant.API_STATUS_SUCCESS); 58 | } 59 | 60 | /** 61 | * @description 获取文件信息 62 | * @param peersUrl peersUrl 63 | * @param md5 md5 64 | * @return com.perfree.common.ResponseBean 65 | * @author Perfree 66 | */ 67 | public ResponseBean details(String peersUrl, String md5) { 68 | HashMap param = new HashMap<>(10); 69 | param.put("md5",md5); 70 | JSONObject parseObj = JSONUtil.parseObj(HttpUtil.post(peersUrl + Constant.API_GET_FILE_INFO, param)); 71 | if(parseObj.getStr("status").equals(Constant.API_STATUS_SUCCESS)) { 72 | FileDetails fileDetails = JSONUtil.toBean(parseObj.getStr("data"), FileDetails.class); 73 | fileDetails.setSize(FileSizeUtil.GetLength(Long.parseLong(fileDetails.getSize()))); 74 | fileDetails.setTimeStamp(DateUtil.getFormatDate(new Date(Long.parseLong(fileDetails.getTimeStamp())* 1000))); 75 | fileDetails.setUrl(peersUrl + "/" + fileDetails.getPath().replace("files/","") + "/" + fileDetails.getName()); 76 | return ResponseBean.success(fileDetails); 77 | } 78 | return ResponseBean.fail("获取文件信息失败"); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/resources/templates/file/upload.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 控制台 6 | 7 | 8 | 9 | 24 | 25 | 26 |
27 |
28 |
29 | 30 |
31 |
上传配置
32 |
33 |
34 | 35 |
36 | 37 |
38 |
39 |
40 | 41 |
42 | 43 |
44 |
45 |
46 | 47 |
48 | 49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | 59 | 60 |
61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 |
文件名大小状态上传进度操作
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/config/ShiroConfig.java: -------------------------------------------------------------------------------- 1 | package com.perfree.config; 2 | 3 | import at.pollux.thymeleaf.shiro.dialect.ShiroDialect; 4 | import org.apache.shiro.codec.Base64; 5 | import org.apache.shiro.spring.web.ShiroFilterFactoryBean; 6 | import org.apache.shiro.web.mgt.CookieRememberMeManager; 7 | import org.apache.shiro.web.mgt.DefaultWebSecurityManager; 8 | import org.apache.shiro.web.servlet.SimpleCookie; 9 | import org.apache.shiro.web.session.mgt.DefaultWebSessionManager; 10 | import org.springframework.context.annotation.Bean; 11 | import org.springframework.context.annotation.Configuration; 12 | 13 | import java.util.LinkedHashMap; 14 | import java.util.Map; 15 | 16 | /** 17 | * @description Shiro配置类 18 | * @author Perfree 19 | * @date 2021/3/23 14:53 20 | */ 21 | @Configuration 22 | public class ShiroConfig { 23 | 24 | @Bean 25 | public ShiroDialect shiroDialect() { 26 | return new ShiroDialect(); 27 | } 28 | 29 | public SimpleCookie rememberMeCookie(){ 30 | SimpleCookie simpleCookie = new SimpleCookie("rememberMe"); 31 | simpleCookie.setMaxAge(2592000); 32 | return simpleCookie; 33 | } 34 | 35 | public CookieRememberMeManager rememberMeManager(){ 36 | CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager(); 37 | cookieRememberMeManager.setCookie(rememberMeCookie()); 38 | cookieRememberMeManager.setCipherKey(Base64.decode("3AvVhmFLUs0KTA3Kprsdag==")); 39 | return cookieRememberMeManager; 40 | } 41 | 42 | @Bean 43 | public DefaultWebSessionManager sessionManager() { 44 | DefaultWebSessionManager sessionManager = new DefaultWebSessionManager(); 45 | sessionManager.setSessionIdUrlRewritingEnabled(false); 46 | return sessionManager; 47 | } 48 | 49 | @Bean 50 | public ShiroFilterFactoryBean shirFilter(org.apache.shiro.mgt.SecurityManager securityManager) { 51 | ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean(); 52 | shiroFilterFactoryBean.setSecurityManager(securityManager); 53 | shiroFilterFactoryBean.setLoginUrl("/login"); 54 | shiroFilterFactoryBean.setSuccessUrl("/"); 55 | shiroFilterFactoryBean.setUnauthorizedUrl("/403"); 56 | Map filterChainDefinitionMap = new LinkedHashMap<>(); 57 | filterChainDefinitionMap.put("/install", "anon"); 58 | filterChainDefinitionMap.put("/install/**", "anon"); 59 | filterChainDefinitionMap.put("/login", "anon"); 60 | filterChainDefinitionMap.put("/doLogin", "anon"); 61 | filterChainDefinitionMap.put("/logout", "anon"); 62 | filterChainDefinitionMap.put("/static/**", "anon"); 63 | filterChainDefinitionMap.put("/**", "user"); 64 | shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); 65 | return shiroFilterFactoryBean; 66 | } 67 | 68 | @Bean 69 | public org.apache.shiro.mgt.SecurityManager securityManager() { 70 | DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager(); 71 | securityManager.setRealm(customRealm()); 72 | securityManager.setSessionManager(sessionManager()); 73 | securityManager.setRememberMeManager(rememberMeManager()); 74 | return securityManager; 75 | } 76 | 77 | @Bean 78 | public ShiroRealm customRealm() { 79 | return new ShiroRealm(); 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/lay/modules/util.js: -------------------------------------------------------------------------------- 1 | /** layui-v2.5.7 MIT License */ 2 | ;layui.define("jquery",function(e){"use strict";var t=layui.$,i={fixbar:function(e){var i,n,a="layui-fixbar",o="layui-fixbar-top",r=t(document),l=t("body");e=t.extend({showHeight:200},e),e.bar1=e.bar1===!0?"":e.bar1,e.bar2=e.bar2===!0?"":e.bar2,e.bgcolor=e.bgcolor?"background-color:"+e.bgcolor:"";var c=[e.bar1,e.bar2,""],u=t(['
    ',e.bar1?'
  • '+c[0]+"
  • ":"",e.bar2?'
  • '+c[1]+"
  • ":"",'
  • '+c[2]+"
  • ","
"].join("")),g=u.find("."+o),s=function(){var t=r.scrollTop();t>=e.showHeight?i||(g.show(),i=1):i&&(g.hide(),i=0)};t("."+a)[0]||("object"==typeof e.css&&u.css(e.css),l.append(u),s(),u.find("li").on("click",function(){var i=t(this),n=i.attr("lay-type");"top"===n&&t("html,body").animate({scrollTop:0},200),e.click&&e.click.call(this,n)}),r.on("scroll",function(){clearTimeout(n),n=setTimeout(function(){s()},100)}))},countdown:function(e,t,i){var n=this,a="function"==typeof t,o=new Date(e).getTime(),r=new Date(!t||a?(new Date).getTime():t).getTime(),l=o-r,c=[Math.floor(l/864e5),Math.floor(l/36e5)%24,Math.floor(l/6e4)%60,Math.floor(l/1e3)%60];a&&(i=t);var u=setTimeout(function(){n.countdown(e,r+1e3,i)},1e3);return i&&i(l>0?c:[0,0,0,0],t,u),l<=0&&clearTimeout(u),u},timeAgo:function(e,t){var i=this,n=[[],[]],a=(new Date).getTime()-new Date(e).getTime();return a>26784e5?(a=new Date(e),n[0][0]=i.digit(a.getFullYear(),4),n[0][1]=i.digit(a.getMonth()+1),n[0][2]=i.digit(a.getDate()),t||(n[1][0]=i.digit(a.getHours()),n[1][1]=i.digit(a.getMinutes()),n[1][2]=i.digit(a.getSeconds())),n[0].join("-")+" "+n[1].join(":")):a>=864e5?(a/1e3/60/60/24|0)+"天前":a>=36e5?(a/1e3/60/60|0)+"小时前":a>=18e4?(a/1e3/60|0)+"分钟前":a<0?"未来":"刚刚"},digit:function(e,t){var i="";e=String(e),t=t||2;for(var n=e.length;n/g,">").replace(/'/g,"'").replace(/"/g,""")},event:function(e,n,a){var o=t("body");return a=a||"click",n=i.event[e]=t.extend(!0,i.event[e],n)||{},i.event.UTIL_EVENT_CALLBACK=i.event.UTIL_EVENT_CALLBACK||{},o.off(a,"*["+e+"]",i.event.UTIL_EVENT_CALLBACK[e]),i.event.UTIL_EVENT_CALLBACK[e]=function(){var i=t(this),a=i.attr(e);"function"==typeof n[a]&&n[a].call(this,i)},o.on(a,"*["+e+"]",i.event.UTIL_EVENT_CALLBACK[e]),n}};!function(e,t,i){"$:nomunge";function n(){a=t[l](function(){o.each(function(){var t=e(this),i=t.width(),n=t.height(),a=e.data(this,u);(i!==a.w||n!==a.h)&&t.trigger(c,[a.w=i,a.h=n])}),n()},r[g])}var a,o=e([]),r=e.resize=e.extend(e.resize,{}),l="setTimeout",c="resize",u=c+"-special-event",g="delay",s="throttleWindow";r[g]=250,r[s]=!0,e.event.special[c]={setup:function(){if(!r[s]&&this[l])return!1;var t=e(this);o=o.add(t),e.data(this,u,{w:t.width(),h:t.height()}),1===o.length&&n()},teardown:function(){if(!r[s]&&this[l])return!1;var t=e(this);o=o.not(t),t.removeData(u),o.length||clearTimeout(a)},add:function(t){function n(t,n,o){var r=e(this),l=e.data(this,u)||{};l.w=n!==i?n:r.width(),l.h=o!==i?o:r.height(),a.apply(this,arguments)}if(!r[s]&&this[l])return!1;var a;return e.isFunction(t)?(a=t,n):(a=t.handler,void(t.handler=n))}}}(t,window),e("util",i)}); -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/lay/modules/carousel.js: -------------------------------------------------------------------------------- 1 | /** layui-v2.5.7 MIT License */ 2 | ;layui.define("jquery",function(e){"use strict";var i=layui.$,n=(layui.hint(),layui.device(),{config:{},set:function(e){var n=this;return n.config=i.extend({},n.config,e),n},on:function(e,i){return layui.onevent.call(this,t,e,i)}}),t="carousel",a="layui-this",l=">*[carousel-item]>*",o="layui-carousel-left",r="layui-carousel-right",d="layui-carousel-prev",s="layui-carousel-next",u="layui-carousel-arrow",c="layui-carousel-ind",m=function(e){var t=this;t.config=i.extend({},t.config,n.config,e),t.render()};m.prototype.config={width:"600px",height:"280px",full:!1,arrow:"hover",indicator:"inside",autoplay:!0,interval:3e3,anim:"",trigger:"click",index:0},m.prototype.render=function(){var e=this,n=e.config;n.elem=i(n.elem),n.elem[0]&&(e.elemItem=n.elem.find(l),n.index<0&&(n.index=0),n.index>=e.elemItem.length&&(n.index=e.elemItem.length-1),n.interval<800&&(n.interval=800),n.full?n.elem.css({position:"fixed",width:"100%",height:"100%",zIndex:9999}):n.elem.css({width:n.width,height:n.height}),n.elem.attr("lay-anim",n.anim),e.elemItem.eq(n.index).addClass(a),e.elemItem.length<=1||(e.indicator(),e.arrow(),e.autoplay(),e.events()))},m.prototype.reload=function(e){var n=this;clearInterval(n.timer),n.config=i.extend({},n.config,e),n.render()},m.prototype.prevIndex=function(){var e=this,i=e.config,n=i.index-1;return n<0&&(n=e.elemItem.length-1),n},m.prototype.nextIndex=function(){var e=this,i=e.config,n=i.index+1;return n>=e.elemItem.length&&(n=0),n},m.prototype.addIndex=function(e){var i=this,n=i.config;e=e||1,n.index=n.index+e,n.index>=i.elemItem.length&&(n.index=0)},m.prototype.subIndex=function(e){var i=this,n=i.config;e=e||1,n.index=n.index-e,n.index<0&&(n.index=i.elemItem.length-1)},m.prototype.autoplay=function(){var e=this,i=e.config;i.autoplay&&(clearInterval(e.timer),e.timer=setInterval(function(){e.slide()},i.interval))},m.prototype.arrow=function(){var e=this,n=e.config,t=i(['",'"].join(""));n.elem.attr("lay-arrow",n.arrow),n.elem.find("."+u)[0]&&n.elem.find("."+u).remove(),n.elem.append(t),t.on("click",function(){var n=i(this),t=n.attr("lay-type");e.slide(t)})},m.prototype.indicator=function(){var e=this,n=e.config,t=e.elemInd=i(['
    ',function(){var i=[];return layui.each(e.elemItem,function(e){i.push("")}),i.join("")}(),"
"].join(""));n.elem.attr("lay-indicator",n.indicator),n.elem.find("."+c)[0]&&n.elem.find("."+c).remove(),n.elem.append(t),"updown"===n.anim&&t.css("margin-top",-(t.height()/2)),t.find("li").on("hover"===n.trigger?"mouseover":n.trigger,function(){var t=i(this),a=t.index();a>n.index?e.slide("add",a-n.index):a'; 27 | } else if (i < postion) { 28 | stepDiv += '
'; 29 | } else { 30 | stepDiv += '
' + number + '
'; 31 | } 32 | 33 | // 标题和描述 34 | var title = stepItems[i].title; 35 | var desc = stepItems[i].desc; 36 | if (title || desc) { 37 | stepDiv += '
'; 38 | if (title) { 39 | stepDiv += '
' + title + '
'; 40 | } 41 | if (desc) { 42 | stepDiv += '
' + desc + '
'; 43 | } 44 | stepDiv += '
'; 45 | } 46 | stepDiv += ''; 47 | } 48 | stepDiv += ''; 49 | 50 | $(elem).prepend(stepDiv); 51 | 52 | // 计算每一个条目的宽度 53 | var bfb = 100 / stepItems.length; 54 | $('.step-item').css('width', bfb + '%'); 55 | }; 56 | 57 | var step = { 58 | // 渲染步骤条 59 | render: function (param) { 60 | param.indicator = 'none'; // 不显示指示器 61 | param.arrow = 'always'; // 始终显示箭头 62 | param.autoplay = false; // 关闭自动播放 63 | if (!param.stepWidth) { 64 | param.stepWidth = '400px'; 65 | } 66 | 67 | // 渲染轮播图 68 | carousel.render(param); 69 | 70 | // 渲染步骤条 71 | var stepItems = param.stepItems; 72 | renderDom(param.elem, stepItems, 0); 73 | $('.lay-step').css('width', param.stepWidth); 74 | 75 | //监听轮播切换事件 76 | carousel.on('change(' + param.filter + ')', function (obj) { 77 | $(param.elem).find('.lay-step').remove(); 78 | renderDom(param.elem, stepItems, obj.index); 79 | $('.lay-step').css('width', param.stepWidth); 80 | }); 81 | 82 | // 隐藏左右箭头按钮 83 | $(param.elem).find('.layui-carousel-arrow').css('display', 'none'); 84 | 85 | // 去掉轮播图的背景颜色 86 | $(param.elem).css('background-color', 'transparent'); 87 | }, 88 | // 下一步 89 | next: function (elem) { 90 | $(elem).find('.layui-carousel-arrow[lay-type=add]').trigger('click'); 91 | }, 92 | // 上一步 93 | pre: function (elem) { 94 | $(elem).find('.layui-carousel-arrow[lay-type=sub]').trigger('click'); 95 | } 96 | }; 97 | exports('step', step); 98 | }); 99 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/service/IndexService.java: -------------------------------------------------------------------------------- 1 | package com.perfree.service; 2 | 3 | import cn.hutool.json.JSONArray; 4 | import cn.hutool.json.JSONObject; 5 | import cn.hutool.json.JSONUtil; 6 | import com.perfree.common.DateUtil; 7 | import com.perfree.common.FileSizeUtil; 8 | import org.springframework.stereotype.Service; 9 | 10 | import java.text.ParseException; 11 | import java.util.*; 12 | 13 | /** 14 | * @author Perfree 15 | * @description 首页相关逻辑处理 16 | * @date 2021/4/7 8:42 17 | */ 18 | @Service 19 | public class IndexService { 20 | 21 | /** 22 | * @description 获取状态 23 | * @param data data 24 | * @return java.util.Map 25 | * @author Perfree 26 | */ 27 | public Map getStatus(Object data) { 28 | // 声明结果集 29 | Map result = new HashMap<>(); 30 | // 声明30天文件大小数据容器 31 | List dayFileSizeList = new ArrayList<>(); 32 | // 声明30天文件数量数据容器 33 | List dayFileCountList = new ArrayList<>(); 34 | // 声明30天内日期容器 35 | List dayNumList = new ArrayList<>(); 36 | JSONObject parseObj = JSONUtil.parseObj(data); 37 | JSONArray parseArray = JSONUtil.parseArray(parseObj.get("Fs.FileStats")); 38 | // 剩余空间 39 | result.put("diskFreeSize", FileSizeUtil.GetLength(Long.parseLong(JSONUtil.parseObj(parseObj.get("Sys.DiskInfo")).getStr("free" ,"0")))); 40 | // 总空间 41 | result.put("diskTotalSize", FileSizeUtil.GetLength(Long.parseLong(JSONUtil.parseObj(parseObj.get("Sys.DiskInfo")).getStr("total","0")))); 42 | // 已使用空间 43 | result.put("diskUsedSize", FileSizeUtil.GetLength(Long.parseLong(JSONUtil.parseObj(parseObj.get("Sys.DiskInfo")).getStr("used","0")))); 44 | // 节点 45 | result.put("inodesTotal", JSONUtil.parseObj(parseObj.get("Sys.DiskInfo")).getStr("inodesTotal","0")); 46 | // 节点 47 | result.put("inodesUsed", JSONUtil.parseObj(parseObj.get("Sys.DiskInfo")).getStr("inodesUsed","0")); 48 | // 节点 49 | result.put("inodesFree", JSONUtil.parseObj(parseObj.get("Sys.DiskInfo")).getStr("inodesFree","0")); 50 | long dayFileSize = 0; 51 | long dayFileCount = 0; 52 | for (int i = 0; i < parseArray.size(); i++) { 53 | JSONObject fileStats = JSONUtil.parseObj(parseArray.getStr(i)); 54 | if (fileStats.get("date").equals("all")) { 55 | // 获取总文件大小,数量 56 | result.put("totalFileSize", FileSizeUtil.GetLength(Long.parseLong(fileStats.getStr("totalSize","0")))); 57 | result.put("totalFileCount", fileStats.getStr("fileCount","0")); 58 | } else { 59 | try { 60 | long subDay = DateUtil.daysBetween(DateUtil.StrToDate(fileStats.getStr("date"), "yyyyMMdd"), new Date(), false); 61 | if (subDay <= 30) { 62 | // 获取30天内文件大小,数量 63 | dayFileSize += Long.parseLong(fileStats.getStr("totalSize","0")); 64 | dayFileCount += Long.parseLong(fileStats.getStr("fileCount","0")); 65 | dayFileSizeList.add(FileSizeUtil.GetMBLength(Long.parseLong(fileStats.getStr("totalSize","0")))); 66 | dayFileCountList.add(fileStats.getStr("fileCount","0")); 67 | dayNumList.add(fileStats.getStr("date").substring(6) + "日"); 68 | } 69 | } catch (ParseException e) { 70 | e.printStackTrace(); 71 | } 72 | } 73 | } 74 | result.put("dayFileSize", FileSizeUtil.GetLength(dayFileSize)); 75 | result.put("dayFileCount", dayFileCount); 76 | result.put("dayFileSizeList", dayFileSizeList); 77 | result.put("dayFileCountList", dayFileCountList); 78 | result.put("dayNumList", dayNumList); 79 | return result; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /src/main/resources/templates/peers/list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 控制台 6 | 7 | 8 | 9 | 17 | 18 | 19 |
20 |
21 |
22 |
23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
ID名称组名管理地址访问域名添加时间操作
37 |
38 |
39 |
40 |
41 |
42 | 47 | 50 | 54 | 55 | 56 | 114 | 115 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/form/InstallForm.java: -------------------------------------------------------------------------------- 1 | package com.perfree.form; 2 | 3 | import cn.hutool.core.util.IdUtil; 4 | import com.perfree.model.Peers; 5 | import com.perfree.model.User; 6 | import org.apache.shiro.crypto.hash.Md5Hash; 7 | 8 | import javax.validation.constraints.Email; 9 | import javax.validation.constraints.NotBlank; 10 | import javax.validation.constraints.Size; 11 | import java.io.Serializable; 12 | import java.util.Date; 13 | 14 | /** 15 | * @description 安装时的参数 16 | * @author Perfree 17 | * @date 2021/3/23 11:50 18 | */ 19 | public class InstallForm implements Serializable { 20 | private static final long serialVersionUID = -6474666305055871893L; 21 | @NotBlank(message = "集群名称不能为空且在50字以内") 22 | @Size(max = 50, message = "集群名称不能为空且在50字以内") 23 | private String name; 24 | @Size(max =50, message = "组名称应在50字以内") 25 | private String groupName; 26 | @NotBlank(message = "集群服务地址不能为空且在100字以内") 27 | @Size(max = 100, message = "集群服务地址不能为空且在100字以内") 28 | private String serverAddress; 29 | 30 | @Size(max = 100, message = "访问域名应在50字以内") 31 | private String showAddress; 32 | 33 | @NotBlank(message = "账户不能为空且在30字以内") 34 | @Size(max = 30, message = "账户不能为空且在30字以内") 35 | private String account; 36 | @NotBlank(message = "密码不能为空且在30字以内") 37 | @Size(max = 30, message = "密码不能为空且在30字以内") 38 | private String password; 39 | @NotBlank(message = "用户名不能为空且在30字以内") 40 | @Size(max = 30, message = "用户名不能为空且在30字以内") 41 | private String userName; 42 | @NotBlank(message = "邮箱不能为空") 43 | @Email(message = "请检查邮箱格式是否正确") 44 | private String email; 45 | 46 | public Peers getPeers() { 47 | Peers peers = new Peers(); 48 | peers.setGroupName(this.groupName); 49 | peers.setName(this.name); 50 | peers.setServerAddress(this.serverAddress); 51 | peers.setShowAddress(this.showAddress); 52 | peers.setCreateTime(new Date()); 53 | return peers; 54 | } 55 | 56 | public User getUser() { 57 | User user = new User(); 58 | String uuid = IdUtil.simpleUUID(); 59 | Md5Hash md5Hash = new Md5Hash(this.password, uuid); 60 | user.setPassword(md5Hash.toString()); 61 | user.setCredentialsSalt(uuid); 62 | user.setAccount(this.account); 63 | user.setEmail(this.email); 64 | user.setName(this.userName); 65 | user.setCreateTime(new Date()); 66 | return user; 67 | } 68 | 69 | public String getName() { 70 | return name; 71 | } 72 | 73 | public void setName(String name) { 74 | this.name = name; 75 | } 76 | 77 | public String getGroupName() { 78 | return groupName; 79 | } 80 | 81 | public void setGroupName(String groupName) { 82 | this.groupName = groupName; 83 | } 84 | 85 | public String getServerAddress() { 86 | return serverAddress; 87 | } 88 | 89 | public void setServerAddress(String serverAddress) { 90 | this.serverAddress = serverAddress; 91 | } 92 | 93 | public String getShowAddress() { 94 | return showAddress; 95 | } 96 | 97 | public void setShowAddress(String showAddress) { 98 | this.showAddress = showAddress; 99 | } 100 | 101 | public String getAccount() { 102 | return account; 103 | } 104 | 105 | public void setAccount(String account) { 106 | this.account = account; 107 | } 108 | 109 | public String getPassword() { 110 | return password; 111 | } 112 | 113 | public void setPassword(String password) { 114 | this.password = password; 115 | } 116 | 117 | public String getUserName() { 118 | return userName; 119 | } 120 | 121 | public void setUserName(String userName) { 122 | this.userName = userName; 123 | } 124 | 125 | public String getEmail() { 126 | return email; 127 | } 128 | 129 | public void setEmail(String email) { 130 | this.email = email; 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/main/resources/templates/settings/user.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 个人资料 6 | 7 | 8 | 9 | 24 | 25 | 26 |
27 |
28 |
29 |
30 |
个人资料
31 |
32 |
33 | 34 |
35 | 36 |
37 | 38 |
39 |
不可修改。用于登入名
40 |
41 |
42 | 43 |
44 | 45 |
46 |
16位字符以内
47 |
48 |
49 | 50 |
51 | 52 |
53 |
54 |
55 | 56 |
57 | 58 |
59 |
6-16位,不可包含特殊字符
60 |
61 |
62 | 63 |
64 | 65 |
66 |
6-16位,不可包含特殊字符
67 |
68 |
69 |
70 | 71 | 72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | 81 | 82 | 100 | 101 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/controller/BaseController.java: -------------------------------------------------------------------------------- 1 | package com.perfree.controller; 2 | 3 | import com.perfree.model.Peers; 4 | import com.perfree.model.User; 5 | import org.apache.commons.lang3.StringUtils; 6 | import org.apache.shiro.SecurityUtils; 7 | import org.apache.shiro.subject.Subject; 8 | import org.springframework.beans.BeanUtils; 9 | import org.springframework.stereotype.Controller; 10 | import org.springframework.web.context.request.RequestContextHolder; 11 | import org.springframework.web.context.request.ServletRequestAttributes; 12 | 13 | import javax.servlet.http.HttpServletRequest; 14 | 15 | /** 16 | * @description controller基类 17 | * @author Perfree 18 | * @date 2021/3/23 15:11 19 | */ 20 | @Controller 21 | public class BaseController { 22 | 23 | /** 24 | * @description 获取已登录用户信息 25 | * @return com.perfree.model.User 26 | * @author Perfree 27 | */ 28 | public User getUser(){ 29 | Subject subject = SecurityUtils.getSubject(); 30 | User user=new User(); 31 | BeanUtils.copyProperties(subject.getPrincipals().getPrimaryPrincipal(), user); 32 | return user; 33 | } 34 | 35 | /** 36 | * @description 获取 HttpServletRequest 37 | * @return javax.servlet.http.HttpServletRequest 38 | * @author Perfree 39 | */ 40 | public HttpServletRequest getRequest() { 41 | ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); 42 | if (servletRequestAttributes != null) { 43 | return servletRequestAttributes.getRequest(); 44 | } 45 | return null; 46 | } 47 | 48 | /** 49 | * @description 获取当前用户使用的集群信息 50 | * @return com.perfree.model.Peers 51 | * @author Perfree 52 | */ 53 | public Peers getPeers(){ 54 | return (Peers) getRequest().getSession().getAttribute("peers"); 55 | } 56 | 57 | /** 58 | * @description 获取组名 59 | * @return java.lang.String 60 | * @author Perfree 61 | */ 62 | public String getPeersGroupName(){ 63 | Peers peers = (Peers) getRequest().getSession().getAttribute("peers"); 64 | return peers.getGroupName(); 65 | } 66 | 67 | /** 68 | * @description 获取集群完整管理地址 69 | * @return java.lang.String 70 | * @author Perfree 71 | */ 72 | public String getPeersUrl(){ 73 | Peers peers = (Peers) getRequest().getSession().getAttribute("peers"); 74 | if(!StringUtils.isBlank(peers.getGroupName())) { 75 | return peers.getServerAddress() + "/" + peers.getGroupName(); 76 | } 77 | return peers.getServerAddress(); 78 | } 79 | 80 | /** 81 | * @description 获取访问域名 82 | * @return java.lang.String 83 | * @author Perfree 84 | */ 85 | public String getShowUrl(){ 86 | Peers peers = (Peers) getRequest().getSession().getAttribute("peers"); 87 | String showAddress = ""; 88 | if(StringUtils.isBlank(peers.getShowAddress())){ 89 | if(StringUtils.isBlank(peers.getGroupName())){ 90 | showAddress = peers.getServerAddress(); 91 | }else{ 92 | showAddress = peers.getServerAddress() + "/" + peers.getGroupName(); 93 | } 94 | }else{ 95 | if(StringUtils.isBlank(peers.getGroupName())){ 96 | showAddress = peers.getShowAddress(); 97 | }else{ 98 | showAddress = peers.getShowAddress() + "/" + peers.getGroupName(); 99 | } 100 | } 101 | return showAddress; 102 | } 103 | 104 | /** 105 | * @description 获取回显域名(不带url) 106 | * @return java.lang.String 107 | * @author Perfree 108 | */ 109 | public String getUploadShowUrl(){ 110 | Peers peers = (Peers) getRequest().getSession().getAttribute("peers"); 111 | String showAddress = ""; 112 | if(StringUtils.isBlank(peers.getShowAddress())){ 113 | showAddress += peers.getServerAddress(); 114 | }else{ 115 | showAddress += peers.getShowAddress(); 116 | } 117 | return showAddress; 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/controller/FileController.java: -------------------------------------------------------------------------------- 1 | package com.perfree.controller; 2 | 3 | import com.perfree.common.ResponseBean; 4 | import com.perfree.service.FileService; 5 | import org.springframework.beans.factory.annotation.Autowired; 6 | import org.springframework.stereotype.Controller; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.ResponseBody; 9 | 10 | import javax.servlet.http.HttpServletRequest; 11 | import javax.servlet.http.HttpServletResponse; 12 | import java.io.BufferedInputStream; 13 | import java.io.IOException; 14 | import java.net.URL; 15 | import java.net.URLEncoder; 16 | 17 | /** 18 | * @description 文件列表相关controller 19 | * @author Perfree 20 | * @date 2021/4/7 11:53 21 | */ 22 | @Controller 23 | public class FileController extends BaseController { 24 | 25 | @Autowired 26 | private FileService fileService; 27 | 28 | /** 29 | * @description 文件列表 30 | * @return java.lang.String 31 | * @author Perfree 32 | */ 33 | @RequestMapping("/file") 34 | public String index() { 35 | return "file/file"; 36 | } 37 | 38 | /** 39 | * @description 获取一级目录 40 | * @return com.perfree.common.ResponseBean 41 | * @author Perfree 42 | */ 43 | @RequestMapping("/file/getParentFile") 44 | @ResponseBody 45 | public ResponseBean getParentFile() { 46 | return ResponseBean.success(fileService.getParentFile(getPeersGroupName(),getPeersUrl())); 47 | } 48 | 49 | /** 50 | * @description 指定目录获取 51 | * @param dir dir 52 | * @return com.perfree.common.ResponseBean 53 | * @author Perfree 54 | */ 55 | @RequestMapping("/file/getDirFile") 56 | @ResponseBody 57 | public ResponseBean getDirFile(String dir) { 58 | return ResponseBean.success(fileService.getDirFile(getShowUrl(),getPeersUrl(), dir)); 59 | } 60 | 61 | /** 62 | * @description 删除文件 63 | * @param md5 md5 64 | * @return com.perfree.common.ResponseBean 65 | * @author Perfree 66 | */ 67 | @RequestMapping("/file/deleteFile") 68 | @ResponseBody 69 | public ResponseBean deleteFile(String md5) { 70 | if (fileService.deleteFile(getPeersUrl(),md5)) { 71 | return ResponseBean.success(); 72 | } 73 | return ResponseBean.fail("删除失败"); 74 | } 75 | 76 | /** 77 | * @description 文件信息 78 | * @param md5 md5 79 | * @return com.perfree.common.ResponseBean 80 | * @author Perfree 81 | */ 82 | @RequestMapping("/file/details") 83 | @ResponseBody 84 | public ResponseBean details(String md5) { 85 | return fileService.details(getPeersUrl(),md5); 86 | } 87 | 88 | /** 89 | * @description 下载文件 90 | * @param path path 91 | * @param name name 92 | * @param request request 93 | * @param response response 94 | * @author Perfree 95 | */ 96 | @RequestMapping("/file/downloadFile") 97 | @ResponseBody 98 | public void downloadFile(String path, String name, HttpServletRequest request, HttpServletResponse response) { 99 | response.setHeader("Content-Disposition", "attachment;filename=" + name); 100 | response.setContentType("application/octet-stream"); 101 | BufferedInputStream in = null; 102 | try { 103 | URL url = new URL(getPeersUrl()+"/"+path+"/"+name); 104 | in = new BufferedInputStream(url.openStream()); 105 | response.reset(); 106 | response.setContentType("application/octet-stream"); 107 | response.setHeader("Content-Disposition","attachment;filename=" + URLEncoder.encode(name, "UTF-8")); 108 | // 将网络输入流转换为输出流 109 | int i; 110 | while ((i = in.read()) != -1) { 111 | response.getOutputStream().write(i); 112 | } 113 | response.getOutputStream().close(); 114 | } catch (IOException e) { 115 | e.printStackTrace(); 116 | }finally { 117 | try { 118 | if (in != null){ 119 | in.close(); 120 | } 121 | } catch (IOException e) { 122 | e.printStackTrace(); 123 | } 124 | } 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /src/main/resources/static/lib/layui-v2.5.6/layui/lay/modules/laypage.js: -------------------------------------------------------------------------------- 1 | /** layui-v2.5.7 MIT License */ 2 | ;layui.define(function(e){"use strict";var a=document,t="getElementById",n="getElementsByTagName",i="laypage",r="layui-disabled",u=function(e){var a=this;a.config=e||{},a.config.index=++s.index,a.render(!0)};u.prototype.type=function(){var e=this.config;if("object"==typeof e.elem)return void 0===e.elem.length?2:3},u.prototype.view=function(){var e=this,a=e.config,t=a.groups="groups"in a?0|a.groups:5;a.layout="object"==typeof a.layout?a.layout:["prev","page","next"],a.count=0|a.count,a.curr=0|a.curr||1,a.limits="object"==typeof a.limits?a.limits:[10,20,30,40,50],a.limit=0|a.limit||10,a.pages=Math.ceil(a.count/a.limit)||1,a.curr>a.pages&&(a.curr=a.pages),t<0?t=1:t>a.pages&&(t=a.pages),a.prev="prev"in a?a.prev:"上一页",a.next="next"in a?a.next:"下一页";var n=a.pages>t?Math.ceil((a.curr+(t>1?1:0))/(t>0?t:1)):1,i={prev:function(){return a.prev?''+a.prev+"":""}(),page:function(){var e=[];if(a.count<1)return"";n>1&&a.first!==!1&&0!==t&&e.push(''+(a.first||1)+"");var i=Math.floor((t-1)/2),r=n>1?a.curr-i:1,u=n>1?function(){var e=a.curr+(t-i-1);return e>a.pages?a.pages:e}():t;for(u-r2&&e.push('');r<=u;r++)r===a.curr?e.push('"+r+""):e.push(''+r+"");return a.pages>t&&a.pages>u&&a.last!==!1&&(u+1…'),0!==t&&e.push(''+(a.last||a.pages)+"")),e.join("")}(),next:function(){return a.next?''+a.next+"":""}(),count:'共 '+a.count+" 条",limit:function(){var e=['"}(),refresh:['','',""].join(""),skip:function(){return['到第','','页',""].join("")}()};return['
',function(){var e=[];return layui.each(a.layout,function(a,t){i[t]&&e.push(i[t])}),e.join("")}(),"
"].join("")},u.prototype.jump=function(e,a){if(e){var t=this,i=t.config,r=e.children,u=e[n]("button")[0],l=e[n]("input")[0],p=e[n]("select")[0],c=function(){var e=0|l.value.replace(/\s|\D/g,"");e&&(i.curr=e,t.render())};if(a)return c();for(var o=0,y=r.length;oi.pages||(i.curr=e,t.render())});p&&s.on(p,"change",function(){var e=this.value;i.curr*e>i.count&&(i.curr=Math.ceil(i.count/e)),i.limit=e,t.render()}),u&&s.on(u,"click",function(){c()})}},u.prototype.skip=function(e){if(e){var a=this,t=e[n]("input")[0];t&&s.on(t,"keyup",function(t){var n=this.value,i=t.keyCode;/^(37|38|39|40)$/.test(i)||(/\D/.test(n)&&(this.value=n.replace(/\D/,"")),13===i&&a.jump(e,!0))})}},u.prototype.render=function(e){var n=this,i=n.config,r=n.type(),u=n.view();2===r?i.elem&&(i.elem.innerHTML=u):3===r?i.elem.html(u):a[t](i.elem)&&(a[t](i.elem).innerHTML=u),i.jump&&i.jump(i,e);var s=a[t]("layui-laypage-"+i.index);n.jump(s),i.hash&&!e&&(location.hash="!"+i.hash+"="+i.curr),n.skip(s)};var s={render:function(e){var a=new u(e);return a.index},index:layui.laypage?layui.laypage.index+1e4:0,on:function(e,a,t){return e.attachEvent?e.attachEvent("on"+a,function(a){a.target=a.srcElement,t.call(e,a)}):e.addEventListener(a,t,!1),this}};e(i,s)}); -------------------------------------------------------------------------------- /src/main/resources/templates/layout/sider.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 8 | 11 |
12 | 13 | 80 |
81 |
82 | 83 | -------------------------------------------------------------------------------- /src/main/resources/templates/file/file.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 文件列表 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
14 |
15 |
16 |
17 |
18 | 21 |
22 |
23 |
24 | 25 | 26 | 27 |
28 |
29 |
30 |
31 |
    32 |
  • 文件名
  • 33 |
  • 大小
  • 34 |
  • 创建日期
  • 35 |
  • 操作
  • 36 |
37 |
38 |
39 | 40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | -------------------------------------------------------------------------------- /src/main/resources/static/js/kit.js: -------------------------------------------------------------------------------- 1 | (function($){ 2 | var kit = function(){} 3 | kit.prototype = { 4 | getIconName: function(suffix) { 5 | var iconName; 6 | switch(suffix) { 7 | //图片 8 | case "jpg": 9 | iconName = "img";break; 10 | case "png": 11 | iconName = "img";break; 12 | case "jpeg": 13 | iconName = "img";break; 14 | case "gif": 15 | iconName = "img";break; 16 | case "psd": 17 | iconName = "img";break; 18 | //压缩包 19 | case "rar": 20 | iconName = "zip";break; 21 | case "zip": 22 | iconName = "zip";break; 23 | case "7z": 24 | iconName = "zip";break; 25 | case "tar": 26 | iconName = "zip";break; 27 | case "gz": 28 | iconName = "zip";break; 29 | //ppt 30 | case "ppt": 31 | iconName = "ppt";break; 32 | case "pptx": 33 | iconName = "ppt";break; 34 | //pdf 35 | case "pdf": 36 | iconName = "pdf";break; 37 | //word 38 | case "doc": 39 | iconName = "word";break; 40 | case "docx": 41 | iconName = "word";break; 42 | //excel 43 | case "xls": 44 | iconName = "excel";break; 45 | case "xlsx": 46 | iconName = "excel";break; 47 | //歌曲 48 | case "wave": 49 | iconName = "music";break; 50 | case "mp3": 51 | iconName = "music";break; 52 | case "mpeg-4": 53 | iconName = "music";break; 54 | case "aac": 55 | iconName = "music";break; 56 | case "mpeg": 57 | iconName = "music";break; 58 | //文本 59 | case "txt": 60 | iconName = "txt";break; 61 | //视频 62 | case "avi": 63 | iconName = "video";break; 64 | case "mp4": 65 | iconName = "video";break; 66 | case "3gp": 67 | iconName = "video";break; 68 | case "rmvb": 69 | iconName = "video";break; 70 | case "flv": 71 | iconName = "video";break; 72 | //exe 73 | case "exe": 74 | iconName = "exe";break; 75 | //脚本文件 76 | case "sh": 77 | iconName = "shell";break; 78 | case "bat": 79 | iconName = "shell";break; 80 | //java 81 | case "java": 82 | iconName = "java";break; 83 | //go 84 | case "go": 85 | iconName = "go";break; 86 | //css 87 | case "css": 88 | iconName = "css";break; 89 | //html 90 | case "html": 91 | iconName = "html";break; 92 | //js 93 | case "js": 94 | iconName = "js";break; 95 | //python 96 | case "py": 97 | iconName = "python";break; 98 | //其他 99 | default: 100 | iconName = "other";break; 101 | } 102 | return iconName; 103 | }, 104 | getFileType: function(suffix) { 105 | var fileType; 106 | if(suffix == "jpg" ||suffix == "png" ||suffix == "jpeg" ||suffix == "gif" ||suffix == "psd"){ 107 | fileType = "image"; 108 | }else if(suffix == "rar" ||suffix == "zip" ||suffix == "7z" ||suffix == "tar" ||suffix == "gz"){ 109 | fileType = "zip"; 110 | }else if(suffix == "ppt" ||suffix == "pptx"){ 111 | fileType = "ppt"; 112 | }else if(suffix == "doc" ||suffix == "docx"){ 113 | fileType = "word"; 114 | }else if(suffix == "xls" ||suffix == "xlsx"){ 115 | fileType = "excel"; 116 | }else if(suffix == "wave" ||suffix == "mp3" ||suffix == "mpeg-4" ||suffix == "aac" ||suffix == "mpeg"){ 117 | fileType = "song"; 118 | }else if(suffix == "txt"){ 119 | fileType = "txt"; 120 | }else if(suffix == "avi" ||suffix == "mp4" ||suffix == "3gp" ||suffix == "rmvb" ||suffix == "flv"){ 121 | fileType = "video"; 122 | }else{ 123 | fileType = "other"; 124 | } 125 | return fileType; 126 | } 127 | } 128 | window.kit = new kit(); 129 | })(window.jQuery); -------------------------------------------------------------------------------- /src/main/resources/static/lib/template-web/template-web.js: -------------------------------------------------------------------------------- 1 | !function(){function a(a){return a.replace(t,"").replace(u,",").replace(v,"").replace(w,"").replace(x,"").split(/^$|,+/)}function b(a){return"'"+a.replace(/('|\\)/g,"\\$1").replace(/\r/g,"\\r").replace(/\n/g,"\\n")+"'"}function c(c,d){function e(a){return m+=a.split(/\n/).length-1,k&&(a=a.replace(/[\n\r\t\s]+/g," ").replace(//g,"")),a&&(a=s[1]+b(a)+s[2]+"\n"),a}function f(b){var c=m;if(j?b=j(b,d):g&&(b=b.replace(/\n/g,function(){return m++,"$line="+m+";"})),0===b.indexOf("=")){var e=l&&!/^=[=#]/.test(b);if(b=b.replace(/^=[=#]?|[\s;]*$/g,""),e){var f=b.replace(/\s*\([^\)]+\)/,"");n[f]||/^(include|print)$/.test(f)||(b="$escape("+b+")")}else b="$string("+b+")";b=s[1]+b+s[2]}return g&&(b="$line="+c+";"+b),r(a(b),function(a){if(a&&!p[a]){var b;b="print"===a?u:"include"===a?v:n[a]?"$utils."+a:o[a]?"$helpers."+a:"$data."+a,w+=a+"="+b+",",p[a]=!0}}),b+"\n"}var g=d.debug,h=d.openTag,i=d.closeTag,j=d.parser,k=d.compress,l=d.escape,m=1,p={$data:1,$filename:1,$utils:1,$helpers:1,$out:1,$line:1},q="".trim,s=q?["$out='';","$out+=",";","$out"]:["$out=[];","$out.push(",");","$out.join('')"],t=q?"$out+=text;return $out;":"$out.push(text);",u="function(){var text=''.concat.apply('',arguments);"+t+"}",v="function(filename,data){data=data||$data;var text=$utils.$include(filename,data,$filename);"+t+"}",w="'use strict';var $utils=this,$helpers=$utils.$helpers,"+(g?"$line=0,":""),x=s[0],y="return new String("+s[3]+");";r(c.split(h),function(a){a=a.split(i);var b=a[0],c=a[1];1===a.length?x+=e(b):(x+=f(b),c&&(x+=e(c)))});var z=w+x+y;g&&(z="try{"+z+"}catch(e){throw {filename:$filename,name:'Render Error',message:e.message,line:$line,source:"+b(c)+".split(/\\n/)[$line-1].replace(/^[\\s\\t]+/,'')};}");try{var A=new Function("$data","$filename",z);return A.prototype=n,A}catch(B){throw B.temp="function anonymous($data,$filename) {"+z+"}",B}}var d=function(a,b){return"string"==typeof b?q(b,{filename:a}):g(a,b)};d.version="3.0.0",d.config=function(a,b){e[a]=b};var e=d.defaults={openTag:"<%",closeTag:"%>",escape:!0,cache:!0,compress:!1,parser:null},f=d.cache={};d.render=function(a,b){return q(a,b)};var g=d.renderFile=function(a,b){var c=d.get(a)||p({filename:a,name:"Render Error",message:"Template not found"});return b?c(b):c};d.get=function(a){var b;if(f[a])b=f[a];else if("object"==typeof document){var c=document.getElementById(a);if(c){var d=(c.value||c.innerHTML).replace(/^\s*|\s*$/g,"");b=q(d,{filename:a})}}return b};var h=function(a,b){return"string"!=typeof a&&(b=typeof a,"number"===b?a+="":a="function"===b?h(a.call(a)):""),a},i={"<":"<",">":">",'"':""","'":"'","&":"&"},j=function(a){return i[a]},k=function(a){return h(a).replace(/&(?![\w#]+;)|[<>"']/g,j)},l=Array.isArray||function(a){return"[object Array]"==={}.toString.call(a)},m=function(a,b){var c,d;if(l(a))for(c=0,d=a.length;d>c;c++)b.call(a,a[c],c,a);else for(c in a)b.call(a,a[c],c)},n=d.utils={$helpers:{},$include:g,$string:h,$escape:k,$each:m};d.helper=function(a,b){o[a]=b};var o=d.helpers=n.$helpers;d.onerror=function(a){var b="Template Error\n\n";for(var c in a)b+="<"+c+">\n"+a[c]+"\n\n";"object"==typeof console&&console.error(b)};var p=function(a){return d.onerror(a),function(){return"{Template Error}"}},q=d.compile=function(a,b){function d(c){try{return new i(c,h)+""}catch(d){return b.debug?p(d)():(b.debug=!0,q(a,b)(c))}}b=b||{};for(var g in e)void 0===b[g]&&(b[g]=e[g]);var h=b.filename;try{var i=c(a,b)}catch(j){return j.filename=h||"anonymous",j.name="Syntax Error",p(j)}return d.prototype=i.prototype,d.toString=function(){return i.toString()},h&&b.cache&&(f[h]=d),d},r=n.$each,s="break,case,catch,continue,debugger,default,delete,do,else,false,finally,for,function,if,in,instanceof,new,null,return,switch,this,throw,true,try,typeof,var,void,while,with,abstract,boolean,byte,char,class,const,double,enum,export,extends,final,float,goto,implements,import,int,interface,long,native,package,private,protected,public,short,static,super,synchronized,throws,transient,volatile,arguments,let,yield,undefined",t=/\/\*[\w\W]*?\*\/|\/\/[^\n]*\n|\/\/[^\n]*$|"(?:[^"\\]|\\[\w\W])*"|'(?:[^'\\]|\\[\w\W])*'|[\s\t\n]*\.[\s\t\n]*[$\w\.]+/g,u=/[^\w$]+/g,v=new RegExp(["\\b"+s.replace(/,/g,"\\b|\\b")+"\\b"].join("|"),"g"),w=/^\d[^,]*|,\d[^,]*/g,x=/^,+|,+$/g;e.openTag="{{",e.closeTag="}}";var y=function(a,b){var c=b.split(":"),d=c.shift(),e=c.join(":")||"";return e&&(e=", "+e),"$helpers."+d+"("+a+e+")"};e.parser=function(a,b){a=a.replace(/^\s/,"");var c=a.split(" "),e=c.shift(),f=c.join(" ");switch(e){case"if":a="if("+f+"){";break;case"else":c="if"===c.shift()?" if("+c.join(" ")+")":"",a="}else"+c+"{";break;case"/if":a="}";break;case"each":var g=c[0]||"$data",h=c[1]||"as",i=c[2]||"$value",j=c[3]||"$index",k=i+","+j;"as"!==h&&(g="[]"),a="$each("+g+",function("+k+"){";break;case"/each":a="});";break;case"echo":a="print("+f+");";break;case"print":case"include":a=e+"("+c.join(",")+");";break;default:if(-1!==f.indexOf("|")){var l=b.escape;0===a.indexOf("#")&&(a=a.substr(1),l=!1);for(var m=0,n=a.split("|"),o=n.length,p=l?"$escape":"$string",q=p+"("+n[m++]+")";o>m;m++)q=y(q,n[m]);a="=#"+q}else a=d.helpers[e]?"=#"+e+"("+c.join(",")+");":"="+a}return a},"function"==typeof define?define(function(){return d}):"undefined"!=typeof exports?module.exports=d:this.template=d}(); 2 | -------------------------------------------------------------------------------- /src/main/java/com/perfree/common/UploadUtils.java: -------------------------------------------------------------------------------- 1 | package com.perfree.common; 2 | 3 | import cn.hutool.http.HttpUtil; 4 | import cn.hutool.json.JSONUtil; 5 | import com.perfree.form.GoFastDfsUploadResult; 6 | import org.apache.http.client.config.RequestConfig; 7 | import org.apache.http.client.methods.CloseableHttpResponse; 8 | import org.apache.http.client.methods.HttpPost; 9 | import org.apache.http.entity.ContentType; 10 | import org.apache.http.entity.mime.HttpMultipartMode; 11 | import org.apache.http.entity.mime.MultipartEntityBuilder; 12 | import org.apache.http.impl.client.CloseableHttpClient; 13 | import org.apache.http.impl.client.HttpClientBuilder; 14 | import org.apache.http.util.EntityUtils; 15 | import org.springframework.web.multipart.MultipartFile; 16 | 17 | import java.io.File; 18 | import java.io.IOException; 19 | import java.nio.charset.StandardCharsets; 20 | import java.util.HashMap; 21 | import java.util.Map; 22 | 23 | /** 24 | * @author Perfree 25 | * @description 文件上传工具类 26 | * @date 2021/4/8 8:42 27 | */ 28 | public class UploadUtils { 29 | 30 | /** 31 | * 文件上传 32 | * 33 | * @param url 服务器地址 34 | * @param path 路径 35 | * @param scene 场景 36 | * @param multipartFile 文件 37 | * @param showUrl 回显url 38 | * @return AjaxResult 39 | */ 40 | public static ResponseBean upload(String tempPath, String url, String path, String scene, MultipartFile multipartFile, String showUrl) { 41 | File parentFile = new File(tempPath); 42 | if (parentFile.exists()) { 43 | if (!parentFile.isDirectory()) { 44 | return ResponseBean.fail("临时目录不是一个文件夹"); 45 | } 46 | } else { 47 | parentFile.mkdir(); 48 | } 49 | File file = UploadUtils.getFile(multipartFile, tempPath); 50 | Map map = new HashMap<>(16); 51 | map.put("output", "json"); 52 | map.put("path", path); 53 | map.put("scene", scene); 54 | map.put("file", file); 55 | try { 56 | String post = HttpUtil.post(url, map); 57 | GoFastDfsUploadResult goFastDfsResult = JSONUtil.toBean(post, GoFastDfsUploadResult.class); 58 | //替换url 59 | goFastDfsResult.setUrl(showUrl + goFastDfsResult.getPath()); 60 | return ResponseBean.success(goFastDfsResult); 61 | } catch (Exception e) { 62 | file.delete(); 63 | return ResponseBean.fail("上传出错"); 64 | } 65 | } 66 | 67 | /** 68 | * 不用hutool方式,采用httpClient方式上传(hutool和okhttp上传大文件都会有内存溢出的报错) 69 | * 70 | * @param file file 71 | * @param path path 72 | * @param showUrl showUrl 73 | * @return ResponseBean 74 | */ 75 | public static ResponseBean upload(MultipartFile file, String path, String showUrl) { 76 | try { 77 | CloseableHttpClient httpClient = HttpClientBuilder.create().build(); 78 | CloseableHttpResponse httpResponse = null; 79 | RequestConfig requestConfig = RequestConfig.custom() 80 | .setConnectTimeout(200000) 81 | .setSocketTimeout(2000000) 82 | .build(); 83 | HttpPost httpPost = new HttpPost(path); 84 | httpPost.setConfig(requestConfig); 85 | MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create() 86 | .setMode(HttpMultipartMode.BROWSER_COMPATIBLE) 87 | .setCharset(StandardCharsets.UTF_8) 88 | .addTextBody("output", "json") 89 | .addBinaryBody("file", file.getInputStream(), 90 | ContentType.DEFAULT_BINARY, file.getOriginalFilename()); 91 | httpPost.setEntity(multipartEntityBuilder.build()); 92 | httpResponse = httpClient.execute(httpPost); 93 | 94 | if (httpResponse.getStatusLine().getStatusCode() == 200) { 95 | String respStr = EntityUtils.toString(httpResponse.getEntity()); 96 | GoFastDfsUploadResult goFastDfsResult = JSONUtil.toBean(respStr, GoFastDfsUploadResult.class); 97 | //替换url 98 | goFastDfsResult.setUrl(showUrl + goFastDfsResult.getPath()); 99 | return ResponseBean.success(goFastDfsResult); 100 | } 101 | httpClient.close(); 102 | httpResponse.close(); 103 | return ResponseBean.fail("上传出错"); 104 | } catch (Exception e) { 105 | return ResponseBean.fail("上传出错"); 106 | } 107 | } 108 | 109 | 110 | /** 111 | * multipartFile转file 112 | * 113 | * @param multipartFile multipartFile 114 | * @return File 115 | */ 116 | private static File getFile(MultipartFile multipartFile, String tempPath) { 117 | String fileName = multipartFile.getOriginalFilename(); 118 | File file = new File(tempPath + fileName); 119 | try { 120 | multipartFile.transferTo(file.getAbsoluteFile()); 121 | } catch (IOException e) { 122 | e.printStackTrace(); 123 | } 124 | return file; 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /src/main/resources/static/js/upload.js: -------------------------------------------------------------------------------- 1 | var xhrOnProgress = function (fun) { 2 | xhrOnProgress.onprogress = fun; //绑定监听 3 | //使用闭包实现监听绑 4 | return function () { 5 | //通过$.ajaxSettings.xhr();获得XMLHttpRequest对象 6 | var xhr = $.ajaxSettings.xhr(); 7 | //判断监听函数是否为函数 8 | if (typeof xhrOnProgress.onprogress !== 'function') 9 | return xhr; 10 | //如果有监听函数并且xhr对象支持绑定时就把监听函数绑定上去 11 | if (xhrOnProgress.onprogress && xhr.upload) { 12 | xhr.upload.onprogress = xhrOnProgress.onprogress; 13 | } 14 | return xhr; 15 | } 16 | } 17 | var count = 0; 18 | layui.use(['upload', 'element'], function () { 19 | var $ = layui.jquery, upload = layui.upload, element = layui.element; 20 | //多文件上传 21 | var demoListView = $('#moreFileList'), uploadListIns = upload.render({ 22 | elem: '#fileList', 23 | url: '/file/upload/moreFileUpload', 24 | accept: 'file', 25 | multiple: true, 26 | auto: false, 27 | bindAction: '#fileListAction', 28 | xhr: xhrOnProgress, 29 | progress: function (value, obj) { 30 | //上传进度回调 value进度值 31 | $("#moreFileList").find('.layui-progress ').each(function () { 32 | if ($(this).attr("file") === obj.name) { 33 | var progressBarName = $(this).attr("lay-filter"); 34 | var percent = ((value.loaded / value.total) * 100).toFixed(2); 35 | if (percent === 100.00) { 36 | percent = 100; 37 | } 38 | element.progress(progressBarName, percent + '%'); 39 | } 40 | }) 41 | 42 | }, 43 | choose: function (obj) { 44 | //将每次选择的文件追加到文件队列 45 | var files = this.files = obj.pushFile(); 46 | //读取本地文件 47 | demoListView.html(" "); 48 | for (var key in files) { 49 | count++; 50 | var tr = $(['', 51 | '' + files[key].name + '', 52 | '' + (files[key].size / 1014).toFixed(1) + 'kb', 53 | '等待上传', 54 | '' + 55 | '
' + 56 | '
' + 57 | '
' + 58 | '', 59 | '', 60 | '', 61 | '', 62 | '', 63 | ''].join('')); 64 | //单个重传 65 | tr.find('.more-file-reload').on('click', function () { 66 | obj.upload(key, files[key]); 67 | }); 68 | //删除 69 | tr.find('.more-file-delete').on('click', function () { 70 | delete files[key]; 71 | tr.remove(); 72 | uploadListIns.config.elem.next()[0].value = ''; 73 | }); 74 | demoListView.append(tr); 75 | element.render('progress'); 76 | } 77 | ; 78 | }, before: function (obj) { 79 | var scene = $("#scene").val(); 80 | var path = $("#path").val(); 81 | var showUrl = $("#showUrl").val(); 82 | this.data = {'scene': scene, 'path': path, 'showUrl': showUrl}; 83 | }, done: function (res, index, upload) { 84 | //上传成功 85 | if (res.code === 200) { 86 | var tr = demoListView.find('tr#upload-' + index), tds = tr.children(); 87 | tds.eq(2).html('上传成功'); 88 | tds.eq(3).children(".layui-progress").children(".layui-progress-bar").attr("lay-percent", "100%"); 89 | //清空操作 90 | tds.eq(4).html(''); 91 | tds.eq(4).html('查看链接'); 92 | //删除文件队列已经上传成功的文件 93 | return delete this.files[index]; 94 | } else { 95 | var tr = demoListView.find('tr#upload-' + index), tds = tr.children(); 96 | tds.eq(2).html('上传失败'); 97 | //显示重传 98 | tds.eq(4).find('.more-file-reload').removeClass('layui-hide'); 99 | } 100 | this.error(index, upload); 101 | }, error: function (index, upload) { 102 | var tr = demoListView.find('tr#upload-' + index), tds = tr.children(); 103 | tds.eq(2).html('上传失败'); 104 | //显示重传 105 | tds.eq(4).find('.more-file-reload').removeClass('layui-hide'); 106 | } 107 | }); 108 | }) 109 | 110 | function showUrl(url) { 111 | layer.confirm('点击访问:
' + url + '', { 112 | btn: ['确定'], title: '查看链接' 113 | }, function (index, layero) { 114 | layer.close(index); 115 | }); 116 | } -------------------------------------------------------------------------------- /.mvn/wrapper/MavenWrapperDownloader.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2007-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | import java.net.*; 18 | import java.io.*; 19 | import java.nio.channels.*; 20 | import java.util.Properties; 21 | 22 | public class MavenWrapperDownloader { 23 | 24 | private static final String WRAPPER_VERSION = "0.5.6"; 25 | /** 26 | * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. 27 | */ 28 | private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" 29 | + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; 30 | 31 | /** 32 | * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to 33 | * use instead of the default one. 34 | */ 35 | private static final String MAVEN_WRAPPER_PROPERTIES_PATH = 36 | ".mvn/wrapper/maven-wrapper.properties"; 37 | 38 | /** 39 | * Path where the maven-wrapper.jar will be saved to. 40 | */ 41 | private static final String MAVEN_WRAPPER_JAR_PATH = 42 | ".mvn/wrapper/maven-wrapper.jar"; 43 | 44 | /** 45 | * Name of the property which should be used to override the default download url for the wrapper. 46 | */ 47 | private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; 48 | 49 | public static void main(String args[]) { 50 | System.out.println("- Downloader started"); 51 | File baseDirectory = new File(args[0]); 52 | System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); 53 | 54 | // If the maven-wrapper.properties exists, read it and check if it contains a custom 55 | // wrapperUrl parameter. 56 | File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); 57 | String url = DEFAULT_DOWNLOAD_URL; 58 | if (mavenWrapperPropertyFile.exists()) { 59 | FileInputStream mavenWrapperPropertyFileInputStream = null; 60 | try { 61 | mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); 62 | Properties mavenWrapperProperties = new Properties(); 63 | mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); 64 | url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); 65 | } catch (IOException e) { 66 | System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); 67 | } finally { 68 | try { 69 | if (mavenWrapperPropertyFileInputStream != null) { 70 | mavenWrapperPropertyFileInputStream.close(); 71 | } 72 | } catch (IOException e) { 73 | // Ignore ... 74 | } 75 | } 76 | } 77 | System.out.println("- Downloading from: " + url); 78 | 79 | File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); 80 | if (!outputFile.getParentFile().exists()) { 81 | if (!outputFile.getParentFile().mkdirs()) { 82 | System.out.println( 83 | "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); 84 | } 85 | } 86 | System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); 87 | try { 88 | downloadFileFromURL(url, outputFile); 89 | System.out.println("Done"); 90 | System.exit(0); 91 | } catch (Throwable e) { 92 | System.out.println("- Error downloading"); 93 | e.printStackTrace(); 94 | System.exit(1); 95 | } 96 | } 97 | 98 | private static void downloadFileFromURL(String urlString, File destination) throws Exception { 99 | if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { 100 | String username = System.getenv("MVNW_USERNAME"); 101 | char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); 102 | Authenticator.setDefault(new Authenticator() { 103 | @Override 104 | protected PasswordAuthentication getPasswordAuthentication() { 105 | return new PasswordAuthentication(username, password); 106 | } 107 | }); 108 | } 109 | URL website = new URL(urlString); 110 | ReadableByteChannel rbc; 111 | rbc = Channels.newChannel(website.openStream()); 112 | FileOutputStream fos = new FileOutputStream(destination); 113 | fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); 114 | fos.close(); 115 | rbc.close(); 116 | } 117 | 118 | } 119 | --------------------------------------------------------------------------------