feat(仪表板): 仪表板样式及主题设置支持视图背景图片设置

This commit is contained in:
wangjiahao 2022-12-14 16:31:32 +08:00
parent 285acbeae3
commit 23f47e6e1e
8 changed files with 575 additions and 14 deletions

View File

@ -1,5 +1,6 @@
import {
BASE_MOBILE_STYLE,
COMMON_BACKGROUND,
COMMON_BACKGROUND_NONE,
HYPERLINKS
} from '@/components/canvas/customComponent/component-list'
@ -86,7 +87,17 @@ export function panelDataPrepare(componentData, componentStyle, callback) {
componentStyle.chartInfo.tabStyle = (componentStyle.chartInfo.tabStyle || deepCopy(TAB_COMMON_STYLE))
componentStyle.themeId = (componentStyle.themeId || 'NO_THEME')
componentStyle.panel.themeColor = (componentStyle.panel.themeColor || 'light')
componentStyle.panel.mobileSetting = (componentStyle.panel.mobileSetting || MOBILE_SETTING)
componentStyle.panel.mobileSetting = (componentStyle.panel.mobileSetting || deepCopy(MOBILE_SETTING))
// 主题增加组件背景设置
if (componentStyle.chartCommonStyle) {
componentStyle.chartCommonStyle.enable = componentStyle.chartCommonStyle.enable || false
componentStyle.chartCommonStyle.backgroundType = componentStyle.chartCommonStyle.backgroundType || 'innerImage'
componentStyle.chartCommonStyle.innerImage = componentStyle.chartCommonStyle.innerImage || 'board/blue_1.svg'
componentStyle.chartCommonStyle.outerImage = componentStyle.chartCommonStyle.outerImage || null
} else {
componentStyle.chartCommonStyle = deepCopy(COMMON_BACKGROUND)
}
componentData.forEach((item, index) => {
if (item.component && item.component === 'de-date') {
const widget = ApplicationContext.getService(item.serviceName)

View File

@ -1932,6 +1932,9 @@ export default {
back_parent: 'Back to previous'
},
panel: {
view_style: 'View Style',
view_color_setting: 'View Color Setting',
border_color_setting: 'Border Color',
unpublished_tips: 'After unpublishing, the panel cannot be viewed. Are you sure you want to cancel publishing? ',
position_adjust_component: 'Position adjust',
active_font_size: 'Selected font size',

View File

@ -1926,6 +1926,9 @@ export default {
back_parent: '返回上一級'
},
panel: {
view_style: '視圖樣式',
view_color_setting: '視圖配色',
border_color_setting: '邊框配色',
unpublished_tips: '取消發布後,該儀表板不能被查看。確定要取消發布?',
position_adjust_component: '位置調整',
active_font_size: '选中字體大小',
@ -2258,7 +2261,7 @@ export default {
show_title: '標題',
default_settings: '默認值設置',
choose_background: '選擇組件背景',
choose_background_tips: '組件自有背景設置會覆蓋當前設置',
choose_background_tips: '組件自有背景會覆蓋當前設置',
setting_background: '設置背景',
setting_jump: '跳轉設置',
select_view: '請選擇視圖...',

View File

@ -1926,6 +1926,9 @@ export default {
back_parent: '返回上一级'
},
panel: {
view_style: '视图样式',
view_color_setting: '视图配色',
border_color_setting: '边框配色',
unpublished_tips: '取消发布后,该仪表板不能被查看。确定要取消发布?',
position_adjust_component: '位置调整',
active_font_size: '选中字体大小',
@ -2258,7 +2261,7 @@ export default {
show_title: '标题',
default_settings: '默认值设置',
choose_background: '选择组件背景',
choose_background_tips: '组件自有背景设置会覆盖当前设置',
choose_background_tips: '组件自有背景会覆盖当前设置',
setting_background: '设置背景',
setting_jump: '跳转设置',
select_view: '请选择视图...',

View File

@ -0,0 +1,148 @@
<template>
<div class="testcase-template">
<div
:class="[
{
['template-img-active']:itemActive
},
'template-img'
]"
:style="itemStyle"
@click.stop="setBoard"
>
<svg-icon
:style="{'color':commonBackground.innerImageColor}"
class="svg-background"
:icon-class="mainIconClass"
/>
</div>
<span class="demonstration">{{ template.name }}</span>
</div>
</template>
<script>
import { imgUrlTrans } from '@/components/canvas/utils/utils'
import { hexColorToRGBA } from '@/views/chart/chart/util'
export default {
name: 'BackgroundItemOverall',
props: {
template: {
type: Object,
default() {
return {}
}
},
commonBackground: {
type: Object,
required: true
}
},
computed: {
itemStyle() {
if (this.commonBackground.backgroundColorSelect) {
return {
'background-color': hexColorToRGBA(this.commonBackground.color, this.commonBackground.alpha)
}
} else {
return {}
}
},
mainIconClass() {
return this.template.url.replace('board/', '').replace('.svg', '')
},
itemActive() {
return this.commonBackground && this.commonBackground.innerImage === this.template.url
},
classBackground() {
if (this.template.url) {
return {
background: `url(${imgUrlTrans(this.template.url)}) no-repeat`,
'background-size': `100% 100%`
}
} else {
return {}
}
}
},
methods: {
setBoard() {
this.commonBackground.innerImage = this.template.url
this.$emit('borderChange')
}
}
}
</script>
<style scoped>
.testcase-template {
display: inline-block;
margin: 5px 0px;
width: 90px;
}
.demonstration {
display: block;
font-size: 8px;
color: gray;
text-align: center;
margin: 10px auto;
width: 110px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.template-img {
position: relative;
height: 70px;
width: 110px;
margin: 0 auto;
/*box-shadow: 0 0 2px 0 rgba(31, 31, 31, 0.15), 0 1px 2px 0 rgba(31, 31, 31, 0.15);*/
/*border: solid px #fff;*/
box-sizing: border-box;
border-radius: 3px;
}
.template-img:hover {
border: solid 1px #4b8fdf;
border-radius: 3px;
color: deepskyblue;
cursor: pointer;
}
.template-img > i {
display: none;
float: right;
color: gray;
margin: 2px;
}
.template-img > i:hover {
color: red;
}
.template-img:hover > .el-icon-error {
display: inline;
}
.template-img:hover > .el-icon-edit {
display: inline;
}
.template-img-active {
border: solid 1px red;
border-radius: 3px;
color: deepskyblue;
}
.svg-background {
position: absolute;
top: 0;
left: 0;
width: 100% !important;
height: 100% !important;
}
</style>

View File

@ -0,0 +1,389 @@
<template>
<el-row>
<el-row>
<el-row style="height: 50px;overflow: hidden">
<el-col :span="8">
<span class="params-title">{{ $t('panel.inner_padding') }}</span>
</el-col>
<el-col :span="16">
<el-slider
v-model="commonBackground.innerPadding"
show-input
:show-input-controls="false"
input-size="mini"
:max="50"
@change="themeChange('innerPadding')"
/>
</el-col>
</el-row>
<el-row style="height: 50px;overflow: hidden">
<el-col :span="8">
<span class="params-title">{{ $t('panel.board_radio') }}</span>
</el-col>
<el-col :span="16">
<el-slider
v-model="commonBackground.borderRadius"
show-input
:show-input-controls="false"
input-size="mini"
@change="themeChange('borderRadius')"
/>
</el-col>
</el-row>
<el-row style="height: 40px;overflow: hidden;">
<el-col
:span="6"
style="padding-top: 5px"
>
<el-checkbox v-model="commonBackground.backgroundColorSelect" @change="themeChange('backgroundColorSelect')">
{{
$t('chart.color')
}}
</el-checkbox>
</el-col>
<el-col
:span="3"
style="padding-top: 5px"
>
<el-color-picker
v-model="commonBackground.color"
:disabled="!commonBackground.backgroundColorSelect"
size="mini"
class="color-picker-style"
:predefine="predefineColors"
@change="themeChange('color')"
/>
</el-col>
<el-col :span="5">
<span class="params-title-small">{{ $t('chart.not_alpha') }}</span>
</el-col>
<el-col :span="10">
<el-slider
v-model="commonBackground.alpha"
:disabled="!commonBackground.backgroundColorSelect"
show-input
:show-input-controls="false"
input-size="mini"
@change="themeChange('alpha')"
/>
</el-col>
</el-row>
<el-row style="height: 50px">
<el-col
:span="4"
style="padding-top: 5px"
>
<el-checkbox v-model="commonBackground.enable" @change="themeChange('enable')">{{
$t('panel.background')
}}
</el-checkbox>
</el-col>
<el-col :span="20">
<span style="color: #909399; font-size: 8px;margin-left:10px;line-height: 40px">
Tips:{{ $t('panel.choose_background_tips') }}
</span>
</el-col>
</el-row>
<el-row
v-if="commonBackground.enable"
style="padding-left: 10px"
>
<el-row style="height: 80px;margin-top:0px;margin-bottom:20px;overflow: hidden">
<el-col
:span="5"
>
<el-radio
v-model="commonBackground.backgroundType"
label="outerImage"
@change="themeChange('backgroundType')"
>{{ $t('panel.photo') }}
</el-radio>
</el-col>
<el-col style="width: 130px!important;">
<el-upload
action=""
accept=".jpeg,.jpg,.png,.gif,.svg"
class="avatar-uploader"
list-type="picture-card"
:class="{disabled:uploadDisabled}"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove"
:http-request="upload"
:file-list="fileList"
>
<i class="el-icon-plus"/>
</el-upload>
<el-dialog
top="25vh"
width="600px"
:append-to-body="true"
:destroy-on-close="true"
:visible.sync="dialogVisible"
>
<img
width="100%"
:src="dialogImageUrl"
>
</el-dialog>
</el-col>
</el-row>
<el-row>
<el-col style="position: relative">
<el-radio
v-model="commonBackground.backgroundType"
label="innerImage"
@change="themeChange('backgroundType')"
>{{ $t('panel.board') }}
</el-radio>
<el-color-picker
v-model="commonBackground.innerImageColor"
:title="$t('panel.border_color_setting')"
style="position: absolute;left:60px;top: -3px"
size="mini"
class="color-picker-style"
:predefine="predefineColors"
@change="themeChange('innerImageColor')"
/>
</el-col>
</el-row>
<el-row>
<el-col
:style="customStyle"
class="main-row"
>
<el-row
v-for="(value, key) in BackgroundShowMap"
:key="key"
>
<el-col
v-for="item in value"
:key="item.id"
:span="12"
>
<background-item-overall
:common-background="commonBackground"
:template="item"
@borderChange="themeChange('innerImage')"
/>
</el-col>
</el-row>
</el-col>
</el-row>
</el-row>
</el-row>
</el-row>
</template>
<script>
import { queryBackground } from '@/api/background/background'
import BackgroundItem from '@/views/background/BackgroundItem'
import { mapState } from 'vuex'
import { imgUrlTrans } from '@/components/canvas/utils/utils'
import { COLOR_PANEL } from '@/views/chart/chart/chart'
import { uploadFileResult } from '@/api/staticResource/staticResource'
import bus from '@/utils/bus'
import BackgroundItemOverall from '@/views/background/BackgroundItemOverall'
export default {
name: 'BackgroundOverall',
components: { BackgroundItemOverall, BackgroundItem },
props: {
position: {
type: String,
required: false,
default: 'component'
}
},
data() {
return {
commonBackground: null,
BackgroundShowMap: {},
checked: false,
backgroundOrigin: {},
fileList: [],
dialogImageUrl: '',
dialogVisible: false,
uploadDisabled: false,
panel: null,
predefineColors: COLOR_PANEL
}
},
computed: {
customStyle() {
let style = {}
if (this.canvasStyleData.openCommonStyle) {
if (this.canvasStyleData.panel.backgroundType === 'image' && this.canvasStyleData.panel.imageUrl) {
style = {
background: `url(${imgUrlTrans(this.canvasStyleData.panel.imageUrl)}) no-repeat`,
...style
}
} else if (this.canvasStyleData.panel.backgroundType === 'color') {
style = {
background: this.canvasStyleData.panel.color,
...style
}
}
}
if (!style.background) {
style.background = '#FFFFFF'
}
return style
},
...mapState([
'componentData',
'canvasStyleData'
])
},
created() {
this.init()
bus.$on('onThemeColorChange', this.init)
},
beforeDestroy() {
bus.$off('onThemeColorChange', this.init)
},
methods: {
init() {
this.commonBackground = this.canvasStyleData.chartInfo.chartCommonStyle
if (this.commonBackground && this.commonBackground.outerImage && typeof (this.commonBackground.outerImage) === 'string') {
this.fileList.push({ url: imgUrlTrans(this.commonBackground.outerImage) })
}
this.queryBackground()
},
queryBackground() {
queryBackground().then(response => {
this.BackgroundShowMap = response.data
})
},
commitStyle() {
this.$store.commit('recordSnapshot')
},
onChangeType() {
this.commitStyle()
},
handleRemove(file, fileList) {
this.uploadDisabled = false
this.commonBackground.outerImage = null
this.themeChange('outerImage')
this.fileList = []
this.commitStyle()
},
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url
this.dialogVisible = true
},
upload(file) {
const _this = this
uploadFileResult(file.file, (fileUrl) => {
_this.commonBackground.outerImage = fileUrl
this.themeChange('outerImage')
})
},
themeChange(modifyName) {
this.componentData.forEach((item, index) => {
if (item.type === 'view') {
item.commonBackground[modifyName] = this.commonBackground[modifyName]
}
})
this.$store.commit('recordSnapshot')
}
}
}
</script>
<style scoped>
.el-card-template {
width: 100%;
height: 100%;
}
.main-row {
background-size: 100% 100% !important;
padding-left: 10px;
margin-top: 10px;
height: 230px;
overflow-y: auto;
}
.root-class {
margin: 15px 0px 5px;
text-align: center;
}
.avatar-uploader ::v-deep .el-upload {
width: 120px;
height: 80px;
line-height: 90px;
}
.avatar-uploader ::v-deep .el-upload-list li {
width: 120px !important;
height: 80px !important;
}
.disabled ::v-deep .el-upload--picture-card {
display: none;
}
.shape-item {
padding: 6px;
border: none;
width: 100%;
display: flex;
justify-content: space-between;
align-items: center;
}
.form-item-slider ::v-deep .el-form-item__label {
font-size: 12px;
line-height: 38px;
}
.form-item ::v-deep .el-form-item__label {
font-size: 12px;
}
.el-select-dropdown__item {
padding: 0 20px;
}
span {
font-size: 12px
}
.el-form-item {
margin-bottom: 6px;
}
.main-content {
}
.params-title {
font-weight: 400 !important;
font-size: 14px !important;
color: var(--TextPrimary, #1F2329) !important;
line-height: 40px;
}
.params-title-small {
font-size: 12px !important;
color: var(--TextPrimary, #1F2329) !important;
line-height: 40px;
}
::v-deep .el-slider__input {
width: 40px;
padding-left: 0px;
padding-right: 0px;
}
::v-deep .el-input__inner {
padding: 0px !important;
}
::v-deep .el-slider__runway {
margin-right: 60px !important;
}
</style>

View File

@ -1,7 +1,7 @@
// eslint-disable-next-line no-unused-vars
import { DEFAULT_COLOR_CASE, DEFAULT_TITLE_STYLE } from '@/views/chart/chart/chart'
import { deepCopy } from '@/components/canvas/utils/utils'
import { COMMON_BACKGROUND_BASE } from '@/components/canvas/customComponent/component-list'
import { COMMON_BACKGROUND } from '@/components/canvas/customComponent/component-list'
export const TAB_COMMON_STYLE = {
headFontColor: '#000000',
@ -50,7 +50,7 @@ export const DEFAULT_PANEL_STYLE = {
export const PANEL_CHART_INFO = {
chartTitle: DEFAULT_TITLE_STYLE,
chartColor: DEFAULT_COLOR_CASE,
chartCommonStyle: COMMON_BACKGROUND_BASE,
chartCommonStyle: COMMON_BACKGROUND,
filterStyle: FILTER_COMMON_STYLE,
tabStyle: TAB_COMMON_STYLE
}

View File

@ -3,7 +3,7 @@
<div class="theme-slider-main">
{{ $t('panel.dashboard_theme') }}
</div>
<div class="theme-slider-position" />
<div class="theme-slider-position"/>
<div>
<slider
v-if="sliderShow"
@ -25,38 +25,38 @@
name="panel"
>
<el-row class="selector-div">
<overall-setting />
<overall-setting/>
</el-row>
</el-collapse-item>
<el-collapse-item
:title="$t('panel.panel_background')"
name="panelBackground"
>
<background-selector />
<background-selector/>
</el-collapse-item>
<el-collapse-item
:title="$t('panel.component_style')"
:title="$t('panel.view_style')"
name="componentStyle"
>
<component-style />
<background-overall></background-overall>
</el-collapse-item>
<el-collapse-item
:title="$t('panel.component_color')"
:title="$t('panel.view_color_setting')"
name="graphical"
>
<panel-color-selector @onColorChange="onColorChange" />
<panel-color-selector @onColorChange="onColorChange"/>
</el-collapse-item>
<el-collapse-item
:title="$t('panel.chart_title')"
name="table"
>
<view-title @onTextChange="onTextChange" />
<view-title @onTextChange="onTextChange"/>
</el-collapse-item>
<el-collapse-item
:title="$t('panel.filter_component')"
name="filterComponent"
>
<FilterStyleSelector />
<FilterStyleSelector/>
</el-collapse-item>
</el-collapse>
</div>
@ -75,9 +75,13 @@ import ViewTitle from '@/views/panel/subjectSetting/panelStyle/ViewTitle'
import ComponentStyle from '@/views/panel/subjectSetting/panelStyle/ComponentStyle'
import { adaptCurThemeCommonStyleAll } from '@/components/canvas/utils/style'
import FilterStyleSelector from '@/views/panel/subjectSetting/panelStyle/FilterStyleSelector'
import Background from '@/views/background'
import BackgroundOverall from '@/views/background/BackgroundOverall'
export default {
components: {
BackgroundOverall,
Background,
FilterStyleSelector,
ComponentStyle,
ViewTitle,