Compare commits

...

4 Commits

Author SHA1 Message Date
jingna
3a4bc50d2b Merge branch 'main' of http://121.37.111.42:3000/ThbTech/gis-bi into main 2025-07-01 18:31:14 +08:00
jingna
bd410a7094 修改 2025-07-01 18:30:49 +08:00
jingna
a2ad8225d7 Merge branch 'main' of http://121.37.111.42:3000/ThbTech/gis-bi into main 2025-06-30 18:30:22 +08:00
jingna
3b296b0999 使用模板创建 2025-06-30 18:30:11 +08:00
21 changed files with 993 additions and 170 deletions

View File

@ -94,7 +94,7 @@ const { wsCache } = useCache('localStorage')
const userStore = useUserStoreWithOut()
const isIframe = computed(() => appStore.getIsIframe)
const desktop = wsCache.get('app.desktop')
const emits = defineEmits(['recoverToPublished'])
const emits = defineEmits(['recoverToPublished','saveAsTemplate'])
defineProps({
createType: {
@ -262,7 +262,7 @@ const saveResource = (checkParams?) => {
canvasSaveWithParams(checkParams, () => {
snapshotStore.resetStyleChangeTimes()
let url = window.location.href
url = url.replace(/(#\/[^?]*)(?:\?[^#]*)?/, `$1?resourceId=${dvInfo.value.id}`)
url = url.replace(/(#\/[^?]*)(?:\?[^#]*)?/, `$1?resourceId=${dvInfo.value.id}&appId=${route.query.appId}`)
if (!embeddedStore.baseUrl) {
window.history.replaceState(
{
@ -524,7 +524,7 @@ const initOpenHandler = newWindow => {
}
}
function saveas(){
emits('saveAsTemplate')
}
</script>
@ -661,7 +661,7 @@ function saveas(){
type="primary">
{{ t('data_set.edit') }}
</el-button>
<el-button class="savebtn" type="primary" @click="saveas">另存为</el-button>
<!-- <el-button class="savebtn" type="primary" @click="saveas">另存为</el-button> -->
<el-button v-if="editMode === 'edit' || editMode === 'preview'" :disabled="styleChangeTimes < 1"
@click="saveCanvasWithCheck()" style="float: right; margin-right: 12px" type="primary" class="savebtn">
{{ t('data_set.save') }}

View File

@ -105,7 +105,7 @@ const onImgChange = imgUrl => {
text-align: left;
}
.m-label {
color: #1f2329;
color: #ffffff;
font-size: 14px;
font-style: normal;
font-weight: 400;

View File

@ -185,7 +185,9 @@ onUnmounted(() => {
:deep(.ed-input-number--dark:not(.is-disabled) .ed-input-number__increase:not(.is-disabled)) {
background-color: #1a1a1a;
}
:deep(.ed-input-number__increase){
background-color: #1a1a1a !important;
}
.custom-divider_scale {
height: 18px;
border-color: #ffffff26;
@ -204,7 +206,7 @@ onUnmounted(() => {
position: absolute;
content: '%';
right: 35px;
top: 1px;
top: -1px;
height: 24px;
line-height: 24px;
}

View File

@ -184,7 +184,7 @@ const saveResource = (checkParams?) => {
snapshotStore.resetStyleChangeTimes()
wsCache.delete('DE-DV-CATCH-' + dvInfo.value.id)
let url = window.location.href
url = url.replace(/(#\/[^?]*)(?:\?[^#]*)?/, `$1?dvId=${dvInfo.value.id}`)
url = url.replace(/(#\/[^?]*)(?:\?[^#]*)?/,`$1?dvId=${dvInfo.value.id}&appId=${route.query.appId}`)
if (!embeddedStore.baseUrl) {
window.history.replaceState(
{

View File

@ -115,7 +115,7 @@ defineExpose({
text-align: left;
}
.m-label {
color: #1f2329;
color: #ffffff;
font-size: 14px;
font-style: normal;
font-weight: 400;

View File

@ -125,39 +125,22 @@ const onComponentNameChange = () => {
</script>
<template>
<div
@keyup.stop
@keydown.stop
class="dv-aside"
:class="['aside-' + asidePosition + '-' + themeInfo, 'aside-area-' + themeInfo]"
:style="slideStyle"
>
<div @keyup.stop @keydown.stop class="dv-aside"
:class="['aside-' + asidePosition + '-' + themeInfo, 'aside-area-' + themeInfo]" :style="slideStyle">
<el-row align="middle" :class="'title-' + themeInfo" justify="space-between">
<div
:id="'attr-slide-component-name' + slideIndex"
v-if="!canvasCollapse[sideName]"
class="name-area-attr"
<div :id="'attr-slide-component-name' + slideIndex" v-if="!canvasCollapse[sideName]" class="name-area-attr"
style="max-width: 180px; text-overflow: ellipsis; white-space: nowrap"
:style="{ width: componentNameEdit ? '300px' : 'auto' }"
:class="{ 'component-name-dark': themeInfo === 'dark' }"
@dblclick="editComponentName"
>
:class="{ 'component-name-dark': themeInfo === 'dark' }" @dblclick="editComponentName">
{{ isViewTitle ? view.title : title }}
<el-popover
show-arrow
:offset="8"
:effect="themes"
placement="bottom"
width="200"
trigger="click"
>
<el-popover show-arrow :offset="8" :effect="themes" placement="bottom" width="200" trigger="click">
<template #reference>
<span>
<el-icon
v-show="element && element['id']"
style="margin: 2px 0 0 4px; cursor: pointer"
><Icon><dvInfoSvg class="svg-icon" /></Icon
></el-icon>
<el-icon v-show="element && element['id']" style="margin: 2px 0 0 4px; cursor: pointer">
<Icon>
<dvInfoSvg class="svg-icon" />
</Icon>
</el-icon>
</span>
</template>
<div style="margin-bottom: 4px; font-size: 14px">
@ -168,18 +151,12 @@ const onComponentNameChange = () => {
</div>
</el-popover>
</div>
<el-icon
:title="title"
:class="['custom-icon-' + themeInfo, 'collapse-icon-' + themeInfo]"
size="20px"
@click="collapseChange"
>
<Expand
v-if="
(canvasCollapse[sideName] && asidePosition === 'left') ||
(!canvasCollapse[sideName] && asidePosition === 'right')
"
/>
<el-icon :title="title" :class="['custom-icon-' + themeInfo, 'collapse-icon-' + themeInfo]" size="20px"
@click="collapseChange">
<Expand v-if="
(canvasCollapse[sideName] && asidePosition === 'left') ||
(!canvasCollapse[sideName] && asidePosition === 'right')
" />
<Fold v-else />
</el-icon>
</el-row>
@ -192,14 +169,8 @@ const onComponentNameChange = () => {
<span>{{ title }}</span>
</div>
<Teleport v-if="componentNameEdit" :to="'#attr-slide-component-name' + slideIndex">
<input
ref="componentNameInputAttr"
v-model="inputComponentName.name"
width="100%"
:effect="themeInfo"
@change="onComponentNameChange"
@blur="closeEditComponentName"
/>
<input ref="componentNameInputAttr" v-model="inputComponentName.name" width="100%" :effect="themeInfo"
@change="onComponentNameChange" @blur="closeEditComponentName" />
</Teleport>
</div>
</template>
@ -212,14 +183,17 @@ const onComponentNameChange = () => {
.aside-area-light {
color: #ebebeb;
background-color: #1a1a1a;
background-color: #1a1a1a !important;
:deep(.title) {
border-bottom: rgba(255, 255, 255, 0.15) 1px solid !important;
}
}
.dv-aside {
position: relative;
transition: 0.5s;
.title-dark {
font-size: 14px;
font-weight: 500;
@ -230,6 +204,7 @@ const onComponentNameChange = () => {
text-overflow: ellipsis;
padding: 8px 10px 8px 8px;
}
.title-light {
font-size: 14px;
font-weight: 500;
@ -240,6 +215,7 @@ const onComponentNameChange = () => {
text-overflow: ellipsis;
padding: 8px 10px 8px 8px;
}
.collapse-title {
width: 35px;
font-size: 14px;
@ -247,15 +223,18 @@ const onComponentNameChange = () => {
text-align: center;
padding: 5px;
margin-top: 5px;
span {
writing-mode: vertical-rl;
text-orientation: mixed;
}
}
.main-content {
height: calc(100% - 45px);
overflow-y: auto;
}
.custom-icon {
position: absolute;
right: 5px;
@ -271,9 +250,11 @@ const onComponentNameChange = () => {
width: var(--de-scroll-width);
}
}
.aside-left-dark {
border-right: @side-outline-border-color 1px solid;
}
.aside-right-dark {
border-left: @side-outline-border-color 1px solid;
}
@ -281,18 +262,23 @@ const onComponentNameChange = () => {
.aside-left-light {
border-right: @side-outline-border-color-light 1px solid;
}
.aside-right-light {
border-left: @side-outline-border-color-light 1px solid;
}
.ed-collapse {
border-top: 0;
}
:deep(.ed-collapse) {
border-top: unset;
}
:deep(.ed-collapse-item__header.is-active) {
border-bottom-color: rgba(31, 35, 41, 0.15);
}
:deep(.ed-collapse-item.ed-collapse--dark .ed-collapse-item__header) {
border-color: rgba(255, 255, 255, 0.15);
border-top: unset;
@ -321,6 +307,7 @@ const onComponentNameChange = () => {
cursor: pointer;
display: flex;
align-items: center;
input {
position: absolute;
left: 0;
@ -346,209 +333,387 @@ const onComponentNameChange = () => {
padding: 0 4px;
height: 100%;
}
.ed-icon{
}
.ed-icon {}
}
</style>
<style>
.ed-popper.is-light {
border: 1px solid #434343 !important;
background: rgba(41, 41, 41, 1) !important;
color: #ffffff ;
border: 1px solid #434343 !important;
background: rgba(41, 41, 41, 1) !important;
color: #ffffff;
}
.ed-popper[data-popper-placement^=bottom] .ed-popper__arrow::before {
background: rgba(41, 41, 41, 1) !important;
background: rgba(41, 41, 41, 1) !important;
}
.ed-popover.ed-popper{
.ed-popover.ed-popper {
background: rgba(41, 41, 41, 1) !important;
border: 1px solid #434343 !important;
}
.ed-collapse-item.ed-collapse--light .ed-collapse-item__header{
.ed-collapse-item.ed-collapse--light .ed-collapse-item__header {
background-color: #1a1a1a;
color: #fff;
}
.ed-collapse-item__header{
border-bottom: 1px solid rgba(255,255,255,0.15) !important;
.ed-collapse-item__header {
color: #EBEBEB !important;
background-color: #1a1a1a !important;
border-bottom: 1px solid rgba(255, 255, 255, 0.15) !important;
}
.ed-collapse-item__wrap{
.ed-collapse-item--light .ed-collapse-item__wrap {
border-bottom: none;
background: #292929;
}
.ed-collapse-item__wrap {
background-color: #292929;
border-bottom: none;
}
.ed-collapse-item__wrap .ed-form--default.ed-form--label-top .ed-form-item .ed-form-item__label{
.ed-collapse-item__wrap .ed-form--default.ed-form--label-top .ed-form-item .ed-form-item__label {
color: #a6a6a6;
}
.ed-collapse-item__wrap .ed-radio .ed-radio__label{
.ed-collapse-item__wrap .ed-radio .ed-radio__label {
color: #fff;
}
.ed-collapse-item__wrap .ed-radio .ed-radio__input.is-checked + .ed-radio__label{
.ed-collapse-item__wrap .ed-radio .ed-radio__input.is-checked+.ed-radio__label {
color: #0089ff !important;
}
.ed-collapse-item__wrap .ed-input.is-disabled .ed-input__wrapper{
.ed-collapse-item__wrap .ed-input.is-disabled .ed-input__wrapper {
background-color: #373737;
box-shadow: none !important;
}
.ed-collapse-item__wrap .ed-input--light .ed-input-group__append .ed-select.ed-select--disabled .ed-input__wrapper {
background: #373737 !important;
box-shadow: none !important;
border-color:#636363 !important;
border-color: #636363 !important;
border-left: none !important;
}
.ed-collapse-item__wrap .ed-input--dark .ed-input-group__append .ed-select .ed-input__wrapper {
background: #373737 !important;
box-shadow: none !important;
border-color:#636363 !important;
border-color: #636363 !important;
border-left: none !important;
}
.ed-collapse-item__wrap .ed-input-group__append, .ed-input-group__prepend{
.ed-collapse-item__wrap .ed-input-group__append,
.ed-input-group__prepend {
background: #373737 !important;
}
.ed-collapse-item__wrap .ed-input-group--append .ed-input-group__append .ed-select:not(.ed-select--disabled) .ed-input .ed-input__wrapper{
box-shadow: none !important;
border:1px solid #636363 !important;
border-left: none !important;
.ed-collapse-item__wrap .ed-input-group--append .ed-input-group__append .ed-select:not(.ed-select--disabled) .ed-input .ed-input__wrapper {
box-shadow: none !important;
border: 1px solid #636363 !important;
border-left: none !important;
}
.ed-collapse-item__wrap .image-hint{
color:#757575 !important;
.ed-collapse-item__wrap .image-hint {
color: #757575 !important;
}
.ed-collapse-item__wrap .avatar-uploader .ed-upload--picture-card {
background: #373737 !important;
border: 1px dashed #373737 !important;
}
.ed-collapse-item__wrap .indented-container .indented-item.disabled .img-area_light .ed-upload--picture-card .ed-icon {
color: #5f5f5f !important;
}
.ed-collapse-item__wrap .avatar-uploader .ed-upload--picture-card .ed-icon{
.ed-collapse-item__wrap .avatar-uploader .ed-upload--picture-card .ed-icon {
color: #ebebeb !important;
}
.ed-collapse-item__wrap .ed-input-number__decrease, .ed-input-number__increase{
.ed-collapse-item__wrap .ed-input-number__decrease,
.ed-input-number__increase {
background-color: #434343 !important;
color:#ffffff !important;
color: #ffffff !important;
}
.ed-input-number__decrease, .ed-input-number__increase{
color:#ffffff !important;
.ed-input-number__decrease,
.ed-input-number__increase {
color: #ffffff !important;
}
.ed-collapse-item__wrap .ed-input-number.is-controls-right .ed-input-number__increase{
.ed-collapse-item__wrap .ed-input-number.is-controls-right .ed-input-number__increase {
border-bottom: 1px solid #434343 !important;
border-left: 1px solid #5f5f5f !important;
}
.ed-collapse-item__wrap .ed-input-number.is-controls-right .ed-input-number__decrease{
.ed-collapse-item__wrap .ed-input-number.is-controls-right .ed-input-number__decrease {
border-left: 1px solid #5f5f5f !important;
}
.ed-collapse-item__wrap .ed-input.is-disabled .ed-select__prefix--light{
.ed-collapse-item__wrap .ed-input.is-disabled .ed-select__prefix--light {
border-color: #5f5f5f;
}
.ed-collapse-item__wrap .ed-color-picker.is-custom.is-disabled .ed-color-picker__trigger{
.ed-collapse-item__wrap .ed-color-picker.is-custom.is-disabled .ed-color-picker__trigger {
border-color: #5f5f5f;
}
.ed-collapse-item__wrap .ed-select .ed-input.is-disabled:not(.ed-input--dark) .ed-input__wrapper:hover{
.ed-collapse-item__wrap .ed-select .ed-input.is-disabled:not(.ed-input--dark) .ed-input__wrapper:hover {
box-shadow: none !important;
}
.ed-collapse-item__wrap .custom-color-setting-btn{
.ed-collapse-item__wrap .custom-color-setting-btn {
border: 1px solid #5f5f5f !important;
color: #fff !important;
}
.ed-collapse-item__wrap .ed-form-item__label{
.ed-collapse-item__wrap .ed-form-item__label {
color: #A6A6A6 !important;
}
.ed-collapse-item__wrap .custom-color-extend-setting{
.ed-collapse-item__wrap .custom-color-extend-setting {
color: #A6A6A6 !important;
}
.ed-collapse-item.ed-collapse--light .ed-collapse-item__content{
color: #A6A6A6 ;
.ed-collapse-item.ed-collapse--light .ed-collapse-item__content {
color: #A6A6A6;
}
.ed-collapse-item__wrap .m-divider{
.ed-collapse-item__content {
background-color: #292929 !important;
}
.ed-collapse-item__wrap .m-divider {
border-color: rgba(233, 236, 241, 0.15) !important;
}
.ed-collapse-item__wrap .icon-btn{
color: #ffffff !important;
.ed-collapse-item__wrap .icon-btn {
color: #ffffff !important;
}
.ed-collapse-item__wrap .icon-btn.active{
.ed-collapse-item__wrap .icon-btn.active {
color: #0089ff !important;
}
.ed-collapse-item__wrap .color-button-outer{
.ed-collapse-item__wrap .color-button-outer {
border-color: rgba(233, 236, 241, 0.15) !important;
}
.ed-collapse-item__wrap .text-area{
.ed-collapse-item__wrap .text-area {
color: #fff !important;
}
.ed-collapse-item__wrap .ed-radio__input.is-disabled.is-checked .ed-radio__inner {
background-color: #5f5f5f;
border: 1px solid #5f5f5f;
}
.ed-collapse-item__wrap .ed-radio__input.is-disabled.is-checked .ed-radio__inner::after {
background-color: #212121;
}
.ed-collapse-item__wrap .ed-radio .ed-radio__input.is-disabled.is-checked + .ed-radio__label {
.ed-collapse-item__wrap .ed-radio .ed-radio__input.is-disabled.is-checked+.ed-radio__label {
color: #bbbfc4 !important;
}
.editor-light .editor-title{
.editor-light .editor-title {
color: #ebebeb;
}
.editor-dark {
border-left: solid 1px rgba(235, 235, 235, 0.15) !important;
}
.content-area {
border-left: solid 1px rgba(235, 235, 235, 0.15) !important;
}
.editor-light .dataset-main {
border-left: 1px solid rgba(235, 235, 235, 0.15) !important;
}
.collapse-title{
.collapse-title {
color: #ebebeb !important;
}
.editor-light .ed-tabs__header {
border-top: 1px solid #363636 !important;
border-top: 1px solid #363636 !important;
}
.de-chart-editor .tab-header .ed-tabs__nav-wrap::after{
.de-chart-editor .tab-header .ed-tabs__nav-wrap::after {
background-color: rgba(235, 235, 235, 0.15) !important;
}
.de-chart-editor .tab-header .ed-tabs__item{
.de-chart-editor .tab-header .ed-tabs__item {
color: #A6A6A6 !important;
}
.de-chart-editor .drag-block-style{
.de-chart-editor .drag-block-style {
border: 1px dashed #5f5f5f !important;
background-color: rgba(235, 235, 235, 0.05) !important;
}
.editor-light .item-span-style{
.editor-light .item-span-style {
color: #fff !important;
}
.ed-input--dark .ed-input__wrapper {
background-color: #292929;
box-shadow: none !important;
}
.el-loading-mask{
background-color: rgba(33,33,33, 0.9) !important;
.el-loading-mask {
background-color: rgba(33, 33, 33, 0.9) !important;
}
.ed-input--dark .ed-input__wrapper:hover{
.ed-input--dark .ed-input__wrapper:hover {
box-shadow: none !important;
}
.ed-input-number--dark:not(.is-disabled) .ed-input-number__decrease:not(.is-disabled):hover~.ed-input:not(.is-disabled) .ed-input__wrapper, .ed-input-number--dark:not(.is-disabled) .ed-input-number__increase:not(.is-disabled):hover~.ed-input:not(.is-disabled) .ed-input__wrapper{
.ed-input-number--dark:not(.is-disabled) .ed-input-number__decrease:not(.is-disabled):hover~.ed-input:not(.is-disabled) .ed-input__wrapper,
.ed-input-number--dark:not(.is-disabled) .ed-input-number__increase:not(.is-disabled):hover~.ed-input:not(.is-disabled) .ed-input__wrapper {
box-shadow: none !important;
border: 1px solid #0089ff !important;
}
.ed-input__wrapper.is-focus {
box-shadow: none !important;
}
.ed-input__wrapper:hover {
box-shadow: none !important;
}
.ed-input__wrapper{
.ed-input__wrapper {
box-shadow: none !important;
}
.ed-input-number--light:not(.is-disabled).is-controls-right .ed-input-number__decrease:not(.is-disabled):hover~.ed-input:not(.is-disabled) .ed-input__wrapper, .ed-input-number--light:not(.is-disabled).is-controls-right .ed-input-number__increase:not(.is-disabled):hover~.ed-input:not(.is-disabled) .ed-input__wrapper{
.ed-input-number--light:not(.is-disabled).is-controls-right .ed-input-number__decrease:not(.is-disabled):hover~.ed-input:not(.is-disabled) .ed-input__wrapper,
.ed-input-number--light:not(.is-disabled).is-controls-right .ed-input-number__increase:not(.is-disabled):hover~.ed-input:not(.is-disabled) .ed-input__wrapper {
box-shadow: none !important;
border: 1px solid #0089ff !important;
}
.ed-input-number--light .ed-input-number__decrease.is-disabled .ed-icon, .ed-input-number--light .ed-input-number__increase.is-disabled .ed-icon {
.ed-input-number--light .ed-input-number__decrease.is-disabled .ed-icon,
.ed-input-number--light .ed-input-number__increase.is-disabled .ed-icon {
color: #ffffff;
}
.ed-input-number__decrease:hover, .ed-input-number__increase:hover {
.ed-input-number__decrease:hover,
.ed-input-number__increase:hover {
color: #0089ff !important;
}
.ed-select .ed-input.is-disabled:not(.ed-input--dark) .ed-input__wrapper:hover{
box-shadow: none!important;;
.ed-select .ed-input.is-disabled:not(.ed-input--dark) .ed-input__wrapper:hover {
box-shadow: none !important;
;
}
.icon-checkbox:before{
content:''
.icon-checkbox:before {
content: ''
}
.ed-select__wrapper {
background-color: transparent;
border: 1px solid #434343;
box-shadow: none;
}
.ed-select__placeholder {
color: #fff;
}
.ed-select__wrapper.is-focused,
.ed-select__wrapper.is-hovering:not(.is-focused):not(.is-disabled) {
box-shadow: none;
}
.ed-select__popper.ed-popper {
background: rgb(41, 41, 41) !important;
color: #fff;
border: 1px solid #434343;
}
.ed-select-dropdown__item.is-hovering {
background: #434343 !important;
}
.ed-select-dropdown__item {
color: #fff;
}
.ed-select-dropdown__footer {
padding: 5px 0px;
border-top: 1px solid #434343;
}
.ed-input-group__append {
border-left: 0;
box-shadow: 0 1px 0 0 #636363 inset,
0 -1px 0 0 #636363 inset,
-1px 0 0 0 #636363 inset;
}
.ed-input-group--append .ed-input-group__append .ed-select .ed-select__wrapper {
box-shadow: none;
}
.ed-input.is-disabled .ed-input__wrapper{
background-color: transparent;
}
.ed-color-picker.is-custom{
border:1px solid #636363 !important;
}
.ed-select__wrapper.is-disabled{
background-color:#434343;
box-shadow:0 0 0 1px #787878 inset;
}
.ed-checkbox__input .ed-checkbox__inner:after{
background: transparent!important;
}
.ed-checkbox__input.is-checked .ed-checkbox__inner:after{
background: #fff !important;
}
.ed-select--light .ed-select__prefix:after {
background-color: #434343;
}
.ed-select__wrapper.is-disabled .ed-select--light .ed-select__prefix:after {
background-color: #292929;
}
.ed-input-number.is-controls-right .ed-input-number__decrease [class*=ed-icon], .ed-input-number.is-controls-right .ed-input-number__increase [class*=ed-icon]{
color: #ffffff;
}
.ed-input-number--light.is-disabled .ed-input-number__decrease.ed-input-number__decrease.ed-input-number__decrease, .ed-input-number--light.is-disabled .ed-input-number__increase.ed-input-number__increase.ed-input-number__increase{
border-color:#636363 !important;
}
.ed-checkbox__input.is-disabled .ed-checkbox__inner{
background-color:#434343;
border: 1px solid #787878;
}
.is-disabled .icon-btn.active{
background-color:#434343 !important;
}
.menu-item-padding span{
color: #fff !important;
}
.menu-item-padding .ed-icon{
color: #fff !important;
}
.ed-message-box{
background: #212121;
}
.ed-message-box__content{
color: #ffffff;
}
.ed-message-box__btns .ed-button--primary{
background: #0089ff;
border-color: #0089ff;
}
.ed-message-box__btns .ed-button.is-secondary{
color: #F2F4F5 !important;
background-color: #212121 !important;
border: 1px solid #434343 !important;
}
</style>

View File

@ -673,7 +673,7 @@ defineExpose({
.preview {
margin-top: 5px;
border: 1px solid #e6e6e6;
border: 1px solid #434343;
border-radius: 4px;
height: 470px !important;
overflow: hidden;
@ -681,7 +681,7 @@ defineExpose({
}
.preview-show {
border-left: 1px solid #e6e6e6;
border-left: 1px solid #434343;
height: 470px;
background-size: 100% 100% !important;
}

View File

@ -785,7 +785,7 @@ defineExpose({
.preview {
margin-top: 5px;
border: 1px solid #e6e6e6;
border: 1px solid #434343;
border-radius: 4px;
height: 470px !important;
overflow: hidden;
@ -1100,6 +1100,7 @@ defineExpose({
.ed-select-dropdown__header {
padding: 0 8px;
border-bottom: 1px solid #434343 !important;
.params-select--header {
--ed-tabs-header-height: 32px;
.ed-tabs__item {
@ -1114,7 +1115,7 @@ defineExpose({
}
.params-attach-setting {
border-left: 1px solid #e6e6e6;
border-left: 1px solid #434343;
}
.params-attach-content {
@ -1135,7 +1136,7 @@ defineExpose({
cursor: pointer;
font-size: 14px;
color: #646a73;
margin: 10px 0 0 4px;
margin: 3px 0 0 4px;
}
:deep(.ed-tree--highlight-current .ed-tree-node.is-current > .ed-tree-node__content){
background: rgb(47,47,47) !important;
@ -1159,3 +1160,14 @@ box-shadow: 0 0 0 1px #434343 inset;
color: #3370ff;
}
</style>
<style>
.root-class .ed-button{
color: #F2F4F5;
background-color: #212121 !important;
border: 1px solid #363636 !important;
}
.root-class .ed-button--primary{
background-color: #0089ff !important;
border: 1px solid #0089ff !important;
}
</style>

View File

@ -440,7 +440,7 @@ init()
</el-button>
</el-row>
<el-row :style="{ marginTop: '16px', borderTop: '1px solid #d5d6d8' }">
<el-row :style="{ marginTop: '16px', borderTop: '1px solid #656565' }">
<el-row
v-for="(item, index) in fieldItem.conditions"
:key="index"
@ -914,9 +914,9 @@ span {
padding: 0 11px;
}
:deep(.ed-input__wrapper){
background-color: #252424 ;
box-shadow: none;
border: 1px solid #636363;
background-color: #252424 !important;
box-shadow: none !important;
border: 1px solid #636363 !important;
}
:deep(.ed-input__inner){
color: #fff;

View File

@ -3521,7 +3521,7 @@ const deleteChartFieldItem = id => {
<div
ref="elDrag"
v-loading="fieldLoading && !fullscreenFlag"
style="height: calc(100% - 137px); min-height: 120px"
style="height: calc(100% - 137px); min-height: 120px;margin-top: 10px;"
>
<div
class="padding-lr field-height first right-dimension"
@ -4810,7 +4810,7 @@ span {
display: flex;
align-items: center;
justify-content: space-between;
color: #1f2329;
color: #fff;
font-weight: 500;
&.dark {
@ -5347,6 +5347,7 @@ span {
color: #A6A6A6 !important;
}
.de-chart-editor .dataset-search-input .ed-input__wrapper{
border:none !important;
border-bottom: 1px solid hsla(0, 0%, 100%, 0.15) !important;
background-color: #1a1a1a !important;
}

View File

@ -823,7 +823,6 @@ const loadModelInternal = (loader, filePath) => {
};
// -
const placeModelByLngLat = (lng: number, lat: number) => {
debugger
if (!model || !myChart?.getScene()) {
console.warn('模型或地图场景未初始化');
return;

View File

@ -246,14 +246,14 @@ defineExpose({
.preview {
margin-top: 5px;
border: 1px solid #e6e6e6;
border: 1px solid #434343;
height: 310px !important;
overflow: hidden;
background-size: 100% 100% !important;
}
.preview-show {
border-left: 1px solid #e6e6e6;
border-left: 1px solid #434343;
height: 310px;
background-size: 100% 100% !important;
}

View File

@ -34,6 +34,7 @@ import eventBus from '@/utils/eventBus'
import { useI18n } from '@/hooks/web/useI18n'
import DashboardHiddenComponent from '@/components/dashboard/DashboardHiddenComponent.vue'
import { recoverToPublished } from '@/api/visualization/dataVisualization'
import { download2AppTemplate } from '@/utils/imgUtils'
const embeddedStore = useEmbedded()
const { wsCache } = useCache()
const canvasCacheOutRef = ref(null)
@ -226,6 +227,18 @@ onMounted(async () => {
// do init
})
}
if (createType === 'template') {
let deTemplateData
let preName
const templateParamsApply = JSON.parse(Base64.decode(decodeURIComponent(templateParams + '')))
await decompressionPre(templateParamsApply, result => {
deTemplateData = result
preName = deTemplateData.baseInfo?.preName
dvMainStore.setComponentData(deTemplateData['componentData'])
dvMainStore.setCanvasStyle(deTemplateData['canvasStyleData'])
dvMainStore.setCanvasViewInfo(deTemplateData['canvasViewInfo'])
})
}
} else if (opt && opt === 'create') {
dataInitState.value = false
let watermarkBaseInfo
@ -325,6 +338,12 @@ onUnmounted(() => {
window.removeEventListener('storage', eventCheck)
window.removeEventListener('message', winMsgHandle)
})
//
function saveAsTemplate(){
const vueDom = document.querySelector('.template-canvas-main');
download2AppTemplate('template', vueDom, dvInfo.value.name, null, () => {
})
}
</script>
<template>
@ -334,7 +353,7 @@ onUnmounted(() => {
v-loading="requestStore.loadingMap[permissionStore.currentPath]"
v-if="loadFinish && !mobileConfig"
>
<DbToolbar @recoverToPublished="doRecoverToPublished" />
<DbToolbar @recoverToPublished="doRecoverToPublished" @saveAsTemplate="saveAsTemplate" />
<el-container
class="dv-layout-container"
:class="{ 'preview-content': editMode === 'preview' }"
@ -346,6 +365,7 @@ onUnmounted(() => {
style="overflow-x: hidden"
v-if="dataInitState"
ref="deCanvasRef"
class="template-canvas-main"
:canvas-id="state.canvasId"
:component-data="dashboardComponentData"
:canvas-style-data="canvasStyleData"

View File

@ -322,14 +322,14 @@ if (props.templateId) {
}
.preview {
margin-top: -8px;
border: 1px solid #e6e6e6;
border: 1px solid #434343;
height: 300px !important;
overflow: auto;
background-size: 100% 100% !important;
border-radius: 4px;
}
.preview-show {
border-left: 1px solid #e6e6e6;
border-left: 1px solid #434343;
height: 300px;
background-size: 100% 100% !important;
}

View File

@ -64,7 +64,7 @@ function cancel() {
<style lang="less" scoped>
.preview {
margin-top: -8px;
border: 1px solid #e6e6e6;
border: 1px solid #434343;
height: 300px !important;
overflow: auto;
background-size: 100% 100% !important;

View File

@ -17,7 +17,11 @@ const props = defineProps({
required: true,
default: 'insert'
},
templateId: {
type: String,
required: true,
default: ''
},
})
const emits = defineEmits(['closeTemplateDialog', 'init'])
const { t } = useI18n()
@ -112,6 +116,12 @@ const classBackground = computed(() => {
}
})
onMounted(() => {
if (props.templateId && props.templateId !== '') {
findOne(props.templateId).then(rsp => {
state.templateInfo = rsp.data
console.log(rsp)
})
}
queryclass()
})
function queryclass() {
@ -223,7 +233,7 @@ function classrefresh(){
</script>
<template>
<div class="template-import">
<el-form ref="ruleFormRef" :model="state.templateInfo" label-width="80px">
<el-form ref="ruleFormRef" :model="state.templateInfo" label-width="80px" style="margin-top: 15px;">
<el-form-item label="模板名称" prop="name">
<div class="flex-template">
<el-input v-model="state.templateInfo.name" />
@ -258,7 +268,7 @@ function classrefresh(){
<style lang="less" scoped>
.preview {
margin-top: -8px;
border: 1px solid #e6e6e6;
border: 1px solid #434343;
height: 300px !important;
overflow: auto;
background-size: 100% 100% !important;

View File

@ -4,7 +4,7 @@ import { useRouter } from 'vue-router'
import { searchMarketPreview } from '@/api/templateMarket'
import { useI18n } from '@/hooks/web/useI18n'
import { useCache } from '@/hooks/web/useCache'
import { ElMessage } from 'element-plus-secondary'
import { ElMessage,ElMessageBox } from 'element-plus-secondary'
import { Base64 } from 'js-base64'
import { useEmbedded } from '@/store/modules/embedded'
import { useAppStoreWithOut } from '@/store/modules/app'
@ -12,7 +12,7 @@ import { useEmitt } from '@/hooks/web/useEmitt'
import type { FormInstance } from 'element-plus'
import AddTemplate from '@/viewsnew/TemplateResource/addtemplate.vue'
import AddTemplateClass from '@/viewsnew/TemplateResource/addclass.vue'
import { update } from 'lodash'
import { templateDelete } from '@/api/template'
const basePath = import.meta.env.VITE_API_BASEPATH
const router = useRouter()
const { t } = useI18n()
@ -22,8 +22,6 @@ const dataList: any = ref([])
const classList: any = ref([])
const mask = ref(-1) //
const activeIndex: any = ref(null)
const detailsList: any = ref([])
const loading: any = ref(false)
const embeddedStore = useEmbedded()
const appStore = useAppStoreWithOut()
const isEmbedded = computed(() => appStore.getIsDataEaseBi || appStore.getIsIframe)
@ -130,7 +128,6 @@ const state = reactive({
}
})
const templateApply = (template: any) => {
state.curApplyTemplate = template
state.dvCreateForm.name = template.title
state.dvCreateForm.nodeType = template.templateType
@ -269,11 +266,42 @@ function closeTemplateDialog() {
function classrefresh() {
init()
}
const templateId = ref('')
function editTemplate(item) {
optType.value = 'template'
console.log(item)
optType.value = 'update'
dialogVisibles.value = true
templateId.value = item.id
}
function refresh(){
searchMarketPreview().then(res => {
classList.value = res.data.contents
if (activeIndex.value) {
dataList.value = classList.value[activeIndex.value].contents
}else{
activeIndex.value = 0
dataList.value = classList.value[activeIndex.value].contents
}
})
}
function delTemplate(item){
console.log(classList.value[activeIndex.value].category.value)
ElMessageBox.confirm('提示,确定删除吗?', {
confirmButtonType: 'primary',
type: 'warning',
confirmButtonText: '确定',
cancelButtonText: '取消',
}).then(() => {
templateDelete(item.id, classList.value[activeIndex.value].category.value).then(() => {
ElMessage({
message: '删除成功',
type: 'success',
showClose: true
})
refresh()
})
})
}
const isclassmask = ref(false)
</script>
<template>
<div class="common-layout">
@ -288,9 +316,14 @@ function editTemplate(item) {
</div>
<div>
<div class="class_list_box">
<div v-for="(item, index) in classList" :key="index"
:class="activeIndex === index ? 'class_list_active' : 'class_list'" @click="classclick(index)">
<div v-for="(item, classindex) in classList" :key="classindex"
:class="activeIndex === classindex ? 'class_list_active' : 'class_list'" @click="classclick(classindex)"
@mouseover="mouseover(classindex)" @mouseleave="mouseleave">
<div class="class_list_text">{{ item.category.label }} ({{ item.contents.length }}) </div>
<div v-if="mask == classindex" style="position: absolute;right: -10px;top: -20px;">
<img src="@/assets/newimg/icon/editpro.png" style="width: 14px;height: 14px;cursor: pointer;" @click="editTemplate(item)" title="编辑模板">
<img src="@/assets/newimg/icon/del.png" alt="" @click="delTemplate(item)" style="width: 14px;height: 14px;margin-left: 5px;cursor: pointer;" title="删除">
</div>
</div>
</div>
<div class="application_list_box">
@ -305,11 +338,11 @@ function editTemplate(item) {
<div class="mask_box" v-if="mask == index">
<div>
<img src="@/assets/newimg/icon/editpro.png" @click="editTemplate(item)" style="cursor: pointer;" title="编辑模板">
<img src="@/assets/newimg/icon/del.png" alt="" style="margin-left: 10px;cursor: pointer;" title="删除">
<img src="@/assets/newimg/icon/del.png" alt="" @click="delTemplate(item)" style="margin-left: 10px;cursor: pointer;" title="删除">
</div>
<div style="display: flex;justify-content: center;margin-top: 20px;">
<div class="yulan" @click="preview(item, index)">预览</div>
<div class="mokuaipeizhi" @click="design(item, index)">设计</div>
<!-- <div class="mokuaipeizhi" @click="design(item, index)">设计</div> -->
</div>
</div>
</div>
@ -319,7 +352,7 @@ function editTemplate(item) {
<AddTemplateClass v-if="dialogVisible" @closeClassDialog="closeClassDialog" :classrefresh="classrefresh" />
</el-dialog>
<el-dialog v-model="dialogVisibles" title="导入模板" width="30%" :before-close="closeTemplateDialog">
<AddTemplate v-if="dialogVisibles" :optType="optType" :classList="classList" @init="init"
<AddTemplate v-if="dialogVisibles" :optType="optType" :classList="classList" :templateId="templateId" @init="init"
@closeTemplateDialog="closeTemplateDialog" />
</el-dialog>
</div>
@ -518,6 +551,7 @@ function editTemplate(item) {
font-size: 14px;
color: #C9C9C9;
cursor: pointer;
position: relative;
}
.class_list_active {
@ -525,7 +559,7 @@ function editTemplate(item) {
height: 40px;
line-height: 40px;
text-align: center;
background-color: rgba(54, 55, 56, 1);
background-color: #0089ff;
border-radius: 4px;
font-size: 14px;
color: #F2F4F5;
@ -660,4 +694,8 @@ function editTemplate(item) {
background: #434343;
color: #fff;
}
.ed-dialog__header{
padding: 0px;
padding-bottom: 10px;
}
</style>

View File

@ -0,0 +1,551 @@
<script lang="ts" setup>
import { ref, onMounted, reactive, computed, } from 'vue'
import { save, nameCheck, findOne, categoryTemplateNameCheck } from '@/api/template'
import { ElMessage, ElMessageBox } from 'element-plus-secondary'
import { useI18n } from '@/hooks/web/useI18n'
import { findCategories } from '@/api/template'
import AddTemplateClass from '@/viewsnew/TemplateResource/addclass.vue'
import { ElTree } from 'element-plus'
import { searchMarketPreview } from '@/api/templateMarket'
import { useEmbedded } from '@/store/modules/embedded'
import { useAppStoreWithOut } from '@/store/modules/app'
import { useEmitt } from '@/hooks/web/useEmitt'
import { Base64 } from 'js-base64'
import { useCache } from '@/hooks/web/useCache'
import { moduleAdd } from '@/api/application/module'
const props = defineProps({
templateinfo: {
type: Object,
required: true
}
})
const { wsCache } = useCache()
const embeddedStore = useEmbedded()
const appStore = useAppStoreWithOut()
const isEmbedded = computed(() => appStore.getIsDataEaseBi || appStore.getIsIframe)
const { t } = useI18n()
const basePath = import.meta.env.VITE_API_BASEPATH
const classname = ref('')
const templatename = ref('')
const classList = ref([])
const defaultProps = {
children: 'children',
label: 'label',
}
const treeRef = ref<InstanceType<typeof ElTree>>()
const treedata = ref([])
const activeIndex = ref(null)
const templateList = ref([])
const handleNodeClick = (data: any) => {
console.log(data)
templateList.value = data.contents
}
const mask = ref(-1) //
const state = reactive({
initReady: true,
curPosition: 'branch',
pid: null,
treeProps: {
value: 'label',
label: 'label'
},
templateType: 'all', //
templateSourceType: 'all', //
templateClassifyType: 'all', //
treeShow: true,
templateClassifyOptions: [
{
value: 'all',
label: t('visualization.all_type')
},
{
value: 'app',
label: t('visualization.apply_template')
},
{
value: 'template',
label: t('visualization.style_template')
}
],
templateSourceOptions: [
{
value: 'all',
label: t('work_branch.all_source')
},
{
value: 'market',
label: t('visualization.template_market')
},
{
value: 'manage',
label: t('template_manage.name')
}
],
templateTypeOptions: [
{
value: 'all',
label: t('work_branch.all_types')
},
{
value: 'PANEL',
label: t('work_branch.dashboard')
},
{
value: 'SCREEN',
label: t('work_branch.big_data_screen')
}
],
loading: false,
hasResult: true,
templateMiniWidth: 250,
templateCurWidth: 310,
templateSpan: '25%',
previewVisible: false,
templatePreviewId: '',
marketTabs: [],
marketActiveTab: null,
searchText: null,
dvCreateForm: {
resourceName: null,
name: null,
pid: null,
nodeType: 'panel',
templateUrl: null,
newFrom: 'new_market_template',
templateId: null,
panelType: 'self',
panelStyle: {},
panelData: '[]'
},
panelGroupList: [],
curApplyTemplate: null,
folderSelectShow: false,
baseUrl: 'https://dataease.io/templates',
currentMarketTemplateShowList: [],
curTemplateShowFilter: [],
curTemplateIndex: 0,
curTemplate: null,
networkStatus: true,
rule: {
name: [
{
required: true,
message: t('visualization.template_name_tips'),
trigger: 'blur'
}
],
pid: [
{
required: true,
message: '',
trigger: 'blur'
}
]
}
})
const isDialog = ref(false)
const dataInfo: any = ref({
pid: '',
level: '',
type: '',
nodeType: '',
name: '',
appId: ''
})
const typeList: any = ref([{
code: '01',
name: '登录页面'
}, {
code: '02',
name: '主框架页面'
}, {
code: '03',
name: 'GIS大屏页面'
}, {
code: '0301',
name: '数据看板页面'
}, {
code: '04',
name: '二级弹窗页面'
}, {
code: '05',
name: '数据填报页面'
}, {
code: '06',
name: '文档资源页面'
}, {
code: '09',
name: '自定义页面'
}])
onMounted(() => {
console.log(props.templateinfo, 66)
init()
})
function paramsCloseForm() {
isDialog.value = false
}
function init() {
treedata.value = []
templateList.value = []
searchMarketPreview().then(res => {
// templateList.value = res.data.contents
res.data.contents.forEach((e, index) => {
treedata.value.push({
label: e.category.label,
slug: e.category.slug,
source: e.category.source,
value: e.category.value,
contents: e.contents
})
classList.value.push({
label: e.category.label,
slug: e.category.slug,
source: e.category.source,
value: e.category.value,
contents: e.contents
})
});
})
}
function preview(item) {
}
const createTemplateInfo = ref({})
function design(item) {
createTemplateInfo.value = item
dataInfo.value = {
appId: props.templateinfo.appId,
pid: props.templateinfo.pid,
level: 2,
nodeType: '02',
name: item.name,
type: props.templateinfo.type,
}
isDialog.value = true
}
const isSwitch = ref(false)
const projectId = ref('')
function saveData() {
if (isSwitch.value == true) {
return
}
isSwitch.value = true
moduleAdd(dataInfo.value).then((res) => {
console.log(res)
projectId.value = res.data.data
ElMessage.success('添加成功')
isDialog.value = false
state.pid = props.templateinfo.pid
templateApply(createTemplateInfo.value)
}).catch(() => {
isSwitch.value = false
})
}
const templateApply = (template: any) => {
state.curApplyTemplate = template
state.dvCreateForm.name = template.title
state.dvCreateForm.nodeType = template.templateType
if (template.source === 'market') {
state.dvCreateForm.newFrom = 'new_market_template'
state.dvCreateForm.templateUrl = template.metas.theme_repo
state.dvCreateForm.resourceName = template.id
} else {
state.dvCreateForm.newFrom = 'new_inner_template'
state.dvCreateForm.templateId = template.id
}
apply()
}
const apply = () => {
if (state.dvCreateForm.newFrom === 'new_market_template' && !state.dvCreateForm.templateUrl) {
ElMessage.warning(t('template_manage.get_download_link_hint'))
return false
}
const templateTemplate = {
newFrom: state.dvCreateForm.newFrom,
templateUrl: state.dvCreateForm.templateUrl,
resourceName: state.dvCreateForm.resourceName,
templateId: state.dvCreateForm.templateId
}
state.curApplyTemplate.recentUseTime = Date.now()
state.curApplyTemplate.categoryNames.push(t('work_branch.recent'))
const baseUrl =
(['dataV', 'SCREEN'].includes(state.dvCreateForm.nodeType)
? '#/dvsCanvas?opt=create&createType=template&dvId=' + projectId.value
: '#/dashboard?opt=create&createType=template&resourceId=' + projectId.value) +
'&pid=' + props.templateinfo.pid + '&appId='+ props.templateinfo.appId+ '&templateParams=' +
encodeURIComponent(Base64.encode(JSON.stringify(templateTemplate)))
let newWindow = null
if (isEmbedded.value) {
embeddedStore.clearState()
embeddedStore.setCreateType('template')
embeddedStore.setTemplateParams(
encodeURIComponent(Base64.encode(JSON.stringify(templateTemplate)))
)
embeddedStore.setOpt('create')
if (state.pid) {
embeddedStore.setPid(state.pid)
}
useEmitt().emitter.emit(
'changeCurrentComponent',
['dataV', 'SCREEN'].includes(state.dvCreateForm.nodeType)
? 'VisualizationEditor'
: 'DashboardEditor'
)
return
}
const openType = wsCache.get('open-backend') === '1' ? '_self' : '_blank'
if (state.pid) {
newWindow = window.open(baseUrl + `&pid=${state.pid}`, openType)
} else {
newWindow = window.open(baseUrl, openType)
}
initOpenHandler(newWindow)
}
const openHandler = ref(null)
const initOpenHandler = newWindow => {
if (openHandler?.value) {
const pm = {
methodName: 'initOpenHandler',
args: newWindow
}
openHandler.value.invokeMethod(pm)
}
}
function mouseover(index) { //
mask.value = index
}
function mouseleave() { //
mask.value = -1
}
</script>
<template>
<div class="template-container" style="margin-top: 15px;">
<div class="template-header">
<div>使用模板创建</div>
<div>
<el-input v-model="templatename" placeholder="模板名称" style="width: 200px;margin-right: 10px;" />
<el-select v-model="classname" placeholder="分类" style="width: 240px">
<el-option v-for="item in classList" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
</div>
<div class="template-main">
<div class="template-main-left">
<el-tree :data="treedata" ref="treeRef" highlight-current node-key="value" :props="defaultProps"
@node-click="handleNodeClick" />
</div>
<div class="template-main-right">
<div class="template-list-box">
<div v-for="(item, index) in templateList" :key="index" class="template_list"
@mouseover="mouseover(index)" @mouseleave="mouseleave">
<img v-if="item.thumbnail != null && item.thumbnail != ''" :src="basePath + item.thumbnail"
alt="" style="width: 267px;height: 155px;">
<img v-else src="@/assets/newimg/u110.png" alt="" style="width: 267px;height: 155px;">
<div style="display: flex;justify-content: space-between;">
<div class="template_list_text">{{ item.title }}</div>
</div>
<div class="mask_box" v-if="mask == index">
<div style="display: flex;justify-content: center;margin-top: 20px;">
<div class="yulan" @click="preview(item)">预览</div>
<div class="mokuaipeizhi" @click="design(item)">创建</div>
</div>
</div>
</div>
</div>
</div>
</div>
<el-dialog title="新建模块" v-model="isDialog" width="570px" class="create-project-dialog"
:before-close="paramsCloseForm">
<el-form ref="paramsObjRef" :model="dataInfo" label-width="100px" style="margin-top: 15px;">
<el-form-item label="模块名称:" prop="name">
<el-input :placeholder="'请输入'" v-model="dataInfo.name" />
</el-form-item>
<el-form-item label="模块类型" prop="type">
<el-select v-model="dataInfo.type" placeholder="" style="width: 100%"
:disabled="dataInfo.nodeType == '02'">
<el-option v-for="item in typeList" :key="item.code" :label="item.name" :value="item.code" />
</el-select>
</el-form-item>
</el-form>
<template #footer>
<el-button class="root-class" @click="paramsCloseForm">{{ t('dataset.cancel') }} </el-button>
<el-button class="root-class" type="primary" @click="saveData">{{ t('dataset.confirm') }} </el-button>
</template>
</el-dialog>
</div>
</template>
<style lang="less" scoped>
.template-container {
height: calc(100vh - 200px);
}
.template-header {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
border-bottom: 1px solid #434343;
padding-bottom: 10px;
}
.template-main {
display: flex;
width: 100%;
.template-main-left {
width: 260px;
height: calc(100vh - 221px);
border-right: 1px solid #434343;
:deep(.el-tree-node__content>.el-tree-node__expand-icon) {
padding: 0px;
}
:deep(.el-tree) {
background: #212121;
color: #fff;
}
:deep(.el-tree-node__content) {
height: 40px;
background: #212121;
}
:deep(.el-tree-node__content:hover) {
background: #3b3c3c;
}
:deep(.el-tree--highlight-current .el-tree-node.is-current>.el-tree-node__content) {
background: #3b3c3c;
}
:deep(.el-tree-node:focus>.el-tree-node__content) {
background: #3b3c3c;
}
:deep(.el-tree-node__label) {
color: #fff;
}
}
.template-main-right {
width: calc(100% - 260px);
background: #151515;
padding: 0px 10px;
}
.template-list-box {
display: flex;
flex-wrap: wrap;
height: calc(100vh - 235px);
overflow: auto;
align-content: flex-start;
.template_list {
position: relative;
margin-top: 10px;
width: 290px;
height: 210px;
background: inherit;
background-color: rgba(37, 38, 38, 1);
box-sizing: border-box;
padding: 10px;
border-width: 1px;
border-style: solid;
border-color: rgba(51, 51, 51, 1);
border-radius: 10px;
margin-right: 10px;
text-align: center;
}
.template_list_text {
font-family: 'Arial Normal', 'Arial';
font-weight: 400;
font-style: normal;
font-size: 12px;
color: #F2F4F5;
padding-top: 13px;
position: relative;
z-index: 11;
}
.mask_box {
position: absolute;
top: 0;
left: 0;
z-index: 10;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.8);
border-radius: 10px;
box-sizing: border-box;
padding-top: 60px;
border: 1px solid #0089ff;
}
.mask_box_img {
display: flex;
justify-content: center;
margin-bottom: 20px;
img {
margin: 0 8px;
cursor: pointer;
}
}
.yulan {
width: 50px;
height: 28px;
line-height: 28px;
text-align: center;
background-color: rgba(255, 255, 255, 0.3);
border: none;
border-radius: 4px;
box-shadow: none;
font-size: 14px;
font-family: 'Arial Normal', 'Arial';
font-weight: 400;
font-style: normal;
color: rgb(255, 255, 255);
margin-right: 10px;
cursor: pointer;
}
.mokuaipeizhi {
width: 50px;
height: 28px;
line-height: 28px;
text-align: center;
background-color: rgba(0, 137, 255, 1);
border: none;
border-radius: 4px;
box-shadow: none;
font-size: 14px;
font-family: 'Arial Normal', 'Arial';
font-weight: 400;
font-style: normal;
color: rgb(255, 255, 255);
cursor: pointer;
}
}
}
</style>
<style>
.ed-select__wrapper {
background-color: #252626 !important;
border: 1px solid #434343 !important;
box-shadow: none !important;
}
::-webkit-scrollbar {
width: 0px !important;
height: 0px !important;
}
</style>

View File

@ -5,6 +5,7 @@ import { ElMessage,ElMessageBox } from 'element-plus-secondary'
import { useI18n } from '@/hooks/web/useI18n'
import { publicTree } from '@/utils/validate';
import { moduleList,moduleAdd,moduleUpdate,moduleDel,moduleCopy } from '@/api/application/module'
import TemplateCreate from '@/viewsnew/TemplateResource/templateinfo.vue'
const emit = defineEmits(['handleNodeClick'])
const { t } = useI18n()
const router = useRouter()
@ -57,7 +58,8 @@ const dataInfo:any =ref({
})
const treeData:any=ref([])//
const defaultProps = { label: "name" }
const templatedialog = ref(false)
const templateinfo = ref({})
watch(() => props.projectInfo, val => { //
projectInfo.value = val
getInit()
@ -91,8 +93,6 @@ function addClic(name:any,level:any,pid:any){ // 新建目录、模块
dataInfo.value.nodeType = '02'
}
title.value = '新建' + name
isSwitch.value = false
isDialog.value=true
@ -260,6 +260,13 @@ function delTreeClic(){ // 删除
}
function templateAdd(){
templateinfo.value = dataInfo.value
templatedialog.value = true
}
function templatedialogClose(){
templatedialog.value = false
}
</script>
<template>
<div class="project-left-box">
@ -279,17 +286,17 @@ function delTreeClic(){ // 删除
<img src="@/assets/newimg/u62.png" alt="">
</template>
</el-input>
<el-scrollbar style="height: calc(100vh - 260px);margin-top: 10px;">
<!-- <el-scrollbar style="margin-top: 10px;"> -->
<el-tree v-loading="treeloading" id="treeRefClickId" ref="treeRef" node-key="id" :data="treeData" default-expand-all
:highlight-current="true" :props="defaultProps" :expand-on-click-node="false"
@node-click="handleNodeClick">
@node-click="handleNodeClick" style="height: calc(100vh - 170px);overflow: auto;">
<template #default="{ data }">
<!-- @mouseleave="isTreeDrag = false" -->
<div class="el-tree-node__content" >
<img v-if="data.node_type=='01'" src="@/assets/newimg/u74.png" alt="" style="width: 14px;height: 13px;margin-right: 10px;">
<div class="el-tree-node__label">{{ data.name }}</div>
<div class="operation-button-box">
<div style="
<div style="
width: 20px;
height: 24px;">
<img v-if="data.node_type == '01'" src="@/assets/newimg/icon/add.png" alt="" style="width: 14px;height: 13px;" @click.stop="addTreeChildNode($event, Number(data.level)+1,data)">
@ -305,7 +312,7 @@ function delTreeClic(){ // 删除
</div>
</template>
</el-tree>
</el-scrollbar>
<!-- </el-scrollbar> -->
<el-dialog
:title="title"
v-model="isDialog"
@ -354,6 +361,7 @@ function delTreeClic(){ // 删除
>
<div class="drag-main-text" v-if="popupType == 1" @click="addTreeClic('目录')">新建目录</div>
<div class="drag-main-text" v-if="popupType == 1" @click="addTreeClic('模块')">新建模块</div>
<div class="drag-main-text" v-if="popupType == 1" @click="templateAdd">使用模板创建模块</div>
<div class="drag-main-text" v-if="popupType == 2" @click="copyClick">复制</div>
@ -363,6 +371,9 @@ function delTreeClic(){ // 删除
</div>
<el-dialog v-model="templatedialog" top="5vh" title="使用模板创建" width="80%" :before-close="templatedialogClose">
<TemplateCreate v-if="templatedialog" :templateinfo="templateinfo" />
</el-dialog>
</div>
</template>
@ -419,6 +430,7 @@ function delTreeClic(){ // 删除
}
:deep(.ed-tree-node__content){
height: 40px;
position: relative;
}
.operation-button-box{
display: none;
@ -426,6 +438,7 @@ function delTreeClic(){ // 删除
right: 20px;
// display: flex;
align-items: center;
top: 13px;
}
:deep(.ed-tree-node__content:hover){
@ -558,14 +571,14 @@ function delTreeClic(){ // 删除
}
.ed-select__popper.ed-popper{
background: rgb(41,41,41) !important;
color: #fff;
border:1px solid #434343;
color: #fff !important;
border:1px solid #434343 !important;
}
.ed-select-dropdown__item{
color: #F2F4F5;
color: #F2F4F5 !important;
}
.ed-select-dropdown__item.hover, .ed-select-dropdown__item:hover{
background-color: rgba(255, 255, 255, .1)
background-color: rgba(255, 255, 255, .1) !important;
}
.ed-select .ed-input__wrapper:hover {
box-shadow: none;

View File

@ -246,14 +246,14 @@ defineExpose({
.preview {
margin-top: 5px;
border: 1px solid #e6e6e6;
border: 1px solid #434343;
height: 310px !important;
overflow: hidden;
background-size: 100% 100% !important;
}
.preview-show {
border-left: 1px solid #e6e6e6;
border-left: 1px solid #434343;
height: 310px;
background-size: 100% 100% !important;
}

View File

@ -413,6 +413,18 @@ onMounted(async () => {
// do init
})
}
if (createType === 'template') {
let deTemplateData
let preName
const templateParamsApply = JSON.parse(Base64.decode(decodeURIComponent(templateParams + '')))
await decompressionPre(templateParamsApply, result => {
deTemplateData = result
preName = deTemplateData.baseInfo?.preName
dvMainStore.setComponentData(deTemplateData['componentData'])
dvMainStore.setCanvasStyle(deTemplateData['canvasStyleData'])
dvMainStore.setCanvasViewInfo(deTemplateData['canvasViewInfo'])
})
}
} else if (opt && opt === 'create') {
state.canvasInitStatus = false
let watermarkBaseInfo