@@ -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,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); | |||
} | |||
} | |||
} | |||
@@ -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 { | |||
@@ -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', | |||
@@ -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> | |||
@@ -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(); | |||
@@ -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> | |||
@@ -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() { | |||
@@ -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" | |||
@@ -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> |
@@ -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> |