|
@@ -1,6 +1,6 @@
|
|
<template>
|
|
<template>
|
|
<WorkspaceCard class="work-common" title="常用功能">
|
|
<WorkspaceCard class="work-common" title="常用功能">
|
|
- <span slot="header-right" class="header-right-set" @click="changeDialogState(true)"><i class="icon-set-img"></i> 设置</span>
|
|
|
|
|
|
+ <span slot="header-right" class="header-right-set" @click="setCommonFun"><i class="icon-set-img"></i> 设置</span>
|
|
<div class="common-lists">
|
|
<div class="common-lists">
|
|
<div class="list-item" v-for="item in commonList" :key="item.id" @click="openLink(item)">
|
|
<div class="list-item" v-for="item in commonList" :key="item.id" @click="openLink(item)">
|
|
<div class="icon-box-container" v-if="item.icon && item.icon.indexOf('icon-') === 0">
|
|
<div class="icon-box-container" v-if="item.icon && item.icon.indexOf('icon-') === 0">
|
|
@@ -13,7 +13,7 @@
|
|
</div>
|
|
</div>
|
|
<span v-html="item.name" class="item-name"></span>
|
|
<span v-html="item.name" class="item-name"></span>
|
|
</div>
|
|
</div>
|
|
- <div v-if="commonList && commonList.length < maxCount" class="list-add" @click="changeDialogState(true)">
|
|
|
|
|
|
+ <div v-if="commonList && commonList.length < maxCount" class="list-add" @click="setCommonFun">
|
|
<span class="icon-add-img"></span>
|
|
<span class="icon-add-img"></span>
|
|
<span class="add-text">添加常用功能</span>
|
|
<span class="add-text">添加常用功能</span>
|
|
</div>
|
|
</div>
|
|
@@ -32,9 +32,54 @@
|
|
<div class="transfer-content">
|
|
<div class="transfer-content">
|
|
<Transfer :maxCount="maxCount" submitKey="id" :left="allFunctions" :right="transferCommonList" @onSave="onTransferSave"></Transfer>
|
|
<Transfer :maxCount="maxCount" submitKey="id" :left="allFunctions" :right="transferCommonList" @onSave="onTransferSave"></Transfer>
|
|
</div>
|
|
</div>
|
|
- <!-- <p class="more-tips">最多可选择 <em style="color:#2CB7CA;">{{ maxCount }}</em> 个常用功能</p> -->
|
|
|
|
</SelectorCard>
|
|
</SelectorCard>
|
|
</el-dialog>
|
|
</el-dialog>
|
|
|
|
+ <!-- 改为抽屉式 -->
|
|
|
|
+ <DrawerCard customClass="drawer-class" title="常用功能设置" percent="600px" :with-header="false" v-model="showDrawer" @close="onCloseDrawer" @saveData="onSaveDrawer">
|
|
|
|
+ <div class="function-drawer-content" @scroll="handleScroll($event)">
|
|
|
|
+ <div class="added-function">
|
|
|
|
+ <h3 class="added-title">已添加({{addedList.length}})</h3>
|
|
|
|
+ <transition-group class="added-container" name="drag" tag="ul" v-if="addedList && addedList.length > 0">
|
|
|
|
+ <li class="added-item" draggable v-for="(item, i) in addedList" :key="item.id" @dragstart="onDragstart(i)" @dragenter="onDragenter($event, i)" @dragover="onDragover($event, i)">
|
|
|
|
+ <div class="icon-box-container">
|
|
|
|
+ <el-image :src="item.icon" :alt="item.name">
|
|
|
|
+ <img slot="error" src="https://www.jianyu360.cn/common-module/public/image/auto.png" />
|
|
|
|
+ </el-image>
|
|
|
|
+ </div>
|
|
|
|
+ <span v-html="item.name" class="item-name"></span>
|
|
|
|
+ <span class="remove-tag" @click.stop="onAddedRemove(item)">-</span>
|
|
|
|
+ </li>
|
|
|
|
+ </transition-group>
|
|
|
|
+ <div v-else class="no-added">暂未设置常用功能</div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="classify-function" ref="refContent">
|
|
|
|
+ <div class="classify-tab" :class="{'tab-fixed': tabFixed}" ref="tabBox">
|
|
|
|
+ <span class="tab-item" :class="{'active': tabActive === index}" v-for="(item, index) in tabNames" :key="item.id" @click="goAnchor(item, index)">{{item.name}}</span>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="classify-content">
|
|
|
|
+ <ul class="outer-container">
|
|
|
|
+ <li class="outer-item" v-for="level in mainFunList" :key="level.id">
|
|
|
|
+ <h3 class="outer-item-name" :id="level.name">{{ level.name }}</h3>
|
|
|
|
+ <ul class="insert-container">
|
|
|
|
+ <li class="insert-item" v-for="next in level.children" :key="next.id">
|
|
|
|
+ <div class="insert-item-left">
|
|
|
|
+ <el-image :src="next.icon" :alt="next.name">
|
|
|
|
+ <img slot="error" src="/common-module/public/image/auto.png" />
|
|
|
|
+ </el-image>
|
|
|
|
+ <span v-html="next.name"></span>
|
|
|
|
+ </div>
|
|
|
|
+ <transition name="el-zoom-in-center">
|
|
|
|
+ <span v-if="next.status" class="handle-btn remove-btn" @click.stop="onRemoveFun(next)">移除</span>
|
|
|
|
+ <span v-else class="handle-btn add-btn" @click.stop="onAddFun(next)">添加</span>
|
|
|
|
+ </transition>
|
|
|
|
+ </li>
|
|
|
|
+ </ul>
|
|
|
|
+ </li>
|
|
|
|
+ </ul>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </DrawerCard>
|
|
</WorkspaceCard>
|
|
</WorkspaceCard>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
@@ -47,6 +92,8 @@ import SelectorCard from '@/components/selector/SelectorCard'
|
|
import Transfer from '@/components/work-desktop/Transfer'
|
|
import Transfer from '@/components/work-desktop/Transfer'
|
|
import { mixinNoPowerMessageTip } from '@/utils/mixins/no-power-message-box'
|
|
import { mixinNoPowerMessageTip } from '@/utils/mixins/no-power-message-box'
|
|
import { tryCallHooks } from '@jianyu/easy-inject-qiankun'
|
|
import { tryCallHooks } from '@jianyu/easy-inject-qiankun'
|
|
|
|
+import { debounce } from '@/utils/globalFunctions'
|
|
|
|
+import DrawerCard from '@/components/drawer/Drawer.vue'
|
|
|
|
|
|
export default {
|
|
export default {
|
|
name: 'CommonUse',
|
|
name: 'CommonUse',
|
|
@@ -57,7 +104,19 @@ export default {
|
|
WorkspaceCard,
|
|
WorkspaceCard,
|
|
SelectorCard,
|
|
SelectorCard,
|
|
JyIcon,
|
|
JyIcon,
|
|
- Transfer
|
|
|
|
|
|
+ Transfer,
|
|
|
|
+ DrawerCard
|
|
|
|
+ },
|
|
|
|
+ data () {
|
|
|
|
+ return {
|
|
|
|
+ addedList: [],
|
|
|
|
+ mainFunList: [],
|
|
|
|
+ dragIndex: '',
|
|
|
|
+ enterIndex: '',
|
|
|
|
+ showDrawer: false,
|
|
|
|
+ tabActive: 0,
|
|
|
|
+ tabFixed: false
|
|
|
|
+ }
|
|
},
|
|
},
|
|
computed: {
|
|
computed: {
|
|
...mapState({
|
|
...mapState({
|
|
@@ -65,8 +124,26 @@ export default {
|
|
dialogShow: state => state.workspace.commonUse.dialogShow,
|
|
dialogShow: state => state.workspace.commonUse.dialogShow,
|
|
allFunctions: state => state.workspace.commonUse.allFunctions, // 所有功能
|
|
allFunctions: state => state.workspace.commonUse.allFunctions, // 所有功能
|
|
transferCommonList: state => state.workspace.commonUse.transferCommonList,
|
|
transferCommonList: state => state.workspace.commonUse.transferCommonList,
|
|
- commonList: state => state.workspace.commonUse.commonList // 常用功能
|
|
|
|
- })
|
|
|
|
|
|
+ commonList: state => state.workspace.commonUse.commonList, // 常用功能
|
|
|
|
+ mainFunctions: state => state.workspace.commonUse.mainFunctions
|
|
|
|
+ }),
|
|
|
|
+ tabNames () {
|
|
|
|
+ return this.mainFunctions.filter(item => item.level === 1)
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ watch: {
|
|
|
|
+ commonList (val) {
|
|
|
|
+ if (val) {
|
|
|
|
+ this.addedList = JSON.parse(JSON.stringify(val))
|
|
|
|
+ this.formatMainFunList(this.mainFunList, this.addedList)
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ mainFunctions (val) {
|
|
|
|
+ if (val) {
|
|
|
|
+ this.mainFunList = JSON.parse(JSON.stringify(val))
|
|
|
|
+ this.formatMainFunList(this.mainFunList, this.addedList)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
},
|
|
},
|
|
async created () {
|
|
async created () {
|
|
await this.getCanUseFunctions()
|
|
await this.getCanUseFunctions()
|
|
@@ -159,6 +236,116 @@ export default {
|
|
} catch (error) {
|
|
} catch (error) {
|
|
this.$toast(error)
|
|
this.$toast(error)
|
|
}
|
|
}
|
|
|
|
+ },
|
|
|
|
+ onDragstart (index) {
|
|
|
|
+ this.dragIndex = index
|
|
|
|
+ },
|
|
|
|
+ onDragenter: debounce(function (e, index) {
|
|
|
|
+ e.preventDefault()
|
|
|
|
+ if (this.dragIndex !== index) {
|
|
|
|
+ const source = this.addedList[this.dragIndex]
|
|
|
|
+ this.addedList.splice(this.dragIndex, 1)
|
|
|
|
+ this.addedList.splice(index, 0, source)
|
|
|
|
+ this.dragIndex = index
|
|
|
|
+ const ids = this.addedList.map(v => {
|
|
|
|
+ return v.id
|
|
|
|
+ })
|
|
|
|
+ this.transferSave(ids)
|
|
|
|
+ console.log(ids)
|
|
|
|
+ }
|
|
|
|
+ }, 200),
|
|
|
|
+ onDragover (e, index) {
|
|
|
|
+ e.preventDefault()
|
|
|
|
+ },
|
|
|
|
+ formatMainFunList (allList = [], addedList = []) {
|
|
|
|
+ allList.forEach(v => {
|
|
|
|
+ v.children.forEach(t => {
|
|
|
|
+ addedList.forEach(s => {
|
|
|
|
+ if (s.id === t.id) {
|
|
|
|
+ t.status = true
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ })
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+ onCloseDrawer () {
|
|
|
|
+ this.showDrawer = false
|
|
|
|
+ },
|
|
|
|
+ onSaveDrawer () {
|
|
|
|
+ this.confirmSaveFn()
|
|
|
|
+ this.showDrawer = false
|
|
|
|
+ },
|
|
|
|
+ setCommonFun () {
|
|
|
|
+ this.showDrawer = true
|
|
|
|
+ },
|
|
|
|
+ onRemoveFun (item) {
|
|
|
|
+ this.addedList.splice(this.addedList.findIndex(add => add.id === item.id), 1)
|
|
|
|
+ item.status = false
|
|
|
|
+ const ids = this.addedList.map(v => {
|
|
|
|
+ return v.id
|
|
|
|
+ })
|
|
|
|
+ this.transferSave(ids)
|
|
|
|
+ this.$forceUpdate()
|
|
|
|
+ },
|
|
|
|
+ onAddFun (item) {
|
|
|
|
+ this.addedList.unshift(item)
|
|
|
|
+ item.status = true
|
|
|
|
+ const ids = this.addedList.map(v => {
|
|
|
|
+ return v.id
|
|
|
|
+ })
|
|
|
|
+ this.transferSave(ids)
|
|
|
|
+ this.$forceUpdate()
|
|
|
|
+ },
|
|
|
|
+ onAddedRemove (item) {
|
|
|
|
+ this.addedList.splice(this.addedList.findIndex(add => add.id === item.id), 1)
|
|
|
|
+ this.mainFunList.forEach(v => {
|
|
|
|
+ if (v.children) {
|
|
|
|
+ v.children.forEach(s => {
|
|
|
|
+ if (item.id === s.id) {
|
|
|
|
+ s.status = false
|
|
|
|
+ this.$forceUpdate()
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+ goAnchor (item, index) {
|
|
|
|
+ this.tabActive = index
|
|
|
|
+ const dom = this.$root.$el.querySelector('#' + item.name)
|
|
|
|
+ const offsetTop = this.getOffsetTop(dom)
|
|
|
|
+ const scrollDom = this.$root.$el.querySelector('.function-drawer-content')
|
|
|
|
+ console.log(offsetTop, index)
|
|
|
|
+ scrollDom.scrollTo({
|
|
|
|
+ /**
|
|
|
|
+ * 抽屉header高度70px, tabs导航栏高度48px, 滚动子元素h3标题高度60px
|
|
|
|
+ */
|
|
|
|
+ top: index === 0 ? (this.tabFixed ? offsetTop - 70 : offsetTop - 70 - 48) : (this.tabFixed ? offsetTop - 70 - 60 : offsetTop - 70 - 60 - 48),
|
|
|
|
+ behavior: 'smooth'
|
|
|
|
+ })
|
|
|
|
+ },
|
|
|
|
+ handleScroll (e) {
|
|
|
|
+ const tabOffsetTop = this.$refs.refContent.getBoundingClientRect().top
|
|
|
|
+ this.tabFixed = tabOffsetTop < 70
|
|
|
|
+ const scrollItems = this.$root.$el.querySelectorAll('.outer-item')
|
|
|
|
+ for (let i = scrollItems.length - 1; i >= 0; i--) {
|
|
|
|
+ // 判断滚动条滚动距离是否大于当前滚动项可滚动距离
|
|
|
|
+ const judge =
|
|
|
|
+ e.target.scrollTop >=
|
|
|
|
+ scrollItems[i].offsetTop - scrollItems[0].offsetTop
|
|
|
|
+ if (judge) {
|
|
|
|
+ this.tabActive = i
|
|
|
|
+ break
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ },
|
|
|
|
+ // 获取当前元素的offsetTop
|
|
|
|
+ getOffsetTop (obj) {
|
|
|
|
+ let offsetTop = 0
|
|
|
|
+ while (obj !== window.document.body && obj != null) {
|
|
|
|
+ offsetTop += obj.offsetTop
|
|
|
|
+ obj = obj.offsetParent
|
|
|
|
+ }
|
|
|
|
+ return offsetTop
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -166,7 +353,9 @@ export default {
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
<style lang="scss" scoped>
|
|
$main: #2cb7ca;
|
|
$main: #2cb7ca;
|
|
-
|
|
|
|
|
|
+.drag-move {
|
|
|
|
+ transition: transform .3s;
|
|
|
|
+}
|
|
::v-deep{
|
|
::v-deep{
|
|
.fn-dialog{
|
|
.fn-dialog{
|
|
.el-dialog__header,.el-dialog__body{
|
|
.el-dialog__header,.el-dialog__body{
|
|
@@ -195,6 +384,180 @@ $main: #2cb7ca;
|
|
text-align: center;
|
|
text-align: center;
|
|
color: #686868;
|
|
color: #686868;
|
|
}
|
|
}
|
|
|
|
+ .drawer-class{
|
|
|
|
+ background: #F2F2F4;
|
|
|
|
+ .el-header{
|
|
|
|
+ padding: 26px 30px;
|
|
|
|
+ font-size: 18px;
|
|
|
|
+ background: #fff;
|
|
|
|
+ box-shadow: 0px -1px 0px 0px rgba(0, 0, 0, 0.05) inset;
|
|
|
|
+ }
|
|
|
|
+ .el-main{
|
|
|
|
+ overflow-y: hidden!important;
|
|
|
|
+ }
|
|
|
|
+ .function-drawer-content{
|
|
|
|
+ height: 100%;
|
|
|
|
+ overflow-y: scroll;
|
|
|
|
+ }
|
|
|
|
+ .added-function{
|
|
|
|
+ padding: 16px 30px 24px;
|
|
|
|
+ background: #fff;
|
|
|
|
+ .added-title{
|
|
|
|
+ line-height: 24px;
|
|
|
|
+ font-size: 16px;
|
|
|
|
+ }
|
|
|
|
+ .no-added{
|
|
|
|
+ padding: 40px;
|
|
|
|
+ text-align: center;
|
|
|
|
+ font-size: 16px;
|
|
|
|
+ color: #686868;
|
|
|
|
+ }
|
|
|
|
+ .added-container{
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-wrap: wrap;
|
|
|
|
+ }
|
|
|
|
+ .added-item{
|
|
|
|
+ position: relative;
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-direction: column;
|
|
|
|
+ align-items: center;
|
|
|
|
+ width: 104px;
|
|
|
|
+ min-height: 70px;
|
|
|
|
+ margin: 16px 0 0 0;
|
|
|
|
+ text-align: center;
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
+ border-radius: 8px;
|
|
|
|
+ cursor: move;
|
|
|
|
+ .item-name{
|
|
|
|
+ margin-top: 8px;
|
|
|
|
+ line-height: 22px;
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ color: #1D1D1D;
|
|
|
|
+ }
|
|
|
|
+ .remove-tag{
|
|
|
|
+ position: absolute;
|
|
|
|
+ top: 0;
|
|
|
|
+ right: 8px;
|
|
|
|
+ display: inline-block;
|
|
|
|
+ width: 14px;
|
|
|
|
+ height: 14px;
|
|
|
|
+ line-height: 12px;
|
|
|
|
+ border-radius: 50%;
|
|
|
|
+ background: #FF3A20;
|
|
|
|
+ color: #fff;
|
|
|
|
+ font-weight: bold;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ .classify-function{
|
|
|
|
+ margin-top: 12px;
|
|
|
|
+ .classify-tab{
|
|
|
|
+ padding: 0 12px;
|
|
|
|
+ height: 48px;
|
|
|
|
+ line-height: 48px;
|
|
|
|
+ background: #fff;
|
|
|
|
+ border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
|
|
|
+ }
|
|
|
|
+ .tab-fixed{
|
|
|
|
+ position: fixed;
|
|
|
|
+ top: 70px;
|
|
|
|
+ width: 100%;
|
|
|
|
+ height: 48px;
|
|
|
|
+ background: #fff;
|
|
|
|
+ z-index: 10;
|
|
|
|
+ }
|
|
|
|
+ .tab-item{
|
|
|
|
+ display: inline-block;
|
|
|
|
+ height: 100%;
|
|
|
|
+ padding: 0 20px;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+ }
|
|
|
|
+ .active{
|
|
|
|
+ position: relative;
|
|
|
|
+ color: $main;
|
|
|
|
+ &::after{
|
|
|
|
+ position: absolute;
|
|
|
|
+ content: '';
|
|
|
|
+ width: 32px;
|
|
|
|
+ height: 2px;
|
|
|
|
+ bottom: 0;
|
|
|
|
+ left: 50%;
|
|
|
|
+ margin-left: -16px;
|
|
|
|
+ background: $main;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ .classify-content{
|
|
|
|
+ .outer-container,
|
|
|
|
+ .insert-container{
|
|
|
|
+ display: flex;
|
|
|
|
+ flex-direction: column;
|
|
|
|
+ }
|
|
|
|
+ .outer-item{
|
|
|
|
+ padding-left: 30px;
|
|
|
|
+ margin-bottom: 8px;
|
|
|
|
+ background: #fff;
|
|
|
|
+ &:last-child{
|
|
|
|
+ min-height: 100%;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ .outer-item-name{
|
|
|
|
+ padding: 24px 0 8px;
|
|
|
|
+ font-size: 18px;
|
|
|
|
+ line-height: 28px;
|
|
|
|
+ font-weight: 700;
|
|
|
|
+ color: #1D1D1D;
|
|
|
|
+ }
|
|
|
|
+ .insert-item{
|
|
|
|
+ position: relative;
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ justify-content: space-between;
|
|
|
|
+ padding: 18px 30px 18px 0;
|
|
|
|
+ &::after{
|
|
|
|
+ position: absolute;
|
|
|
|
+ content: '';
|
|
|
|
+ right: 0;
|
|
|
|
+ left: 60px;
|
|
|
|
+ bottom: 0;
|
|
|
|
+ border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
|
|
|
+ }
|
|
|
|
+ .el-image{
|
|
|
|
+ width: 44px;
|
|
|
|
+ height: 44px;
|
|
|
|
+ flex-shrink: 0;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ .insert-item-left{
|
|
|
|
+ display: flex;
|
|
|
|
+ align-items: center;
|
|
|
|
+ span{
|
|
|
|
+ margin-left: 16px;
|
|
|
|
+ font-size: 16px;
|
|
|
|
+ line-height: 24px;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ .handle-btn{
|
|
|
|
+ width: 72px;
|
|
|
|
+ height: 30px;
|
|
|
|
+ line-height: 28px;
|
|
|
|
+ text-align: center;
|
|
|
|
+ background: transparent;
|
|
|
|
+ cursor: pointer;
|
|
|
|
+ }
|
|
|
|
+ .add-btn{
|
|
|
|
+ border: 1px solid #E0E0E0;
|
|
|
|
+ color: #1D1D1D;
|
|
|
|
+ border-radius: 4px;
|
|
|
|
+ }
|
|
|
|
+ .remove-btn{
|
|
|
|
+ border: 0;
|
|
|
|
+ font-size: 14px;
|
|
|
|
+ color: #FF3A20;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
.icon-box-container {
|
|
.icon-box-container {
|
|
display: flex;
|
|
display: flex;
|