This commit is contained in:
pushuo 2022-08-25 14:28:46 +08:00
parent 6bbb4d1cbd
commit 69090d84ca
3 changed files with 460 additions and 420 deletions

View File

@ -31,7 +31,8 @@ class FileManagerController extends Controller
{
$baseFolder = $request->get('base_folder');
$page = (int)$request->get('page');
return (new FileManagerService)->getFiles($baseFolder, $page);
$perPage = (int)$request->get('per_page');
return (new FileManagerService)->getFiles($baseFolder, $page, $perPage);
}

View File

@ -57,7 +57,7 @@ class FileManagerService
* @return array
* @throws \Exception
*/
public function getFiles($baseFolder, int $page = 1): array
public function getFiles($baseFolder, int $page = 1, int $perPage = 20): array
{
$currentBasePath = rtrim($this->fileBasePath . $baseFolder, '/');
$files = glob($currentBasePath . '/*');
@ -75,7 +75,7 @@ class FileManagerService
}
$page = $page > 0 ? $page : 1;
$perPage = 20;
// $perPage = $perPage;
$imageCollection = collect($images);
$data = [
'images' => $imageCollection->forPage($page, $perPage)->values()->toArray(),

View File

@ -1,5 +1,6 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<base href="{{ $admin_base_url }}">
@ -18,36 +19,31 @@
<script src="{{ mix('build/beike/admin/js/app.js') }}"></script>
<title>beike filemanager</title>
</head>
<body class="page-filemanager">
<div class="filemanager-wrap" id="filemanager-wrap-app" v-cloak ref="splitPane">
<div class="filemanager-navbar" :style="'width:' + paneLengthValue">
<el-tree
:props="defaultProps"
node-key="path"
:data="treeData"
:current-node-key="folderCurrent"
:default-expanded-keys="defaultkeyarr"
:expand-on-click-node="false"
highlight-current
ref="tree"
@node-click="handleNodeClick"
@node-expand="(node) => {updateDefaultExpandedKeys(node, 'expand')}"
@node-collapse="(node) => {updateDefaultExpandedKeys(node, 'collapse')}"
class="tree-wrap">
<el-tree :props="defaultProps" node-key="path" :data="treeData" :current-node-key="folderCurrent"
:default-expanded-keys="defaultkeyarr" :expand-on-click-node="false" highlight-current ref="tree"
@node-click="handleNodeClick" @node-expand="(node) => {updateDefaultExpandedKeys(node, 'expand')}"
@node-collapse="(node) => {updateDefaultExpandedKeys(node, 'collapse')}" class="tree-wrap">
<div class="custom-tree-node" slot-scope="{ node, data }">
<div>@{{ node.label }}</div>
{{-- v-if="node.isCurrent" --}}
<div class="right" >
<div class="right">
<el-tooltip class="item" effect="dark" content="创建文件夹" placement="top">
<span @click.stop="() => {openInputBox('addFolder', node, data)}"><i class="el-icon-circle-plus-outline"></i></span>
<span @click.stop="() => {openInputBox('addFolder', node, data)}"><i
class="el-icon-circle-plus-outline"></i></span>
</el-tooltip>
<el-tooltip class="item" effect="dark" content="重命名" placement="top">
<span v-if="node.level != 1" @click.stop="() => {openInputBox('renameFolder', node, data)}"><i class="el-icon-edit"></i></span>
<span v-if="node.level != 1" @click.stop="() => {openInputBox('renameFolder', node, data)}"><i
class="el-icon-edit"></i></span>
</el-tooltip>
<el-tooltip class="item" effect="dark" content="删除" placement="top">
<span v-if="node.level != 1" @click.stop="() => {deleteFolder(node, data)}"><i class="el-icon-delete"></i></span>
<span v-if="node.level != 1" @click.stop="() => {deleteFolder(node, data)}"><i
class="el-icon-delete"></i></span>
</el-tooltip>
</div>
@ -57,18 +53,25 @@
<div class="filemanager-divider" @mousedown="handleMouseDown"></div>
<div class="filemanager-content" v-loading="loading" element-loading-background="rgba(255, 255, 255, 0.5)">
<div class="content-head">
<div class="left">
<el-link :underline="false" :disabled="!!!selectImageIndex.length" icon="el-icon-download" @click="downloadImages">下载</el-link>
<el-link :underline="false" :disabled="!!!selectImageIndex.length" @click="deleteFile" icon="el-icon-delete">删除</el-link>
<el-link :underline="false" :disabled="selectImageIndex.length == 1 ? false : true" @click="openInputBox('image')" icon="el-icon-edit">重命名</el-link>
<el-link :underline="false" :disabled="!!!images.length && !!!selectImageIndex.length" @click="selectAll()" icon="el-icon-finished">全选</el-link>
<div class="left d-flex">
<el-button class="me-5" size="small" icon="el-icon-check" type="primary" @click="fileChecked" :disabled="!!!selectImageIndex.length">选择</el-button>
<el-link :underline="false" :disabled="!!!selectImageIndex.length" icon="el-icon-download"
@click="downloadImages">下载</el-link>
<el-link :underline="false" :disabled="!!!selectImageIndex.length" @click="deleteFile"
icon="el-icon-delete">删除</el-link>
<el-link :underline="false" :disabled="selectImageIndex.length == 1 ? false : true"
@click="openInputBox('image')" icon="el-icon-edit">重命名</el-link>
<el-link :underline="false" :disabled="!!!images.length && !!!selectImageIndex.length"
@click="selectAll()" icon="el-icon-finished">全选</el-link>
</div>
<div class="right">
<el-button size="small" type="primary" @click="openUploadFile" icon="el-icon-upload2">上传文件</el-button>
<el-button size="small" plain type="primary" @click="openUploadFile" icon="el-icon-upload2">上传文件</el-button>
</div>
</div>
<div v-if="images.length" class="content-center" v-batch-select="{ className: '.image-list', selectImageIndex, setSelectStatus: updateSelectStatus }">
<div :class="['image-list', file.selected ? 'active' : '']" v-for="file, index in images" :key="index" @click="checkedImage(index)">
<div v-if="images.length" class="content-center"
v-batch-select="{ className: '.image-list', selectImageIndex, setSelectStatus: updateSelectStatus }">
<div :class="['image-list', file.selected ? 'active' : '']" v-for="file, index in images"
:key="index" @click="checkedImage(index)">
<div class="img"><img :src="file.url"></div>
<div class="text">
<span :title="file.name">@{{ file.name }}</span>
@ -80,455 +83,491 @@
<div class="content-footer">
<div class="right"></div>
<div class="pagination-wrap">
{{-- <el-pagination @current-change="pageCurrentChange" :page-size="20" layout="prev, pager, next"
:total="image_total">
</el-pagination> --}}
<el-pagination
@size-change="pageSizeChange"
@current-change="pageCurrentChange"
:current-page="image_page"
:page-sizes="[20, 40, 60, 80, 100]"
:page-size="20"
layout="prev, pager, next"
layout="total, sizes, prev, pager, next, jumper"
:total="image_total">
</el-pagination>
</div>
<div class="right">
</div>
<div class="right"><el-button size="small" icon="el-icon-check" type="primary" @click="fileChecked" :disabled="!!!selectImageIndex.length">选择</el-button></div>
</div>
</div>
<el-dialog
title="上传文件"
top="12vh"
:visible.sync="uploadFileDialog.show"
width="500px"
@close="uploadFileDialogClose"
custom-class="upload-wrap">
<el-upload
class="photos-upload"
target="photos-upload"
id="photos-upload"
element-loading-text="图片上传中..."
element-loading-background="rgba(0, 0, 0, 0.6)"
drag
action=""
:show-file-list="false"
accept=".jpg,.jpeg,.png,.JPG,.JPEG,.PNG,.mp4,.MP4"
:before-upload="beforePhotoUpload"
:on-success="handlePhotoSuccess"
:on-change="handleUploadChange"
:http-request="uploadFile"
:multiple="true">
<i class="el-icon-upload"></i>
<div class="el-upload__text">点击上传,或将图片拖到此处</div>
</el-upload>
<div class="upload-image">
<div v-for="image, index in uploadFileDialog.images" :key="index" class="list">
<div class="info">
<div class="name">@{{ index + 1 }}. @{{ image.name }}</div>
<div class="status">@{{ image.status == 'complete' ? '完成' : '上传中' }}</div>
</div>
<el-progress :percentage="image.progre" :show-text="false" :stroke-width="4"></el-progress>
<el-dialog title="上传文件" top="12vh" :visible.sync="uploadFileDialog.show" width="500px"
@close="uploadFileDialogClose" custom-class="upload-wrap">
<el-upload class="photos-upload" target="photos-upload" id="photos-upload" element-loading-text="图片上传中..."
element-loading-background="rgba(0, 0, 0, 0.6)" drag action="" :show-file-list="false"
accept=".jpg,.jpeg,.png,.JPG,.JPEG,.PNG,.mp4,.MP4" :before-upload="beforePhotoUpload"
:on-success="handlePhotoSuccess" :on-change="handleUploadChange" :http-request="uploadFile"
:multiple="true">
<i class="el-icon-upload"></i>
<div class="el-upload__text">点击上传,或将图片拖到此处</div>
</el-upload>
<div class="upload-image">
<div v-for="image, index in uploadFileDialog.images" :key="index" class="list">
<div class="info">
<div class="name">@{{ index + 1 }}. @{{ image.name }}</div>
<div class="status">@{{ image.status == 'complete' ? '完成' : '上传中' }}</div>
</div>
<el-progress :percentage="image.progre" :show-text="false" :stroke-width="4"></el-progress>
</div>
</div>
</el-dialog>
</div>
<script>
var callback = null;
var callback = null;
var app = new Vue({
el: '#filemanager-wrap-app',
components: {},
data: {
min: 10,
max: 40,
paneLengthPercent: 26,
triggerLength: 10,
isShift: false,
var app = new Vue({
el: '#filemanager-wrap-app',
components: {},
data: {
min: 10,
max: 40,
paneLengthPercent: 26,
triggerLength: 10,
isShift: false,
ssss:[],
loading: false,
isBatchSelect: false,
ssss: [],
loading: false,
isBatchSelect: false,
selectImageIndex: [],
selectImageIndex: [],
treeData: [{name: '图片空间', path: '/', children: @json($directories)}],
treeData: [{
name: '图片空间',
path: '/',
children: @json($directories)
}],
defaultProps: {
children: 'children',
label: 'name',
isLeaf: 'leaf'
},
selectIdxs: [],
uploadFileDialog: {
show: false,
total: 0,
images: []
},
folderCurrent: '/',
defaultkeyarr: ['/'],
triggerLeftOffset: 0,
images: [],
image_total: 0,
image_page: 1,
},
// 计算属性
computed: {
paneLengthValue() {
return `calc(${this.paneLengthPercent}% - ${this.triggerLength / 2 + 'px'})`
},
},
// 侦听器
watch: {
images: {
handler(val) {
if (this.isBatchSelect) return;
// 将选中的图片索引放入 selectImageIndex未选中则清空
this.selectImageIndex = val.filter(item => item.selected).map(e => this.images.indexOf(e));
defaultProps: {
children: 'children',
label: 'name',
isLeaf: 'leaf'
},
deep: true
},
selectIdxs: [],
selectImageIndex(indexs) {
this.images.forEach((item, index) => {
item.selected = indexs.includes(index);
});
},
},
// 组件方法
methods: {
handleNodeClick(e, node) {
if (e.path == this.folderCurrent) {
return;
}
uploadFileDialog: {
show: false,
total: 0,
images: []
},
this.folderCurrent = e.path
this.image_page = 1;
sessionStorage.setItem('folderCurrent', this.folderCurrent);
this.loadData(e, node)
},
folderCurrent: '/',
defaultkeyarr: ['/'],
updateSelectStatus(status) {
this.isBatchSelect = status
},
triggerLeftOffset: 0,
pageCurrentChange(e) {
this.image_page = e
this.loadData()
images: [],
image_total: 0,
image_page: 1,
per_page: 20,
},
// 计算属性
computed: {
paneLengthValue() {
return `calc(${this.paneLengthPercent}% - ${this.triggerLength / 2 + 'px'})`
},
},
// 侦听器
watch: {
images: {
handler(val) {
if (this.isBatchSelect) return;
// 将选中的图片索引放入 selectImageIndex未选中则清空
this.selectImageIndex = val.filter(item => item.selected).map(e => this.images.indexOf(e));
},
deep: true
},
uploadFileDialogClose() {
if (this.uploadFileDialog.images.length) {
selectImageIndex(indexs) {
this.images.forEach((item, index) => {
item.selected = indexs.includes(index);
});
},
},
// 组件方法
methods: {
handleNodeClick(e, node) {
if (e.path == this.folderCurrent) {
return;
}
this.folderCurrent = e.path
this.image_page = 1;
sessionStorage.setItem('folderCurrent', this.folderCurrent);
this.loadData(e, node)
},
updateSelectStatus(status) {
this.isBatchSelect = status
},
pageCurrentChange(e) {
this.image_page = e
this.loadData()
}
},
this.uploadFileDialog.images = [];
},
pageSizeChange(e) {
this.per_page = e
this.loadData()
},
openUploadFile() {
this.uploadFileDialog.show = true
},
beforePhotoUpload(file) {
// this.editing.photoLoading = true;
},
handlePhotoSuccess(data) {
// this.editing.photoLoading = false;
// if (data.images) {
// this.images.push(data.images);
// }
},
// 文件上传
uploadFile(file) {
const that = this;
let newFile = {};
if (file.file.type != 'image/png' && file.file.type != 'image/jpeg') {
return;
}
var formData = new FormData();
formData.append("file", file.file, file.file.name);
formData.append("path", this.folderCurrent);
newFile = {
// index: this.images.length,
name: file.file.name,
progre: 0,
status: 'padding'
};
this.uploadFileDialog.images.push(newFile);
let index = this.uploadFileDialog.images.length - 1;
$http.post('file_manager/upload', formData).then((res) => {
this.uploadFileDialog.images[index].status = 'complete';
this.uploadFileDialog.images[index].progre = 100;
}).finally(() => {index += 1})
},
handleUploadChange(e) {
console.log(e);
// console.log('handleUploadChange');
},
updateDefaultExpandedKeys(node, type) {
const isExist = this.defaultkeyarr.some(item => item === node.path)
if (type == 'expand') {
if (!isExist) {
this.defaultkeyarr.push(node.path)
uploadFileDialogClose() {
if (this.uploadFileDialog.images.length) {
this.loadData()
}
} else {
const index = this.defaultkeyarr.findIndex(e => e == node.path);
if (index > -1) {
this.defaultkeyarr.splice(index, 1);
this.uploadFileDialog.images = [];
},
openUploadFile() {
this.uploadFileDialog.show = true
},
beforePhotoUpload(file) {
// this.editing.photoLoading = true;
},
handlePhotoSuccess(data) {
// this.editing.photoLoading = false;
// if (data.images) {
// this.images.push(data.images);
// }
},
// 文件上传
uploadFile(file) {
const that = this;
let newFile = {};
if (file.file.type != 'image/png' && file.file.type != 'image/jpeg') {
return;
}
}
sessionStorage.setItem('defaultkeyarr', this.defaultkeyarr);
},
var formData = new FormData();
formData.append("file", file.file, file.file.name);
formData.append("path", this.folderCurrent);
loadData(e, node) {
this.loading = true;
newFile = {
// index: this.images.length,
name: file.file.name,
progre: 0,
status: 'padding'
};
$http.get(`file_manager/files?base_folder=${this.folderCurrent}`, {page: this.image_page}, {hload: true}).then((res) => {
this.images = res.images
this.image_page = res.image_page
this.image_total = res.image_total
this.uploadFileDialog.images.push(newFile);
if (node) {
node.expanded = true
this.updateDefaultExpandedKeys(node.data, 'expand')
let index = this.uploadFileDialog.images.length - 1;
$http.post('file_manager/upload', formData).then((res) => {
this.uploadFileDialog.images[index].status = 'complete';
this.uploadFileDialog.images[index].progre = 100;
}).finally(() => {
index += 1
})
},
handleUploadChange(e) {
console.log(e);
// console.log('handleUploadChange');
},
updateDefaultExpandedKeys(node, type) {
const isExist = this.defaultkeyarr.some(item => item === node.path)
if (type == 'expand') {
if (!isExist) {
this.defaultkeyarr.push(node.path)
}
} else {
const index = this.defaultkeyarr.findIndex(e => e == node.path);
if (index > -1) {
this.defaultkeyarr.splice(index, 1);
}
}
}).finally(() => this.loading = false);
},
// 按下滑动器
handleMouseDown(e) {
document.addEventListener('mousemove', this.handleMouseMove)
document.addEventListener('mouseup', this.handleMouseUp)
this.triggerLeftOffset = e.pageX - e.srcElement.getBoundingClientRect().left
},
// 按下滑动器后移动鼠标
handleMouseMove(e) {
const clientRect = this.$refs.splitPane.getBoundingClientRect()
let paneLengthPercent = 0
const offset = e.pageX - clientRect.left - this.triggerLeftOffset + this.triggerLength / 2
paneLengthPercent = (offset / clientRect.width) * 100
if (paneLengthPercent < this.min) {
paneLengthPercent = this.min
}
if (paneLengthPercent > this.max) {
paneLengthPercent = this.max
}
this.paneLengthPercent = paneLengthPercent;
},
// 松开滑动器
handleMouseUp() {
document.removeEventListener('mousemove', this.handleMouseMove)
},
checkedImage(index) {
// 获取当前选中的 index
const selectedIndex = this.images.findIndex(e => e.selected);
if (this.isShift) {
// 获取 selectedIndex 与 index 之间的所有图片
let selectedImages = this.images.slice(Math.min(selectedIndex, index), Math.max(selectedIndex, index) + 1);
selectedImages.map(e => e.selected = true)
return;
}
if (this.isCtrl) {
this.images[index].selected = !this.images[index].selected;
return;
}
if (this.selectImageIndex.length > 1) {
this.images.map((e,i) => i != index ? e.selected = false : e.selected = true)
return;
}
this.images.map((e,i) => i != index ? e.selected = false : '')
this.images[index].selected = !this.images[index].selected
},
// 选取
fileChecked() {
let typedFiles = this.images.filter(e => e.selected)
if (callback !== null) {
callback(typedFiles);
}
// 关闭弹窗
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
},
deleteFile() {
this.$confirm('是否要删除选中文件', '提示', {
type: 'warning'
}).then(() => {
const selectImageIndex = this.selectImageIndex;
// 获取images中下标与selectImageIndex相同的图片
const images = this.images.filter(e => selectImageIndex.includes(this.images.indexOf(e)));
// images 取 path 组成数组 然后用 | 分割成字符串
const files = images.map(e => e.name);
sessionStorage.setItem('defaultkeyarr', this.defaultkeyarr);
},
loadData(e, node) {
this.loading = true;
$http.delete('file_manager/files', {path: this.folderCurrent, files: files}, {hload: true}).then((res) => {
layer.msg(res.message)
this.loadData()
})
}).catch(_=>{});
},
$http.get(`file_manager/files?base_folder=${this.folderCurrent}`, {
page: this.image_page,
per_page: this.per_page
}, {
hload: true
}).then((res) => {
this.images = res.images
this.image_page = res.image_page
this.image_total = res.image_total
deleteFolder(node, data) {
if (data.path) {
this.$confirm('正在进行删除文件夹操作,文件夹内所有文件都将被删除,是否确认?', '提示', {
if (node) {
node.expanded = true
this.updateDefaultExpandedKeys(node.data, 'expand')
}
}).finally(() => this.loading = false);
},
// 按下滑动器
handleMouseDown(e) {
document.addEventListener('mousemove', this.handleMouseMove)
document.addEventListener('mouseup', this.handleMouseUp)
this.triggerLeftOffset = e.pageX - e.srcElement.getBoundingClientRect().left
},
// 按下滑动器后移动鼠标
handleMouseMove(e) {
const clientRect = this.$refs.splitPane.getBoundingClientRect()
let paneLengthPercent = 0
const offset = e.pageX - clientRect.left - this.triggerLeftOffset + this.triggerLength / 2
paneLengthPercent = (offset / clientRect.width) * 100
if (paneLengthPercent < this.min) {
paneLengthPercent = this.min
}
if (paneLengthPercent > this.max) {
paneLengthPercent = this.max
}
this.paneLengthPercent = paneLengthPercent;
},
// 松开滑动器
handleMouseUp() {
document.removeEventListener('mousemove', this.handleMouseMove)
},
checkedImage(index) {
// 获取当前选中的 index
const selectedIndex = this.images.findIndex(e => e.selected);
if (this.isShift) {
// 获取 selectedIndex 与 index 之间的所有图片
let selectedImages = this.images.slice(Math.min(selectedIndex, index), Math.max(selectedIndex, index) +
1);
selectedImages.map(e => e.selected = true)
return;
}
if (this.isCtrl) {
this.images[index].selected = !this.images[index].selected;
return;
}
if (this.selectImageIndex.length > 1) {
this.images.map((e, i) => i != index ? e.selected = false : e.selected = true)
return;
}
this.images.map((e, i) => i != index ? e.selected = false : '')
this.images[index].selected = !this.images[index].selected
},
// 选取
fileChecked() {
let typedFiles = this.images.filter(e => e.selected)
if (callback !== null) {
callback(typedFiles);
}
// 关闭弹窗
var index = parent.layer.getFrameIndex(window.name);
parent.layer.close(index);
},
deleteFile() {
this.$confirm('是否要删除选中文件', '提示', {
type: 'warning'
}).then(() => {
$http.delete(`file_manager/directories`, {name: this.folderCurrent}).then((res) => {
const selectImageIndex = this.selectImageIndex;
// 获取images中下标与selectImageIndex相同的图片
const images = this.images.filter(e => selectImageIndex.includes(this.images.indexOf(e)));
// images 取 path 组成数组 然后用 | 分割成字符串
const files = images.map(e => e.name);
this.loading = true;
$http.delete('file_manager/files', {
path: this.folderCurrent,
files: files
}, {
hload: true
}).then((res) => {
layer.msg(res.message)
this.$refs.tree.setCurrentKey(node.parent.data.path)
this.folderCurrent = node.parent.data.path;
this.$refs.tree.remove(data.path)
}).finally(() => this.loadData())
}).catch(_=>{});
}
},
selectAll() {
// 获取 this.images 中的 selected 是否全部为 true
const isAllSelected = this.images.every(e => e.selected);
this.images.map(e => e.selected = !isAllSelected)
},
downloadImages() {
// 获取选中的图片
const selectedImages = this.images.filter(e => e.selected);
// 创建 a 标签
selectedImages.forEach(e => {
const a = document.createElement('a');
// 设置 a 标签的 href 属性
a.href = e.origin_url;
// 设置 a 标签的 download 属性
a.download = e.name;
// 触发 a 标签的 click 事件
a.click();
});
},
openInputBox(type, node, data) {
this.$prompt('', type == 'addFolder' ? '新建文件夹' : '重命名', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputPattern: /^.+$/,
closeOnClickModal: false,
inputValue: type == 'image' ? this.images[this.selectImageIndex].name : (type == 'renameFolder' ? data.name : '新建文件夹'),
inputErrorMessage: '不能为空'
}).then(({ value }) => {
if (type == 'addFolder') {
let fileAllPathName = this.folderCurrent + '/' + value;
$http.post(`file_manager/directories`, {name: fileAllPathName}).then((res) => {
layer.msg(res.message)
node.expanded = true
this.$refs.tree.append({name: value, path: fileAllPathName, leaf: true}, node);
this.$refs.tree.setCurrentKey(fileAllPathName)
this.folderCurrent = fileAllPathName;
this.updateDefaultExpandedKeys(node.data, 'expand')
this.loadData()
})
}).catch(_ => {});
},
deleteFolder(node, data) {
if (data.path) {
this.$confirm('正在进行删除文件夹操作,文件夹内所有文件都将被删除,是否确认?', '提示', {
type: 'warning'
}).then(() => {
$http.delete(`file_manager/directories`, {
name: this.folderCurrent
}).then((res) => {
layer.msg(res.message)
this.$refs.tree.setCurrentKey(node.parent.data.path)
this.folderCurrent = node.parent.data.path;
this.$refs.tree.remove(data.path)
}).finally(() => this.loadData())
}).catch(_ => {});
}
},
if (type == 'renameFolder') {
$http.post(`file_manager/rename`, {origin_name: this.folderCurrent, new_name: value}).then((res) => {
layer.msg(res.message)
data.name = value;
data.path = data.path.replace(/\/[^\/]*$/, '/' + value);
this.folderCurrent = this.folderCurrent.replace(/\/[^\/]*$/, '/' + value);
// 递归修改 data 内所有 children -> path 的对应 level = value
this.changeChildren(data, node, value);
})
}
selectAll() {
// 获取 this.images 中的 selected 是否全部为 true
const isAllSelected = this.images.every(e => e.selected);
this.images.map(e => e.selected = !isAllSelected)
},
if (type == 'image') {
const name = this.images[this.selectImageIndex].name;
const origin_name = this.folderCurrent == '/' ? '/' + name : this.folderCurrent + '/' + name;
downloadImages() {
// 获取选中的图片
const selectedImages = this.images.filter(e => e.selected);
// 创建 a 标签
selectedImages.forEach(e => {
const a = document.createElement('a');
// 设置 a 标签的 href 属性
a.href = e.origin_url;
// 设置 a 标签的 download 属性
a.download = e.name;
// 触发 a 标签的 click 事件
a.click();
});
},
$http.post(`file_manager/rename`, {origin_name: origin_name, new_name: value}).then((res) => {
layer.msg(res.message)
})
}
}).catch(() => {});
},
changeChildren(data, node, value) {
if (data.children) {
data.children.map(e => {
if (e.path) {
// 将字符串转换为数组
let path = e.path.split('/')
path[node.level - 1] = value
// 将数组转换为字符串
e.path = path.join('/')
openInputBox(type, node, data) {
this.$prompt('', type == 'addFolder' ? '新建文件夹' : '重命名', {
confirmButtonText: '确定',
cancelButtonText: '取消',
inputPattern: /^.+$/,
closeOnClickModal: false,
inputValue: type == 'image' ? this.images[this.selectImageIndex].name : (type == 'renameFolder' ? data
.name : '新建文件夹'),
inputErrorMessage: '不能为空'
}).then(({
value
}) => {
if (type == 'addFolder') {
let fileAllPathName = this.folderCurrent + '/' + value;
$http.post(`file_manager/directories`, {
name: fileAllPathName
}).then((res) => {
layer.msg(res.message)
node.expanded = true
this.$refs.tree.append({
name: value,
path: fileAllPathName,
leaf: true
}, node);
this.$refs.tree.setCurrentKey(fileAllPathName)
this.folderCurrent = fileAllPathName;
this.updateDefaultExpandedKeys(node.data, 'expand')
})
}
if (e.children) {
this.changeChildren(e, node, value)
if (type == 'renameFolder') {
$http.post(`file_manager/rename`, {
origin_name: this.folderCurrent,
new_name: value
}).then((res) => {
layer.msg(res.message)
data.name = value;
data.path = data.path.replace(/\/[^\/]*$/, '/' + value);
this.folderCurrent = this.folderCurrent.replace(/\/[^\/]*$/, '/' + value);
// 递归修改 data 内所有 children -> path 的对应 level = value
this.changeChildren(data, node, value);
})
}
})
if (type == 'image') {
const name = this.images[this.selectImageIndex].name;
const origin_name = this.folderCurrent == '/' ? '/' + name : this.folderCurrent + '/' + name;
$http.post(`file_manager/rename`, {
origin_name: origin_name,
new_name: value
}).then((res) => {
layer.msg(res.message)
})
}
}).catch(() => {});
},
changeChildren(data, node, value) {
if (data.children) {
data.children.map(e => {
if (e.path) {
// 将字符串转换为数组
let path = e.path.split('/')
path[node.level - 1] = value
// 将数组转换为字符串
e.path = path.join('/')
}
if (e.children) {
this.changeChildren(e, node, value)
}
})
}
}
}
},
},
created () {
const defaultkeyarr = sessionStorage.getItem('defaultkeyarr');
const folderCurrent = sessionStorage.getItem('folderCurrent');
created() {
const defaultkeyarr = sessionStorage.getItem('defaultkeyarr');
const folderCurrent = sessionStorage.getItem('folderCurrent');
if (defaultkeyarr) {
this.defaultkeyarr = defaultkeyarr.split(',');
}
if (folderCurrent) {
this.folderCurrent = folderCurrent;
}
},
// 实例被挂载后调用
mounted () {
this.loadData()
// 获取键盘事件 是否按住 shift/ctrl 键 兼容 mac 和 windows
document.addEventListener('keydown', (e) => {
this.isShift = e.shiftKey;
this.isCtrl = e.ctrlKey || e.metaKey;
})
// 获取键盘事件 是否松开 shift/ctrl 键
document.addEventListener('keyup', (e) => {
this.isShift = e.shiftKey;
this.isCtrl = e.ctrlKey || e.metaKey;
})
// 判断鼠标是否点击 .image-list 元素
document.addEventListener('click', (e) => {
if (this.isBatchSelect) return;
const targets = ['filemanager-navbar', 'content-center']
if (targets.indexOf(e.target.className) > -1) {
this.selectImageIndex = [];
this.images.map(e => e.selected = false)
if (defaultkeyarr) {
this.defaultkeyarr = defaultkeyarr.split(',');
}
})
},
})
if (folderCurrent) {
this.folderCurrent = folderCurrent;
}
},
// 实例被挂载后调用
mounted() {
this.loadData()
// 获取键盘事件 是否按住 shift/ctrl 键 兼容 mac 和 windows
document.addEventListener('keydown', (e) => {
this.isShift = e.shiftKey;
this.isCtrl = e.ctrlKey || e.metaKey;
})
// 获取键盘事件 是否松开 shift/ctrl 键
document.addEventListener('keyup', (e) => {
this.isShift = e.shiftKey;
this.isCtrl = e.ctrlKey || e.metaKey;
})
// 判断鼠标是否点击 .image-list 元素
document.addEventListener('click', (e) => {
if (this.isBatchSelect) return;
const targets = ['filemanager-navbar', 'content-center']
if (targets.indexOf(e.target.className) > -1) {
this.selectImageIndex = [];
this.images.map(e => e.selected = false)
}
})
},
})
</script>
</body>
</html>