ソースを参照

新增工作空间文件搜索

dev-remain
kim131 4年前
コミット
e4f0b2710f
11個のファイルの変更185行の追加212行の削除
  1. +4
    -4
      public/static/css/main.css
  2. +3
    -3
      src/components/change-btn/change-btn.vue
  3. +1
    -2
      src/components/search-bar/search-bar.vue
  4. +0
    -5
      src/router.js
  5. +2
    -2
      src/views/components_web/projDetail/components/plain-folder-list.vue
  6. +6
    -4
      src/views/components_web/projDetail/projDetail.vue
  7. +0
    -104
      src/views/main_web/index/components/search-proj.vue
  8. +5
    -4
      src/views/main_web/index/index.vue
  9. +18
    -19
      src/views/main_web/workspace/components/add-file-button.vue
  10. +0
    -38
      src/views/main_web/workspace/components/search-file.vue
  11. +146
    -27
      src/views/main_web/workspace/workspace.new.vue

+ 4
- 4
public/static/css/main.css ファイルの表示

@@ -4575,7 +4575,7 @@ button:focus {
align-items: center;
width: 680px;
height: 100px;
margin : 0 auto 50px;
margin : 0 auto;
border-radius: 10px;
background-color: rgba(252, 252, 252, 1);
@@ -9062,15 +9062,15 @@ h5.dulilabel{
}
/* 绿色协同图标 */
.green-icon {
background: url('/static/img/FileStatus/已协同协同.svg') center/100%;
background: url('/static/img/FileStatus/已协同协同.svg');
}
/* 灰色图标 未启用协同*/
.gray-icon {
background: url('/static/img/FileStatus/未启用协同.svg') center/100%;
background: url('/static/img/FileStatus/未启用协同.svg');
}
/* 蓝色图标 待更新协同 */
.blue-icon {
background: url('/static/img/FileStatus/待更新协同.svg') center/100%;
background: url('/static/img/FileStatus/待更新协同.svg');
}
/* 新版项目概况 工作指派微调样式 */


+ 3
- 3
src/components/change-btn/change-btn.vue ファイルの表示

@@ -3,7 +3,7 @@
<div class="btn" v-for="(title, index) in titleList"
:key="index"
:class="{'active-btn': currentIndex === index}"
@click="changeModelBtnClick(index)">
@click="changeContentBtnClick(index)">
{{title}}
</div>
</div>
@@ -25,9 +25,9 @@
}
},
methods: {
changeModelBtnClick(i) {
changeContentBtnClick(i) {
this.currentIndex = i;
this.$emit('changeModelBtnClick',i);
this.$emit('changeContentBtnClick',i);
}
}
}


+ 1
- 2
src/components/search-bar/search-bar.vue ファイルの表示

