471 lines
18 KiB
Vue
471 lines
18 KiB
Vue
<template>
|
||
<div>
|
||
<el-popover :placement="placement" popper-class="'nz-pop nz-pop-select-panel right-box-select-top right-public-box-dropdown-top nz-pop-select-panel__dropdown'" transition="slide" v-model="popBox.show" :width="536" :disabled="disabled">
|
||
<div class="dashboard-select-wrap">
|
||
<div class="dashboard-select-left">
|
||
<ul class="dashboard-select-list">
|
||
<li class="dashboard-select-item" :class="{active:currentTab===item.value}" v-for="item in tabList" :key="item.value" @click="tabChange(item.value)">
|
||
<i class="nz-icon" :class="item.icon"></i>
|
||
<span>{{item.name}}</span>
|
||
</li>
|
||
</ul>
|
||
<div class="dashboard-select-tail">
|
||
<slot name="button"></slot>
|
||
</div>
|
||
</div>
|
||
<div class="pop-item-wider">
|
||
<div class="dashboard-select-header">
|
||
<el-input v-model="filterPanel" :placeholder="$t('overall.search')" clearable size="small"></el-input>
|
||
<button v-has="'main_add'" :title="$t('dashboard.createPlaylist')" class="top-tool-btn margin-l-10" type="button" @click="addPlaylist" v-if="currentTab==='playlist'">
|
||
<i class="nz-icon-create-square nz-icon"></i>
|
||
</button>
|
||
</div>
|
||
<!-- 全部仪表盘数据(树形结构)-->
|
||
<div :class="{'movable': !panelLock}" class="select-dashboard-tree" v-if="currentTab==='all'">
|
||
<el-tree
|
||
:data="panelData"
|
||
:draggable="!panelLock"
|
||
:expand-on-click-node="false"
|
||
:filter-node-method="filterNode"
|
||
:props="{label: 'name', children: 'children'}"
|
||
@node-click="selectDashboard"
|
||
@node-drop="nodeDrop"
|
||
check-on-click-node
|
||
check-strictly
|
||
default-expand-all
|
||
:highlight-current="true"
|
||
node-key="id"
|
||
ref="panelTree">
|
||
<div class="tree--node" slot-scope="{ node, data }">
|
||
<HighlightText :queries="filterPanel" :highlightClass="'highlight-keyword'" style="vertical-align: middle" :title="node.label + ' (' + data.chartNum +' charts)' ">{{node.label}}</HighlightText>
|
||
<el-row class="block-col-2" style="margin-left:10px;margin-right:8px">
|
||
<el-col>
|
||
<el-dropdown placement="bottom-end" trigger="click" style="margin-right:10px" v-has="['main_edit', 'main_delete']">
|
||
<span class="el-dropdown-link tree--operation" @click.stop><i class="nz-icon nz-icon-more1"></i></span>
|
||
<el-dropdown-menu class="right-box-select-top" slot="dropdown">
|
||
<el-dropdown-item>
|
||
<div @click="editPanel(data)" v-has="'main_edit'"><i class="nz-icon nz-icon-edit"></i>{{$t('overall.edit')}}</div>
|
||
</el-dropdown-item>
|
||
<el-dropdown-item>
|
||
<div @click="deletePanel(data)" v-has="'main_delete'"><i class="nz-icon nz-icon-delete"></i>{{$t('overall.delete')}}</div>
|
||
</el-dropdown-item>
|
||
</el-dropdown-menu>
|
||
</el-dropdown>
|
||
<template>
|
||
<i v-if="data.starred===1" class="nz-icon nz-icon-a-xingzhuang2" @click.stop="delStarred(data)" :title ="$t('overall.starred')"></i>
|
||
<i v-else class="nz-icon nz-icon-xingzhuang" @click.stop="addStarred(data)" :title ="$t('overall.unstarred')"></i>
|
||
</template>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
</el-tree>
|
||
</div>
|
||
<!-- 我的收藏、我的创建、最近浏览数据、轮播列表(无层级关系) -->
|
||
<div class="select-dashboard-tree" :class="{'playlistTree':currentTab==='playlist'}" v-else>
|
||
<el-tree
|
||
:data="otherData"
|
||
:expand-on-click-node="false"
|
||
:filter-node-method="filterNode"
|
||
:props="{label: 'name', children: 'children'}"
|
||
@node-click="selectDashboard"
|
||
@node-drop="nodeDrop"
|
||
check-on-click-node
|
||
check-strictly
|
||
default-expand-all
|
||
:highlight-current="currentTab!=='playlist'"
|
||
node-key="id"
|
||
ref="otherTree">
|
||
<div class="tree--node" slot-scope="{ node, data }" v-if="currentTab!=='playlist'">
|
||
<HighlightText :queries="filterPanel" :highlightClass="'highlight-keyword'" style="vertical-align: middle" :title="node.label + ' (' + data.chartNum +' charts)' ">{{node.label}}</HighlightText>
|
||
<el-row class="block-col-2" style="margin-left:10px;margin-right:8px">
|
||
<el-col>
|
||
<el-dropdown placement="bottom-end" trigger="click" style="margin-right:10px" v-has="['main_edit', 'main_delete']">
|
||
<span class="el-dropdown-link tree--operation" @click.stop><i class="nz-icon nz-icon-more1"></i></span>
|
||
<el-dropdown-menu class="right-box-select-top nz-el-dropdown-menu" slot="dropdown">
|
||
<el-dropdown-item>
|
||
<div @click="editPanel(data)" v-has="'main_edit'"><i class="nz-icon nz-icon-edit"></i>{{$t('overall.edit')}}</div>
|
||
</el-dropdown-item>
|
||
<el-dropdown-item>
|
||
<div @click="deletePanel(data)" v-has="'main_delete'"><i class="nz-icon nz-icon-delete"></i>{{$t('overall.delete')}}</div>
|
||
</el-dropdown-item>
|
||
</el-dropdown-menu>
|
||
</el-dropdown>
|
||
<template>
|
||
<i v-if="data.starred===1" class="nz-icon nz-icon-a-xingzhuang2" @click.stop="delStarred(data)" :title ="$t('overall.starred')"></i>
|
||
<i v-else class="nz-icon nz-icon-xingzhuang" @click.stop="addStarred(data)" :title ="$t('overall.unstarred')"></i>
|
||
</template>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
<!-- 轮播列表 -->
|
||
<div class="tree--node" slot-scope="{ node, data }" v-else>
|
||
<HighlightText :queries="filterPanel" :highlightClass="'highlight-keyword'" style="vertical-align: middle">{{node.label}}</HighlightText>
|
||
<el-row class="block-col-2" style="margin-left:10px;margin-right:8px">
|
||
<el-col>
|
||
<el-dropdown placement="bottom-end" trigger="click" style="margin-right:10px" v-has="['main_edit', 'main_delete']">
|
||
<span class="el-dropdown-link tree--operation" @click.stop><i class="nz-icon nz-icon-more1"></i></span>
|
||
<el-dropdown-menu class="right-box-select-top nz-el-dropdown-menu" slot="dropdown">
|
||
<el-dropdown-item>
|
||
<div @click="editPlaylist(data)" v-has="'main_edit'"><i class="nz-icon nz-icon-edit"></i>{{$t('overall.edit')}}</div>
|
||
</el-dropdown-item>
|
||
<el-dropdown-item>
|
||
<div @click="deletePlaylist(data)" v-has="'main_delete'"><i class="nz-icon nz-icon-delete"></i>{{$t('overall.delete')}}</div>
|
||
</el-dropdown-item>
|
||
</el-dropdown-menu>
|
||
</el-dropdown>
|
||
<template>
|
||
<i class="nz-icon nz-icon-bofang" @click.stop="startPlay(data)" :title ="$t('dashboard.startPlaylist')"></i>
|
||
</template>
|
||
</el-col>
|
||
</el-row>
|
||
</div>
|
||
</el-tree>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div slot="reference">
|
||
<slot name="trigger"></slot>
|
||
</div>
|
||
</el-popover>
|
||
<transition name="right-box">
|
||
<playlistBox v-if="playlistVisible" @close="closePlaylist" :obj="playlistObj"></playlistBox>
|
||
</transition>
|
||
</div>
|
||
</template>
|
||
<script>
|
||
import bus from '@/libs/bus'
|
||
import HighlightText from 'vue-text-highlight'
|
||
import playlistBox from '@/components/common/rightBox/playlistBox'
|
||
export default {
|
||
name: 'selectDashboard',
|
||
components: {
|
||
HighlightText,
|
||
playlistBox
|
||
},
|
||
props: {
|
||
placement: { type: String },
|
||
panelData: { type: Array },
|
||
showPanel: { type: Object },
|
||
panelLock: { type: Boolean, default: true },
|
||
disabled: { type: Boolean, default: false }
|
||
},
|
||
watch: {
|
||
filterPanel: {
|
||
handler (n) {
|
||
if (this.currentTab === 'all') {
|
||
this.$refs.panelTree && this.$refs.panelTree.filter(n)
|
||
} else {
|
||
this.$refs.otherTree && this.$refs.otherTree.filter(n)
|
||
}
|
||
}
|
||
},
|
||
showPanel: {
|
||
immediate: true,
|
||
handler (n) {
|
||
if (n) {
|
||
this.panel = JSON.parse(JSON.stringify(n))
|
||
// 设置最近浏览数据
|
||
this.setBrowse()
|
||
this.setData()
|
||
}
|
||
}
|
||
},
|
||
panelData: {
|
||
immediate: true,
|
||
async handler () {
|
||
// 获取收藏列表
|
||
this.getStarred()
|
||
this.setData()
|
||
}
|
||
}
|
||
},
|
||
data () {
|
||
return {
|
||
popBox: { show: false },
|
||
panel: { id: 0, name: '' },
|
||
tabList: [
|
||
{ name: this.$t('dashboard.allDashboards'), icon: 'nz-icon-a-leimucuquanbu', value: 'all' },
|
||
{ name: this.$t('dashboard.starredDashboards'), icon: 'nz-icon-xingzhuang', value: 'starred' },
|
||
{ name: this.$t('dashboard.createdByYou'), icon: 'nz-icon-wodechuangjian', value: 'create' },
|
||
{ name: this.$t('dashboard.recentlyViewed'), icon: 'nz-icon-liulanlishi', value: 'browse' },
|
||
{ name: this.$t('dashboard.playlist'), icon: 'nz-icon-Playlists', value: 'playlist' }
|
||
],
|
||
currentTab: 'all',
|
||
// 过滤值
|
||
filterPanel: '',
|
||
// 其他tab的数据(我的收藏、我的创建、最近浏览数据)
|
||
otherData: [],
|
||
// 收藏列表
|
||
starredList: [],
|
||
playlist: [],
|
||
playlistVisible: false,
|
||
playlistObj: {}
|
||
}
|
||
},
|
||
created () {
|
||
this.getPlaylist()
|
||
},
|
||
methods: {
|
||
// 左侧tab点击
|
||
tabChange (value) {
|
||
if (this.currentTab !== value) {
|
||
this.currentTab = value
|
||
this.filterPanel = ''
|
||
}
|
||
this.setData()
|
||
},
|
||
// 设置树形菜单数据
|
||
setData (type = this.currentTab) {
|
||
const userId = localStorage.getItem('nz-user-id')
|
||
switch (type) {
|
||
case 'starred': { // 我的收藏
|
||
this.otherData = JSON.parse(JSON.stringify(this.starredList))
|
||
break
|
||
}
|
||
case 'create': { // 我的创建
|
||
const flatArr = bus.flatten(this.panelData)
|
||
this.otherData = flatArr.filter(item => item.createBy == userId)
|
||
break
|
||
}
|
||
case 'browse': { // 最近浏览
|
||
const browseArr = JSON.parse(localStorage.getItem(`nz-view-dashboard-${userId}`) || '[]')
|
||
const flatArr = bus.flatten(this.panelData)
|
||
const tempArr = []
|
||
// 比对id获取最近浏览的数据
|
||
browseArr.forEach(item => {
|
||
flatArr.forEach(subItem => {
|
||
if (item.id === subItem.id) {
|
||
tempArr.push(subItem)
|
||
}
|
||
})
|
||
})
|
||
this.otherData = JSON.parse(JSON.stringify(tempArr))
|
||
break
|
||
}
|
||
case 'playlist': {
|
||
this.otherData = JSON.parse(JSON.stringify(this.playlist))
|
||
break
|
||
}
|
||
}
|
||
// 设置当前面板高亮 以及保持搜索状态
|
||
this.$nextTick(() => {
|
||
if (this.currentTab === 'all') {
|
||
this.$refs.panelTree && this.$refs.panelTree.setCurrentKey(this.showPanel)
|
||
this.$refs.panelTree && this.$refs.panelTree.filter(this.filterPanel)
|
||
} else {
|
||
this.$refs.otherTree && this.$refs.otherTree.setCurrentKey(this.showPanel)
|
||
this.$refs.otherTree && this.$refs.otherTree.filter(this.filterPanel)
|
||
}
|
||
})
|
||
},
|
||
startPlay (val) {
|
||
const data = this.$lodash.cloneDeep(val)
|
||
data.dashboardIds = JSON.parse(data.dashboardIds)
|
||
if (data.dashboardIds.length) {
|
||
this.esc()
|
||
this.$emit('startPlay', data)
|
||
} else {
|
||
this.$message.error(this.$t('PLAYLIST_DASHBOARD_IDS_ISNULL'))
|
||
}
|
||
},
|
||
async getPlaylist () {
|
||
const res = await this.$get('/visual/playlist', { pageSize: -1 })
|
||
this.playlist = res.data.list
|
||
this.setData()
|
||
},
|
||
addPlaylist () {
|
||
this.esc()
|
||
this.playlistObj = {
|
||
name: '',
|
||
intvl: undefined,
|
||
dashboardIds: [],
|
||
mode: 'normal'
|
||
}
|
||
this.playlistVisible = true
|
||
},
|
||
async editPlaylist (data) {
|
||
this.esc()
|
||
const res = await this.$get('/visual/playlist/' + data.id)
|
||
this.playlistObj = {
|
||
id: res.data.id,
|
||
name: res.data.name,
|
||
intvl: res.data.intvl,
|
||
dashboardIds: res.data.dashboardIds,
|
||
mode: res.data.mode || 'normal'
|
||
}
|
||
this.playlistObj.dashboardIds = JSON.parse(this.playlistObj.dashboardIds)
|
||
this.playlistVisible = true
|
||
},
|
||
async deletePlaylist (data) {
|
||
this.$confirm(this.$t('tip.confirmDelete'), {
|
||
confirmButtonText: this.$t('tip.yes'),
|
||
cancelButtonText: this.$t('tip.no'),
|
||
type: 'warning'
|
||
}).then(() => {
|
||
this.$delete('/visual/playlist?ids=' + data.id).then((response) => {
|
||
if (response.code === 200) {
|
||
this.$message({
|
||
duration: 1000,
|
||
type: 'success',
|
||
message: this.$t('tip.deleteSuccess')
|
||
})
|
||
this.getPlaylist(true)
|
||
} else {
|
||
this.$message.error(response.msg)
|
||
}
|
||
})
|
||
})
|
||
},
|
||
closePlaylist (refresh) {
|
||
this.playlistVisible = false
|
||
if (refresh) {
|
||
this.getPlaylist()
|
||
}
|
||
},
|
||
// 获取收藏的列表
|
||
async getStarred () {
|
||
// 1: 已收藏 0:未收藏
|
||
const flatArr = bus.flatten(this.panelData) // 数组对象扁平化
|
||
this.starredList = flatArr.filter(item => {
|
||
return item.starred === 1
|
||
})
|
||
},
|
||
// 存储最近浏览的面板
|
||
setBrowse () {
|
||
const userId = localStorage.getItem('nz-user-id')
|
||
// 获取最近浏览id数组
|
||
let browseArr = JSON.parse(localStorage.getItem(`nz-view-dashboard-${userId}`) || '[]')
|
||
const flatArr = bus.flatten(this.panelData)
|
||
// 若最近浏览的数据已被删除 则截取掉
|
||
for (let i = 0; i < browseArr.length; i++) {
|
||
const flag = flatArr.some(item => {
|
||
return item.id === browseArr[i].id
|
||
})
|
||
if (flag === false) {
|
||
browseArr.splice(i, 1)
|
||
i--
|
||
}
|
||
}
|
||
// 若已经存在 则先删除
|
||
const value = browseArr.find(item => item.id === this.panel.id)
|
||
if (value) {
|
||
browseArr = browseArr.filter(item => item.id !== value.id)
|
||
}
|
||
// 追加到数组前边
|
||
browseArr.unshift({ id: this.panel.id })
|
||
// 如果数组长度大于10则截取
|
||
browseArr.splice(10)
|
||
localStorage.setItem(`nz-view-dashboard-${userId}`, JSON.stringify(browseArr))
|
||
},
|
||
// 新增收藏
|
||
addStarred: bus.debounceFn(function (data) {
|
||
const params = {
|
||
type: 'dashboard',
|
||
tid: data.id
|
||
}
|
||
this.$post('/sys/user/starred', params).then(async response => {
|
||
if (response.code === 200) {
|
||
data.starred = 1
|
||
// 更新panelData收藏状态
|
||
handler(this.panelData)
|
||
function handler (list) {
|
||
list.forEach(item => {
|
||
if (item.id === data.id) {
|
||
item.starred = 1
|
||
} else if (item.children && item.children.length > 0) {
|
||
handler(item.children)
|
||
}
|
||
})
|
||
}
|
||
this.getStarred()
|
||
this.setData()
|
||
// 更新父组件面板收藏状态
|
||
this.$set(this.$parent.showPanel, 'starred', this.starredList.some(item => item.id === this.showPanel.id) ? 1 : 0)
|
||
}
|
||
})
|
||
},
|
||
300, true),
|
||
// 删除收藏
|
||
delStarred: bus.debounceFn(function (data) {
|
||
this.$delete('/sys/user/starred?type=dashboard&tid=' + data.id).then(async response => {
|
||
if (response.code === 200) {
|
||
data.starred = 0
|
||
// 更新panelData收藏状态
|
||
handler(this.panelData)
|
||
function handler (list) {
|
||
list.forEach(item => {
|
||
if (item.id === data.id) {
|
||
item.starred = 0
|
||
} else if (item.children && item.children.length > 0) {
|
||
handler(item.children)
|
||
}
|
||
})
|
||
}
|
||
this.getStarred()
|
||
this.setData()
|
||
// 更新父组件面板收藏状态
|
||
this.$set(this.$parent.showPanel, 'starred', this.starredList.some(item => item.id === this.showPanel.id) ? 1 : 0)
|
||
}
|
||
})
|
||
},
|
||
300, true),
|
||
|
||
/*
|
||
* node: 被拖的节点
|
||
* relative: 发生关系的节点
|
||
* position: ['before', 'after', 'inner'] 与relative节点的关系
|
||
* */
|
||
nodeDrop (node, relative, position, event) {
|
||
if (position === 'inner') {
|
||
node.data.pid = relative.data.id
|
||
} else {
|
||
node.data.pid = relative.data.pid
|
||
}
|
||
this.updateWeight()
|
||
},
|
||
filterNode (value, data) {
|
||
if (!value) return true
|
||
// 不区分大小写
|
||
return data.name.toLowerCase().indexOf(value.toLowerCase()) !== -1
|
||
},
|
||
updateWeight (data) {
|
||
const toUpdate = []
|
||
let count = 0
|
||
|
||
handler(this.panelData)
|
||
function handler (panelData) {
|
||
panelData.forEach(panel => {
|
||
panel.weight = count++
|
||
toUpdate.push({ id: panel.id, pid: panel.pid, weight: panel.weight })
|
||
if (panel.children && panel.children.length > 0) {
|
||
handler(panel.children)
|
||
}
|
||
})
|
||
}
|
||
this.$put('visual/dashboard/tree', toUpdate)
|
||
},
|
||
deletePanel (data) {
|
||
this.$emit('deletePanel', data)
|
||
},
|
||
editPanel (data) {
|
||
this.$emit('editPanel', data)
|
||
this.esc()
|
||
},
|
||
esc () {
|
||
this.popBox.show = false
|
||
},
|
||
// 确认选择某个节点,与父组件交互
|
||
selectDashboard (data, checked, child) {
|
||
if (this.currentTab === 'all') {
|
||
this.$refs.panelTree && this.$refs.panelTree.setCurrentKey(data)
|
||
} else {
|
||
this.$refs.otherTree && this.$refs.otherTree.setCurrentKey(data)
|
||
}
|
||
if (this.currentTab === 'playlist') return
|
||
this.$emit('selectDashboard', data, 'select')
|
||
this.esc()
|
||
}
|
||
}
|
||
}
|
||
</script>
|