feat:新建仪表盘修改 同时支持自建 复用 导入

This commit is contained in:
wangjiahao 2021-04-21 18:48:57 +08:00
parent 3c17fc57c0
commit 290502b35b
8 changed files with 385 additions and 184 deletions

View File

@ -56,6 +56,10 @@ public class PanelTemplateService {
public PanelTemplateDTO save(PanelTemplateRequest request) {
if (StringUtils.isEmpty(request.getId())) {
//如果level 是0第一级设置父级为对应的templateType
if(request.getLevel()==0){
request.setPid(request.getTemplateType());
}
request.setId(UUID.randomUUID().toString());
request.setCreateTime(System.currentTimeMillis());
panelTemplateMapper.insert(request);

View File

@ -0,0 +1,113 @@
<template xmlns:el-col="http://www.w3.org/1999/html">
<el-col>
<el-row style="margin-top: 5px">
<el-row>
<el-input
v-model="templateFilterText"
placeholder="输入关键字进行过滤"
size="mini"
clearable
prefix-icon="el-icon-search"
/>
</el-row>
<el-row style="margin-top: 5px">
<el-tree
ref="templateTree"
:default-expanded-keys="defaultExpandedKeys"
:data="templateList"
node-key="id"
:expand-on-click-node="true"
:filter-node-method="filterNode"
:highlight-current="true"
@node-click="nodeClick"
>
<span slot-scope="{ node, data }" class="custom-tree-node">
<span>
<span v-if="data.nodeType==='template'">
<el-button
icon="el-icon-picture-outline"
type="text"
/>
</span>
<span v-if="data.nodeType==='folder'">
<el-button
icon="el-icon-folder"
type="text"
/>
</span>
<span style="margin-left: 6px">{{ data.name }}</span>
</span>
</span></el-tree>
</el-row>
</el-row>
</el-col>
</template>
<script>
export default {
name: 'TemplateAllList',
components: { },
props: {
templateList: {
type: Array,
default: function() {
return []
}
}
},
data() {
return {
templateFilterText: '',
defaultExpandedKeys: [],
currentTemplateShowList: []
}
},
computed: {
},
watch: {
templateFilterText(val) {
this.$refs.templateTree.filter(val)
}
},
methods: {
clickMore(param) {
console.log(param)
switch (param.type) {
case 'edit':
this.templateEdit(param.data)
break
case 'delete':
this.templateDelete(param.data)
break
}
},
beforeClickMore(type, data, node) {
return {
'type': type,
'data': data,
'node': node
}
},
filterNode(value, data) {
if (!value) return true
return data.label.indexOf(value) !== -1
},
nodeClick(data, node) {
this.$emit('showCurrentTemplateInfo', data)
}
}
}
</script>
<style scoped>
.custom-tree-node {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
font-size: 14px;
padding-right: 8px;
}
</style>

View File

@ -0,0 +1,167 @@
<template>
<el-row>
<el-row v-if="editPanel.optType==='new' && editPanel.panelInfo.nodeType==='panel'">
<el-col :span="18" style="height: 40px">
<el-radio v-model="inputType" label="self">自定义</el-radio>
<el-radio v-model="inputType" label="import">导入模板</el-radio>
<el-radio v-model="inputType" label="copy">复用模板</el-radio>
</el-col>
<el-col v-if="inputType==='import'" :span="6">
<el-button class="el-icon-upload" size="small" type="primary" @click="goFile">上传模板</el-button>
<input id="input" ref="files" type="file" accept=".DE" hidden @change="handleFileChange">
</el-col>
</el-row>
<el-row style="margin-top: 5px">
<el-col :span="4">{{ editPanel.titleSuf }}名称</el-col>
<el-col :span="20">
<el-input v-model="editPanel.panelInfo.name" clearable size="mini" />
</el-col>
</el-row>
<el-row v-if="inputType==='copy'" class="preview">
<el-col :span="8" style="overflow: auto">
<template-all-list :template-list="templateList" @showCurrentTemplateInfo="showCurrentTemplateInfo" />
</el-col>
<el-col :span="16" :style="classBackground" class="preview-show" />
</el-row>
<el-row v-if="inputType==='import'" class="preview" :style="classBackground" />
<el-row class="root-class">
<el-button @click="cancel()"> </el-button>
<el-button type="primary" @click="save()"> </el-button>
</el-row>
</el-row>
</template>
<script>
import { post } from '@/api/panel/panel'
import TemplateAllList from './TemplateAllList'
export default {
components: { TemplateAllList },
props: {
editPanel: {
type: Object,
required: true
}
},
data() {
return {
inputType: 'self',
fieldName: 'name',
tableRadio: null,
keyWordSearch: '',
columnLabel: '所属类别',
templateList: [],
importTemplateInfo: {
snapshot: ''
}
}
},
computed: {
classBackground() {
return {
background: `url(${this.importTemplateInfo.snapshot}) no-repeat`
}
}
},
watch: {
inputType() {
this.editPanel.panelInfo.name = null
this.editPanel.panelInfo.panelStyle = null
this.editPanel.panelInfo.panelData = null
this.importTemplateInfo.snapshot = null
}
},
created() {
this.getTree()
},
methods: {
showCurrentTemplateInfo(data) {
this.editPanel.panelInfo.name = data.name
this.editPanel.panelInfo.panelStyle = data.templateStyle
this.editPanel.panelInfo.panelData = data.templateData
this.importTemplateInfo.snapshot = data.snapshot
},
getTree() {
const request = {
level: '-1',
withChildren: true
}
post('/template/templateList', request).then(res => {
this.templateList = res.data
})
},
handleExceed(file) {
console.log(file.name)
},
cancel() {
this.$emit('closeEditPanelDialog')
},
save() {
if (!this.editPanel.panelInfo.name) {
this.$warning('名称不能为空')
return false
}
post('/panel/group/save', this.editPanel.panelInfo).then(response => {
this.$message({
message: '保存成功',
type: 'success',
showClose: true
})
this.$emit('closeEditPanelDialog')
})
},
handleFileChange(e) {
debugger
const file = e.target.files[0]
const reader = new FileReader()
reader.onload = (res) => {
const result = res.target.result
this.importTemplateInfo = JSON.parse(result)
this.editPanel.panelInfo.name = this.importTemplateInfo.name
this.editPanel.panelInfo.panelStyle = this.importTemplateInfo.panelStyle
this.editPanel.panelInfo.panelData = this.importTemplateInfo.panelData
console.log(this.importTemplateInfo)
}
reader.readAsText(file)
},
goFile() {
this.$refs.files.click()
}
}
}
</script>
<style scoped>
.my_table >>> .el-table__row>td{
/* 去除表格线 */
border: none;
padding: 0 0;
}
.my_table >>> .el-table th.is-leaf {
/* 去除上边框 */
border: none;
}
.my_table >>> .el-table::before{
/* 去除下边框 */
height: 0;
}
.root-class {
margin: 15px 0px 5px;
text-align: center;
}
.preview {
margin-top: 5px;
border:1px solid #E6E6E6;
height:300px !important;
overflow:auto;
background-size: 100% 100% !important;
}
.preview-show {
border-left:1px solid #E6E6E6;
height:300px;
background-size: 100% 100% !important;
}
</style>

View File

@ -51,7 +51,7 @@
</span>
<span>
<span v-if="data.nodeType ==='folder'" @click.stop>
<el-dropdown trigger="click" size="small" @command="clickAdd">
<el-dropdown trigger="click" size="small" @command="showEditPanel">
<span class="el-dropdown-link">
<el-button
icon="el-icon-plus"
@ -60,10 +60,10 @@
/>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item icon="el-icon-circle-plus" :command="beforeClickAdd('folder',data,node)">
<el-dropdown-item icon="el-icon-circle-plus" :command="beforeClickEdit('folder','new',data,node)">
{{ $t('panel.groupAdd') }}
</el-dropdown-item>
<el-dropdown-item icon="el-icon-folder-add" :command="beforeClickAdd('panel',data,node)">
<el-dropdown-item icon="el-icon-folder-add" :command="beforeClickEdit('panel','new',data,node)">
{{ $t('panel.panelAdd') }}
</el-dropdown-item>
</el-dropdown-menu>
@ -79,7 +79,7 @@
/>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item icon="el-icon-edit-outline" :command="beforeClickMore('rename',data,node)">
<el-dropdown-item icon="el-icon-edit-outline" :command="beforeClickMore('edit',data,node)">
{{ $t('panel.rename') }}
</el-dropdown-item>
<el-dropdown-item icon="el-icon-delete" :command="beforeClickMore('delete',data,node)">
@ -136,6 +136,10 @@
<el-button @click="copyUri">复制链接</el-button>
</span> -->
</el-dialog>
<!--新建仪表盘dialog-->
<el-dialog :title="panelDialogTitle" :visible.sync="editPanel.visible" :show-close="true" width="600px">
<edit-panel v-if="editPanel.visible" :edit-panel="editPanel" @closeEditPanelDialog="closeEditPanelDialog" />
</el-dialog>
</el-col>
</el-col>
</template>
@ -145,14 +149,44 @@ import GrantAuth from '../GrantAuth'
import LinkGenerate from '@/views/link/generate'
import { uuid } from 'vue-uuid'
import bus from '@/utils/bus'
import eventBus from '@/components/canvas/utils/eventBus'
import { loadTable, getScene, addGroup, delGroup, addTable, delTable, groupTree, defaultTree, get } from '@/api/panel/panel'
import EditPanel from './EditPanel'
import { addGroup, delGroup, groupTree, defaultTree, get } from '@/api/panel/panel'
export default {
name: 'PanelList',
components: { GrantAuth, LinkGenerate },
components: { GrantAuth, LinkGenerate, EditPanel },
data() {
return {
editPanelModel: {
titlePre: null,
titleSuf: null,
visible: false,
optType: null,
panelInfo: {
name: null,
pid: null,
level: null,
nodeType: null,
panelType: null,
panelStyle: null,
panelDate: null
}
},
editPanel: {
titlePre: null,
titleSuf: '仪表盘',
visible: false,
optType: 'new',
panelInfo: {
name: null,
pid: null,
level: null,
nodeType: null,
panelType: null,
panelStyle: null,
panelDate: null
}
},
linkTitle: '链接分享',
linkVisible: false,
linkResourceId: null,
@ -163,7 +197,6 @@ export default {
dialogTitle: '',
search: '',
editGroup: false,
editTable: false,
tData: [],
tableData: [],
currGroup: {},
@ -197,87 +230,99 @@ export default {
}
},
computed: {
panelDialogTitle() {
return this.editPanel.titlePre + this.editPanel.titleSuf
}
},
watch: {
// search(val){
// this.groupForm.name = val;
// this.tree(this.groupForm);
// }
},
mounted() {
this.defaultTree()
this.tree(this.groupForm)
this.refresh()
this.tableTree()
// this.$router.push('/dataset');
},
methods: {
clickAdd(param) {
// console.log(param);
this.add(param.type)
this.groupForm.pid = param.data.id
this.groupForm.level = param.data.level + 1
closeEditPanelDialog() {
this.editPanel.visible = false
this.tree(this.groupForm)
},
beforeClickAdd(type, data, node) {
showEditPanel(param) {
this.editPanel = JSON.parse(JSON.stringify(this.editPanelModel))
this.editPanel.optType = param.optType
this.editPanel.panelInfo.nodeType = param.type
this.editPanel.visible = true
switch (param.optType) {
case 'new':
this.editPanel.titlePre = '新建'
this.editPanel.panelInfo.name = '新建仪表盘'
this.editPanel.panelInfo.pid = param.data.id
this.editPanel.panelInfo.level = param.data.level + 1
break
case 'edit':
this.editPanel.titlePre = '编辑'
this.editPanel.panelInfo.id = param.data.id
this.editPanel.panelInfo.name = param.data.name
break
}
switch (param.type) {
case 'folder':
this.editPanel.titleSuf = '目录'
break
case 'panel':
this.editPanel.titleSuf = '仪表盘'
break
}
},
beforeClickEdit(type, optType, data, node) {
return {
'type': type,
'data': data,
'node': node
'node': node,
'optType': optType
}
},
clickMore(param) {
console.log(param)
switch (param.type) {
case 'rename':
this.add(param.data.nodeType)
this.groupForm = JSON.parse(JSON.stringify(param.data))
debugger
switch (param.optType) {
case 'edit':
this.showEditPanel(param)
break
case 'move':
break
case 'delete':
this.delete(param.data)
break
case 'editTable':
this.editTable = true
this.tableForm = JSON.parse(JSON.stringify(param.data))
this.tableForm.mode = this.tableForm.mode + ''
break
case 'deleteTable':
this.deleteTable(param.data)
break
case 'share':
this.share(param.data)
break
case 'edit':
this.edit(param.data)
break
case 'link':
this.link(param.data)
break
}
},
beforeClickMore(type, data, node) {
beforeClickMore(optType, data, node) {
return {
'type': type,
'type': data.nodeType,
'data': data,
'node': node
'node': node,
'optType': optType
}
},
add(nodeType) {
this.groupForm.nodeType = nodeType
switch (nodeType) {
case 'folder':
this.dialogTitle = this.$t('panel.groupAdd')
this.editGroup = true
break
case 'panel':
this.dialogTitle = this.$t('panel.panelAdd')
this.editPanel.title = this.$t('panel.panelAdd')
this.editPanel.visible = true
break
}
this.groupForm.nodeType = nodeType
this.editGroup = true
},
saveGroup(group) {
@ -304,34 +349,6 @@ export default {
})
},
saveTable(table) {
// console.log(table)
table.mode = parseInt(table.mode)
this.$refs['tableForm'].validate((valid) => {
if (valid) {
addTable(table).then(response => {
this.closeTable()
this.$message({
message: this.$t('commons.save_success'),
type: 'success',
showClose: true
})
this.tableTree()
// this.$router.push('/dataset/home')
this.$emit('switchComponent', { name: '' })
this.$store.dispatch('dataset/setTable', null)
})
} else {
this.$message({
message: this.$t('commons.input_content'),
type: 'error',
showClose: true
})
return false
}
})
},
delete(data) {
this.$confirm(this.$t('panel.confirm_delete'), this.$t('panel.tips'), {
confirmButtonText: this.$t('panel.confirm'),
@ -350,27 +367,6 @@ export default {
})
},
deleteTable(data) {
this.$confirm(this.$t('panel.confirm_delete'), this.$t('panel.tips'), {
confirmButtonText: this.$t('panel.confirm'),
cancelButtonText: this.$t('panel.cancel'),
type: 'warning'
}).then(() => {
delTable(data.id).then(response => {
this.$message({
type: 'success',
message: this.$t('panel.delete_success'),
showClose: true
})
this.tableTree()
// this.$router.push('/dataset/home')
this.$emit('switchComponent', { name: '' })
this.$store.dispatch('dataset/setTable', null)
})
}).catch(() => {
})
},
close() {
this.editGroup = false
this.groupForm = {
@ -382,14 +378,6 @@ export default {
sort: 'node_type desc,name asc'
}
},
closeTable() {
this.editTable = false
this.tableForm = {
name: ''
}
},
tree(group) {
groupTree(group).then(res => {
this.tData = res.data
@ -404,18 +392,6 @@ export default {
})
},
tableTree() {
this.tableData = []
if (this.currGroup.id) {
loadTable({
sort: 'type asc,create_time desc,name asc',
sceneId: this.currGroup.id
}).then(res => {
this.tableData = res.data
})
}
},
nodeClick(data, node) {
if (data.nodeType === 'panel') {
//
@ -440,72 +416,12 @@ export default {
this.$store.dispatch('dataset/setSceneData', null)
this.$emit('switchComponent', { name: '' })
},
clickAddData(param) {
// console.log(param);
switch (param.type) {
case 'db':
this.addDB()
break
case 'sql':
this.$message(param.type)
break
case 'excel':
this.$message(param.type)
break
case 'custom':
this.$message(param.type)
break
}
},
beforeClickAddData(type) {
return {
'type': type
}
},
addDB() {
// this.$router.push({
// name: 'add_db',
// params: {
// scene: this.currGroup
// }
// })
this.$emit('switchComponent', { name: 'AddDB', param: this.currGroup })
},
sceneClick(data, node) {
// console.log(data);
this.$store.dispatch('dataset/setTable', null)
this.$store.dispatch('dataset/setTable', data.id)
// this.$router.push({
// name: 'table',
// params: {
// table: data
// }
// })
this.$emit('switchComponent', { name: 'ViewTable' })
},
refresh() {
const path = this.$route.path
if (path === '/dataset/table') {
this.sceneMode = true
const sceneId = this.$store.state.dataset.sceneData
getScene(sceneId).then(res => {
this.currGroup = res.data
})
}
},
panelDefaultClick(data, node) {
console.log(data)
console.log(node)
this.$store.dispatch('panel/setPanelInfo', data)
// view
this.$emit('switchComponent', { name: 'PanelView' })
},
share(data) {
this.authResourceId = data.id
this.authTitle = '把[' + data.label + ']分享给'

View File

@ -95,6 +95,7 @@ export default {
templateStyle: JSON.stringify(this.canvasStyleData),
templateData: JSON.stringify(this.componentData),
templateType: 'self',
nodeType: 'folder',
level: 1,
pid: null,
dynamicData: ''
@ -105,12 +106,12 @@ export default {
downloadToTemplate() {
html2canvas(this.$refs.imageWrapper).then(canvas => {
debugger
const snapShot = canvas.toDataURL('image/jpeg', 0.2) // 0.2
if (snapShot !== '') {
const snapshot = canvas.toDataURL('image/jpeg', 0.2) // 0.2
if (snapshot !== '') {
this.templateInfo = {
name: this.$store.state.panel.panelInfo.name,
templateType: 'self',
snapShot: snapShot,
snapshot: snapshot,
panelStyle: JSON.stringify(this.canvasStyleData),
panelData: JSON.stringify(this.componentData),
dynamicData: ''
@ -124,10 +125,10 @@ export default {
this.templateInfo = ''
html2canvas(this.$refs.imageWrapper).then(canvas => {
debugger
const snapShot = canvas.toDataURL('image/jpeg', 0.2) // 0.2
if (snapShot !== '') {
const snapshot = canvas.toDataURL('image/jpeg', 0.2) // 0.2
if (snapshot !== '') {
this.templateInfo = {
snapShot: snapShot,
snapshot: snapshot,
panelStyle: JSON.stringify(this.canvasStyleData),
panelData: JSON.stringify(this.componentData),
dynamicData: ''

View File

@ -1,8 +1,8 @@
<template>
<el-row>
<el-row>
<el-col span="4">模板名称</el-col>
<el-col span="20">
<el-col :span="4">模板名称</el-col>
<el-col :span="20">
<el-input v-model="templateInfo.name" clearable size="mini" />
</el-col>
</el-row>

View File

@ -67,7 +67,7 @@
<script>
export default {
name: 'SystemTemplateList',
name: 'TemplateList',
components: { },
props: {
templateType: {

View File

@ -98,7 +98,7 @@ export default {
this.templateEditForm = JSON.parse(JSON.stringify(templateInfo))
} else {
this.dialogTitle = '新建'
this.templateEditForm = { name: '', templateType: this.currentTemplateType, level: 0 }
this.templateEditForm = { name: '', nodeType: 'template', templateType: this.currentTemplateType, level: 0 }
}
this.editTemplate = true
},