mirror of
https://github.com/dataease/dataease.git
synced 2026-05-23 22:08:34 +08:00
Merge branch 'dev-v2' into pr@dev-v2_dzz
This commit is contained in:
@@ -2,33 +2,33 @@ import request from '@/config/axios'
|
||||
|
||||
export function save(data) {
|
||||
return request.post({
|
||||
url: '/template/save',
|
||||
url: '/templateManage/save',
|
||||
data: data,
|
||||
loading: true
|
||||
})
|
||||
}
|
||||
export function templateDelete(id) {
|
||||
return request.post({
|
||||
url: '/template/delete/' + id
|
||||
url: '/templateManage/delete/' + id
|
||||
})
|
||||
}
|
||||
|
||||
export function showTemplateList(data) {
|
||||
return request.post({
|
||||
url: '/template/templateList',
|
||||
url: '/templateManage/templateList',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
export function findOne(id) {
|
||||
return request.get({
|
||||
url: '/template/findOne/' + id
|
||||
url: '/templateManage/findOne/' + id
|
||||
})
|
||||
}
|
||||
|
||||
export function find(data) {
|
||||
return request.post({
|
||||
url: '/template/find',
|
||||
url: '/templateManage/find',
|
||||
data: data,
|
||||
loading: true
|
||||
})
|
||||
@@ -36,7 +36,7 @@ export function find(data) {
|
||||
|
||||
export function nameCheck(data) {
|
||||
return request.post({
|
||||
url: '/template/nameCheck',
|
||||
url: '/templateManage/nameCheck',
|
||||
data: data
|
||||
})
|
||||
}
|
||||
|
||||
BIN
core/core-frontend/src/assets/none.png
Normal file
BIN
core/core-frontend/src/assets/none.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
BIN
core/core-frontend/src/assets/nothing.png
Normal file
BIN
core/core-frontend/src/assets/nothing.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.0 KiB |
@@ -361,3 +361,9 @@ em {
|
||||
background-color: #1F232999;
|
||||
}
|
||||
}
|
||||
|
||||
.de-icon-sense {
|
||||
margin-right: 9px;
|
||||
width: 16px !important;
|
||||
height: 12px !important;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
import html2canvas from 'html2canvas'
|
||||
import JsPDF from 'jspdf'
|
||||
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { findResourceAsBase64 } from '@/api/staticResource'
|
||||
import FileSaver from 'file-saver'
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const { canvasStyleData, componentData, canvasViewInfo, dvInfo } = storeToRefs(dvMainStore)
|
||||
const basePath = import.meta.env.VITE_API_BASEPATH
|
||||
|
||||
export function imgUrlTrans(url) {
|
||||
@@ -20,6 +25,37 @@ export function imgUrlTrans(url) {
|
||||
}
|
||||
}
|
||||
|
||||
export function download2AppTemplate(downloadType, canvasDom, name, callBack?) {
|
||||
try {
|
||||
findStaticSource(function (staticResource) {
|
||||
html2canvas(canvasDom).then(canvas => {
|
||||
const snapshot = canvas.toDataURL('image/jpeg', 0.1) // 0.1是图片质量
|
||||
if (snapshot !== '') {
|
||||
const templateInfo = {
|
||||
name: name,
|
||||
templateType: 'self',
|
||||
snapshot: snapshot,
|
||||
dvType: dvInfo.value.type,
|
||||
canvasStyleData: JSON.stringify(canvasStyleData.value),
|
||||
componentData: JSON.stringify(componentData.value),
|
||||
dynamicData: JSON.stringify(canvasViewInfo.value),
|
||||
staticResource: JSON.stringify(staticResource || {})
|
||||
}
|
||||
const blob = new Blob([JSON.stringify(templateInfo)], { type: '' })
|
||||
if (downloadType === 'template') {
|
||||
FileSaver.saveAs(blob, name + '-TEMPLATE.DET2')
|
||||
}
|
||||
}
|
||||
if (callBack) {
|
||||
callBack()
|
||||
}
|
||||
})
|
||||
})
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
|
||||
export function downloadCanvas(type, canvasDom, name, callBack?) {
|
||||
// const canvasDom = document.getElementById(canvasId)
|
||||
if (canvasDom) {
|
||||
@@ -56,15 +92,57 @@ export function downloadCanvas(type, canvasDom, name, callBack?) {
|
||||
}
|
||||
}
|
||||
|
||||
export function dataURLToBlob(dataurl) {
|
||||
export function dataURLToBlob(dataUrl) {
|
||||
// ie 图片转格式
|
||||
const arr = dataurl.split(',')
|
||||
const arr = dataUrl.split(',')
|
||||
const mime = arr[0].match(/:(.*?);/)[1]
|
||||
const bstr = atob(arr[1])
|
||||
let n = bstr.length
|
||||
const bStr = atob(arr[1])
|
||||
let n = bStr.length
|
||||
const u8arr = new Uint8Array(n)
|
||||
while (n--) {
|
||||
u8arr[n] = bstr.charCodeAt(n)
|
||||
u8arr[n] = bStr.charCodeAt(n)
|
||||
}
|
||||
return new Blob([u8arr], { type: mime })
|
||||
}
|
||||
|
||||
// 解析静态文件
|
||||
export function findStaticSource(callBack) {
|
||||
const staticResource = []
|
||||
// 系统背景文件
|
||||
if (
|
||||
typeof canvasStyleData.value.background === 'string' &&
|
||||
canvasStyleData.value.background.indexOf('static-resource') > -1
|
||||
) {
|
||||
staticResource.push(canvasStyleData.value.background)
|
||||
}
|
||||
componentData.value.forEach(item => {
|
||||
if (
|
||||
typeof item.commonBackground.outerImage === 'string' &&
|
||||
item.commonBackground.outerImage.indexOf('static-resource') > -1
|
||||
) {
|
||||
staticResource.push(item.commonBackground.outerImage)
|
||||
}
|
||||
if (
|
||||
item.component === 'Picture' &&
|
||||
item.propValue['url'] &&
|
||||
typeof item.propValue['url'] === 'string' &&
|
||||
item.propValue['url'].indexOf('static-resource') > -1
|
||||
) {
|
||||
staticResource.push(item.propValue)
|
||||
}
|
||||
})
|
||||
if (staticResource.length > 0) {
|
||||
try {
|
||||
findResourceAsBase64({ resourcePathList: staticResource }).then(rsp => {
|
||||
callBack(rsp.data)
|
||||
})
|
||||
} catch (e) {
|
||||
console.error('findResourceAsBase64 error', e)
|
||||
callBack()
|
||||
}
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
callBack()
|
||||
}, 0)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import { useRequestStoreWithOut } from '@/store/modules/request'
|
||||
import { usePermissionStoreWithOut } from '@/store/modules/permission'
|
||||
import { useMoveLine } from '@/hooks/web/useMoveLine'
|
||||
import { Icon } from '@/components/icon-custom'
|
||||
import { downloadCanvas } from '@/utils/imgUtils'
|
||||
import { download2AppTemplate, downloadCanvas } from '@/utils/imgUtils'
|
||||
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const previewCanvasContainer = ref(null)
|
||||
@@ -89,7 +89,16 @@ const downloadH2 = type => {
|
||||
downloadCanvas(type, vueDom, state.dvInfo.name, () => {
|
||||
downloadStatus.value = false
|
||||
})
|
||||
}, 200)
|
||||
})
|
||||
}
|
||||
|
||||
const downloadAsAppTemplate = downloadType => {
|
||||
nextTick(() => {
|
||||
const vueDom = previewCanvasContainer.value.querySelector('.canvas-container')
|
||||
download2AppTemplate(downloadType, vueDom, state.dvInfo.name, () => {
|
||||
downloadStatus.value = false
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const slideOpenChange = () => {
|
||||
@@ -155,7 +164,12 @@ defineExpose({
|
||||
</div>
|
||||
<!--从store中判断当前是否有点击仪表板 复用时也符合-->
|
||||
<template v-if="previewShowFlag">
|
||||
<preview-head v-if="showPosition === 'preview'" @reload="reload" @download="downloadH2" />
|
||||
<preview-head
|
||||
v-if="showPosition === 'preview'"
|
||||
@reload="reload"
|
||||
@download="downloadH2"
|
||||
@downloadAsAppTemplate="downloadAsAppTemplate"
|
||||
/>
|
||||
<div ref="previewCanvasContainer" class="content">
|
||||
<de-preview
|
||||
ref="dashboardPreview"
|
||||
|
||||
@@ -8,7 +8,7 @@ import { ref, watch } from 'vue'
|
||||
import { XpackComponent } from '@/components/plugin'
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const { dvInfo } = storeToRefs(dvMainStore)
|
||||
const emit = defineEmits(['reload', 'download'])
|
||||
const emit = defineEmits(['reload', 'download', 'downloadAsAppTemplate'])
|
||||
const { t } = useI18n()
|
||||
|
||||
const favorited = ref(false)
|
||||
@@ -24,6 +24,9 @@ const reload = () => {
|
||||
const download = type => {
|
||||
emit('download', type)
|
||||
}
|
||||
const downloadAsAppTemplate = downloadType => {
|
||||
emit('downloadAsAppTemplate', downloadType)
|
||||
}
|
||||
|
||||
const dvEdit = () => {
|
||||
const baseUrl = dvInfo.value.type === 'dataV' ? '#/dvCanvas?dvId=' : '#/dashboard?resourceId='
|
||||
@@ -124,6 +127,9 @@ watch(
|
||||
<el-dropdown-item style="width: 118px" @click="download('pdf')"
|
||||
>PDF</el-dropdown-item
|
||||
>
|
||||
<el-dropdown-item style="width: 118px" @click="downloadAsAppTemplate('template')"
|
||||
>模版</el-dropdown-item
|
||||
>
|
||||
<el-dropdown-item @click="download('img')">{{
|
||||
t('chart.image')
|
||||
}}</el-dropdown-item>
|
||||
|
||||
@@ -1,3 +1,48 @@
|
||||
<template>
|
||||
<h2>template setting page for jiahao.wang</h2>
|
||||
<p class="router-title">模版管理</p>
|
||||
<div class="sys-setting-p">
|
||||
<div class="container-sys-param">
|
||||
<template-manage></template-manage>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { ref } from 'vue'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import TemplateManage from '@/views/template/index.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const activeName = ref('basic')
|
||||
const handleClick = (tab, event: Event) => {
|
||||
console.log(tab, event)
|
||||
}
|
||||
</script>
|
||||
<style lang="less">
|
||||
.router-title {
|
||||
color: #1f2329;
|
||||
font-feature-settings: 'clig' off, 'liga' off;
|
||||
font-family: PingFang SC;
|
||||
font-size: 20px;
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
line-height: 28px;
|
||||
}
|
||||
.sys-setting-p {
|
||||
width: 100%;
|
||||
background: var(--ContentBG, #ffffff);
|
||||
height: calc(100vh - 176px);
|
||||
box-sizing: border-box;
|
||||
margin-top: 12px;
|
||||
}
|
||||
.setting-auto-h {
|
||||
height: auto !important;
|
||||
}
|
||||
|
||||
.container-sys-param {
|
||||
height: 100%;
|
||||
overflow-y: auto;
|
||||
}
|
||||
</style>
|
||||
<style lang="less" scoped></style>
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
<template>
|
||||
<h2>template marget page for jiahao.wang</h2>
|
||||
<template-manage></template-manage>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import TemplateManage from '@/views/template/index.vue'
|
||||
</script>
|
||||
|
||||
@@ -6,17 +6,17 @@
|
||||
:model="state.templateInfo"
|
||||
:rules="state.templateInfoRules"
|
||||
>
|
||||
<el-form-item :label="t('system_parameter_setting.template_name')" prop="name">
|
||||
<el-form-item :label="'模版名称'" prop="name">
|
||||
<div class="flex-template">
|
||||
<el-input v-model="state.templateInfo.name" clearable size="small" />
|
||||
<el-button style="margin-left: 10px" class="el-icon-upload2" secondary @click="goFile">{{
|
||||
t('panel.upload_template')
|
||||
t('visualization.upload_template')
|
||||
}}</el-button>
|
||||
<input
|
||||
id="input"
|
||||
ref="filesRef"
|
||||
type="file"
|
||||
accept=".DET"
|
||||
accept=".DET2"
|
||||
hidden
|
||||
@change="handleFileChange"
|
||||
/>
|
||||
@@ -25,8 +25,8 @@
|
||||
</el-form>
|
||||
<el-row class="preview" :style="classBackground" />
|
||||
<el-row class="de-root-class">
|
||||
<deBtn secondary @click="cancel()">{{ t('commons.cancel') }}</deBtn>
|
||||
<deBtn type="primary" @click="saveTemplate()">{{ t('commons.confirm') }}</deBtn>
|
||||
<el-button secondary @click="cancel()">{{ t('commons.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="saveTemplate()">{{ t('commons.confirm') }}</el-button>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
@@ -65,6 +65,7 @@ const state = reactive({
|
||||
templateInfo: {
|
||||
level: '1',
|
||||
pid: props.pid,
|
||||
dvType: 'dashboard',
|
||||
name: '',
|
||||
templateStyle: null,
|
||||
templateData: null,
|
||||
@@ -115,7 +116,7 @@ const saveTemplate = () => {
|
||||
type: 'primary',
|
||||
cb: () =>
|
||||
save(state.templateInfo).then(response => {
|
||||
ElMessage.success(t('system_parameter_setting.import_succeeded'))
|
||||
ElMessage.success('导入成功')
|
||||
emits('refresh')
|
||||
emits('closeEditTemplateDialog')
|
||||
}),
|
||||
@@ -124,7 +125,7 @@ const saveTemplate = () => {
|
||||
handlerConfirm(options)
|
||||
} else {
|
||||
save(state.templateInfo).then(response => {
|
||||
ElMessage.success(t('system_parameter_setting.import_succeeded'))
|
||||
ElMessage.success(t('导入成功'))
|
||||
emits('refresh')
|
||||
emits('closeEditTemplateDialog')
|
||||
})
|
||||
@@ -143,8 +144,9 @@ const handleFileChange = e => {
|
||||
const result = res.target.result as string
|
||||
state.importTemplateInfo = JSON.parse(result)
|
||||
state.templateInfo.name = state.importTemplateInfo['name']
|
||||
state.templateInfo.templateStyle = state.importTemplateInfo['panelStyle']
|
||||
state.templateInfo.templateData = state.importTemplateInfo['panelData']
|
||||
state.templateInfo.dvType = state.importTemplateInfo['dvType']
|
||||
state.templateInfo.templateStyle = state.importTemplateInfo['canvasStyleData']
|
||||
state.templateInfo.templateData = state.importTemplateInfo['componentData']
|
||||
state.templateInfo.snapshot = state.importTemplateInfo.snapshot
|
||||
state.templateInfo.dynamicData = state.importTemplateInfo['dynamicData']
|
||||
state.templateInfo.staticResource = state.importTemplateInfo['staticResource']
|
||||
@@ -161,7 +163,7 @@ onMounted(() => {
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
<style scoped lang="less">
|
||||
.my_table :deep(.el-table__row > td) {
|
||||
/* 去除表格线 */
|
||||
border: none;
|
||||
@@ -178,7 +180,7 @@ onMounted(() => {
|
||||
|
||||
.de-root-class {
|
||||
margin-top: 24px;
|
||||
text-align: right;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.preview {
|
||||
margin-top: -12px;
|
||||
@@ -1,23 +1,35 @@
|
||||
<template>
|
||||
<div :style="classBackground" class="de-card-model">
|
||||
<div class="card-img-model" :style="classImg">
|
||||
<img :src="model.snapshot" alt="" />
|
||||
<img :src="imgUrlTrans(model.snapshot)" alt="" />
|
||||
</div>
|
||||
<div class="card-info">
|
||||
<el-tooltip class="item" effect="dark" :content="model.name" placement="top">
|
||||
<span class="de-model-text">{{ model.name }}</span>
|
||||
</el-tooltip>
|
||||
<div style="display: flex; align-items: center">
|
||||
<el-tooltip class="item" effect="dark" :content="dvTypeName" placement="top">
|
||||
<el-icon style="font-size: 18px" v-if="model.dvType === 'dashboard'">
|
||||
<Icon name="dv-dashboard-spine"></Icon>
|
||||
</el-icon>
|
||||
<el-icon class="icon-screen-new" style="font-size: 18px" v-else>
|
||||
<Icon name="icon_operation-analysis_outlined"></Icon>
|
||||
</el-icon>
|
||||
</el-tooltip>
|
||||
|
||||
<el-tooltip class="item" effect="dark" :content="model.name" placement="top">
|
||||
<span class="de-model-text">{{ model.name }}</span>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
|
||||
<el-dropdown size="medium" trigger="click" @command="handleCommand">
|
||||
<i class="el-icon-more" />
|
||||
<el-icon class="el-icon-more"><MoreFilled /></el-icon>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu class="de-card-dropdown">
|
||||
<slot>
|
||||
<el-dropdown-item command="rename">
|
||||
<i class="el-icon-edit" />
|
||||
<el-icon><EditPen /></el-icon>
|
||||
{{ $t('chart.rename') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="delete">
|
||||
<i class="el-icon-delete" />
|
||||
<el-icon><Delete /></el-icon>
|
||||
{{ $t('chart.delete') }}
|
||||
</el-dropdown-item>
|
||||
</slot>
|
||||
@@ -29,6 +41,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { imgUrlTrans } from '@/utils/imgUtils'
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
const { t } = useI18n()
|
||||
@@ -43,6 +56,10 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
const dvTypeName = computed(() => {
|
||||
return props.model.dvType === 'dashboard' ? '仪表板' : '数据大屏'
|
||||
})
|
||||
|
||||
const classBackground = computed(() => {
|
||||
return {
|
||||
width: props.width + 'px',
|
||||
@@ -68,6 +85,7 @@ const handleCommand = key => {
|
||||
border: 1px solid var(--deCardStrokeColor, #dee0e3);
|
||||
border-radius: 4px;
|
||||
margin: 0 24px 25px 0;
|
||||
overflow: hidden;
|
||||
.card-img-model {
|
||||
border-bottom: 1px solid var(--deCardStrokeColor, #dee0e3);
|
||||
height: 144px;
|
||||
@@ -112,6 +130,7 @@ const handleCommand = key => {
|
||||
}
|
||||
|
||||
.de-model-text {
|
||||
margin-left: 8px;
|
||||
font-family: 'PingFang SC';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
@@ -137,4 +156,11 @@ const handleCommand = key => {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-screen-new {
|
||||
background: #3370ff;
|
||||
border-radius: 4px;
|
||||
color: #fff;
|
||||
padding: 3px;
|
||||
}
|
||||
</style>
|
||||
@@ -2,24 +2,26 @@
|
||||
<div class="de-template-list">
|
||||
<el-input
|
||||
v-model="state.templateFilterText"
|
||||
:placeholder="t('system_parameter_setting.search_keywords')"
|
||||
:placeholder="'搜索关键字'"
|
||||
size="small"
|
||||
class="de-input-search"
|
||||
clearable
|
||||
>
|
||||
<template #prefix>
|
||||
<svg-icon icon-class="de-search" />
|
||||
<el-icon>
|
||||
<Icon name="de-search" />
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-input>
|
||||
<el-empty
|
||||
v-if="!templateListComputed.length && state.templateFilterText === ''"
|
||||
:image="state.noneImg"
|
||||
:description="t('components.no_classification')"
|
||||
:image="NoneImage"
|
||||
:description="'当前无分类'"
|
||||
/>
|
||||
<el-empty
|
||||
v-if="!templateListComputed.length && state.templateFilterText !== ''"
|
||||
:image="state.nothingImg"
|
||||
:description="t('components.relevant_content_found')"
|
||||
:image="NothingImage"
|
||||
:description="'没有找到相关内容'"
|
||||
/>
|
||||
<ul>
|
||||
<li
|
||||
@@ -28,7 +30,9 @@
|
||||
:class="[{ select: state.activeTemplate === ele.id }]"
|
||||
@click="nodeClick(ele)"
|
||||
>
|
||||
<svg-icon icon-class="scene" class="de-icon-sense" />
|
||||
<el-icon class="de-icon-sense">
|
||||
<Icon name="scene" />
|
||||
</el-icon>
|
||||
<span class="text-template-overflow" :title="ele.name">{{ ele.name }}</span>
|
||||
<span class="more" @click.stop>
|
||||
<el-dropdown trigger="click" size="small" @command="type => clickMore(type, ele)">
|
||||
@@ -38,13 +42,13 @@
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu class="de-template-dropdown">
|
||||
<el-dropdown-item icon="el-icon-upload2" command="import">
|
||||
{{ t('panel.import') }}
|
||||
{{ t('visualization.import') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-edit" command="edit">
|
||||
{{ t('panel.rename') }}
|
||||
{{ t('visualization.rename') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item icon="el-icon-delete" command="delete">
|
||||
{{ t('panel.delete') }}
|
||||
{{ t('visualization.delete') }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
@@ -59,7 +63,7 @@
|
||||
secondary
|
||||
@click="add()"
|
||||
>
|
||||
{{ t('panel.add_category') }}
|
||||
{{ t('visualization.add_category') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
@@ -67,6 +71,8 @@
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { computed, reactive } from 'vue'
|
||||
import NoneImage from '@/assets/none.png'
|
||||
import NothingImage from '@/assets/nothing.png'
|
||||
const { t } = useI18n()
|
||||
|
||||
const emits = defineEmits([
|
||||
@@ -93,7 +99,7 @@ const props = defineProps({
|
||||
const state = reactive({
|
||||
templateFilterText: '',
|
||||
activeTemplate: '',
|
||||
noneImg: '@/assets/None.png',
|
||||
noneImg: '@/assets/none.png',
|
||||
nothingImg: '@/assets/nothing.png'
|
||||
})
|
||||
|
||||
@@ -141,6 +147,10 @@ const templateImport = template => {
|
||||
const handlerConfirm = options => {
|
||||
// do handlerConfirm
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
nodeClick
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
@@ -244,4 +254,9 @@ const handlerConfirm = options => {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
|
||||
.sense {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,21 +1,21 @@
|
||||
<template>
|
||||
<div>
|
||||
<div style="width: 100%; height: 100%">
|
||||
<div class="de-template">
|
||||
<el-tabs v-model="state.currentTemplateType" class="de-tabs" @tab-click="handleClick">
|
||||
<el-tabs v-model="state.currentTemplateType" @tab-click="handleClick">
|
||||
<el-tab-pane name="self">
|
||||
<template #label>
|
||||
<span>{{ t('panel.user_template') }}</span>
|
||||
<span>{{ t('visualization.user_template') }}</span>
|
||||
</template>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane name="system">
|
||||
<template #label>
|
||||
<span>{{ t('panel.sys_template') }}</span>
|
||||
<span>{{ t('visualization.sys_template') }}</span>
|
||||
</template>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<div class="tabs-container flex-tabs">
|
||||
<div class="de-tabs-left">
|
||||
<template-list
|
||||
<de-template-list
|
||||
ref="templateListRef"
|
||||
:template-type="state.currentTemplateType"
|
||||
:template-list="state.templateList"
|
||||
@@ -31,19 +31,19 @@
|
||||
{{ state.currentTemplateLabel }} ({{ state.currentTemplateShowList.length }})
|
||||
<el-button
|
||||
type="primary"
|
||||
icon="el-icon-upload2"
|
||||
icon="Upload"
|
||||
@click="templateImport(state.currentTemplateId)"
|
||||
>
|
||||
{{ t('panel.import') }}
|
||||
{{ t('visualization.import') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<el-empty
|
||||
v-if="!state.currentTemplateShowList.length"
|
||||
:image="state.noneImg"
|
||||
:description="t('components.no_template')"
|
||||
:image="NoneImage"
|
||||
:description="'暂无模版'"
|
||||
/>
|
||||
<div v-show="state.currentTemplateId !== ''" id="template-box" class="template-box">
|
||||
<template-item
|
||||
<de-template-item
|
||||
v-for="item in state.currentTemplateShowList"
|
||||
:key="item.id"
|
||||
:width="state.templateCurWidth"
|
||||
@@ -56,7 +56,7 @@
|
||||
</div>
|
||||
<el-dialog
|
||||
:title="state.dialogTitle"
|
||||
v-model:visible="state.editTemplate"
|
||||
v-model="state.editTemplate"
|
||||
append-to-body
|
||||
class="de-dialog-form"
|
||||
width="600px"
|
||||
@@ -80,16 +80,15 @@
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!--导入templatedialog-->
|
||||
<!--导入templateDialog-->
|
||||
<el-dialog
|
||||
:title="state.templateDialog.title"
|
||||
v-model:visible="state.templateDialog.visible"
|
||||
v-model="state.templateDialog.visible"
|
||||
:show-close="true"
|
||||
class="de-dialog-form"
|
||||
width="600px"
|
||||
>
|
||||
<template-import
|
||||
<de-template-import
|
||||
v-if="state.templateDialog.visible"
|
||||
:pid="state.templateDialog.pid"
|
||||
@refresh="showCurrentTemplate(state.currentTemplateId, state.currentTemplateLabel)"
|
||||
@@ -105,10 +104,13 @@ import elementResizeDetectorMaker from 'element-resize-detector'
|
||||
import { computed, nextTick, onMounted, reactive, ref } from 'vue'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { ElMessage } from 'element-plus-secondary'
|
||||
import TemplateList from '@/views/template/component/TemplateList.vue'
|
||||
import DeTemplateList from '@/views/template/component/DeTemplateList.vue'
|
||||
const { t } = useI18n()
|
||||
const templateEditFormRef = ref(null)
|
||||
const templateListRef = ref(null)
|
||||
import NoneImage from '@/assets/none.png'
|
||||
import DeTemplateImport from '@/views/template/component/DeTemplateImport.vue'
|
||||
import DeTemplateItem from '@/views/template/component/DeTemplateItem.vue'
|
||||
|
||||
const roleValidator = (rule, value, callback) => {
|
||||
if (nameRepeat(value)) {
|
||||
@@ -160,7 +162,7 @@ const state = reactive({
|
||||
formType: '',
|
||||
originName: '',
|
||||
templateDialog: {
|
||||
title: t('panel.import_template'),
|
||||
title: t('visualization.import_template'),
|
||||
visible: false,
|
||||
pid: ''
|
||||
}
|
||||
@@ -251,14 +253,10 @@ const showTemplateEditDialog = (type, templateInfo) => {
|
||||
state.formType = type
|
||||
if (type === 'edit') {
|
||||
state.templateEditForm = JSON.parse(JSON.stringify(templateInfo))
|
||||
state.dialogTitle = t(
|
||||
`system_parameter_setting.${
|
||||
state.templateEditForm['nodeType'] === 'folder' ? 'edit_classification' : 'edit_template'
|
||||
}`
|
||||
)
|
||||
state.dialogTitle = state.templateEditForm['nodeType'] === 'folder' ? '编辑分类' : '编辑模版'
|
||||
state.originName = state.templateEditForm['label']
|
||||
} else {
|
||||
state.dialogTitle = t('panel.add_category')
|
||||
state.dialogTitle = t('visualization.add_category')
|
||||
state.templateEditForm = {
|
||||
name: '',
|
||||
nodeType: 'folder',
|
||||
@@ -266,11 +264,7 @@ const showTemplateEditDialog = (type, templateInfo) => {
|
||||
level: 0
|
||||
}
|
||||
}
|
||||
state.dialogTitleLabel = t(
|
||||
`system_parameter_setting.${
|
||||
state.templateEditForm['nodeType'] === 'folder' ? 'classification_name' : 'template_name'
|
||||
}`
|
||||
)
|
||||
state.dialogTitleLabel = state.templateEditForm['nodeType'] === 'folder' ? '分类名称' : '模版名称'
|
||||
state.editTemplate = true
|
||||
}
|
||||
|
||||
@@ -300,13 +294,15 @@ const close = () => {
|
||||
state.editTemplate = false
|
||||
}
|
||||
const getTree = () => {
|
||||
const request = {
|
||||
templateType: state.currentTemplateType,
|
||||
level: '0'
|
||||
}
|
||||
find(request).then(res => {
|
||||
state.templateList = res.data
|
||||
showFirst()
|
||||
nextTick(() => {
|
||||
const request = {
|
||||
templateType: state.currentTemplateType,
|
||||
level: '0'
|
||||
}
|
||||
find(request).then(res => {
|
||||
state.templateList = res.data
|
||||
showFirst()
|
||||
})
|
||||
})
|
||||
}
|
||||
const showFirst = () => {
|
||||
@@ -367,6 +363,7 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
.flex-tabs {
|
||||
margin-top: 16px;
|
||||
display: flex;
|
||||
background: #f5f6f7;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user