文件管理器 ui

This commit is contained in:
pushuo 2022-07-11 17:25:10 +08:00
parent e0cb232909
commit ff26e62d06
8 changed files with 478 additions and 21 deletions

View File

@ -0,0 +1,15 @@
<?php
namespace Beike\Admin\Http\Controllers;
use Illuminate\Http\Request;
class FilemanagerController extends Controller
{
public function index()
{
$data = [];
return view('admin::pages.filemanager.index', $data);
}
}

View File

@ -17,6 +17,8 @@ Route::prefix('admin')
Route::Resource('files', \Beike\Admin\Http\Controllers\FileController::class);
Route::Resource('filemanager', \Beike\Admin\Http\Controllers\FilemanagerController::class);
Route::Resource('customers', \Beike\Admin\Http\Controllers\CustomerController::class);
Route::resource('customers.addresses', \Beike\Admin\Http\Controllers\AddressController::class);
Route::resource('countries.zones', \Beike\Admin\Http\Controllers\ZoneController::class);

View File

@ -0,0 +1,98 @@
[v-cloak] {
display: none;
}
body.page-filemanager {
height: 100vh;
overflow: hidden;
}
body.page-filemanager .filemanager-wrap {
display: flex;
height: 100vh;
position: relative;
}
body.page-filemanager .filemanager-wrap .filemanager-navbar {
width: 20%;
}
body.page-filemanager .filemanager-wrap .filemanager-divider {
position: absolute;
top: 0;
height: 100%;
left: 20%;
width: 10px;
display: flex;
justify-content: center;
align-items: center;
cursor: move;
}
body.page-filemanager .filemanager-wrap .filemanager-divider:hover {
background: red;
}
body.page-filemanager .filemanager-wrap .filemanager-content {
width: 80%;
padding-left: 10px;
display: flex;
flex-direction: column;
justify-content: space-between;
}
body.page-filemanager .filemanager-wrap .filemanager-content .content-head {
height: 56px;
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 16px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
body.page-filemanager .filemanager-wrap .filemanager-content .content-head .left a {
margin-right: 20px;
}
body.page-filemanager .filemanager-wrap .filemanager-content .content-center {
height: calc(100% - 56px);
display: flex;
align-items: flex-start;
flex-wrap: wrap;
background: #f9fafa;
padding: 20px;
margin-right: -10px;
overflow-y: auto;
}
body.page-filemanager .filemanager-wrap .filemanager-content .content-center .image-list {
width: calc(20% - 10px);
display: flex;
flex-direction: column;
margin-bottom: 20px;
background: #fff;
margin-right: 10px;
box-shadow: 0 0 2px 1px rgba(0, 0, 0, 0.1);
cursor: pointer;
}
body.page-filemanager .filemanager-wrap .filemanager-content .content-center .image-list.active {
outline: 1px solid #fd560f;
}
body.page-filemanager .filemanager-wrap .filemanager-content .content-center .image-list .text {
border-top: 1px solid #eee;
font-size: 12px;
padding: 10px;
display: flex;
align-items: center;
justify-content: space-between;
}
body.page-filemanager .filemanager-wrap .filemanager-content .content-center .image-list .text span {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
body.page-filemanager .filemanager-wrap .filemanager-content .content-center .image-list .text .el-icon-check {
color: #fd560f;
font-size: 18px;
font-weight: 600;
}
body.page-filemanager .filemanager-wrap .filemanager-content .content-footer {
height: 56px;
padding: 0 16px;
display: flex;
box-shadow: 0 -2px 4px rgba(0, 0, 0, 0.1);
align-items: center;
justify-content: center;
}

View File

@ -2234,6 +2234,19 @@ axios.defaults.baseURL = process.env.VUE_APP_BASE_URL; // axios.defaults.headers
}
});
/***/ }),
/***/ "./resources/beike/shop/default/css/design/app.scss":
/*!**********************************************************!*\
!*** ./resources/beike/shop/default/css/design/app.scss ***!
\**********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
// extracted by mini-css-extract-plugin
/***/ }),
/***/ "./resources/beike/admin/css/bootstrap/bootstrap.scss":
@ -2260,6 +2273,19 @@ __webpack_require__.r(__webpack_exports__);
// extracted by mini-css-extract-plugin
/***/ }),
/***/ "./resources/beike/admin/css/filemanager/app.scss":
/*!********************************************************!*\
!*** ./resources/beike/admin/css/filemanager/app.scss ***!
\********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
// extracted by mini-css-extract-plugin
/***/ }),
/***/ "./resources/beike/shop/default/css/bootstrap/bootstrap.scss":
@ -2286,19 +2312,6 @@ __webpack_require__.r(__webpack_exports__);
// extracted by mini-css-extract-plugin
/***/ }),
/***/ "./resources/beike/shop/default/css/design/app.scss":
/*!**********************************************************!*\
!*** ./resources/beike/shop/default/css/design/app.scss ***!
\**********************************************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
__webpack_require__.r(__webpack_exports__);
// extracted by mini-css-extract-plugin
/***/ }),
/***/ "./node_modules/process/browser.js":
@ -2605,11 +2618,12 @@ module.exports = JSON.parse('{"name":"axios","version":"0.21.4","description":"P
/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded
/******/ var installedChunks = {
/******/ "/build/beike/admin/js/app": 0,
/******/ "build/beike/shop/default/css/design/app": 0,
/******/ "build/beike/shop/default/css/app": 0,
/******/ "build/beike/shop/default/css/bootstrap": 0,
/******/ "build/beike/admin/css/filemanager": 0,
/******/ "build/beike/admin/css/app": 0,
/******/ "build/beike/admin/css/bootstrap": 0
/******/ "build/beike/admin/css/bootstrap": 0,
/******/ "build/beike/shop/default/css/design/app": 0
/******/ };
/******/
/******/ // no chunk on demand loading
@ -2659,12 +2673,13 @@ module.exports = JSON.parse('{"name":"axios","version":"0.21.4","description":"P
/******/ // startup
/******/ // Load entry module and return exports
/******/ // This entry module depends on other loaded chunks and execution need to be delayed
/******/ __webpack_require__.O(undefined, ["build/beike/shop/default/css/design/app","build/beike/shop/default/css/app","build/beike/shop/default/css/bootstrap","build/beike/admin/css/app","build/beike/admin/css/bootstrap"], () => (__webpack_require__("./resources/beike/admin/js/app.js")))
/******/ __webpack_require__.O(undefined, ["build/beike/shop/default/css/design/app","build/beike/shop/default/css/app","build/beike/shop/default/css/bootstrap","build/beike/admin/css/app","build/beike/admin/css/bootstrap"], () => (__webpack_require__("./resources/beike/admin/css/bootstrap/bootstrap.scss")))
/******/ __webpack_require__.O(undefined, ["build/beike/shop/default/css/design/app","build/beike/shop/default/css/app","build/beike/shop/default/css/bootstrap","build/beike/admin/css/app","build/beike/admin/css/bootstrap"], () => (__webpack_require__("./resources/beike/admin/css/app.scss")))
/******/ __webpack_require__.O(undefined, ["build/beike/shop/default/css/design/app","build/beike/shop/default/css/app","build/beike/shop/default/css/bootstrap","build/beike/admin/css/app","build/beike/admin/css/bootstrap"], () => (__webpack_require__("./resources/beike/shop/default/css/bootstrap/bootstrap.scss")))
/******/ __webpack_require__.O(undefined, ["build/beike/shop/default/css/design/app","build/beike/shop/default/css/app","build/beike/shop/default/css/bootstrap","build/beike/admin/css/app","build/beike/admin/css/bootstrap"], () => (__webpack_require__("./resources/beike/shop/default/css/app.scss")))
/******/ var __webpack_exports__ = __webpack_require__.O(undefined, ["build/beike/shop/default/css/design/app","build/beike/shop/default/css/app","build/beike/shop/default/css/bootstrap","build/beike/admin/css/app","build/beike/admin/css/bootstrap"], () => (__webpack_require__("./resources/beike/shop/default/css/design/app.scss")))
/******/ __webpack_require__.O(undefined, ["build/beike/shop/default/css/app","build/beike/shop/default/css/bootstrap","build/beike/admin/css/filemanager","build/beike/admin/css/app","build/beike/admin/css/bootstrap","build/beike/shop/default/css/design/app"], () => (__webpack_require__("./resources/beike/admin/js/app.js")))
/******/ __webpack_require__.O(undefined, ["build/beike/shop/default/css/app","build/beike/shop/default/css/bootstrap","build/beike/admin/css/filemanager","build/beike/admin/css/app","build/beike/admin/css/bootstrap","build/beike/shop/default/css/design/app"], () => (__webpack_require__("./resources/beike/admin/css/bootstrap/bootstrap.scss")))
/******/ __webpack_require__.O(undefined, ["build/beike/shop/default/css/app","build/beike/shop/default/css/bootstrap","build/beike/admin/css/filemanager","build/beike/admin/css/app","build/beike/admin/css/bootstrap","build/beike/shop/default/css/design/app"], () => (__webpack_require__("./resources/beike/admin/css/app.scss")))
/******/ __webpack_require__.O(undefined, ["build/beike/shop/default/css/app","build/beike/shop/default/css/bootstrap","build/beike/admin/css/filemanager","build/beike/admin/css/app","build/beike/admin/css/bootstrap","build/beike/shop/default/css/design/app"], () => (__webpack_require__("./resources/beike/admin/css/filemanager/app.scss")))
/******/ __webpack_require__.O(undefined, ["build/beike/shop/default/css/app","build/beike/shop/default/css/bootstrap","build/beike/admin/css/filemanager","build/beike/admin/css/app","build/beike/admin/css/bootstrap","build/beike/shop/default/css/design/app"], () => (__webpack_require__("./resources/beike/shop/default/css/bootstrap/bootstrap.scss")))
/******/ __webpack_require__.O(undefined, ["build/beike/shop/default/css/app","build/beike/shop/default/css/bootstrap","build/beike/admin/css/filemanager","build/beike/admin/css/app","build/beike/admin/css/bootstrap","build/beike/shop/default/css/design/app"], () => (__webpack_require__("./resources/beike/shop/default/css/app.scss")))
/******/ var __webpack_exports__ = __webpack_require__.O(undefined, ["build/beike/shop/default/css/app","build/beike/shop/default/css/bootstrap","build/beike/admin/css/filemanager","build/beike/admin/css/app","build/beike/admin/css/bootstrap","build/beike/shop/default/css/design/app"], () => (__webpack_require__("./resources/beike/shop/default/css/design/app.scss")))
/******/ __webpack_exports__ = __webpack_require__.O(__webpack_exports__);
/******/
/******/ })()

