提交 290502b3 authored 作者: wangjiahao's avatar wangjiahao

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

上级 3c17fc57
...@@ -56,6 +56,10 @@ public class PanelTemplateService { ...@@ -56,6 +56,10 @@ public class PanelTemplateService {
public PanelTemplateDTO save(PanelTemplateRequest request) { public PanelTemplateDTO save(PanelTemplateRequest request) {
if (StringUtils.isEmpty(request.getId())) { if (StringUtils.isEmpty(request.getId())) {
//如果level 是0(第一级)设置父级为对应的templateType
if(request.getLevel()==0){
request.setPid(request.getTemplateType());
}
request.setId(UUID.randomUUID().toString()); request.setId(UUID.randomUUID().toString());
request.setCreateTime(System.currentTimeMillis()); request.setCreateTime(System.currentTimeMillis());
panelTemplateMapper.insert(request); panelTemplateMapper.insert(request);
......
<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>
<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>
...@@ -51,7 +51,7 @@ ...@@ -51,7 +51,7 @@
</span> </span>
<span> <span>
<span v-if="data.nodeType ==='folder'" @click.stop> <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"> <span class="el-dropdown-link">
<el-button <el-button
icon="el-icon-plus" icon="el-icon-plus"
...@@ -60,10 +60,10 @@ ...@@ -60,10 +60,10 @@
/> />
</span> </span>
<el-dropdown-menu slot="dropdown"> <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') }} {{ $t('panel.groupAdd') }}
</el-dropdown-item> </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') }} {{ $t('panel.panelAdd') }}
</el-dropdown-item> </el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
...@@ -79,7 +79,7 @@ ...@@ -79,7 +79,7 @@
/> />
</span> </span>
<el-dropdown-menu slot="dropdown"> <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') }} {{ $t('panel.rename') }}
</el-dropdown-item> </el-dropdown-item>
<el-dropdown-item icon="el-icon-delete" :command="beforeClickMore('delete',data,node)"> <el-dropdown-item icon="el-icon-delete" :command="beforeClickMore('delete',data,node)">
...@@ -136,6 +136,10 @@ ...@@ -136,6 +136,10 @@
<el-button @click="copyUri">复制链接</el-button> <el-button @click="copyUri">复制链接</el-button>
</span> --> </span> -->
</el-dialog> </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>
</el-col> </el-col>
</template> </template>
...@@ -145,14 +149,44 @@ import GrantAuth from '../GrantAuth' ...@@ -145,14 +149,44 @@ import GrantAuth from '../GrantAuth'
import LinkGenerate from '@/views/link/generate' import LinkGenerate from '@/views/link/generate'
import { uuid } from 'vue-uuid' import { uuid } from 'vue-uuid'
import bus from '@/utils/bus' import bus from '@/utils/bus'
import eventBus from '@/components/canvas/utils/eventBus' import EditPanel from './EditPanel'
import { loadTable, getScene, addGroup, delGroup, addTable, delTable, groupTree, defaultTree, get } from '@/api/panel/panel' import { addGroup, delGroup, groupTree, defaultTree, get } from '@/api/panel/panel'
export default { export default {
name: 'PanelList', name: 'PanelList',
components: { GrantAuth, LinkGenerate }, components: { GrantAuth, LinkGenerate, EditPanel },
data() { data() {
return { 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: '链接分享', linkTitle: '链接分享',
linkVisible: false, linkVisible: false,
linkResourceId: null, linkResourceId: null,
...@@ -163,7 +197,6 @@ export default { ...@@ -163,7 +197,6 @@ export default {
dialogTitle: '', dialogTitle: '',
search: '', search: '',
editGroup: false, editGroup: false,
editTable: false,
tData: [], tData: [],
tableData: [], tableData: [],
currGroup: {}, currGroup: {},
...@@ -197,87 +230,99 @@ export default { ...@@ -197,87 +230,99 @@ export default {
} }
}, },
computed: { computed: {
panelDialogTitle() {
return this.editPanel.titlePre + this.editPanel.titleSuf
}
}, },
watch: { watch: {
// search(val){
// this.groupForm.name = val;
// this.tree(this.groupForm);
// }
}, },
mounted() { mounted() {
this.defaultTree() this.defaultTree()
this.tree(this.groupForm) this.tree(this.groupForm)
this.refresh()
this.tableTree()
// this.$router.push('/dataset');
}, },
methods: { methods: {
clickAdd(param) { closeEditPanelDialog() {
// console.log(param); this.editPanel.visible = false
this.add(param.type) this.tree(this.groupForm)
this.groupForm.pid = param.data.id
this.groupForm.level = param.data.level + 1
}, },
showEditPanel(param) {
beforeClickAdd(type, data, node) { 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 { return {
'type': type, 'type': type,
'data': data, 'data': data,
'node': node 'node': node,
'optType': optType
} }
}, },
clickMore(param) { clickMore(param) {
console.log(param) debugger
switch (param.type) { switch (param.optType) {
case 'rename': case 'edit':
this.add(param.data.nodeType) this.showEditPanel(param)
this.groupForm = JSON.parse(JSON.stringify(param.data))
break break
case 'move': case 'move':
break break
case 'delete': case 'delete':
this.delete(param.data) this.delete(param.data)
break 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': case 'share':
this.share(param.data) this.share(param.data)
break break
case 'edit':
this.edit(param.data)
break
case 'link': case 'link':
this.link(param.data) this.link(param.data)
break break
} }
}, },
beforeClickMore(type, data, node) { beforeClickMore(optType, data, node) {
return { return {
'type': type, 'type': data.nodeType,
'data': data, 'data': data,
'node': node 'node': node,
'optType': optType
} }
}, },
add(nodeType) { add(nodeType) {
this.groupForm.nodeType = nodeType
switch (nodeType) { switch (nodeType) {
case 'folder': case 'folder':
this.dialogTitle = this.$t('panel.groupAdd') this.dialogTitle = this.$t('panel.groupAdd')
this.editGroup = true
break break
case 'panel': case 'panel':
this.dialogTitle = this.$t('panel.panelAdd') this.editPanel.title = this.$t('panel.panelAdd')
this.editPanel.visible = true
break break
} }
this.groupForm.nodeType = nodeType
this.editGroup = true
}, },
saveGroup(group) { saveGroup(group) {
...@@ -304,34 +349,6 @@ export default { ...@@ -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) { delete(data) {
this.$confirm(this.$t('panel.confirm_delete'), this.$t('panel.tips'), { this.$confirm(this.$t('panel.confirm_delete'), this.$t('panel.tips'), {
confirmButtonText: this.$t('panel.confirm'), confirmButtonText: this.$t('panel.confirm'),
...@@ -350,27 +367,6 @@ export default { ...@@ -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() { close() {
this.editGroup = false this.editGroup = false
this.groupForm = { this.groupForm = {
...@@ -382,14 +378,6 @@ export default { ...@@ -382,14 +378,6 @@ export default {
sort: 'node_type desc,name asc' sort: 'node_type desc,name asc'
} }
}, },
closeTable() {
this.editTable = false
this.tableForm = {
name: ''
}
},
tree(group) { tree(group) {
groupTree(group).then(res => { groupTree(group).then(res => {
this.tData = res.data this.tData = res.data
...@@ -404,18 +392,6 @@ export default { ...@@ -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) { nodeClick(data, node) {
if (data.nodeType === 'panel') { if (data.nodeType === 'panel') {
// 加载视图数据 // 加载视图数据
...@@ -440,72 +416,12 @@ export default { ...@@ -440,72 +416,12 @@ export default {
this.$store.dispatch('dataset/setSceneData', null) this.$store.dispatch('dataset/setSceneData', null)
this.$emit('switchComponent', { name: '' }) 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) { beforeClickAddData(type) {
return { return {
'type': type '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) { share(data) {
this.authResourceId = data.id this.authResourceId = data.id
this.authTitle = '把[' + data.label + ']分享给' this.authTitle = '把[' + data.label + ']分享给'
......
...@@ -95,6 +95,7 @@ export default { ...@@ -95,6 +95,7 @@ export default {
templateStyle: JSON.stringify(this.canvasStyleData), templateStyle: JSON.stringify(this.canvasStyleData),
templateData: JSON.stringify(this.componentData), templateData: JSON.stringify(this.componentData),
templateType: 'self', templateType: 'self',
nodeType: 'folder',
level: 1, level: 1,
pid: null, pid: null,
dynamicData: '' dynamicData: ''
...@@ -105,12 +106,12 @@ export default { ...@@ -105,12 +106,12 @@ export default {
downloadToTemplate() { downloadToTemplate() {
html2canvas(this.$refs.imageWrapper).then(canvas => { html2canvas(this.$refs.imageWrapper).then(canvas => {
debugger debugger
const snapShot = canvas.toDataURL('image/jpeg', 0.2) // 0.2是图片质量 const snapshot = canvas.toDataURL('image/jpeg', 0.2) // 0.2是图片质量
if (snapShot !== '') { if (snapshot !== '') {
this.templateInfo = { this.templateInfo = {
name: this.$store.state.panel.panelInfo.name, name: this.$store.state.panel.panelInfo.name,
templateType: 'self', templateType: 'self',
snapShot: snapShot, snapshot: snapshot,
panelStyle: JSON.stringify(this.canvasStyleData), panelStyle: JSON.stringify(this.canvasStyleData),
panelData: JSON.stringify(this.componentData), panelData: JSON.stringify(this.componentData),
dynamicData: '' dynamicData: ''
...@@ -124,10 +125,10 @@ export default { ...@@ -124,10 +125,10 @@ export default {
this.templateInfo = '' this.templateInfo = ''
html2canvas(this.$refs.imageWrapper).then(canvas => { html2canvas(this.$refs.imageWrapper).then(canvas => {
debugger debugger
const snapShot = canvas.toDataURL('image/jpeg', 0.2) // 0.2是图片质量 const snapshot = canvas.toDataURL('image/jpeg', 0.2) // 0.2是图片质量
if (snapShot !== '') { if (snapshot !== '') {
this.templateInfo = { this.templateInfo = {
snapShot: snapShot, snapshot: snapshot,
panelStyle: JSON.stringify(this.canvasStyleData), panelStyle: JSON.stringify(this.canvasStyleData),
panelData: JSON.stringify(this.componentData), panelData: JSON.stringify(this.componentData),
dynamicData: '' dynamicData: ''
......
<template> <template>
<el-row> <el-row>
<el-row> <el-row>
<el-col span="4">模板名称</el-col> <el-col :span="4">模板名称</el-col>
<el-col span="20"> <el-col :span="20">
<el-input v-model="templateInfo.name" clearable size="mini" /> <el-input v-model="templateInfo.name" clearable size="mini" />
</el-col> </el-col>
</el-row> </el-row>
......
...@@ -67,7 +67,7 @@ ...@@ -67,7 +67,7 @@
<script> <script>
export default { export default {
name: 'SystemTemplateList', name: 'TemplateList',
components: { }, components: { },
props: { props: {
templateType: { templateType: {
......
...@@ -98,7 +98,7 @@ export default { ...@@ -98,7 +98,7 @@ export default {
this.templateEditForm = JSON.parse(JSON.stringify(templateInfo)) this.templateEditForm = JSON.parse(JSON.stringify(templateInfo))
} else { } else {
this.dialogTitle = '新建' this.dialogTitle = '新建'
this.templateEditForm = { name: '', templateType: this.currentTemplateType, level: 0 } this.templateEditForm = { name: '', nodeType: 'template', templateType: this.currentTemplateType, level: 0 }
} }
this.editTemplate = true this.editTemplate = true
}, },
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论