Merge branch 'dev-v2' into pr@dev-v2@perf_free_resource
This commit is contained in:
commit
3fb3b97d9e
@ -113,8 +113,9 @@ public class DatasetDataManage {
|
||||
sql = provider.transSqlDialect(sql, datasourceRequest.getDsList());
|
||||
} else {
|
||||
// parser sql params and replace default value
|
||||
String originSql = provider.replaceComment(new String(Base64.getDecoder().decode(tableInfoDTO.getSql())));
|
||||
originSql = SqlparserUtils.handleVariableDefaultValue(originSql, datasetTableDTO.getSqlVariableDetails(), false, false, null, false, datasourceRequest.getDsList(), pluginManage);
|
||||
String s = new String(Base64.getDecoder().decode(tableInfoDTO.getSql()));
|
||||
String originSql = SqlparserUtils.handleVariableDefaultValue(s, datasetTableDTO.getSqlVariableDetails(), false, false, null, false, datasourceRequest.getDsList(), pluginManage);
|
||||
originSql = provider.replaceComment(originSql);
|
||||
// add sql table schema
|
||||
|
||||
sql = SQLUtils.buildOriginPreviewSql(SqlPlaceholderConstants.TABLE_PLACEHOLDER, 0, 0);
|
||||
@ -403,8 +404,9 @@ public class DatasetDataManage {
|
||||
|
||||
// parser sql params and replace default value
|
||||
|
||||
String originSql = provider.replaceComment(new String(Base64.getDecoder().decode(dto.getSql())));
|
||||
originSql = SqlparserUtils.handleVariableDefaultValue(datasetSQLManage.subPrefixSuffixChar(originSql), dto.getSqlVariableDetails(), true, true, null, false, dsMap, pluginManage);
|
||||
String s = new String(Base64.getDecoder().decode(dto.getSql()));
|
||||
String originSql = SqlparserUtils.handleVariableDefaultValue(datasetSQLManage.subPrefixSuffixChar(s), dto.getSqlVariableDetails(), true, true, null, false, dsMap, pluginManage);
|
||||
originSql = provider.replaceComment(originSql);
|
||||
|
||||
// sql 作为临时表,外层加上limit
|
||||
String sql;
|
||||
|
||||
@ -451,8 +451,9 @@ public class DatasetSQLManage {
|
||||
} else if (StringUtils.equalsIgnoreCase(currentDs.getType(), DatasetTableTypeConstants.DATASET_TABLE_SQL)) {
|
||||
Provider provider = ProviderFactory.getProvider(dsMap.entrySet().iterator().next().getValue().getType());
|
||||
// parser sql params and replace default value
|
||||
String sql = provider.replaceComment(new String(Base64.getDecoder().decode(infoDTO.getSql())));
|
||||
sql = SqlparserUtils.handleVariableDefaultValue(sql, currentDs.getSqlVariableDetails(), false, isFromDataSet, parameters, isCross, dsMap, pluginManage);
|
||||
String s = new String(Base64.getDecoder().decode(infoDTO.getSql()));
|
||||
String sql = SqlparserUtils.handleVariableDefaultValue(s, currentDs.getSqlVariableDetails(), false, isFromDataSet, parameters, isCross, dsMap, pluginManage);
|
||||
sql = provider.replaceComment(sql);
|
||||
// add table schema
|
||||
if (isCross) {
|
||||
sql = SqlUtils.addSchema(sql, tableSchema);
|
||||
|
||||
@ -0,0 +1,16 @@
|
||||
package io.dataease.msgCenter;
|
||||
|
||||
import io.dataease.api.msgCenter.MsgCenterApi;
|
||||
import io.dataease.license.config.XpackInteract;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/msg-center")
|
||||
public class MsgCenterServer implements MsgCenterApi {
|
||||
@Override
|
||||
@XpackInteract(value = "msgCenterServer", replace = true)
|
||||
public long count() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@ -43,6 +43,7 @@
|
||||
<result column="publicJumpId" jdbcType="VARCHAR" property="publicJumpId"/>
|
||||
<collection property="targetViewInfoList"
|
||||
ofType="io.dataease.api.visualization.vo.VisualizationLinkJumpTargetViewInfoVO">
|
||||
<result column="target_id" jdbcType="BIGINT" property="targetId"/>
|
||||
<result column="target_view_id" jdbcType="BIGINT" property="targetViewId"/>
|
||||
<result column="target_field_id" jdbcType="BIGINT" property="targetFieldId"/>
|
||||
<result column="source_field_active_id" jdbcType="VARCHAR" property="sourceFieldActiveId"/>
|
||||
@ -87,6 +88,7 @@
|
||||
xpack_share.uuid AS publicJumpId,
|
||||
ifnull( visualization_link_jump_info.checked, 0 ) AS checked,
|
||||
ifnull( visualization_link_jump_info.attach_params, 0 ) AS attach_params,
|
||||
visualization_link_jump_target_view_info.target_id,
|
||||
visualization_link_jump_target_view_info.target_view_id,
|
||||
visualization_link_jump_target_view_info.target_field_id,
|
||||
visualization_link_jump_target_view_info.target_type,
|
||||
@ -102,7 +104,7 @@
|
||||
LEFT JOIN visualization_link_jump_target_view_info ON visualization_link_jump_info.id = visualization_link_jump_target_view_info.link_jump_info_id
|
||||
LEFT JOIN xpack_share ON xpack_share.creator = #{uid}
|
||||
AND visualization_link_jump_info.target_dv_id = xpack_share.resource_id
|
||||
left join visualization_outer_params_info on visualization_outer_params_info.params_id = visualization_link_jump_target_view_info.target_view_id
|
||||
left join visualization_outer_params_info on visualization_outer_params_info.params_info_id = visualization_link_jump_target_view_info.target_view_id
|
||||
WHERE
|
||||
core_chart_view.id = #{source_view_id}
|
||||
AND core_chart_view.type != 'VQuery'
|
||||
@ -162,7 +164,7 @@
|
||||
|
||||
<select id="queryOutParamsTargetWithDvId" resultType="io.dataease.api.visualization.vo.VisualizationOutParamsJumpVO">
|
||||
SELECT
|
||||
vopi.params_id as id,
|
||||
vopi.params_info_id as id,
|
||||
vopi.param_name as name,
|
||||
vopi.param_name as title,
|
||||
'outerParams' as type
|
||||
|
||||
3
core/core-frontend/src/api/msg.ts
Normal file
3
core/core-frontend/src/api/msg.ts
Normal file
@ -0,0 +1,3 @@
|
||||
import request from '@/config/axios'
|
||||
|
||||
export const msgCountApi = () => request.post({ url: '/msg-center/count', data: {} })
|
||||
12
core/core-frontend/src/assets/svg/dv-style-blur.svg
Normal file
12
core/core-frontend/src/assets/svg/dv-style-blur.svg
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="44px" height="44px" viewBox="0 0 44 44" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<title>模糊修复</title>
|
||||
<g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="模糊修复" fill="#BBBFC3" fill-rule="nonzero">
|
||||
<path d="M4.94539535,3.06976745 C3.90986044,3.06976745 3.06976745,3.90883718 3.06976745,4.94539535 L3.06976745,39.0546046 C3.06976745,40.0901396 3.90883718,40.9302326 4.94539535,40.9302326 L39.0546046,40.9302326 C40.0901396,40.9302326 40.9302326,40.0911628 40.9302326,39.0546046 L40.9302326,4.94539535 C40.9302326,3.90986044 40.0911628,3.06976745 39.0546046,3.06976745 L4.94539535,3.06976745 Z M0,4.94539535 C0,2.21412892 2.21412892,0 4.94539535,0 L39.0546046,0 C41.7858711,0 44,2.21412892 44,4.94539535 L44,39.0546046 C44,41.7858711 41.7858711,44 39.0546046,44 L4.94539535,44 C2.21412892,44 0,41.7858711 0,39.0546046 L0,4.94539535 L0,4.94539535 Z" id="形状"></path>
|
||||
<path d="M10,11.4868562 C10,10.6656882 10.6656354,10 11.4867383,10 L33.5132617,10 C34.3343646,10 35,10.6656882 35,11.4868562 L35,33.5131438 C35,34.3343118 34.3343646,35 33.5132617,35 L11.4867383,35 C10.6656354,35 10,34.3343118 10,33.5131438 L10,11.4868562 L10,11.4868562 Z M12.9734765,12.9737123 L12.9734765,32.0262877 L32.0265234,32.0262877 L32.0265234,12.9737123 L12.9734765,12.9737123 Z" id="形状"></path>
|
||||
<path d="M34.5646998,20.3474464 C35.1451,20.9280211 35.1451,21.8691328 34.5646998,22.4497075 L22.4506634,34.5647187 C22.074953,34.9402515 21.5274377,35.0868193 21.0143611,34.9492114 C20.5012846,34.8116035 20.1005953,34.4107259 19.9632291,33.8975852 C19.8258629,33.3844446 19.972689,32.8369991 20.3483993,32.4614663 L32.4624357,20.3474464 C33.0430113,19.7670469 33.9841243,19.7670469 34.5646998,20.3474464 L34.5646998,20.3474464 Z M24.6540264,10.4357952 C25.2344267,11.01637 25.2344267,11.9574817 24.6540264,12.5380565 L12.5380077,24.6530676 C11.9572098,25.233591 11.0157722,25.2333691 10.435248,24.652572 C9.85472385,24.0717749 9.85494572,23.1303387 10.4357436,22.5498153 L22.54978,10.4357952 C22.828627,10.1567699 23.206932,10 23.6014076,10 C23.9958833,10 24.3741883,10.1567699 24.6530352,10.4357952 L24.6540264,10.4357952 Z M34.5646998,10.4357952 C35.1451001,11.01637 35.1451001,11.9574817 34.5646998,12.5380565 L12.5389988,34.5647187 C11.9582009,35.1452421 11.0167634,35.1450202 10.4362392,34.5642231 C9.85571504,33.983426 9.8559369,33.0419897 10.4367348,32.4614663 L32.4624357,10.4357952 C33.0430113,9.85539577 33.9841243,9.85539577 34.5646998,10.4357952 Z" id="形状"></path>
|
||||
<path d="M11.4859238,18.8111098 C11.8802783,18.8111098 12.258481,18.9677602 12.5373316,19.2465999 C12.8161823,19.5254395 12.972839,19.9036272 12.972839,20.297966 L12.972839,32.0262877 L24.7036082,32.0262877 C25.2348319,32.0262876 25.7257028,32.3096808 25.9913146,32.7697157 C26.2569264,33.2297506 26.2569264,33.796537 25.9913146,34.2565719 C25.7257028,34.7166069 25.2348319,35 24.7036082,35 L11.4869151,35 C10.6657146,35 10,34.3343118 10,33.5131438 L10,20.297966 C10,19.9036272 10.1566567,19.5254395 10.4355073,19.2465999 C10.714358,18.9677602 11.0925607,18.8111098 11.4869151,18.8111098 L11.4859238,18.8111098 Z M18.8084853,11.4868562 C18.8084853,11.0925174 18.965142,10.7143297 19.2439927,10.4354901 C19.5228434,10.1566504 19.9010461,10 20.2954005,10 L33.5130849,10 C34.3342854,10 35,10.6656882 35,11.4868562 L35,24.7030253 C35,25.5241932 34.3342854,26.1898814 33.5130849,26.1898814 C32.6918843,26.1898814 32.0261697,25.5241932 32.0261697,24.7030253 L32.0261697,12.9737123 L20.2954005,12.9737123 C19.9010461,12.9737124 19.5228434,12.8170619 19.2439927,12.5382223 C18.965142,12.2593826 18.8084853,11.881195 18.8084853,11.4868562 L18.8084853,11.4868562 Z" id="形状"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.8 KiB |
@ -224,7 +224,15 @@ const saveResource = () => {
|
||||
ElMessage.success(t('common.save_success'))
|
||||
let url = window.location.href
|
||||
url = url.replace(/\?opt=create/, `?resourceId=${dvInfo.value.id}`)
|
||||
window.history.replaceState(null, '', url)
|
||||
if (!embeddedStore.baseUrl) {
|
||||
window.history.replaceState(
|
||||
{
|
||||
path: url
|
||||
},
|
||||
'',
|
||||
url
|
||||
)
|
||||
}
|
||||
|
||||
if (appData.value) {
|
||||
initCanvasData(dvInfo.value.id, 'dashboard', () => {
|
||||
|
||||
@ -23,6 +23,21 @@
|
||||
</color-button>
|
||||
</el-space>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="dvInfo.type === 'dashboard'"
|
||||
class="form-item"
|
||||
:class="'form-item-' + themes"
|
||||
label="仪表板字体选择"
|
||||
>
|
||||
<el-select :effect="themes" v-model="canvasStyleData.fontFamily" @change="fontFamilyChange()">
|
||||
<el-option
|
||||
v-for="option in fontFamily"
|
||||
:key="option.value"
|
||||
:label="option.name"
|
||||
:value="option.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="dvInfo.type === 'dashboard'"
|
||||
class="form-item"
|
||||
@ -225,6 +240,7 @@ import {
|
||||
LIGHT_THEME_DASHBOARD_BACKGROUND
|
||||
} from '@/utils/canvasStyle'
|
||||
import {
|
||||
CHART_FONT_FAMILY,
|
||||
DEFAULT_COLOR_CASE_DARK,
|
||||
DEFAULT_COLOR_CASE_LIGHT,
|
||||
DEFAULT_TAB_COLOR_CASE_DARK,
|
||||
@ -245,8 +261,11 @@ import {
|
||||
COMMON_COMPONENT_BACKGROUND_DARK,
|
||||
COMMON_COMPONENT_BACKGROUND_LIGHT
|
||||
} from '@/custom-component/component-list'
|
||||
import { ElFormItem, ElIcon, ElMessage, ElSpace } from 'element-plus-secondary'
|
||||
import { ElFormItem, ElIcon, ElSpace } from 'element-plus-secondary'
|
||||
import Icon from '@/components/icon-custom/src/Icon.vue'
|
||||
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
||||
const appearanceStore = useAppearanceStoreWithOut()
|
||||
|
||||
const snapshotStore = snapshotStoreWithOut()
|
||||
const props = defineProps({
|
||||
themes: {
|
||||
@ -254,6 +273,13 @@ const props = defineProps({
|
||||
default: 'light'
|
||||
}
|
||||
})
|
||||
const fontFamily = CHART_FONT_FAMILY.concat(
|
||||
appearanceStore.fontList.map(ele => ({
|
||||
name: ele.name,
|
||||
value: ele.name
|
||||
}))
|
||||
)
|
||||
|
||||
const toolTip = computed(() => {
|
||||
return props.themes === 'dark' ? 'ndark' : 'dark'
|
||||
})
|
||||
@ -271,6 +297,9 @@ const onRefreshChange = val => {
|
||||
}
|
||||
themeChange()
|
||||
}
|
||||
const fontFamilyChange = () => {
|
||||
appearanceStore.setCurrentFont(canvasStyleData.fontFamily)
|
||||
}
|
||||
|
||||
const themeChange = (modifyName?) => {
|
||||
if (modifyName === 'themeColor') {
|
||||
|
||||
@ -166,7 +166,15 @@ const saveResource = () => {
|
||||
ElMessage.success('保存成功')
|
||||
let url = window.location.href
|
||||
url = url.replace(/\?opt=create/, `?dvId=${dvInfo.value.id}`)
|
||||
window.history.replaceState(null, '', url)
|
||||
if (!embeddedStore.baseUrl) {
|
||||
window.history.replaceState(
|
||||
{
|
||||
path: url
|
||||
},
|
||||
'',
|
||||
url
|
||||
)
|
||||
}
|
||||
if (appData.value) {
|
||||
initCanvasData(dvInfo.value.id, 'dataV', () => {
|
||||
useEmitt().emitter.emit('refresh-dataset-selector')
|
||||
|
||||
@ -196,6 +196,8 @@ const onMouseEnter = () => {
|
||||
const componentBackgroundStyle = computed(() => {
|
||||
if (config.value.commonBackground) {
|
||||
const {
|
||||
backdropFilterEnable,
|
||||
backdropFilter,
|
||||
backgroundColorSelect,
|
||||
backgroundColor,
|
||||
backgroundImageEnable,
|
||||
@ -243,6 +245,9 @@ const componentBackgroundStyle = computed(() => {
|
||||
if (config.value.component !== 'UserView') {
|
||||
style['overflow'] = 'hidden'
|
||||
}
|
||||
if (backdropFilterEnable) {
|
||||
style['backdrop-filter'] = 'blur(' + backdropFilter + 'px)'
|
||||
}
|
||||
return style
|
||||
}
|
||||
return {}
|
||||
|
||||
@ -881,6 +881,8 @@ const padding3D = computed(() => {
|
||||
const componentBackgroundStyle = computed(() => {
|
||||
if (element.value.commonBackground && element.value.component !== 'GroupArea') {
|
||||
const {
|
||||
backdropFilterEnable,
|
||||
backdropFilter,
|
||||
backgroundColorSelect,
|
||||
backgroundColor,
|
||||
backgroundImageEnable,
|
||||
@ -931,6 +933,9 @@ const componentBackgroundStyle = computed(() => {
|
||||
if (element.value.component !== 'UserView') {
|
||||
style['overflow'] = 'hidden'
|
||||
}
|
||||
if (backdropFilterEnable) {
|
||||
style['backdrop-filter'] = 'blur(' + backdropFilter + 'px)'
|
||||
}
|
||||
return style
|
||||
}
|
||||
return {}
|
||||
|
||||
@ -1,6 +1,25 @@
|
||||
<template>
|
||||
<div style="width: 100%" ref="bgForm">
|
||||
<el-form label-position="top" style="width: 100%; margin-bottom: 16px">
|
||||
<el-form-item
|
||||
class="form-item no-margin-bottom"
|
||||
:class="'form-item-' + themes"
|
||||
label="数据大屏字体选择"
|
||||
>
|
||||
<el-select
|
||||
:effect="themes"
|
||||
v-model="canvasStyleData.fontFamily"
|
||||
@change="onFontFamilyChange"
|
||||
>
|
||||
<el-option
|
||||
v-for="option in fontFamily"
|
||||
:key="option.value"
|
||||
:label="option.name"
|
||||
:value="option.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item class="form-item no-margin-bottom" :class="'form-item-' + themes">
|
||||
<el-checkbox
|
||||
size="small"
|
||||
@ -63,11 +82,22 @@ import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { ElFormItem, ElIcon } from 'element-plus-secondary'
|
||||
import Icon from '../icon-custom/src/Icon.vue'
|
||||
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
||||
import { CHART_FONT_FAMILY } from '@/views/chart/components/editor/util/chart'
|
||||
const snapshotStore = snapshotStoreWithOut()
|
||||
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const { canvasStyleData } = storeToRefs(dvMainStore)
|
||||
|
||||
const appearanceStore = useAppearanceStoreWithOut()
|
||||
const fontFamily = CHART_FONT_FAMILY.concat(
|
||||
appearanceStore.fontList.map(ele => ({
|
||||
name: ele.name,
|
||||
value: ele.name
|
||||
}))
|
||||
)
|
||||
const onFontFamilyChange = () => {
|
||||
appearanceStore.setCurrentFont(canvasStyleData.fontFamily)
|
||||
}
|
||||
const onThemeChange = () => {
|
||||
snapshotStore.recordSnapshotCache()
|
||||
}
|
||||
|
||||
@ -324,7 +324,7 @@
|
||||
<el-button
|
||||
class="m-del-icon-btn"
|
||||
text
|
||||
@click="deleteLinkJumpField(index)"
|
||||
@click="deleteLinkJumpFieldById(targetViewInfo.targetId)"
|
||||
>
|
||||
<el-icon size="20px">
|
||||
<Icon name="icon_delete-trash_outlined"
|
||||
@ -442,7 +442,7 @@
|
||||
<el-button
|
||||
class="m-del-icon-btn"
|
||||
text
|
||||
@click="deleteLinkJumpField(index)"
|
||||
@click="deleteLinkJumpFieldById(targetViewInfo.targetId)"
|
||||
>
|
||||
<el-icon size="20px">
|
||||
<Icon name="icon_delete-trash_outlined"
|
||||
@ -601,6 +601,7 @@ import { useAppStoreWithOut } from '@/store/modules/app'
|
||||
import { XpackComponent } from '@/components/plugin'
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
import { useEmbedded } from '@/store/modules/embedded'
|
||||
import { guid } from '@/views/visualized/data/dataset/form/util'
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const { dvInfo, canvasViewInfo, componentData } = storeToRefs(dvMainStore)
|
||||
const linkJumpInfoTree = ref(null)
|
||||
@ -909,14 +910,25 @@ const dvNodeClick = data => {
|
||||
}
|
||||
const addLinkJumpField = (type = 'view') => {
|
||||
state.linkJumpInfo.targetViewInfoList.push({
|
||||
targetId: guid(),
|
||||
targetViewId: '',
|
||||
targetType: type,
|
||||
targetFieldId: ''
|
||||
})
|
||||
}
|
||||
|
||||
const deleteLinkJumpFieldById = index => {
|
||||
state.linkJumpInfo.targetViewInfoList.splice(index, 1)
|
||||
const deleteLinkJumpFieldById = targetId => {
|
||||
if (targetId) {
|
||||
let indexResult
|
||||
state.linkJumpInfo.targetViewInfoList.forEach((item, index) => {
|
||||
if (targetId === item.targetId) {
|
||||
indexResult = index
|
||||
}
|
||||
})
|
||||
if (indexResult !== undefined) {
|
||||
state.linkJumpInfo.targetViewInfoList.splice(indexResult, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const deleteLinkJumpField = index => {
|
||||
|
||||
@ -596,8 +596,14 @@ const jsonArrayCheck = params => {
|
||||
const save = () => {
|
||||
const outerParamsCopy = deepCopy(state.outerParams)
|
||||
let checkErrorNum = 0
|
||||
let checkNullErrorNum = 0
|
||||
let checkMessage = ''
|
||||
const paramNameArray = []
|
||||
outerParamsCopy.outerParamsInfoArray?.forEach(outerParamsInfo => {
|
||||
if (!outerParamsInfo.paramName || paramNameArray.includes(outerParamsInfo.paramName)) {
|
||||
checkNullErrorNum++
|
||||
}
|
||||
paramNameArray.push(outerParamsInfo.paramName)
|
||||
if (outerParamsInfo.defaultValue && !jsonArrayCheck(outerParamsInfo.defaultValue)) {
|
||||
checkErrorNum++
|
||||
checkMessage = checkMessage + `【${outerParamsInfo.paramName}】`
|
||||
@ -636,6 +642,14 @@ const save = () => {
|
||||
})
|
||||
return
|
||||
}
|
||||
if (checkNullErrorNum > 0) {
|
||||
ElMessage({
|
||||
message: `存在未配置的参数名或者参数名称重复!`,
|
||||
type: 'warning',
|
||||
showClose: true
|
||||
})
|
||||
return
|
||||
}
|
||||
updateOuterParamsSet(outerParamsCopy).then(() => {
|
||||
ElMessage({
|
||||
message: t('commons.save_success'),
|
||||
|
||||
@ -53,6 +53,34 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-form-item class="form-item no-margin-bottom" :class="'form-item-' + themes">
|
||||
<el-checkbox
|
||||
size="small"
|
||||
:effect="themes"
|
||||
v-model="state.commonBackground.backdropFilterEnable"
|
||||
@change="onBackgroundChange"
|
||||
>
|
||||
{{ $t('chart.backdrop_blur') }}
|
||||
</el-checkbox>
|
||||
</el-form-item>
|
||||
<div class="indented-container">
|
||||
<div class="indented-item">
|
||||
<el-form-item class="form-item" :class="'form-item-' + themes">
|
||||
<el-input-number
|
||||
style="width: 100%"
|
||||
:effect="themes"
|
||||
controls-position="right"
|
||||
size="middle"
|
||||
:min="0"
|
||||
:max="30"
|
||||
:disabled="!state.commonBackground.backdropFilterEnable"
|
||||
v-model="state.commonBackground.backdropFilter"
|
||||
@change="onBackgroundChange"
|
||||
/>
|
||||
</el-form-item>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-form-item class="form-item no-margin-bottom" :class="'form-item-' + themes">
|
||||
<el-checkbox
|
||||
size="small"
|
||||
|
||||
@ -96,6 +96,7 @@ watch(
|
||||
class="color-picker-style"
|
||||
:triggerWidth="65"
|
||||
is-custom
|
||||
show-alpha
|
||||
:predefine="state.predefineColors"
|
||||
@change="changeStylePre('borderColor')"
|
||||
>
|
||||
@ -135,6 +136,7 @@ watch(
|
||||
class="color-picker-style"
|
||||
:triggerWidth="65"
|
||||
is-custom
|
||||
show-alpha
|
||||
:effect="themes"
|
||||
:predefine="state.predefineColors"
|
||||
@change="changeStylePre('borderColor')"
|
||||
|
||||
@ -57,6 +57,7 @@
|
||||
:prefix-icon="styleColorKey.icon"
|
||||
:triggerWidth="styleColorKey.width"
|
||||
is-custom
|
||||
show-alpha
|
||||
:predefine="state.predefineColors"
|
||||
@change="
|
||||
changeStyle({ key: styleColorKey.value, value: styleForm[styleColorKey.value] })
|
||||
@ -291,6 +292,7 @@ import dvStyleHeadFontColor from '@/assets/svg/dv-style-headFontColor.svg'
|
||||
import dvStyleScrollSpeed from '@/assets/svg/dv-style-scroll-speed.svg'
|
||||
import dvStyleOpacity from '@/assets/svg/dv-style-opacity.svg'
|
||||
import dvStyleTabHead from '@/assets/svg/dv-style-tab-head.svg'
|
||||
import dvStyleBlur from '@/assets/svg/dv-style-blur.svg'
|
||||
import dvStyleFontSize from '@/assets/svg/dv-style-fontSize.svg'
|
||||
import dvStyleLetterSpacing from '@/assets/svg/dv-style-letterSpacing.svg'
|
||||
import dvStyleActiveFont from '@/assets/svg/dv-style-activeFont.svg'
|
||||
@ -371,6 +373,39 @@ const opacitySizeList = [
|
||||
{ name: '0.9', value: 0.9 },
|
||||
{ name: '1', value: 1 }
|
||||
]
|
||||
const backdropBlurList = [
|
||||
{ name: '0', value: 'blur(0px)' },
|
||||
{ name: '1', value: 'blur(1px)' },
|
||||
{ name: '2', value: 'blur(2px)' },
|
||||
{ name: '3', value: 'blur(3px)' },
|
||||
{ name: '4', value: 'blur(4px)' },
|
||||
{ name: '5', value: 'blur(5px)' },
|
||||
{ name: '6', value: 'blur(6px)' },
|
||||
{ name: '7', value: 'blur(7px)' },
|
||||
{ name: '8', value: 'blur(8px)' },
|
||||
{ name: '9', value: 'blur(9px)' },
|
||||
{ name: '10', value: 'blur(10px)' },
|
||||
{ name: '11', value: 'blur(11px)' },
|
||||
{ name: '12', value: 'blur(12px)' },
|
||||
{ name: '13', value: 'blur(13px)' },
|
||||
{ name: '14', value: 'blur(14px)' },
|
||||
{ name: '15', value: 'blur(15px)' },
|
||||
{ name: '16', value: 'blur(16px)' },
|
||||
{ name: '17', value: 'blur(17px)' },
|
||||
{ name: '18', value: 'blur(18px)' },
|
||||
{ name: '19', value: 'blur(19px)' },
|
||||
{ name: '20', value: 'blur(20px)' },
|
||||
{ name: '21', value: 'blur(21px)' },
|
||||
{ name: '22', value: 'blur(22px)' },
|
||||
{ name: '23', value: 'blur(23px)' },
|
||||
{ name: '24', value: 'blur(24px)' },
|
||||
{ name: '25', value: 'blur(25px)' },
|
||||
{ name: '26', value: 'blur(26px)' },
|
||||
{ name: '27', value: 'blur(27px)' },
|
||||
{ name: '28', value: 'blur(28px)' },
|
||||
{ name: '29', value: 'blur(29px)' },
|
||||
{ name: '30', value: 'blur(30px)' }
|
||||
]
|
||||
|
||||
const titleHideList = [
|
||||
{ name: '隐藏', value: true },
|
||||
@ -479,6 +514,13 @@ const styleOptionKeyArray = [
|
||||
customOption: titleHideList,
|
||||
width: '90px',
|
||||
icon: dvStyleTabHead
|
||||
},
|
||||
{
|
||||
value: 'backdropFilter',
|
||||
label: '背景模糊',
|
||||
customOption: backdropBlurList,
|
||||
width: '90px',
|
||||
icon: dvStyleBlur
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
@ -177,12 +177,14 @@ export const MULTI_DIMENSIONAL = {
|
||||
|
||||
export const COMMON_COMPONENT_BACKGROUND_BASE = {
|
||||
backgroundColorSelect: true,
|
||||
backdropFilterEnable: false,
|
||||
backgroundImageEnable: false,
|
||||
backgroundType: 'innerImage',
|
||||
innerImage: 'board/board_1.svg',
|
||||
outerImage: null,
|
||||
innerPadding: 12,
|
||||
borderRadius: 0
|
||||
borderRadius: 0,
|
||||
backdropFilter: 4
|
||||
}
|
||||
|
||||
export const COMMON_COMPONENT_BACKGROUND_LIGHT = {
|
||||
@ -455,7 +457,8 @@ const list = [
|
||||
style: {
|
||||
width: 40,
|
||||
height: 40,
|
||||
color: ''
|
||||
color: '',
|
||||
backdropFilter: 'blur(0px)'
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -474,7 +477,8 @@ const list = [
|
||||
style: {
|
||||
width: 600,
|
||||
height: 300,
|
||||
color: 'rgb(255, 255, 255,1)'
|
||||
color: 'rgb(255, 255, 255,1)',
|
||||
backdropFilter: 'blur(0px)'
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -487,7 +491,8 @@ const list = [
|
||||
width: 200,
|
||||
height: 200,
|
||||
backgroundColor: 'rgba(236,231,231,0.1)',
|
||||
borderActive: true
|
||||
borderActive: true,
|
||||
backdropFilter: 'blur(0px)'
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -502,7 +507,8 @@ const list = [
|
||||
borderWidth: 1,
|
||||
borderStyle: 'solid',
|
||||
borderColor: '#cccccc',
|
||||
backgroundColor: 'rgba(236,231,231,0.1)'
|
||||
backgroundColor: 'rgba(236,231,231,0.1)',
|
||||
backdropFilter: 'blur(0px)'
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -516,7 +522,8 @@ const list = [
|
||||
height: 200,
|
||||
borderWidth: 1,
|
||||
borderColor: '#cccccc',
|
||||
backgroundColor: 'rgba(236,231,231,0.1)'
|
||||
backgroundColor: 'rgba(236,231,231,0.1)',
|
||||
backdropFilter: 'blur(0px)'
|
||||
}
|
||||
},
|
||||
{
|
||||
|
||||
@ -143,7 +143,7 @@ const curFontFamily = () => {
|
||||
value: ele.name
|
||||
}))
|
||||
).forEach(font => {
|
||||
result = result + font.name + '=' + font.name + ';'
|
||||
result = result + font.name + '=' + font.value + ';'
|
||||
})
|
||||
return result
|
||||
}
|
||||
|
||||
@ -197,7 +197,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
value: 'thisMonth'
|
||||
},
|
||||
{
|
||||
label: t('dynamic_month.dynamic_month'),
|
||||
label: t('dynamic_month.last'),
|
||||
value: 'lastMonth'
|
||||
},
|
||||
{
|
||||
|
||||
@ -198,7 +198,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
value: 'thisMonth'
|
||||
},
|
||||
{
|
||||
label: t('dynamic_month.dynamic_month'),
|
||||
label: t('dynamic_month.last'),
|
||||
value: 'lastMonth'
|
||||
},
|
||||
{
|
||||
@ -283,7 +283,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
<div class="setting" v-if="timeRange.intervalType !== 'timeInterval'">
|
||||
<div class="setting-label">{{ t('dynamic_time.relative') }}</div>
|
||||
<div class="setting-value select">
|
||||
<el-select v-model="timeRange.relativeToCurrent">
|
||||
<el-select :teleported="false" v-model="timeRange.relativeToCurrent">
|
||||
<el-option
|
||||
v-for="item in relativeToCurrentList"
|
||||
:key="item.value"
|
||||
@ -296,7 +296,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
<div class="setting" v-if="timeRange.relativeToCurrent === 'custom'">
|
||||
<div class="setting-input">
|
||||
<el-input-number v-model="timeRange.timeNum" :min="0" controls-position="right" />
|
||||
<el-select v-model="timeRange.relativeToCurrentType">
|
||||
<el-select :teleported="false" v-model="timeRange.relativeToCurrentType">
|
||||
<el-option
|
||||
v-for="item in relativeToCurrentTypeList"
|
||||
:key="item.value"
|
||||
@ -304,7 +304,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-select v-model="timeRange.around">
|
||||
<el-select :teleported="false" v-model="timeRange.around">
|
||||
<el-option
|
||||
v-for="item in aroundList"
|
||||
:key="item.value"
|
||||
@ -319,7 +319,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
<div class="setting">
|
||||
<div class="setting-label">{{ t('dynamic_time.relative') }}</div>
|
||||
<div class="setting-value select">
|
||||
<el-select v-model="timeRange.relativeToCurrentRange">
|
||||
<el-select :teleported="false" v-model="timeRange.relativeToCurrentRange">
|
||||
<el-option
|
||||
v-for="item in relativeToCurrentListRange"
|
||||
:key="item.value"
|
||||
@ -342,7 +342,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
:min="0"
|
||||
controls-position="right"
|
||||
/>
|
||||
<el-select v-model="timeRange.relativeToCurrentType">
|
||||
<el-select :teleported="false" v-model="timeRange.relativeToCurrentType">
|
||||
<el-option
|
||||
v-for="item in relativeToCurrentTypeList"
|
||||
:key="item.value"
|
||||
@ -350,7 +350,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-select v-model="timeRange.around">
|
||||
<el-select :teleported="false" v-model="timeRange.around">
|
||||
<el-option
|
||||
v-for="item in aroundList"
|
||||
:key="item.value"
|
||||
@ -372,7 +372,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
step-strictly
|
||||
controls-position="right"
|
||||
/>
|
||||
<el-select v-model="timeRange.relativeToCurrentTypeRange">
|
||||
<el-select :teleported="false" v-model="timeRange.relativeToCurrentTypeRange">
|
||||
<el-option
|
||||
v-for="item in relativeToCurrentTypeList"
|
||||
:key="item.value"
|
||||
@ -380,7 +380,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-select v-model="timeRange.aroundRange">
|
||||
<el-select :teleported="false" v-model="timeRange.aroundRange">
|
||||
<el-option
|
||||
v-for="item in aroundList"
|
||||
:key="item.value"
|
||||
|
||||
@ -1948,7 +1948,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
value: 'thisMonth'
|
||||
},
|
||||
{
|
||||
label: t('dynamic_month.dynamic_month'),
|
||||
label: t('dynamic_month.last'),
|
||||
value: 'lastMonth'
|
||||
},
|
||||
{
|
||||
|
||||
@ -209,7 +209,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
value: 'thisMonth'
|
||||
},
|
||||
{
|
||||
label: t('dynamic_month.dynamic_month'),
|
||||
label: t('dynamic_month.last'),
|
||||
value: 'lastMonth'
|
||||
},
|
||||
{
|
||||
@ -294,7 +294,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
<div class="setting" v-if="timeRange.intervalType !== 'timeInterval'">
|
||||
<div class="setting-label">{{ t('dynamic_time.relative') }}</div>
|
||||
<div class="setting-value select">
|
||||
<el-select v-model="timeRange.relativeToCurrent">
|
||||
<el-select :teleported="false" v-model="timeRange.relativeToCurrent">
|
||||
<el-option
|
||||
v-for="item in relativeToCurrentList"
|
||||
:key="item.value"
|
||||
@ -307,7 +307,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
<div class="setting" v-if="timeRange.relativeToCurrent === 'custom'">
|
||||
<div class="setting-input">
|
||||
<el-input-number v-model="timeRange.timeNum" :min="0" controls-position="right" />
|
||||
<el-select v-model="timeRange.relativeToCurrentType">
|
||||
<el-select :teleported="false" v-model="timeRange.relativeToCurrentType">
|
||||
<el-option
|
||||
v-for="item in relativeToCurrentTypeList"
|
||||
:key="item.value"
|
||||
@ -315,7 +315,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-select v-model="timeRange.around">
|
||||
<el-select :teleported="false" v-model="timeRange.around">
|
||||
<el-option
|
||||
v-for="item in aroundList"
|
||||
:key="item.value"
|
||||
@ -330,7 +330,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
<div class="setting">
|
||||
<div class="setting-label">{{ t('dynamic_time.relative') }}</div>
|
||||
<div class="setting-value select">
|
||||
<el-select v-model="timeRange.relativeToCurrentRange">
|
||||
<el-select :teleported="false" v-model="timeRange.relativeToCurrentRange">
|
||||
<el-option
|
||||
v-for="item in relativeToCurrentListRange"
|
||||
:key="item.value"
|
||||
@ -356,7 +356,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
:min="0"
|
||||
controls-position="right"
|
||||
/>
|
||||
<el-select v-model="timeRange.relativeToCurrentType">
|
||||
<el-select :teleported="false" v-model="timeRange.relativeToCurrentType">
|
||||
<el-option
|
||||
v-for="item in relativeToCurrentTypeList"
|
||||
:key="item.value"
|
||||
@ -364,7 +364,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-select v-model="timeRange.around">
|
||||
<el-select :teleported="false" v-model="timeRange.around">
|
||||
<el-option
|
||||
v-for="item in aroundList"
|
||||
:key="item.value"
|
||||
@ -389,7 +389,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
step-strictly
|
||||
controls-position="right"
|
||||
/>
|
||||
<el-select v-model="timeRange.relativeToCurrentTypeRange">
|
||||
<el-select :teleported="false" v-model="timeRange.relativeToCurrentTypeRange">
|
||||
<el-option
|
||||
v-for="item in relativeToCurrentTypeList"
|
||||
:key="item.value"
|
||||
@ -397,7 +397,7 @@ const relativeToCurrentListRange = computed(() => {
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
<el-select v-model="timeRange.aroundRange">
|
||||
<el-select :teleported="false" v-model="timeRange.aroundRange">
|
||||
<el-option
|
||||
v-for="item in aroundList"
|
||||
:key="item.value"
|
||||
|
||||
@ -8,7 +8,9 @@ export const useMoveLine = (type: Sidebar) => {
|
||||
const width = ref(wsCache.get(type) || 280)
|
||||
|
||||
const getCoordinates = () => {
|
||||
document.querySelector('.sidebar-move-line').className = 'sidebar-move-line dragging'
|
||||
if (document.querySelector('.sidebar-move-line')) {
|
||||
document.querySelector('.sidebar-move-line').className = 'sidebar-move-line dragging'
|
||||
}
|
||||
document.addEventListener('mousemove', setCoordinates)
|
||||
document.addEventListener('mouseup', cancelEvent)
|
||||
document.querySelector('body').style['user-select'] = 'none'
|
||||
@ -26,7 +28,9 @@ export const useMoveLine = (type: Sidebar) => {
|
||||
}
|
||||
|
||||
const cancelEvent = () => {
|
||||
document.querySelector('.sidebar-move-line').className = 'sidebar-move-line'
|
||||
if (document.querySelector('.sidebar-move-line')) {
|
||||
document.querySelector('.sidebar-move-line').className = 'sidebar-move-line'
|
||||
}
|
||||
document.querySelector('body').style['user-select'] = 'auto'
|
||||
wsCache.set(type, width.value)
|
||||
document.removeEventListener('mousemove', setCoordinates)
|
||||
|
||||
@ -11,7 +11,6 @@ import { formatRoute } from '@/router/establish'
|
||||
import HeaderMenuItem from './HeaderMenuItem.vue'
|
||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
import { Icon } from '@/components/icon-custom'
|
||||
import { ElHeader, ElMenu } from 'element-plus-secondary'
|
||||
import SystemCfg from './SystemCfg.vue'
|
||||
import ToolboxCfg from './ToolboxCfg.vue'
|
||||
import { useRouter, useRoute } from 'vue-router'
|
||||
@ -30,6 +29,7 @@ const { push } = useRouter()
|
||||
const route = useRoute()
|
||||
import { useCache } from '@/hooks/web/useCache'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { msgCountApi } from '@/api/msg'
|
||||
const { wsCache } = useCache('localStorage')
|
||||
const aiBaseUrl = ref('https://maxkb.fit2cloud.com/ui/chat/2ddd8b594ce09dbb?mode=embed')
|
||||
const handleIconClick = () => {
|
||||
@ -119,12 +119,17 @@ const copilotConfirm = () => {
|
||||
wsCache.set('DE-COPILOT-TIPS-CHECK', 'CHECKED')
|
||||
showOverlayCopilot.value = false
|
||||
}
|
||||
const badgeCount = ref(0)
|
||||
|
||||
onMounted(() => {
|
||||
initShowSystem()
|
||||
initShowToolbox()
|
||||
initAiBase()
|
||||
initCopilotBase()
|
||||
|
||||
msgCountApi().then(res => {
|
||||
badgeCount.value = res?.data || 0
|
||||
})
|
||||
})
|
||||
</script>
|
||||
|
||||
@ -184,15 +189,17 @@ onMounted(() => {
|
||||
<ToolboxCfg v-if="showToolbox" />
|
||||
<TopDoc v-if="appearanceStore.getShowDoc" />
|
||||
<el-tooltip effect="dark" :content="$t('v_query.msg_center')" placement="bottom">
|
||||
<el-icon
|
||||
class="preview-download_icon"
|
||||
style="margin-right: 10px"
|
||||
:class="navigateBg === 'light' && 'is-light-setting'"
|
||||
>
|
||||
<Icon name="dv-preview-download"
|
||||
><msgNotice @click="msgNoticePush" class="svg-icon"
|
||||
/></Icon>
|
||||
</el-icon>
|
||||
<el-badge :hidden="badgeCount === 0" :value="badgeCount" class="item">
|
||||
<el-icon
|
||||
class="preview-download_icon"
|
||||
style="margin-right: 10px"
|
||||
:class="navigateBg === 'light' && 'is-light-setting'"
|
||||
>
|
||||
<Icon name="dv-preview-download"
|
||||
><msgNotice @click="msgNoticePush" class="svg-icon"
|
||||
/></Icon>
|
||||
</el-icon>
|
||||
</el-badge>
|
||||
</el-tooltip>
|
||||
|
||||
<SystemCfg v-if="showSystem" />
|
||||
|
||||
@ -1231,6 +1231,7 @@ export default {
|
||||
quick_calc: '快速計算',
|
||||
show_name_set: '編輯顯示名稱',
|
||||
show_name: '顯示名稱',
|
||||
backdrop_blur: '背景模糊',
|
||||
color: '顏色',
|
||||
color_case: '配色方案',
|
||||
pls_slc_color_case: '請選擇配色方案',
|
||||
|
||||
@ -1244,6 +1244,7 @@ export default {
|
||||
quick_calc: '快速计算',
|
||||
show_name_set: '编辑显示名称',
|
||||
show_name: '显示名称',
|
||||
backdrop_blur: '背景模糊',
|
||||
color: '颜色',
|
||||
color_case: '配色方案',
|
||||
pls_slc_color_case: '请选择配色方案',
|
||||
|
||||
@ -147,6 +147,10 @@ declare interface ChartThreshold {
|
||||
* 文本卡阈值
|
||||
*/
|
||||
textLabelThreshold: Threshold[]
|
||||
/**
|
||||
* 折线阈值
|
||||
*/
|
||||
lineThreshold: TableThreshold[]
|
||||
}
|
||||
declare interface TableThreshold {
|
||||
/**
|
||||
|
||||
@ -35,7 +35,9 @@ const { inMobile, dvInfo, canvasStyleData, componentData, canvasViewInfo, appDat
|
||||
storeToRefs(dvMainStore)
|
||||
const snapshotStore = snapshotStoreWithOut()
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { useAppearanceStoreWithOut } from '@/store/modules/appearance'
|
||||
const { t } = useI18n()
|
||||
const appearanceStore = useAppearanceStoreWithOut()
|
||||
|
||||
export function chartTransStr2Object(targetIn, copy) {
|
||||
const target = copy === 'Y' ? cloneDeep(targetIn) : targetIn
|
||||
@ -223,6 +225,7 @@ export function historyAdaptor(
|
||||
canvasVersion
|
||||
) {
|
||||
//历史字段适配
|
||||
canvasStyleResult['fontFamily'] = canvasStyleResult['fontFamily'] || 'PingFang'
|
||||
canvasStyleResult.dashboard['showGrid'] = canvasStyleResult.dashboard['showGrid'] || false
|
||||
canvasStyleResult.dashboard['matrixBase'] = canvasStyleResult.dashboard['matrixBase'] || 4
|
||||
canvasStyleResult.component['seniorStyleSetting'] =
|
||||
@ -345,6 +348,7 @@ export function initCanvasDataPrepare(dvId, busiFlag, callBack) {
|
||||
dvInfo.type === 'dashboard' && canvasStyleResult['dashboard'].gap === 'yes'
|
||||
? canvasStyleResult['dashboard'].gapSize
|
||||
: 0
|
||||
appearanceStore.setCurrentFont(canvasStyleData.fontFamily)
|
||||
callBack({ canvasDataResult, canvasStyleResult, dvInfo, canvasViewInfoPreview, curPreviewGap })
|
||||
})
|
||||
}
|
||||
|
||||
@ -200,7 +200,8 @@ export function getCanvasStyle(canvasStyleData, canvasId = 'canvas-main') {
|
||||
backgroundColor,
|
||||
backgroundImageEnable,
|
||||
fontSize,
|
||||
mobileSetting
|
||||
mobileSetting,
|
||||
fontFamily
|
||||
} = canvasStyleData
|
||||
const style = { fontSize: fontSize + 'px', color: canvasStyleData.color }
|
||||
if (isMainCanvas(canvasId)) {
|
||||
@ -225,6 +226,7 @@ export function getCanvasStyle(canvasStyleData, canvasId = 'canvas-main') {
|
||||
style['background'] = `url(${imgUrlTrans(background)}) no-repeat`
|
||||
}
|
||||
}
|
||||
style['font-family'] = fontFamily + '!important'
|
||||
}
|
||||
|
||||
return style
|
||||
|
||||
@ -7,6 +7,7 @@ import { DEFAULT_THRESHOLD } from '@/views/chart/components/editor/util/chart'
|
||||
import TableThresholdEdit from '@/views/chart/components/editor/editor-senior/components/dialog/TableThresholdEdit.vue'
|
||||
import TextLabelThresholdEdit from '@/views/chart/components/editor/editor-senior/components/dialog/TextLabelThresholdEdit.vue'
|
||||
import TextThresholdEdit from '@/views/chart/components/editor/editor-senior/components/dialog/TextThresholdEdit.vue'
|
||||
import LineThresholdEdit from '@/views/chart/components/editor/editor-senior/components/dialog/LineThresholdEdit.vue'
|
||||
import { fieldType } from '@/utils/attr'
|
||||
import { defaultsDeep } from 'lodash-es'
|
||||
import { iconFieldMap } from '@/components/icon-group/field-list'
|
||||
@ -50,7 +51,9 @@ const state = reactive({
|
||||
editLabelThresholdDialog: false,
|
||||
thresholdArr: [],
|
||||
editTableThresholdDialog: false,
|
||||
tableThresholdArr: []
|
||||
tableThresholdArr: [],
|
||||
editLineThresholdDialog: false,
|
||||
lineThresholdArr: []
|
||||
})
|
||||
|
||||
const init = () => {
|
||||
@ -63,6 +66,7 @@ const init = () => {
|
||||
state.textThresholdArr = JSON.parse(JSON.stringify(state.thresholdForm.textLabelThreshold))
|
||||
state.thresholdArr = JSON.parse(JSON.stringify(state.thresholdForm.labelThreshold))
|
||||
state.tableThresholdArr = JSON.parse(JSON.stringify(state.thresholdForm.tableThreshold))
|
||||
state.lineThresholdArr = JSON.parse(JSON.stringify(state.thresholdForm.lineThreshold ?? []))
|
||||
}
|
||||
}
|
||||
const changeThreshold = () => {
|
||||
@ -257,6 +261,77 @@ const changeTableThreshold = () => {
|
||||
changeThreshold()
|
||||
closeTableThreshold()
|
||||
}
|
||||
|
||||
const lineThresholdChange = val => {
|
||||
state.lineThresholdArr = val
|
||||
}
|
||||
const editLineThreshold = () => {
|
||||
state.editLineThresholdDialog = true
|
||||
}
|
||||
const closeLineThreshold = () => {
|
||||
state.editLineThresholdDialog = false
|
||||
}
|
||||
const changeLineThreshold = () => {
|
||||
// check line config
|
||||
for (let i = 0; i < state.lineThresholdArr?.length; i++) {
|
||||
const field = state.lineThresholdArr[i]
|
||||
if (!field.fieldId) {
|
||||
ElMessage.error(t('chart.field_can_not_empty'))
|
||||
return
|
||||
}
|
||||
if (!field.conditions || field.conditions.length === 0) {
|
||||
ElMessage.error(t('chart.conditions_can_not_empty'))
|
||||
return
|
||||
}
|
||||
for (let j = 0; j < field.conditions.length; j++) {
|
||||
const ele = field.conditions[j]
|
||||
if (!ele.term || ele.term === '') {
|
||||
ElMessage.error(t('chart.exp_can_not_empty'))
|
||||
return
|
||||
}
|
||||
if (ele.term === 'between') {
|
||||
if (
|
||||
!ele.term.includes('null') &&
|
||||
!ele.term.includes('empty') &&
|
||||
(ele.min === '' || ele.max === '')
|
||||
) {
|
||||
ElMessage.error(t('chart.value_can_not_empty'))
|
||||
return
|
||||
}
|
||||
if (
|
||||
(field.field.deType === 2 || field.field.deType === 3 || field.field.deType === 4) &&
|
||||
(parseFloat(ele.min).toString() === 'NaN' || parseFloat(ele.max).toString() === 'NaN')
|
||||
) {
|
||||
ElMessage.error(t('chart.value_error'))
|
||||
return
|
||||
}
|
||||
if (
|
||||
(field.field.deType === 2 || field.field.deType === 3 || field.field.deType === 4) &&
|
||||
parseFloat(ele.min) > parseFloat(ele.max)
|
||||
) {
|
||||
ElMessage.error(t('chart.value_min_max_invalid'))
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if (!ele.term.includes('null') && !ele.term.includes('empty') && ele.value === '') {
|
||||
ElMessage.error(t('chart.value_can_not_empty'))
|
||||
return
|
||||
}
|
||||
if (
|
||||
(field.field.deType === 2 || field.field.deType === 3 || field.field.deType === 4) &&
|
||||
parseFloat(ele.value).toString() === 'NaN'
|
||||
) {
|
||||
ElMessage.error(t('chart.value_error'))
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
state.thresholdForm.lineThreshold = JSON.parse(JSON.stringify(state.lineThresholdArr ?? []))
|
||||
changeThreshold()
|
||||
closeLineThreshold()
|
||||
}
|
||||
|
||||
const getFieldName = field => (field.chartShowName ? field.chartShowName : field.name)
|
||||
|
||||
const getDynamicStyleLabel = (item, fieldObj) => {
|
||||
@ -713,6 +788,129 @@ init()
|
||||
</div>
|
||||
</el-col>
|
||||
</el-col>
|
||||
<!--折线-->
|
||||
<el-col v-show="showProperty('lineThreshold')">
|
||||
<el-col>
|
||||
<div class="inner-container">
|
||||
<span class="label" :class="'label-' + props.themes">条件样式设置</span>
|
||||
<span class="right-btns">
|
||||
<span
|
||||
class="set-text-info"
|
||||
:class="{ 'set-text-info-dark': themes === 'dark' }"
|
||||
v-if="state.thresholdForm?.tableThreshold?.length > 0"
|
||||
>
|
||||
已设置
|
||||
</span>
|
||||
<el-button
|
||||
:title="t('chart.edit')"
|
||||
:class="'label-' + props.themes"
|
||||
:style="{ width: '24px', marginLeft: '6px' }"
|
||||
:disabled="!state.thresholdForm.enable"
|
||||
class="circle-button"
|
||||
text
|
||||
size="small"
|
||||
@click="editLineThreshold"
|
||||
>
|
||||
<template #icon>
|
||||
<el-icon size="14px">
|
||||
<Icon name="icon_edit_outlined"><icon_edit_outlined class="svg-icon" /></Icon>
|
||||
</el-icon>
|
||||
</template>
|
||||
</el-button>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="threshold-container"
|
||||
:class="{ 'threshold-container-dark': themes === 'dark' }"
|
||||
v-if="state.thresholdForm.lineThreshold?.length > 0"
|
||||
>
|
||||
<el-row
|
||||
v-for="(fieldItem, fieldIndex) in state.thresholdForm.lineThreshold"
|
||||
:key="fieldIndex"
|
||||
style="flex-direction: column"
|
||||
>
|
||||
<div class="field-style" :class="{ 'field-style-dark': themes === 'dark' }">
|
||||
<el-icon>
|
||||
<Icon :className="`field-icon-${fieldType[fieldItem.field.deType]}`"
|
||||
><component
|
||||
class="svg-icon"
|
||||
:class="`field-icon-${fieldType[fieldItem.field.deType]}`"
|
||||
:is="iconFieldMap[fieldType[fieldItem.field.deType]]"
|
||||
></component
|
||||
></Icon>
|
||||
</el-icon>
|
||||
<span :title="fieldItem.field.name" class="field-text">{{
|
||||
fieldItem.field.name
|
||||
}}</span>
|
||||
</div>
|
||||
<div v-for="(item, index) in fieldItem.conditions" :key="index" class="line-style">
|
||||
<div style="flex: 1">
|
||||
<span v-if="item.term === 'lt'" :title="t('chart.filter_lt')">
|
||||
{{ t('chart.filter_lt') }}
|
||||
</span>
|
||||
<span v-else-if="item.term === 'gt'" :title="t('chart.filter_gt')">
|
||||
{{ t('chart.filter_gt') }}
|
||||
</span>
|
||||
<span v-else-if="item.term === 'le'" :title="t('chart.filter_le')">
|
||||
{{ t('chart.filter_le') }}
|
||||
</span>
|
||||
<span v-else-if="item.term === 'ge'" :title="t('chart.filter_ge')">
|
||||
{{ t('chart.filter_ge') }}
|
||||
</span>
|
||||
<span v-else-if="item.term === 'between'" :title="t('chart.filter_between')">
|
||||
{{ t('chart.filter_between') }}
|
||||
</span>
|
||||
<span v-else-if="item.term === 'default'" title="默认"> 默认 </span>
|
||||
</div>
|
||||
<div v-if="item.type !== 'dynamic'" style="flex: 1; margin: 0 8px">
|
||||
<span style="margin: 0 8px">
|
||||
{{ t('chart.fix') }}
|
||||
</span>
|
||||
</div>
|
||||
<div v-else style="flex: 1; margin: 0 8px">
|
||||
<span style="margin: 0 8px">
|
||||
{{ t('chart.dynamic') }}
|
||||
</span>
|
||||
</div>
|
||||
<div v-if="item.type !== 'dynamic'" style="flex: 1; margin: 0 8px">
|
||||
<span
|
||||
v-if="
|
||||
!item.term.includes('null') &&
|
||||
!item.term.includes('default') &&
|
||||
!item.term.includes('empty') &&
|
||||
item.term !== 'between'
|
||||
"
|
||||
:title="item.value + ''"
|
||||
>{{ item.value }}</span
|
||||
>
|
||||
<span
|
||||
v-else-if="
|
||||
!item.term.includes('null') &&
|
||||
!item.term.includes('empty') &&
|
||||
item.term === 'between'
|
||||
"
|
||||
:title="item.min + ' ≤= ' + t('chart.drag_block_label_value') + ' ≤ ' + item.max"
|
||||
>
|
||||
{{ item.min }} ≤{{ t('chart.drag_block_label_value') }}≤ {{ item.max }}
|
||||
</span>
|
||||
<span v-else> </span>
|
||||
</div>
|
||||
<template v-if="chart.type !== 'picture-group'">
|
||||
<div
|
||||
:title="t('chart.color')"
|
||||
:style="{
|
||||
backgroundColor: item.color
|
||||
}"
|
||||
class="color-div"
|
||||
:class="{ 'color-div-dark': themes === 'dark' }"
|
||||
></div>
|
||||
</template>
|
||||
</div>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-col>
|
||||
|
||||
<!--编辑文本卡阈值-->
|
||||
<el-dialog
|
||||
@ -794,6 +992,30 @@ init()
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
<!--编辑折线阈值-->
|
||||
<el-dialog
|
||||
v-if="state.editLineThresholdDialog"
|
||||
v-model="state.editLineThresholdDialog"
|
||||
:title="t('chart.threshold')"
|
||||
:visible="state.editLineThresholdDialog"
|
||||
width="1050px"
|
||||
class="dialog-css"
|
||||
append-to-body
|
||||
>
|
||||
<line-threshold-edit
|
||||
:threshold="state.thresholdForm.lineThreshold"
|
||||
:chart="chart"
|
||||
@onLineThresholdChange="lineThresholdChange"
|
||||
/>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button @click="closeLineThreshold">{{ t('chart.cancel') }}</el-button>
|
||||
<el-button type="primary" @click="changeLineThreshold">{{
|
||||
t('chart.confirm')
|
||||
}}</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@ -0,0 +1,499 @@
|
||||
<script lang="tsx" setup>
|
||||
import icon_info_filled from '@/assets/svg/icon_info_filled.svg'
|
||||
import icon_deleteTrash_outlined from '@/assets/svg/icon_delete-trash_outlined.svg'
|
||||
import icon_add_outlined from '@/assets/svg/icon_add_outlined.svg'
|
||||
import { PropType, reactive } from 'vue'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { COLOR_PANEL } from '../../../util/chart'
|
||||
import { fieldType } from '@/utils/attr'
|
||||
import { iconFieldMap } from '@/components/icon-group/field-list'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps({
|
||||
chart: {
|
||||
type: Object as PropType<ChartObj>,
|
||||
required: true
|
||||
},
|
||||
threshold: {
|
||||
type: Array,
|
||||
required: true,
|
||||
default: () => []
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['onLineThresholdChange'])
|
||||
|
||||
const thresholdCondition = {
|
||||
term: 'lt',
|
||||
field: '0',
|
||||
value: '0',
|
||||
color: '#ff0000ff',
|
||||
backgroundColor: '#ffffff00',
|
||||
min: '0',
|
||||
max: '1',
|
||||
type: 'fixed'
|
||||
}
|
||||
const valueOptions = [
|
||||
{
|
||||
label: '',
|
||||
options: [
|
||||
{
|
||||
value: 'lt',
|
||||
label: t('chart.filter_lt')
|
||||
},
|
||||
{
|
||||
value: 'gt',
|
||||
label: t('chart.filter_gt')
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
label: '',
|
||||
options: [
|
||||
{
|
||||
value: 'between',
|
||||
label: t('chart.filter_between')
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
const predefineColors = COLOR_PANEL
|
||||
|
||||
const state = reactive({
|
||||
thresholdArr: [] as LineThreshold[],
|
||||
fields: [],
|
||||
thresholdObj: {
|
||||
fieldId: '',
|
||||
field: {},
|
||||
conditions: []
|
||||
} as LineThreshold
|
||||
})
|
||||
|
||||
const init = () => {
|
||||
state.thresholdArr = JSON.parse(JSON.stringify(props.threshold)) as LineThreshold[]
|
||||
initFields()
|
||||
}
|
||||
const initOptions = (item, fieldObj) => {
|
||||
if (fieldObj) {
|
||||
item.options = JSON.parse(JSON.stringify(valueOptions))
|
||||
item.conditions &&
|
||||
item.conditions.forEach(ele => {
|
||||
ele.term = ''
|
||||
})
|
||||
}
|
||||
}
|
||||
const initFields = () => {
|
||||
let fields = []
|
||||
const yAxis = JSON.parse(JSON.stringify(props.chart.yAxis))
|
||||
fields = [...yAxis]
|
||||
state.fields.splice(0, state.fields.length, ...fields)
|
||||
// 字段不存在时
|
||||
let change = false
|
||||
state.thresholdArr.forEach(item => {
|
||||
const fieldItemObj = state.fields.filter(ele => ele.id === item.fieldId)
|
||||
if (fieldItemObj.length === 0) {
|
||||
change = true
|
||||
item.fieldId = null
|
||||
}
|
||||
})
|
||||
if (change) {
|
||||
changeThreshold()
|
||||
}
|
||||
}
|
||||
const addThreshold = () => {
|
||||
state.thresholdArr.push(JSON.parse(JSON.stringify(state.thresholdObj)))
|
||||
changeThreshold()
|
||||
}
|
||||
const removeThreshold = index => {
|
||||
state.thresholdArr.splice(index, 1)
|
||||
changeThreshold()
|
||||
}
|
||||
|
||||
const changeThreshold = () => {
|
||||
emit('onLineThresholdChange', state.thresholdArr)
|
||||
}
|
||||
|
||||
const addConditions = item => {
|
||||
const newCondition = JSON.parse(JSON.stringify(thresholdCondition))
|
||||
item.conditions.push(newCondition)
|
||||
changeThreshold()
|
||||
}
|
||||
const removeCondition = (item, index) => {
|
||||
item.conditions.splice(index, 1)
|
||||
changeThreshold()
|
||||
}
|
||||
|
||||
const addField = item => {
|
||||
// get field
|
||||
if (state.fields && state.fields.length > 0) {
|
||||
state.fields.forEach(ele => {
|
||||
if (item.fieldId === ele.id) {
|
||||
item.field = JSON.parse(JSON.stringify(ele))
|
||||
initOptions(item, item.field)
|
||||
}
|
||||
})
|
||||
}
|
||||
changeThreshold()
|
||||
}
|
||||
|
||||
const fieldOptions = [{ label: t('chart.field_fixed'), value: 'fixed' }]
|
||||
|
||||
const isNotEmptyAndNull = item => {
|
||||
return !item.term.includes('null') && !item.term.includes('empty')
|
||||
}
|
||||
|
||||
const isBetween = item => {
|
||||
return item.term === 'between'
|
||||
}
|
||||
|
||||
const isDynamic = item => {
|
||||
return item.type === 'dynamic'
|
||||
}
|
||||
|
||||
const getFieldOptions = fieldItem => {
|
||||
const deType = state.fields.filter(ele => ele.id === fieldItem.fieldId)?.[0]?.deType
|
||||
if (deType === 1) {
|
||||
return fieldOptions.filter(ele => ele.value === 'fixed')
|
||||
} else {
|
||||
return fieldOptions
|
||||
}
|
||||
}
|
||||
|
||||
init()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-col>
|
||||
<div class="tip">
|
||||
<Icon name="icon_info_filled" class="icon-style"
|
||||
><icon_info_filled class="svg-icon icon-style"
|
||||
/></Icon>
|
||||
<span style="padding-left: 10px">{{ t('chart.table_threshold_tip') }}</span>
|
||||
</div>
|
||||
|
||||
<div @keydown.stop @keyup.stop style="max-height: 50vh; overflow-y: auto">
|
||||
<div
|
||||
v-for="(fieldItem, fieldIndex) in state.thresholdArr"
|
||||
:key="fieldIndex"
|
||||
class="field-item"
|
||||
>
|
||||
<el-row style="margin-top: 6px; align-items: center; justify-content: space-between">
|
||||
<el-form-item class="form-item">
|
||||
<el-select v-model="fieldItem.fieldId" @change="addField(fieldItem)">
|
||||
<el-option
|
||||
class="series-select-option"
|
||||
v-for="fieldOption in state.fields"
|
||||
:key="fieldOption.id"
|
||||
:label="fieldOption.name"
|
||||
:value="fieldOption.id"
|
||||
:disabled="chart.type === 'table-info' && fieldOption.deType === 7"
|
||||
>
|
||||
<el-icon style="margin-right: 8px">
|
||||
<Icon
|
||||
><component
|
||||
:class="`field-icon-${
|
||||
fieldType[[2, 3].includes(fieldOption.deType) ? 2 : 0]
|
||||
}`"
|
||||
class="svg-icon"
|
||||
:is="iconFieldMap[fieldType[fieldOption.deType]]"
|
||||
></component
|
||||
></Icon>
|
||||
</el-icon>
|
||||
{{ fieldOption.name }}
|
||||
</el-option>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-button
|
||||
class="circle-button m-icon-btn"
|
||||
text
|
||||
:style="{ float: 'right' }"
|
||||
@click="removeThreshold(fieldIndex)"
|
||||
>
|
||||
<el-icon size="20px" style="color: #646a73">
|
||||
<Icon name="icon_delete-trash_outlined"
|
||||
><icon_deleteTrash_outlined class="svg-icon"
|
||||
/></Icon>
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</el-row>
|
||||
|
||||
<el-row :style="{ marginTop: '16px', borderTop: '1px solid #d5d6d8' }">
|
||||
<el-row
|
||||
v-for="(item, index) in fieldItem.conditions"
|
||||
:key="index"
|
||||
class="line-item"
|
||||
:gutter="12"
|
||||
>
|
||||
<el-col :span="4">
|
||||
<el-form-item class="form-item">
|
||||
<el-select v-model="item.term" @change="changeThreshold">
|
||||
<el-option-group
|
||||
v-for="(group, idx) in fieldItem.options"
|
||||
:key="idx"
|
||||
:label="group.label"
|
||||
>
|
||||
<el-option
|
||||
v-for="opt in group.options"
|
||||
:key="opt.value"
|
||||
:label="opt.label"
|
||||
:value="opt.value"
|
||||
/>
|
||||
</el-option-group>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4" v-if="isNotEmptyAndNull(item)" style="padding-left: 0 !important">
|
||||
<el-form-item class="form-item">
|
||||
<el-select v-model="item.type" class="select-item" style="width: 100%">
|
||||
<el-option
|
||||
v-for="opt in getFieldOptions(fieldItem)"
|
||||
:key="opt.value"
|
||||
:label="opt.label"
|
||||
:value="opt.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!--不是between 不是动态值-->
|
||||
<el-col
|
||||
v-if="isNotEmptyAndNull(item) && !isBetween(item) && !isDynamic(item)"
|
||||
:span="12"
|
||||
style="text-align: center"
|
||||
>
|
||||
<el-form-item class="form-item">
|
||||
<el-input-number
|
||||
v-model="item.value"
|
||||
v-if="[2, 3].includes(fieldItem.field.deType)"
|
||||
:placeholder="t('chart.drag_block_label_value')"
|
||||
controls-position="right"
|
||||
class="value-item"
|
||||
clearable
|
||||
@change="changeThreshold"
|
||||
/>
|
||||
<el-input
|
||||
v-model="item.value"
|
||||
v-else
|
||||
:placeholder="t('chart.drag_block_label_value')"
|
||||
controls-position="right"
|
||||
clearable
|
||||
@change="changeThreshold"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!--between 开始值-->
|
||||
<el-col
|
||||
v-if="isNotEmptyAndNull(item) && isBetween(item) && !isDynamic(item)"
|
||||
:span="5"
|
||||
style="text-align: center"
|
||||
>
|
||||
<el-form-item class="form-item">
|
||||
<el-input-number
|
||||
v-model="item.min"
|
||||
controls-position="right"
|
||||
class="between-item"
|
||||
:placeholder="t('chart.axis_value_min')"
|
||||
clearable
|
||||
@change="changeThreshold"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col
|
||||
v-if="isBetween(item) && !isDynamic(item)"
|
||||
:span="2"
|
||||
style="margin-top: 4px; text-align: center"
|
||||
>
|
||||
<span style="margin: 0 -5px">
|
||||
≤ {{ t('chart.drag_block_label_value') }} ≤
|
||||
</span>
|
||||
</el-col>
|
||||
<!--between 结束值-->
|
||||
<el-col
|
||||
v-if="isNotEmptyAndNull(item) && isBetween(item) && !isDynamic(item)"
|
||||
:span="5"
|
||||
style="text-align: center"
|
||||
>
|
||||
<el-form-item class="form-item">
|
||||
<el-input-number
|
||||
v-model="item.max"
|
||||
controls-position="right"
|
||||
class="between-item"
|
||||
:placeholder="t('chart.axis_value_max')"
|
||||
clearable
|
||||
@change="changeThreshold"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="3">
|
||||
<el-form-item class="form-item" :label="t('chart.textColor')">
|
||||
<el-color-picker
|
||||
is-custom
|
||||
size="large"
|
||||
v-model="item.color"
|
||||
show-alpha
|
||||
class="color-picker-style"
|
||||
:predefine="predefineColors"
|
||||
@change="changeThreshold"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="1">
|
||||
<div style="display: flex; align-items: center; justify-content: center">
|
||||
<el-button
|
||||
class="circle-button m-icon-btn"
|
||||
text
|
||||
@click="removeCondition(fieldItem, index)"
|
||||
>
|
||||
<el-icon size="20px" style="color: #646a73">
|
||||
<Icon name="icon_delete-trash_outlined"
|
||||
><icon_deleteTrash_outlined class="svg-icon"
|
||||
/></Icon>
|
||||
</el-icon>
|
||||
</el-button>
|
||||
</div>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-row>
|
||||
|
||||
<el-button
|
||||
style="margin-top: 10px"
|
||||
class="circle-button"
|
||||
type="primary"
|
||||
text
|
||||
@click="addConditions(fieldItem)"
|
||||
>
|
||||
<template #icon>
|
||||
<Icon name="icon_add_outlined"><icon_add_outlined class="svg-icon" /></Icon>
|
||||
</template>
|
||||
{{ t('chart.add_style') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<el-button
|
||||
class="circle-button"
|
||||
text
|
||||
type="primary"
|
||||
style="margin-top: 10px"
|
||||
@click="addThreshold"
|
||||
>
|
||||
<template #icon>
|
||||
<Icon name="icon_add_outlined"><icon_add_outlined class="svg-icon" /></Icon>
|
||||
</template>
|
||||
{{ t('chart.add_condition') }}
|
||||
</el-button>
|
||||
</el-col>
|
||||
</template>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.field-item {
|
||||
width: 100%;
|
||||
border-radius: 4px;
|
||||
padding: 10px 16px;
|
||||
margin-top: 10px;
|
||||
background: #f5f6f7;
|
||||
}
|
||||
|
||||
.line-item {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: left;
|
||||
align-items: center;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.form-item {
|
||||
height: 28px !important;
|
||||
:deep(.el-form-item__label) {
|
||||
font-size: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.value-item {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.between-item {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.select-item {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.el-select-dropdown__item {
|
||||
padding: 0 20px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.color-picker-style {
|
||||
cursor: pointer;
|
||||
z-index: 1003;
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.color-picker-style :deep(.el-color-picker__trigger) {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.color-title {
|
||||
color: #646a73;
|
||||
font-size: 14px;
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
line-height: 22px;
|
||||
padding: 0 8px;
|
||||
}
|
||||
|
||||
.tip {
|
||||
font-size: 12px;
|
||||
background: #d6e2ff;
|
||||
border-radius: 4px;
|
||||
padding: 10px 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
:deep(.ed-form-item) {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.icon-style {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
color: var(--ed-color-primary);
|
||||
}
|
||||
|
||||
.m-icon-btn {
|
||||
&:hover {
|
||||
background: rgba(31, 35, 41, 0.1) !important;
|
||||
}
|
||||
&:focus {
|
||||
background: rgba(31, 35, 41, 0.1) !important;
|
||||
}
|
||||
&:active {
|
||||
background: rgba(31, 35, 41, 0.2) !important;
|
||||
}
|
||||
}
|
||||
|
||||
.series-select-option {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
padding: 0 11px;
|
||||
}
|
||||
</style>
|
||||
@ -297,6 +297,33 @@ initParams()
|
||||
:predefine="COLOR_PANEL"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item class="form-item margin-bottom-8" :class="'form-item-' + themes">
|
||||
<el-checkbox
|
||||
size="small"
|
||||
:effect="themes"
|
||||
v-model="commonBackgroundPop.backdropFilterEnable"
|
||||
>
|
||||
{{ $t('chart.backdrop_blur') }}
|
||||
</el-checkbox>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
style="padding-left: 20px"
|
||||
class="form-item margin-bottom-8"
|
||||
:class="'form-item-' + themes"
|
||||
>
|
||||
<el-input-number
|
||||
style="width: 100%"
|
||||
:effect="themes"
|
||||
controls-position="right"
|
||||
size="middle"
|
||||
:min="0"
|
||||
:max="30"
|
||||
:disabled="!commonBackgroundPop.backdropFilterEnable"
|
||||
v-model="commonBackgroundPop.backdropFilter"
|
||||
/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item class="form-item margin-bottom-8" :class="'form-item-' + themes">
|
||||
<el-checkbox
|
||||
:effect="themes"
|
||||
|
||||
@ -706,6 +706,7 @@ onMounted(() => {
|
||||
v-model="state.basicStyleForm.areaBorderColor"
|
||||
:effect="themes"
|
||||
is-custom
|
||||
show-alpha
|
||||
:trigger-width="108"
|
||||
class="color-picker-style"
|
||||
:predefine="predefineColors"
|
||||
@ -725,6 +726,7 @@ onMounted(() => {
|
||||
:persistent="false"
|
||||
v-model="state.basicStyleForm.areaBaseColor"
|
||||
is-custom
|
||||
show-alpha
|
||||
:effect="themes"
|
||||
:trigger-width="108"
|
||||
class="color-picker-style"
|
||||
|
||||
@ -761,7 +761,8 @@ export const DEFAULT_THRESHOLD: ChartThreshold = {
|
||||
liquidThreshold: '',
|
||||
labelThreshold: [],
|
||||
tableThreshold: [],
|
||||
textLabelThreshold: []
|
||||
textLabelThreshold: [],
|
||||
lineLabelThreshold: []
|
||||
}
|
||||
export const DEFAULT_SCROLL: ScrollCfg = {
|
||||
open: false,
|
||||
|
||||
@ -102,7 +102,8 @@ export const DEFAULT_CANVAS_STYLE_DATA_BASE = {
|
||||
background: '',
|
||||
openCommonStyle: true,
|
||||
opacity: 1, // 废弃
|
||||
fontSize: 14
|
||||
fontSize: 14,
|
||||
fontFamily: 'PingFang' //字体设置 默认PingFang
|
||||
}
|
||||
|
||||
// 基础亮色主题
|
||||
|
||||
@ -13,6 +13,8 @@ import {
|
||||
import { cloneDeep } from 'lodash-es'
|
||||
import {
|
||||
flow,
|
||||
getLineConditions,
|
||||
getLineLabelColorByCondition,
|
||||
hexColorToRGBA,
|
||||
parseJson,
|
||||
setUpStackSeriesColor
|
||||
@ -135,6 +137,7 @@ export class Area extends G2PlotChartView<AreaOptions, G2Area> {
|
||||
}
|
||||
}
|
||||
const { label: labelAttr, basicStyle } = parseJson(chart.customAttr)
|
||||
const conditions = getLineConditions(chart)
|
||||
const formatterMap = labelAttr.seriesLabelFormatter?.reduce((pre, next) => {
|
||||
pre[next.id] = next
|
||||
return pre
|
||||
@ -163,6 +166,9 @@ export class Area extends G2PlotChartView<AreaOptions, G2Area> {
|
||||
? -2 - basicStyle.lineSymbolSize
|
||||
: 10 + basicStyle.lineSymbolSize
|
||||
const value = valueFormatter(data.value, labelCfg.formatterCfg)
|
||||
const color =
|
||||
getLineLabelColorByCondition(conditions, data.value, data.quotaList[0].id) ||
|
||||
labelCfg.color
|
||||
const group = new Group({})
|
||||
group.addShape({
|
||||
type: 'text',
|
||||
@ -173,7 +179,7 @@ export class Area extends G2PlotChartView<AreaOptions, G2Area> {
|
||||
textAlign: 'start',
|
||||
textBaseline: 'top',
|
||||
fontSize: labelCfg.fontSize,
|
||||
fill: labelCfg.color
|
||||
fill: color
|
||||
}
|
||||
})
|
||||
return group
|
||||
@ -281,7 +287,8 @@ export class Area extends G2PlotChartView<AreaOptions, G2Area> {
|
||||
this.configXAxis,
|
||||
this.configYAxis,
|
||||
this.configSlider,
|
||||
this.configAnalyse
|
||||
this.configAnalyse,
|
||||
this.configConditions
|
||||
)(chart, options, {}, this)
|
||||
}
|
||||
|
||||
@ -310,6 +317,7 @@ export class StackArea extends Area {
|
||||
}
|
||||
protected configLabel(chart: Chart, options: AreaOptions): AreaOptions {
|
||||
const { label: labelAttr, basicStyle } = parseJson(chart.customAttr)
|
||||
const conditions = getLineConditions(chart)
|
||||
if (!labelAttr?.show) {
|
||||
return {
|
||||
...options,
|
||||
@ -333,7 +341,10 @@ export class StackArea extends Area {
|
||||
fill: labelAttr.color,
|
||||
fontSize: labelAttr.fontSize
|
||||
},
|
||||
formatter: function (param: Datum) {
|
||||
formatter: function (param: Datum, point) {
|
||||
point.color =
|
||||
getLineLabelColorByCondition(conditions, param.value, point._origin.quotaList[0]) ||
|
||||
labelAttr.color
|
||||
return valueFormatter(param.value, labelAttr.labelFormatter)
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,7 +11,8 @@ export const LINE_EDITOR_PROPERTY: EditorProperty[] = [
|
||||
'assist-line',
|
||||
'function-cfg',
|
||||
'jump-set',
|
||||
'linkage'
|
||||
'linkage',
|
||||
'threshold'
|
||||
]
|
||||
export const LINE_EDITOR_PROPERTY_INNER: EditorPropertyInner = {
|
||||
'background-overall-component': ['all'],
|
||||
@ -59,7 +60,8 @@ export const LINE_EDITOR_PROPERTY_INNER: EditorPropertyInner = {
|
||||
'fontShadow'
|
||||
],
|
||||
'legend-selector': ['icon', 'orient', 'fontSize', 'color', 'hPosition', 'vPosition'],
|
||||
'function-cfg': ['slider', 'emptyDataStrategy']
|
||||
'function-cfg': ['slider', 'emptyDataStrategy'],
|
||||
threshold: ['lineThreshold']
|
||||
}
|
||||
|
||||
export const LINE_AXIS_TYPE: AxisType[] = [
|
||||
|
||||
@ -11,6 +11,8 @@ import {
|
||||
} from '../../common/common_antv'
|
||||
import {
|
||||
flow,
|
||||
getLineConditions,
|
||||
getLineLabelColorByCondition,
|
||||
hexColorToRGBA,
|
||||
parseJson,
|
||||
setUpGroupSeriesColor
|
||||
@ -134,6 +136,7 @@ export class Line extends G2PlotChartView<LineOptions, G2Line> {
|
||||
}
|
||||
}
|
||||
const { label: labelAttr, basicStyle } = parseJson(chart.customAttr)
|
||||
const conditions = getLineConditions(chart)
|
||||
const formatterMap = labelAttr.seriesLabelFormatter?.reduce((pre, next) => {
|
||||
pre[next.id] = next
|
||||
return pre
|
||||
@ -162,6 +165,9 @@ export class Line extends G2PlotChartView<LineOptions, G2Line> {
|
||||
? -2 - basicStyle.lineSymbolSize
|
||||
: 10 + basicStyle.lineSymbolSize
|
||||
const value = valueFormatter(data.value, labelCfg.formatterCfg)
|
||||
const color =
|
||||
getLineLabelColorByCondition(conditions, data.value, data.quotaList[0].id) ||
|
||||
labelCfg.color
|
||||
const group = new Group({})
|
||||
group.addShape({
|
||||
type: 'text',
|
||||
@ -172,7 +178,7 @@ export class Line extends G2PlotChartView<LineOptions, G2Line> {
|
||||
textAlign: 'start',
|
||||
textBaseline: 'top',
|
||||
fontSize: labelCfg.fontSize,
|
||||
fill: labelCfg.color
|
||||
fill: color
|
||||
}
|
||||
})
|
||||
return group
|
||||
@ -358,7 +364,8 @@ export class Line extends G2PlotChartView<LineOptions, G2Line> {
|
||||
this.configXAxis,
|
||||
this.configYAxis,
|
||||
this.configSlider,
|
||||
this.configAnalyse
|
||||
this.configAnalyse,
|
||||
this.configConditions
|
||||
)(chart, options)
|
||||
}
|
||||
|
||||
|
||||
@ -220,7 +220,7 @@ export class BubbleMap extends L7PlotChartView<ChoroplethOptions, Choropleth> {
|
||||
const senior = parseJson(chart.senior)
|
||||
const curAreaNameMapping = senior.areaMapping?.[areaId]
|
||||
handleGeoJson(geoJson, curAreaNameMapping)
|
||||
options.color = hexColorToRGBA(basicStyle.areaBaseColor, basicStyle.alpha)
|
||||
options.color = basicStyle.areaBaseColor
|
||||
if (!chart.data?.data?.length || !geoJson?.features?.length) {
|
||||
options.label && (options.label.field = 'name')
|
||||
return options
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { hexColorToRGBA, parseJson } from '../../util'
|
||||
import { hexColorToRGBA, isAlphaColor, isTransparent, parseJson } from '../../util'
|
||||
import {
|
||||
DEFAULT_BASIC_STYLE,
|
||||
DEFAULT_XAXIS_STYLE,
|
||||
@ -1328,3 +1328,56 @@ export const TOOLTIP_TPL =
|
||||
'<span class="g2-tooltip-name">{name}</span>:' +
|
||||
'<span class="g2-tooltip-value">{value}</span>' +
|
||||
'</li>'
|
||||
|
||||
export function getConditions(chart: Chart) {
|
||||
const { threshold } = parseJson(chart.senior)
|
||||
const annotations = []
|
||||
if (!threshold.enable) return annotations
|
||||
const conditions = threshold.lineThreshold ?? []
|
||||
const yAxisIds = chart.yAxis.map(i => i.id)
|
||||
for (const field of conditions) {
|
||||
if (!yAxisIds.includes(field.fieldId)) {
|
||||
continue
|
||||
}
|
||||
for (const t of field.conditions) {
|
||||
if ([2, 3, 4].includes(field.field.deType)) {
|
||||
const annotation = {
|
||||
type: 'regionFilter',
|
||||
start: ['start', 'median'],
|
||||
end: ['end', 'min'],
|
||||
color: t.color
|
||||
}
|
||||
// 加中线
|
||||
const annotationLine = {
|
||||
type: 'line',
|
||||
start: ['start', t.value],
|
||||
end: ['end', t.value],
|
||||
style: {
|
||||
stroke: t.color,
|
||||
lineDash: [2, 2]
|
||||
}
|
||||
}
|
||||
if (t.term === 'between') {
|
||||
annotation.start = ['start', parseFloat(t.min)]
|
||||
annotation.end = ['end', parseFloat(t.max)]
|
||||
annotationLine.start = ['start', parseFloat(t.min)]
|
||||
annotationLine.end = ['end', parseFloat(t.min)]
|
||||
annotations.push(JSON.parse(JSON.stringify(annotationLine)))
|
||||
annotationLine.start = ['start', parseFloat(t.max)]
|
||||
annotationLine.end = ['end', parseFloat(t.max)]
|
||||
annotations.push(annotationLine)
|
||||
} else if (['lt', 'le'].includes(t.term)) {
|
||||
annotation.start = ['start', t.value]
|
||||
annotation.end = ['end', 'min']
|
||||
annotations.push(annotationLine)
|
||||
} else if (['gt', 'ge'].includes(t.term)) {
|
||||
annotation.start = ['start', t.value]
|
||||
annotation.end = ['end', 'max']
|
||||
annotations.push(annotationLine)
|
||||
}
|
||||
annotations.push(annotation)
|
||||
}
|
||||
}
|
||||
}
|
||||
return annotations
|
||||
}
|
||||
|
||||
@ -10,7 +10,8 @@ import {
|
||||
getTheme,
|
||||
getTooltip,
|
||||
getXAxis,
|
||||
getYAxis
|
||||
getYAxis,
|
||||
getConditions
|
||||
} from '@/views/chart/components/js/panel/common/common_antv'
|
||||
import {
|
||||
AntVAbstractChartView,
|
||||
@ -171,6 +172,14 @@ export abstract class G2PlotChartView<
|
||||
return undefined
|
||||
}
|
||||
|
||||
protected configConditions(chart: Chart, options: O) {
|
||||
const annotations = getConditions(chart)
|
||||
return {
|
||||
...options,
|
||||
annotations: [...annotations, ...((options as unknown as Options).annotations || [])]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 流式配置公共参数,处理常用的配置,后续如果有其他通用配置也可以放进来,需要单独配置的属性在各个图表自行实现。
|
||||
* @param chart 数据库图表对象。
|
||||
|
||||
@ -1071,3 +1071,51 @@ export function filterEmptyMinValue(sourceData, field) {
|
||||
)
|
||||
return notEmptyMinValue
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取折线条件样式
|
||||
* @param chart
|
||||
*/
|
||||
export function getLineConditions(chart) {
|
||||
const { threshold } = parseJson(chart.senior)
|
||||
const conditions = []
|
||||
if (threshold.enable) {
|
||||
threshold.lineThreshold?.forEach(item =>
|
||||
item.conditions?.forEach(c =>
|
||||
conditions.push({
|
||||
fieldId: item.fieldId,
|
||||
term: c.term,
|
||||
value: c.value,
|
||||
color: c.color,
|
||||
min: c.min,
|
||||
max: c.max
|
||||
})
|
||||
)
|
||||
)
|
||||
}
|
||||
return conditions
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据折线阈值条件获取新的标签颜色
|
||||
* @param conditions
|
||||
* @param value
|
||||
* @param fieldId
|
||||
*/
|
||||
export function getLineLabelColorByCondition(conditions, value, fieldId) {
|
||||
const fieldConditions = conditions.filter(item => item.fieldId === fieldId)
|
||||
let color = undefined
|
||||
if (fieldConditions.length) {
|
||||
fieldConditions.some(item => {
|
||||
if (
|
||||
(item.term === 'lt' && value <= item.value) ||
|
||||
(item.term === 'gt' && value >= item.value) ||
|
||||
(item.term === 'between' && value >= item.min && value <= item.max)
|
||||
) {
|
||||
color = item.color
|
||||
return true
|
||||
}
|
||||
})
|
||||
}
|
||||
return color
|
||||
}
|
||||
|
||||
@ -252,7 +252,7 @@ defineExpose({
|
||||
<el-container
|
||||
class="preview-area"
|
||||
:class="{ 'no-data': !hasTreeData }"
|
||||
v-loading="requestStore.loadingMap[permissionStore.currentPath]"
|
||||
v-loading="requestStore.loadingMap && requestStore.loadingMap[permissionStore.currentPath]"
|
||||
>
|
||||
<div
|
||||
@click="slideOpenChange"
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import { nextTick, onMounted, reactive, ref } from 'vue'
|
||||
import { nextTick, onMounted, reactive, ref, watch } from 'vue'
|
||||
import DePreview from '@/components/data-visualization/canvas/DePreview.vue'
|
||||
import router from '@/router'
|
||||
import { useEmitt } from '@/hooks/web/useEmitt'
|
||||
@ -16,6 +16,8 @@ import { propTypes } from '@/utils/propTypes'
|
||||
import { downloadCanvas2 } from '@/utils/imgUtils'
|
||||
import { setTitle } from '@/utils/utils'
|
||||
import EmptyBackground from '../../components/empty-background/src/EmptyBackground.vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
const routeWatch = useRoute()
|
||||
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const { t } = useI18n()
|
||||
@ -151,6 +153,15 @@ const downloadH2 = type => {
|
||||
})
|
||||
})
|
||||
}
|
||||
// 监听路由变化
|
||||
// 监听路由变化
|
||||
watch(
|
||||
() => ({ path: routeWatch.path, params: routeWatch.params }),
|
||||
() => {
|
||||
location.reload() // 重新加载浏览器页面
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
let p = null
|
||||
const XpackLoaded = () => p(true)
|
||||
|
||||
@ -216,6 +216,9 @@ const handleDragOver = e => {
|
||||
|
||||
const handleMouseDown = e => {
|
||||
// e.stopPropagation()
|
||||
if (isSpaceDown.value) {
|
||||
return
|
||||
}
|
||||
dvMainStore.setClickComponentStatus(false)
|
||||
// 点击画布的空区域 提前清空curComponent 防止右击菜单内容抖动
|
||||
dvMainStore.setCurComponent({ component: null, index: null })
|
||||
@ -224,6 +227,9 @@ const handleMouseDown = e => {
|
||||
}
|
||||
|
||||
const deselectCurComponent = e => {
|
||||
if (isSpaceDown.value) {
|
||||
return
|
||||
}
|
||||
if (!isClickComponent.value) {
|
||||
curComponent.value && dvMainStore.setCurComponent({ component: null, index: null })
|
||||
}
|
||||
@ -245,13 +251,15 @@ listenGlobalKeyDown()
|
||||
|
||||
const initScroll = () => {
|
||||
nextTick(() => {
|
||||
const { width, height } = canvasStyleData.value
|
||||
const mainWidth = canvasCenterRef.value.clientWidth
|
||||
mainHeight.value = canvasCenterRef.value.clientHeight
|
||||
const scrollX = (1.5 * width - mainWidth) / 2
|
||||
const scrollY = (1.5 * height - mainHeight.value) / 2 + 20
|
||||
// 设置画布初始滚动条位置
|
||||
canvasOut.value.scrollTo(scrollX, scrollY)
|
||||
if (canvasCenterRef.value) {
|
||||
const { width, height } = canvasStyleData.value
|
||||
const mainWidth = canvasCenterRef.value.clientWidth
|
||||
mainHeight.value = canvasCenterRef.value.clientHeight
|
||||
const scrollX = (1.5 * width - mainWidth) / 2
|
||||
const scrollY = (1.5 * height - mainHeight.value) / 2 + 20
|
||||
// 设置画布初始滚动条位置
|
||||
canvasOut.value.scrollTo(scrollX, scrollY)
|
||||
}
|
||||
})
|
||||
}
|
||||
const doUseCache = flag => {
|
||||
@ -471,7 +479,7 @@ eventBus.on('tabSort', tabSort)
|
||||
<div class="custom-dv-divider" />
|
||||
<el-container
|
||||
v-if="loadFinish"
|
||||
v-loading="requestStore.loadingMap[permissionStore.currentPath]"
|
||||
v-loading="requestStore.loadingMap && requestStore.loadingMap[permissionStore.currentPath]"
|
||||
element-loading-background="rgba(0, 0, 0, 0)"
|
||||
class="dv-layout-container"
|
||||
:class="{ 'preview-layout-container': previewStatus }"
|
||||
@ -513,7 +521,6 @@ eventBus.on('tabSort', tabSort)
|
||||
@mousemove="onMouseMove"
|
||||
@mouseleave="disableDragging"
|
||||
>
|
||||
<div v-if="isSpaceDown" class="canvas-drag" :style="contentStyle"></div>
|
||||
<div
|
||||
id="canvas-dv-outer"
|
||||
ref="canvasInner"
|
||||
@ -523,6 +530,7 @@ eventBus.on('tabSort', tabSort)
|
||||
@mousedown="handleMouseDown"
|
||||
@mouseup="deselectCurComponent"
|
||||
>
|
||||
<div v-if="isSpaceDown" class="canvas-drag"></div>
|
||||
<div class="canvas-dv-inner">
|
||||
<canvas-core
|
||||
class="canvas-area-shadow editor-main"
|
||||
@ -715,6 +723,8 @@ eventBus.on('tabSort', tabSort)
|
||||
z-index: 1;
|
||||
opacity: 0.3;
|
||||
cursor: pointer;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.canvas-drag-tip {
|
||||
|
||||
@ -0,0 +1,12 @@
|
||||
package io.dataease.api.msgCenter;
|
||||
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
|
||||
@Tag(name = "消息中心")
|
||||
public interface MsgCenterApi {
|
||||
|
||||
@PostMapping("/count")
|
||||
long count();
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user