0
public/catalog/index.html Executable file
View File

View File

@ -0,0 +1,124 @@
@charset "UTF-8";
$primary: #fd560f;
[v-cloak] {
display: none;
}
body.page-filemanager {
height: 100vh;
overflow: hidden;
.filemanager-wrap {
display: flex;
height: 100vh;
position: relative;
.filemanager-navbar {
width: 20%;
}
.filemanager-divider {
position: absolute;
top: 0;
height: 100%;
left: 20%;
width: 10px;
display: flex;
justify-content: center;
align-items: center;
// cursor: col-resize;
cursor: move;
&:hover {
background: red;
}
}
.filemanager-content {
width: 80%;
padding-left: 10px;
display: flex;
flex-direction: column;
justify-content: space-between;
.content-head {
height: 56px;
position: relative;
display: flex;
align-items: center; // flex-start | center
justify-content: space-between; // flex-end | center | space-between
// flex-wrap: wrap;
padding: 0 16px;
box-shadow: 0 2px 4px rgba(0, 0, 0, .1);
.left {
a {
margin-right: 20px;
}
}
}
.content-center {
height: calc(100% - 56px);
display: flex;
align-items: flex-start;
flex-wrap: wrap;
// align-items: center; // flex-start | center
background: #f9fafa;
padding: 20px;
// justify-content: space-between; // flex-end | center | space-between
// flex-wrap: wrap;
margin-right: -10px;
overflow-y: auto;
.image-list {
width: calc(20% - 10px);
display: flex;
flex-direction: column;
// align-items: center;
margin-bottom: 20px;
background: #fff;
margin-right: 10px;
box-shadow: 0 0 2px 1px rgba(0, 0, 0, .1);
cursor: pointer;
// border: 1px solid transparent;
&.active {
outline: 1px solid $primary;
}
.text {
border-top: 1px solid #eee;
font-size: 12px;
padding: 10px;
display: flex;
align-items: center; // flex-start | center
justify-content: space-between;
// flex-wrap: wrap;
span {
overflow: hidden;
text-overflow:ellipsis;
white-space: nowrap;
}
.el-icon-check {
color: $primary;
font-size: 18px;
font-weight: 600;
}
}
}
}
.content-footer {
height: 56px;
padding: 0 16px;
display: flex;
box-shadow: 0 -2px 4px rgba(0, 0, 0, .1);
align-items: center; // flex-start | center
justify-content: center; // flex-end | center | space-between
}
}
}
}

