perf: 优化文件浏览查看路径

This commit is contained in:
kuaifan 2022-04-12 10:49:55 +08:00
parent 86886ded16
commit b1ee3fe3cd
7 changed files with 198 additions and 88 deletions

View File

@ -7,18 +7,18 @@
</transition>
<Spinner/>
<RightBottom/>
<PreviewImage/>
<PreviewImageState/>
</div>
</template>
<script>
import Spinner from "./components/Spinner";
import RightBottom from "./components/RightBottom";
import PreviewImage from "./components/PreviewImage";
import PreviewImageState from "./components/PreviewImage/state";
import {mapState} from "vuex";
export default {
components: {PreviewImage, RightBottom, Spinner},
components: {PreviewImageState, RightBottom, Spinner},
data() {
return {

View File

@ -1,14 +1,13 @@
<template>
<Modal
:value="previewImageList.length > 0"
v-model="show"
:mask="false"
:mask-closable="false"
:footer-hide="true"
:transition-names="['', '']"
fullscreen
@on-visible-change="visibleChange"
class-name="common-preview-image">
<PreviewImageView v-if="previewImageList.length > 0" :initial-index="previewImageIndex" :url-list="previewImageList" infinite/>
<PreviewImageView v-if="list.length > 0" :initial-index="index" :url-list="list" infinite/>
</Modal>
</template>
@ -19,8 +18,10 @@ body {
.ivu-modal {
margin: 0;
padding: 0;
.ivu-modal-content {
background: transparent;
.ivu-modal-close {
display: flex;
align-items: center;
@ -32,6 +33,7 @@ body {
right: 40px;
top: 40px;
width: 40px;
.ivu-icon-ios-close {
top: 0;
right: 0;
@ -39,6 +41,7 @@ body {
color: #fff;
}
}
.ivu-modal-body {
padding: 0;
}
@ -51,27 +54,38 @@ body {
<script>
import PreviewImageView from "./view";
import {mapState} from "vuex";
export default {
name: 'PreviewImage',
components: {PreviewImageView},
computed: {
...mapState([
'previewImageIndex',
'previewImageList',
]),
},
methods: {
visibleChange(val) {
if (!val) {
this.close()
props: {
value: {
type: Boolean,
default: false
},
index: {
type: Number,
default: 0
},
list: {
type: Array,
default: () => {
return [];
}
}
},
data() {
return {
show: this.value,
}
},
watch: {
value(v) {
this.show = v;
},
close() {
this.$store.state.previewImageIndex = 0;
this.$store.state.previewImageList = [];
},
show(v) {
this.value !== v && this.$emit("input", v)
}
}
};
</script>

View File

@ -0,0 +1,37 @@
<template>
<PreviewImage v-model="show" :index="previewImageIndex" :list="previewImageList"/>
</template>
<script>
import {mapState} from "vuex";
import PreviewImage from "./index";
export default {
name: 'PreviewImageState',
components: {PreviewImage},
computed: {
...mapState([
'previewImageIndex',
'previewImageList',
]),
},
data() {
return {
show: false,
}
},
watch: {
show(v) {
if (!v) {
this.$store.state.previewImageIndex = 0;
this.$store.state.previewImageList = [];
}
},
previewImageList(l) {
if (l.length > 0) {
this.show = true;
}
}
}
};
</script>

View File

@ -615,7 +615,6 @@ export default {
watch: {
'$route' (route) {
this.curPath = route.path;
this.chackPass();
},
userInfo() {
@ -663,6 +662,14 @@ export default {
}
},
curPath: {
handler(path) {
this.$store.dispatch("websocketPath", path);
this.chackPass();
},
immediate: true
},
unreadTotal: {
handler(num) {
if (this.$Electron) {
@ -720,6 +727,9 @@ export default {
toggleRoute(path) {
this.show768Menu = false;
if (path === 'file' && $A.getStorageInt("filePid") > 0) {
path += `/${$A.getStorageInt("filePid")}`
}
this.goForward({path: '/manage/' + path});
},
@ -779,7 +789,7 @@ export default {
classNameRoute(path) {
return {
"active": this.curPath == '/manage/' + path,
"active": $A.leftExists(this.curPath, '/manage/' + path),
};
},
@ -787,7 +797,7 @@ export default {
let path = 'project/' + item.id;
let openMenu = this.openMenu[item.id];
return {
"active": this.curPath == '/manage/' + path,
"active": $A.leftExists(this.curPath, '/manage/' + path),
"open-menu": openMenu === true,
"operate": item.id == this.topOperateItem.id && this.topOperateVisible
};

View File

@ -187,16 +187,10 @@ export default {
},
deep: true,
},
wsOpenNum() {
if (this.$isSubElectron) {
this.$store.dispatch("websocketPath", "file/content/" + this.fileId);
}
},
},
computed: {
...mapState(['fileContent', 'wsMsg', 'userId', 'wsOpenNum']),
...mapState(['fileContent', 'wsMsg', 'userId']),
equalContent() {
return this.contentBak == $A.jsonStringify(this.contentDetail);

View File

@ -23,9 +23,9 @@
<div class="file-navigator">
<ul>
<li @click="backHomeDirectory">{{$L('全部文件')}}</li>
<li @click="browseFolder(0)">{{$L('全部文件')}}</li>
<li v-if="searchKey">{{$L('搜索')}} "{{searchKey}}"</li>
<li v-else v-for="item in navigator" @click="pid=item.id">
<li v-else v-for="item in navigator" @click="browseFolder(item.id)">
<i v-if="item.share" class="taskfont">&#xe63f;</i>
<span :title="item.name">{{item.name}}</span>
<span v-if="item.share && item.permission == 0" class="readonly">{{$L('只读')}}</span>
@ -76,7 +76,7 @@
highlight: selectIds.includes(item.id),
}"
@contextmenu.prevent.stop="handleRightClick($event, item)"
@click="openFile(item)">
@click="dropFile(item, 'openCheckMenu')">
<div class="file-check" :class="{'file-checked':selectIds.includes(item.id)}" @click.stop="dropFile(item, 'select')">
<Checkbox :value="selectIds.includes(item.id)"/>
</div>
@ -332,6 +332,12 @@
<FileContent v-else v-model="fileShow" :file="fileInfo"/>
</DrawerOverlay>
<!--预览文件-->
<PreviewImage
v-model="imageShow"
:index="imageIndex"
:list="imageList"/>
<!--拖动上传提示-->
<Modal
v-model="pasteShow"
@ -359,21 +365,20 @@ import {mapState} from "vuex";
import {sortBy} from "lodash";
import UserInput from "../../components/UserInput";
import DrawerOverlay from "../../components/DrawerOverlay";
import PreviewImage from "../../components/PreviewImage";
const FilePreview = () => import('./components/FilePreview');
const FileContent = () => import('./components/FileContent');
export default {
components: {FilePreview, DrawerOverlay, UserInput, FileContent},
components: {PreviewImage, FilePreview, DrawerOverlay, UserInput, FileContent},
data() {
return {
loadIng: 0,
searchKey: '',
searchTimeout: null,
pid: $A.getStorageInt("fileOpenPid"),
types: [
{
"value": "folder",
@ -441,6 +446,10 @@ export default {
fileShow: false,
fileInfo: {permission: -1},
imageShow: false,
imageIndex: 0,
imageList:[],
uploadDir: false,
uploadIng: 0,
uploadShow: false,
@ -497,13 +506,28 @@ export default {
},
activated() {
this.$store.dispatch("websocketPath", "file");
this.getFileList();
},
computed: {
...mapState(['userId', 'userToken', 'userIsAdmin', 'userInfo', 'files', 'wsOpenNum']),
pid() {
let {pid} = this.$route.params;
if (!/^\d+$/.test(pid)) {
pid = 0
}
return parseInt(pid);
},
fid() {
let {fid} = this.$route.params;
if (!/^\d+$/.test(fid)) {
fid = 0
}
return parseInt(fid);
},
actionUrl() {
return $A.apiUrl('file/content/upload?pid=' + this.pid)
},
@ -582,20 +606,28 @@ export default {
watch: {
pid() {
this.searchKey = '';
this.selectIds = [];
this.getFileList();
},
fid() {
this.openFileJudge();
},
tableMode(val) {
$A.setStorage("fileTableMode", val)
},
fileShow(val) {
if (val) {
this.$store.dispatch("websocketPath", "file/content/" + this.fileInfo.id);
} else {
this.$store.dispatch("websocketPath", "file");
this.getFileList();
if (!val) {
this.browseFile(0)
}
},
imageShow(val) {
if (!val) {
this.browseFile(0)
}
},
@ -620,11 +652,7 @@ export default {
wsOpenNum(num) {
if (num <= 1) return
this.wsOpenTimeout && clearTimeout(this.wsOpenTimeout)
this.wsOpenTimeout = setTimeout(() => {
if (this.$route.name == 'manage-file') {
this.getFileList();
}
}, 5000)
this.wsOpenTimeout = setTimeout(this.getFileList, 5000)
}
},
@ -814,22 +842,21 @@ export default {
return name;
},
backHomeDirectory() {
this.pid = 0
this.searchKey = ''
},
getFileList() {
if (this.$route.name !== 'manage-file') {
return;
}
this.loadIng++;
this.$store.dispatch("getFiles", this.pid).then(() => {
this.loadIng--;
$A.setStorage("fileOpenPid", this.pid)
this.openFileJudge()
$A.setStorage("filePid", this.pid)
}).catch(({msg}) => {
this.loadIng--;
$A.modalError({
content: msg,
onOk: () => {
this.backHomeDirectory();
this.browseFolder(0);
}
});
});
@ -876,41 +903,55 @@ export default {
})
},
openFile(item, checkMenuVisible = true) {
if (checkMenuVisible && this.contextMenuVisible) {
return;
}
if (this.fileList.findIndex((file) => file._edit === true) > -1) {
return;
}
if (item._load) {
return;
}
if (item.type == 'folder') {
this.searchKey = '';
this.pid = item.id;
browseFolder(id) {
if (id > 0) {
this.goForward({params: {pid: id, fid: undefined}});
} else {
//
if (item.image_url) {
const list = this.fileList.filter(({image_url}) => !!image_url)
if (list.length > 0) {
this.$store.state.previewImageIndex = list.findIndex(({id}) => item.id === id);
this.$store.state.previewImageList = list.map(item => item.image_url);
return;
}
}
//
if (this.$Electron) {
this.openSingle(item);
return;
}
//
this.fileInfo = item;
this.fileShow = true;
this.goForward({name: 'manage-file'});
}
},
openSingle(item) {
browseFile(id) {
if (id > 0) {
this.goForward({params: {pid: this.pid, fid: id}});
} else {
this.browseFolder(this.pid);
}
},
openFileJudge() {
if (this.fid <= 0) {
this.fileShow = false;
this.imageShow = false;
return;
}
const item = this.fileList.find(({id}) => id === this.fid)
if (!item) {
this.fileShow = false;
this.imageShow = false;
return;
}
//
if (item.image_url) {
const list = this.fileList.filter(({image_url}) => !!image_url)
if (list.length > 0) {
this.imageIndex = list.findIndex(({id}) => item.id === id)
this.imageList = list.map(item => item.image_url)
this.imageShow = true
return;
}
}
//
if (this.$Electron) {
this.openFileSingle(item);
return;
}
//
this.fileInfo = item;
this.fileShow = true;
},
openFileSingle(item) {
this.$Electron.sendMessage('windowRouter', {
name: 'file-' + item.id,
path: "/single/file/" + item.id,
@ -962,7 +1003,21 @@ export default {
dropFile(item, command) {
switch (command) {
case 'open':
this.openFile(item, false);
case 'openCheckMenu':
if (command === 'openCheckMenu' && this.contextMenuVisible) {
return;
}
if (this.fileList.findIndex((file) => file._edit === true) > -1) {
return;
}
if (item._load) {
return;
}
if (item.type == 'folder') {
this.browseFolder(item.id)
} else {
this.browseFile(item.id)
}
break;
case 'select':

View File

@ -65,7 +65,7 @@ export default [
},
{
name: 'manage-file',
path: 'file',
path: 'file/:pid?/:fid?',
component: () => import('./pages/manage/file.vue'),
},
]