@@ -60,10 +60,9 @@
}
.search-icon, .close-icon {
position: absolute;
top: 50%;
top: 16px;
width: 22px;
height: 22px;
transform: translate(0, -50%);
cursor: pointer;
}
.search-icon {


+ 0
- 5
src/router.js ファイルの表示

@@ -79,11 +79,6 @@ const router = new Router({
name: 'recycle',
component: () => import('@/views/main_web/recycle'),
},
{
path: '/search',
name: 'search',
component: () => import('@/views/main_web/search'),
},
{
path: '/cloud',
name: 'cloud',


+ 2
- 2
src/views/components_web/projDetail/components/plain-folder-list.vue ファイルの表示

@@ -1,7 +1,7 @@
<template>
<div>
<div
v-for="folder in folderList"
v-for="(folder,index) in folderList"
:key="folder.id"
>
<div >
@@ -60,7 +60,7 @@
</div>
<div class="stand-place" v-if="isNest(folder.nodeId)"/>
<!-- 嵌套模板入口 -->
<div class="add_nest" v-if="isNest(folder.nodeId)">
<div class="add_nest" v-if="isNest(folder.nodeId) && !isEnterEdit">
<div class="add_nest_box" @click.stop="enterNestTemp(folder)">
<i class="el-icon-plus"></i>
<p>嵌套模板</p>


+ 6
- 4
src/views/components_web/projDetail/projDetail.vue ファイルの表示

@@ -204,7 +204,7 @@
import TempSelectedUserList from './components/temp-selected-user-list';
import FileUploader from "@/components/file-uploader";
import { getUserInfo,fetchDeptList,getUserListByNode } from '@/services/user.js';
import { cloneDeep } from 'lodash';
import { cloneDeep, uniqBy } from 'lodash';
import { fetchApi } from '@/utils/request';
import { firstCharToLowerCase, firstCharToUpperCase } from '@/utils/tool';
import { AssignedWork, EditProject } from '@/services/project.js';
@@ -1096,9 +1096,11 @@ import NestTemp from '../project/nestTemp.vue';
this.isProjManager = !!this.listManagerUser.find(m => m.id == this.userId) || this.currUser.id == this.userId;
}
this.oldListManagerUser = cloneDeep(this.listManagerUser);
const folderList = mergeFolderList(folder, userHash);
//
this.getfolderPerm(folderList)

let uniqFolder = uniqBy(folder, 'Id');
// console.log(folder, uniqFolder);
const folderList = mergeFolderList(uniqFolder, userHash);
this.getfolderPerm(folderList);
this.listNewFolder = folderList;
this.oldFolderList = cloneDeep(this.listNewFolder);
this.getPlainOldFolderList();


+ 0
- 104
src/views/main_web/index/components/search-proj.vue ファイルの表示

@@ -1,104 +0,0 @@
<template>
<div id="search-proj">
<app-header class="search-proj-header"
backBtnTitle="退出" theme="basis" :title="showTitle"
:showUserCenter="true" :showBackBtn="true"
>
<template #right>
<search-bar class="proj-search-bar"
@changeSearchContent="changeSearchContent"
@searchContentClick="searchForProj"/>
</template>
</app-header>
<div class="content-wrap">
<change-btn :titleList="titleList" class="operate-bar"/>
<div v-for="proj in projList" :key="proj.id" class="layout_content">
<proj-item
:projPageList="projList"
/>
</div>
</div>
</div>
</template>

<script>
import AppHeader from "@/components/app-header";
import SearchBar from "@/components/search-bar/search-bar";

import ProjItem from "@/views/main_web/proj-item";
import * as projService from '@/services/project';
export default {
data() {
return {
projList: [],
searchContent: '',
titleList: ['工作文件','协作文件','我的项目'],
bigbodyEl: null,
}
},
mounted() {
this.bigbodyEl = document.querySelector('#bigbody');

},
beforeDestroy() {
if(this.bigbodyEl) {
this.bigbodyEl.classList.add('bigbody')
}
},
components: {
AppHeader,
SearchBar,
ChangeBtn,
ProjItem,
},
props: {

},
computed: {
showTitle() {
return this.searchContent ? `“${this.searchContent}”` + '搜索结果' : "搜索结果";
}
},
methods: {
// 全局搜索项目
async searchForProj(searchContent) {
const res = await projService.searchProject(searchContent);
if(res.Code == 0) {
this.projList = res.Data;
} else {
this.$notify({
type: ['error'],
message:'查询数据失败, 请稍后重试。'
})
}

},
changeSearchContent(content) {
this.searchContent = content;
},
}
}
</script>

<style scoped lang="scss">
#search-proj {
.content-wrap {
padding: 0 64px;
margin: 44px 0 0 0;
}
}
.operate-bar {
position: fixed;
top: 66px;
left: 50%;
transform: translate(-50%, 0);
width: 284px;
}
</style>
<style>
.search-proj-header .app-header-content-right {
display: flex;
}
</style>


+ 5
- 4
src/views/main_web/index/index.vue ファイルの表示

@@ -26,7 +26,7 @@
:class="{'hide-search-bar': !isShowSearchBar, 'show-search-bar': isShowSearchBar}"
placeholder="搜索项目名称"
@changeSearchContent="changeSearchContent"
@hideSearchBar="isShowSearchBar = false"
@hideSearchBar="hideSearchBar"
@goToSearch="searchForProj"/>
<div class="search-entry" @click.stop="isShowSearchBar = true" v-if="!isShowSearchBar"></div>
</template>
@@ -288,6 +288,10 @@ export default {
}
},
methods: {
hideSearchBar() {
this.isShowSearchBar = false;
this.searchContent = '';
},
searchForProj: debounce(async function searchForProj() {
// 判断输入内容是否有效
const rg = /^\s*$/;
@@ -308,9 +312,6 @@ export default {
},500),
changeSearchContent(content) {
this.searchContent = content;
},
goToSearchProj() {
},
// 新版创建项目入口
createNewProjectClick() {


+ 18
- 19
src/views/main_web/workspace/components/add-file-button.vue ファイルの表示

@@ -36,27 +36,26 @@
<img src="static\img\文件夹.svg" alt class="uploadBtnImg" />
<span class="uploadText">点击上传本地文件夹</span>
</div>
<div class="creatbox_mid mt-10" v-if="listTempFiles.length > 0">
<div class="title-head">
<div class="title-text">从样板文件中创建</div>
</div>
<div class="temp-file-container">
<ul class="listTemplateList">
<li class="temp-file"
v-for="(item, index) in listTempFiles"
:key="item.id"
@click.stop="fileTempClick(item, index)"
>
<span class="listTemplateTextBig" :title="item.extension">{{
item.extension
}}</span>
<span class="listTemplateText">{{ item.fileName }}</span>
</li>
</ul>
</div>
</div>
<div class="creatbox_mid mt-10" v-if="listTempFiles.length > 0">
<div class="title-head">
<div class="title-text">从样板文件中创建</div>
</div>
<div class="temp-file-container">
<ul class="listTemplateList">
<li class="temp-file"
v-for="(item, index) in listTempFiles"
:key="item.id"
@click.stop="fileTempClick(item, index)"
>
<span class="listTemplateTextBig" :title="item.extension">{{
item.extension
}}</span>
<span class="listTemplateText">{{ item.fileName }}</span>
</li>
</ul>
</div>
</div>

<!-- <div
class="listimg"
:title="item.name"


+ 0
- 38
src/views/main_web/workspace/components/search-file.vue ファイルの表示

@@ -1,38 +0,0 @@
<template>
<div>
<app-header
backBtnTitle="退出" theme="basis" :title="centerTitle"
:showUserCenter="true" :showBackBtn="true"
>
<template #right>
<search-bar class="proj-search-bar" @searchContentClick="searchForProj"/>
</template>
</app-header>
</div>
</template>

<script>
import AppHeader from "@/components/app-header";
import SearchBar from "@/components/search-bar/search-bar";
export default {
data() {
return {
centerTitle: `“${this.searchContent}”的搜索结果`
}
},
components: {
AppHeader,
SearchBar,
},
props: {
searchContent: {
type: String,
default: ''
}
}
}
</script>

<style scoped lang="scss">

</style>

+ 146
- 27
src/views/main_web/workspace/workspace.new.vue ファイルの表示

@@ -1,23 +1,75 @@
<template>
<div v-cloak>
<app-header
:title="projectName"
:title="showTitle"
backBtnTitle="退出"
:showUserCenter="true"
class="app-header-style"
:class="{'set-bg': isShowSearchPage}"
v-if="!showWorkline"
>
<!-- <template #right>
<template #right>
<search-bar v-if="isShowSearchBar" class="proj-search-bar"
placeholder="请输入要搜索的文件名"
@changeSearchContent="changeSearchContent"
@hideSearchBar="isShowSearchBar = false"
@goToSearch="searchForProj"/>
@hideSearchBar="hideSearchBar"
@goToSearch="searchForFile"/>
<div class="search-entry" @click.stop="isShowSearchBar = true" v-if="!isShowSearchBar"></div>
</template> -->
</template>
</app-header>
<div v-if="isShowSearchPage">
<change-btn :titleList="titleList" class="operate-bar"/>
<div v-if="isShowSearchPage" class="search-res-page">
<change-btn :titleList="titleList" class="operate-bar"
@changeContentBtnClick="changeContentBtnClick"/>
<div class="out-wrap">
<div class="search-res-page-wrap">
<div class="list-group" v-if="currentBtnIndex == 0">
<FileItem
class="lisy-group-item"
v-for="file in searchWorkFileList"
:key="file.id"
:file="file"
:clientDownLoad="clientDownLoad"
:showFileMilestone="showFileMilestone"
:nodeFolder="currentNodeFolder"
:currentFolder="currentFolder"
:commitFile="commitFile"
@dblclickFile="fileClick(file)"
@filePreview="filePreview"
@openFileWith="openFileWith(file)"
@openfileBtnClick="fileClick(file)"
@copyFileBtnClick="copyWorkFileBtnClick(file)"
@oneFileRightBtnClick="oneFileRightBtnClick"
@deleteFileClick="deleteFileClick"
:tempRightFileId="tempRightFileId"
:localFileHashMap="localFileHashMap"
:loadingState="localFileLoadStateMap[file.id]"
@dragstart.native="onfileDragStart(file, $event)"
draggable
/>
</div>
<div class="list-group" v-else-if="currentBtnIndex == 1">
<FileItem
v-for="file in searchWorkFileList"
:key="file.id"
:file="file"
:tempRightFileId="tempRightFileId"
:clientDownLoad="clientDownLoad"
:showFileMilestone="showFileMilestone"
:nodeFolder="currentNodeFolder"
:currentFolder="currentFolder"
@dblclickFile="fileClick(file)"
@filePreview="filePreview"
@openFileWith="openFileWith(file)"
@openfileBtnClick="fileClick(file)"
@oneFileRightBtnClick="oneFileRightBtnClick"
:localFileHashMap="localFileHashMap"
:loadingState="localFileLoadStateMap[file.id]"
@dragstart.native="onfileDragStart(file, $event)"
draggable
/>
</div>
</div>
</div>
</div>
<div v-else>
<app-header
@@ -46,7 +98,6 @@
<div class="layout_content2" v-show="!showWorkline" v-loading="loading">
<section
id="workspace"
ref="workfilescrollbar"
:class="`${closepageH} layerout_H2`"
@contextmenu.prevent="rightShowMenu($event, '新建文件夹', 4)"
>
@@ -405,7 +456,7 @@
<script>
import Vue from "vue";
import AppHeader from "@/components/app-header";
// import SearchBar from "@/components/search-bar/search-bar";
import SearchBar from "@/components/search-bar/search-bar";
import ChangeBtn from "@/components/change-btn/change-btn";
import commonJs from "@/common/webCommon";
// import forgeview from "@/views/components/forgeview/forgeview.vue";
@@ -427,7 +478,7 @@ import { firstCharToLowerCase, firstCharToUpperCase, notify } from '@/utils/tool
import FileItem from './components/file-item';
import FolderItem from './components/folder-item';
import { FileWorkStatus, getFileStoreKey, injectionFileLocalStatus, LoadingEnum, VirtualFolder, analyzeRelativePath, imgExtensionList, RecExtensionList, VideoExtensionList, office, filePreviewList } from './helper';
import { propertyOf, uniqBy, throttle, flatten } from 'lodash';
import { propertyOf, uniqBy, throttle, flatten, debounce } from 'lodash';
import { fetchApi } from '@/utils/request';
const $ = window.jQuery;
const Velocity = window.Velocity;
@@ -475,7 +526,7 @@ const initialFolderData = () =>({
export default {
components: {
AppHeader,
// SearchBar,
SearchBar,
ChangeBtn,
WorkLine,
AddFileButton,
@@ -552,14 +603,17 @@ export default {
localFolderLoadStateMap: {},

tempRightFileId: "", // 存储点击了右键菜单的id
workFileScrollBar: null,
isShowStartNodeFolders: true,//协作文件是否显示一开始的节点文件夹
isfinishGetExchangeNodes: false,
exchangeNodeListsInCoop: [],//存储与当前节点具有交换关系的节点列表
reverseLocalFileHashMap: {},//键名是 ipfscid 键值是localFileHashMap的键名

currentBtnIndex: 0,//0 是工作文件按钮 1是协作文件按钮
titleList: ['工作文件', '协作文件'],
isShowSearchBar: false,//控制搜索框显示隐藏
isShowSearchPage: false,//是否显示搜索文件页面
searchContent: '',//搜索的文件名称
searchWorkFileList: [],//搜索得到的工作文件列表
searchCoopFileList: [],//搜索得到的协作文件列表
};
},
mounted: function () {
@@ -585,10 +639,6 @@ export default {
}
);
this.intervalTask();


this.workFileScrollBar = this.$refs.workfilescrollbar;
// this.workFileScrollBar && this.workFileScrollBar.addEventListener('scroll', this.workFilePartScrollListener);
},
destroyed: function () {
window.removeEventListener("scroll", this.onscroll);
@@ -600,6 +650,14 @@ export default {
sessionStorage.removeItem('nowFolderIndex');
},
computed: {
// 搜索文件时 中间导航栏的标题
showTitle() {
return this.isShowSearchBar && this.searchContent ? `“${this.searchContent}”搜索结果` : this.projectName;
},
isShowSearchPage() {
const rg = /^\s*$/;
return this.isShowSearchBar && !rg.test(this.searchContent);
},
// 创建样板文件的标题 创建XXX文件
showNewTemplateFileDialogTitle() {
return `创建${this.currentSelectTempFile ? this.currentSelectTempFile.extension : ''}文件`;
@@ -618,6 +676,42 @@ export default {
}
},
methods: {
/**
* 搜索文件
*/
//切换点击工作文件 协作文件
changeContentBtnClick(index) {
this.currentBtnIndex = index;
console.log(index);
},
changeSearchContent(content) {
this.searchContent = content;
},
hideSearchBar() {
this.isShowSearchBar = false;
this.searchContent = '';
},
searchForFile: debounce(async function() {
const rg = /^\s*$/;
if(rg.test(this.searchContent)) {
return;
} else {
const folderId = this.currentNodeFolder.id;
const res = await services.searchFileListByFolderIdAndFileName(folderId, this.searchContent);
if(res.Code === 0) {
const tempWorkFileList = res.Data.workFile || [];
const tempCoopFileList = res.Data.coordinationFiles || [];
this.searchWorkFileList = tempWorkFileList.length > 0 ? tempWorkFileList.map(f => firstCharToLowerCase(f)) : [];
this.searchCoopFileList = tempCoopFileList.length > 0 ? tempCoopFileList.map(cf => firstCharToLowerCase(cf)) : [];
} else {
this.$notify({
type: ['error'],
message:'查询数据失败, 请稍后重试。'
})
}
}
}, 500),
notPicIcon() {
return !this.oneOf(this.currentSelectTempFile.extension, imgExtensionList) && !this.oneOf(this.currentSelectTempFile.extension, VideoExtensionList)
},
@@ -738,14 +832,6 @@ export default {
videoClose(){
this.videoSrc="";
},
// 工作文件区域滚动条监听 卷去的头部 scrollTop >= scrollHeight - clientHeight的时候 认为滑到了底部
workFilePartScrollListener() {
const tempBar = this.workFileScrollBar;
if(tempBar && tempBar.scrollTop >= tempBar.scrollHeight - tempBar.clientHeight) {
console.log('滑到了底部');
this.openCopage();
}
},
// 删除文件夹 递归删除文件夹下面的所有文件
deleteFolderClick(id) {
const { isClient, subFolderList, workFileList, subFolderMap, userId, localFileHashMap, reverseLocalFileHashMap } = this;
@@ -1565,7 +1651,6 @@ export default {
this.neibianju = "neibianju";
this.closepageH = "";
// this.workFileScrollBar ? this.workFileScrollBar.scrollTop = 0 : "";
},
/**
* 点击了复制文件副本的按钮
@@ -1635,6 +1720,9 @@ export default {
}
},
watch: {
searchContent() {
this.searchForFile();
},
localFileHashMap(val) {
let temp = {};
for(let key in val) {
@@ -1688,6 +1776,7 @@ export default {
.app-header-style .app-header-content-right {
display: flex;
}

</style>
<style lang="scss" scoped>
.titleBox {
@@ -1817,6 +1906,36 @@ export default {

</style>
<style scoped lang="scss">
.set-bg {
background-color: #f6f6f6;
}
.operate-bar {
width: 162px;
margin: 28px auto 15px;
}

.search-res-page-wrap {
margin: 0 64px;
box-sizing: border-box;
}
.out-wrap {
height: calc(100vh - (48px + 28px + 28px + 15px));
overflow: scroll;
}
.out-wrap::-webkit-scrollbar{
width: 8px;
border-radius: 4px;
}

.out-wrap::-webkit-scrollbar-thumb {
-webkit-border-radius: 10px;
border-radius: 10px;
height: 10px;
background-color: #adadad;
}

/*当前窗口失去焦点时的滑块样式*/
.out-wrap::-webkit-scrollbar-thumb:window-inactive {
background-color: #adadad;
}
</style>

読み込み中…
キャンセル
保存