View File

@ -0,0 +1,200 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1">
<script src="{{ asset('vendor/vue/2.6.12/vue.js') }}"></script>
<script src="{{ asset('vendor/element-ui/2.6.2/js.js') }}"></script>
<script src="{{ asset('vendor/jquery/jquery-3.6.0.min.js') }}"></script>
<script src="{{ asset('vendor/layer/3.5.1/layer.js') }}"></script>
<link href="{{ mix('/build/beike/admin/css/bootstrap.css') }}" rel="stylesheet">
<link rel="stylesheet" href="{{ asset('vendor/element-ui/2.6.2/css.css') }}">
<link href="{{ mix('build/beike/admin/css/filemanager.css') }}" rel="stylesheet">
<script src="{{ mix('build/beike/admin/js/app.js') }}"></script>
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>beike filemanager</title>
</head>
<body class="page-filemanager">
<div class="filemanager-wrap" id="filemanager-wrap-app" v-cloak>
<div class="filemanager-navbar" ref='letfDom'>
<el-tree :data="tree" :props="defaultProps" @node-click="handleNodeClick"></el-tree>
</div>
<div class="filemanager-divider" draggable="true" @dragstart="myFunction(event)" ref='moveDom'></div>
<div class="filemanager-content">
<div class="content-head">
<div class="left">
<el-link :underline="false" icon="el-icon-edit">下载</el-link>
<el-link :underline="false" icon="el-icon-edit">删除</el-link>
<el-link :underline="false" icon="el-icon-edit">重命名</el-link>
{{-- <el-link :underline="false" icon="el-icon-edit">无下划线</el-link> --}}
{{-- <el-link :underline="false" icon="el-icon-edit">无下划线</el-link> --}}
</div>
<div class="right"><el-button size="mini" type="primary">上传文件</el-button></div>
</div>
<div class="content-center">
<div :class="['image-list', file.selected ? 'active' : '']" v-for="file, index in files" :key="index" @click="checkedImage(index)">
<img :src="file.src">
<div class="text">
<span :title="file.name">@{{ file.name }}</span>
<i v-if="file.selected" class="el-icon-check"></i>
</div>
</div>
</div>
<div class="content-footer">
<div class="pagination-wrap">
<el-pagination
layout="prev, pager, next"
:total="50">
</el-pagination>
</div>
</div>
</div>
</div>
<script>
var app = new Vue({
el: '#filemanager-wrap-app',
components: {},
data: {
letfDom: null,
clientStartX: 0,
tree: [
{
label: '一级 1',
id: '2222',
children: [
{
label: '二级 1-1',
id: '2222',
children: [
{
label: '三级 1-1-1',
id: '2222',
}
]
}
]
},
{
label: '一级 2',
id: '423423',
},
{
label: '一级 2',
id: '423423',
},
{
label: '一级 2',
id: '423423',
},
{
label: '一级 2',
id: '423423',
},
],
defaultProps: {
children: 'children',
label: 'label'
},
files: [
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
{type: 'image', src: 'https://via.placeholder.com/140x140.png/eeeeee', name: '文件名称', selected: false},
]
},
// 计算属性
computed: {},
// 侦听器
watch: {},
// 组件方法
methods: {
handleNodeClick(e) {
console.log(e)
},
moveHandle(nowClientX, letfDom) {
let computedX = nowClientX - this.clientStartX;
let leftBoxWidth = parseInt(letfDom.style.width);
let changeWidth = leftBoxWidth + computedX;
if (changeWidth < 280) {
changeWidth = 280;
}
if (changeWidth > 400) {
changeWidth = 400;
}
letfDom.style.width = changeWidth + "px";
this.clientStartX = nowClientX;
},
checkedImage(index) {
this.files.map(e => !e.index ? e.selected = false : '')
this.files[index].selected = !this.files[index].selected
}
},
// 在实例初始化之后组件属性计算之前如data属性等
beforeCreate () {
},
// 在实例创建完成后被立即同步调用
created () {
},
// 在挂载开始之前被调用:相关的 render 函数首次被调用
beforeMount () {
},
// 实例被挂载后调用
mounted () {
this.letfDom = this.$refs.letfDom;
let moveDom = this.$refs.moveDom;
moveDom.onmousedown = e => {
this.clientStartX = e.clientX;
e.preventDefault();
document.onmousemove = e => {
this.moveHandle(e.clientX, this.letfDom);
};
document.onmouseup = e => {
document.onmouseup = null;
document.onmousemove = null;
};
};
},
})
document.ondragover=function(e){
e.preventDefault();
}
</script>
</body>
</html>

3
webpack.mix.js vendored
View File

@ -23,6 +23,9 @@ mix.sass('resources/beike/admin/css/bootstrap/bootstrap.scss', 'public/build/bei
mix.sass('resources/beike/admin/css/app.scss', 'public/build/beike/admin/css/app.css');
mix.js('resources/beike/admin/js/app.js', 'public/build/beike/admin/js/app.js');
// filemanager
mix.sass('resources/beike/admin/css/filemanager/app.scss', 'public/build/beike/admin/css/filemanager.css');
// 前端 default 模版
mix.sass('resources/beike/shop/default/css/bootstrap/bootstrap.scss', 'public/build/beike/shop/default/css/bootstrap.css');
mix.sass('resources/beike/shop/default/css/app.scss', 'public/build/beike/shop/default/css/app.css');