Merge pull request #9582 from dataease/dev-v2

merge v2.6.1
This commit is contained in:
fit2cloudrd 2024-05-10 11:38:48 +08:00 committed by GitHub
commit 8fb2ea224e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
27 changed files with 205 additions and 70 deletions

View File

@ -673,7 +673,7 @@ public class ChartDataManage {
item[dataIndex] = null; item[dataIndex] = null;
} else { } else {
item[dataIndex] = new BigDecimal(cValue) item[dataIndex] = new BigDecimal(cValue)
.divide(new BigDecimal(lastValue), 8, RoundingMode.HALF_UP) .divide(new BigDecimal(lastValue).abs(), 8, RoundingMode.HALF_UP)
.subtract(new BigDecimal(1)) .subtract(new BigDecimal(1))
.setScale(8, RoundingMode.HALF_UP) .setScale(8, RoundingMode.HALF_UP)
.toString(); .toString();

View File

@ -3,6 +3,7 @@ package io.dataease.datasource.manage;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import io.dataease.datasource.dao.auto.entity.CoreDatasource; import io.dataease.datasource.dao.auto.entity.CoreDatasource;
import io.dataease.datasource.dao.auto.entity.CoreDeEngine; import io.dataease.datasource.dao.auto.entity.CoreDeEngine;
import io.dataease.datasource.dao.auto.mapper.CoreDatasourceMapper;
import io.dataease.datasource.dao.auto.mapper.CoreDeEngineMapper; import io.dataease.datasource.dao.auto.mapper.CoreDeEngineMapper;
import io.dataease.datasource.provider.EngineProvider; import io.dataease.datasource.provider.EngineProvider;
import io.dataease.datasource.provider.ProviderUtil; import io.dataease.datasource.provider.ProviderUtil;
@ -21,7 +22,9 @@ import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@ -33,6 +36,9 @@ public class EngineManage {
@Resource @Resource
private CoreDeEngineMapper deEngineMapper; private CoreDeEngineMapper deEngineMapper;
@Resource
private CoreDatasourceMapper datasourceMapper;
public CoreDeEngine info() throws DEException { public CoreDeEngine info() throws DEException {
List<CoreDeEngine> deEngines = deEngineMapper.selectList(null); List<CoreDeEngine> deEngines = deEngineMapper.selectList(null);
@ -89,6 +95,7 @@ public class EngineManage {
} }
public void initSimpleEngine() throws Exception { public void initSimpleEngine() throws Exception {
initLocalDataSource();
QueryWrapper<CoreDeEngine> queryWrapper = new QueryWrapper<>(); QueryWrapper<CoreDeEngine> queryWrapper = new QueryWrapper<>();
if (ModelUtils.isDesktop()) { if (ModelUtils.isDesktop()) {
queryWrapper.eq("type", engineType.h2.name()); queryWrapper.eq("type", engineType.h2.name());
@ -147,4 +154,40 @@ public class EngineManage {
return alias; return alias;
} }
} }
public void initLocalDataSource(){
QueryWrapper<CoreDatasource> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("id",985188400292302848L);
queryWrapper.ne("create_time",1715053684176L);
if(!datasourceMapper.exists(queryWrapper) && !ModelUtils.isDesktop()){
Pattern WITH_SQL_FRAGMENT = Pattern.compile("jdbc:mysql://(.*):(\\d+)/(.*)\\?(.*)");
Matcher matcher = WITH_SQL_FRAGMENT.matcher(env.getProperty("spring.datasource.url"));
if (!matcher.find()) {
return;
}
Map configuration = new HashMap<>();
configuration.put("dataBase",matcher.group(3));
configuration.put("username",env.getProperty("spring.datasource.username"));
configuration.put("password",env.getProperty("spring.datasource.password"));
configuration.put("host",matcher.group(1));
configuration.put("port",Integer.valueOf(matcher.group(2)));
configuration.put("extraParams","");
CoreDatasource initDatasource = new CoreDatasource();
initDatasource.setId(985188400292302848L);
initDatasource.setName("Demo");
initDatasource.setType("mysql");
initDatasource.setPid(0L);
initDatasource.setConfiguration(JsonUtil.toJSONString(configuration).toString());
initDatasource.setCreateTime(System.currentTimeMillis());
initDatasource.setUpdateTime(System.currentTimeMillis());
initDatasource.setCreateBy("1");
initDatasource.setUpdateBy(1L);
initDatasource.setStatus("success");
initDatasource.setTaskStatus("WaitingForExecution");
datasourceMapper.deleteById(985188400292302848L);
datasourceMapper.insert(initDatasource);
}
}
} }

View File

@ -404,6 +404,9 @@ public class CalciteProvider {
" database = '%s' \n" + " database = '%s' \n" +
" AND table = '%s' ", configuration.getDataBase(), datasourceRequest.getTable()); " AND table = '%s' ", configuration.getDataBase(), datasourceRequest.getTable());
break; break;
case impala:
sql = String.format("DESCRIBE `%s`", datasourceRequest.getTable());
break;
default: default:
break; break;
} }

View File

@ -13,18 +13,20 @@ import io.dataease.utils.IDUtils;
import io.dataease.utils.SystemSettingUtils; import io.dataease.utils.SystemSettingUtils;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import java.util.Comparator; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@Component @Component
public class SysParameterManage { public class SysParameterManage {
@Value("${dataease.show-demo-tips:false}")
private boolean showDemoTips;
private static final String mapKey = "map.key"; private static final String mapKey = "map.key";
@Resource @Resource
@ -93,7 +95,13 @@ public class SysParameterManage {
@XpackInteract(value = "perSetting", replace = true) @XpackInteract(value = "perSetting", replace = true)
public List<Object> getUiList() { public List<Object> getUiList() {
return null; Map<String, Object> loginTipsItem = new HashMap<>();
loginTipsItem.put("pkey", "showDemoTips");
loginTipsItem.put("pval", showDemoTips);
loginTipsItem.put("sort", 1);
List<Object> result = new ArrayList<>();
result.add(loginTipsItem);
return result;
} }

View File

@ -29,7 +29,6 @@ set
where a.id = b.id and a.type = 'table-pivot'; where a.id = b.id and a.type = 'table-pivot';
INSERT INTO `core_datasource` (`id`, `name`, `description`, `type`, `pid`, `edit_type`, `configuration`, `create_time`, `update_time`, `update_by`, `create_by`, `status`, `qrtz_instance`, `task_status`) VALUES (985188400292302848, 'Demo', '', 'mysql', 0, NULL, '{\"dataBase\":\"dataease\",\"extraParams\":\"\",\"username\":\"root\",\"password\":\"Password123@mysql\",\"host\":\"mysql-de\",\"authMethod\":\"\",\"port\":3306,\"initialPoolSize\":5,\"minPoolSize\":5,\"maxPoolSize\":5,\"queryTimeout\":30}', 1715053684176, 1715100309074, 1, '1', 'Success', NULL, 'WaitingForExecution');
INSERT INTO `core_dataset_table` (`id`, `name`, `table_name`, `datasource_id`, `dataset_group_id`, `type`, `info`, `sql_variable_details`) VALUES (7193457660727922688, NULL, 'demo_tea_material', 985188400292302848, 985189703189925888, 'db', '{\"table\":\"demo_tea_material\",\"sql\":\"\"}', NULL); INSERT INTO `core_dataset_table` (`id`, `name`, `table_name`, `datasource_id`, `dataset_group_id`, `type`, `info`, `sql_variable_details`) VALUES (7193457660727922688, NULL, 'demo_tea_material', 985188400292302848, 985189703189925888, 'db', '{\"table\":\"demo_tea_material\",\"sql\":\"\"}', NULL);
INSERT INTO `core_dataset_table` (`id`, `name`, `table_name`, `datasource_id`, `dataset_group_id`, `type`, `info`, `sql_variable_details`) VALUES (7193537020143079424, NULL, 'demo_tea_order', 985188400292302848, 985189053949415424, 'db', '{\"table\":\"demo_tea_order\",\"sql\":\"\"}', NULL); INSERT INTO `core_dataset_table` (`id`, `name`, `table_name`, `datasource_id`, `dataset_group_id`, `type`, `info`, `sql_variable_details`) VALUES (7193537020143079424, NULL, 'demo_tea_order', 985188400292302848, 985189053949415424, 'db', '{\"table\":\"demo_tea_order\",\"sql\":\"\"}', NULL);

View File

@ -54,7 +54,9 @@ watch(
</el-icon> </el-icon>
<div class="filter-texts-container" ref="container"> <div class="filter-texts-container" ref="container">
<p v-for="(ele, index) in filterTexts" :key="ele" class="text"> <p v-for="(ele, index) in filterTexts" :key="ele" class="text">
{{ ele }} <el-tooltip effect="dark" :content="ele" placement="top-start">
{{ ele }}
</el-tooltip>
<el-icon @click="clearFilter(index)"> <el-icon @click="clearFilter(index)">
<Icon name="icon_close_outlined"></Icon> <Icon name="icon_close_outlined"></Icon>
</el-icon> </el-icon>

View File

@ -852,11 +852,16 @@ defineExpose({
} }
.head-filter { .head-filter {
flex: 1; flex: 1;
text-align: right; display: flex;
align-items: center;
justify-content: end;
margin-right: 16px; margin-right: 16px;
font-weight: 400; font-weight: 400;
font-size: 12px; font-size: 12px;
color: #646a73; color: #646a73;
.ed-switch {
margin-left: 8px;
}
} }
} }

View File

@ -534,11 +534,16 @@ defineExpose({
} }
.head-filter { .head-filter {
flex: 1; flex: 1;
text-align: right; display: flex;
align-items: center;
justify-content: end;
margin-right: 16px; margin-right: 16px;
font-weight: 400; font-weight: 400;
font-size: 12px; font-size: 12px;
color: #646a73; color: #646a73;
.ed-switch {
margin-left: 8px;
}
} }
} }

View File

@ -70,7 +70,7 @@ const releaseSelect = inject('release-unmount-select', Function, true)
const queryDataForId = inject('query-data-for-id', Function, true) const queryDataForId = inject('query-data-for-id', Function, true)
const setDefaultMapValue = arr => { const setDefaultMapValue = arr => {
const { displayId, field } = config.value const { displayId, field } = config.value
if (!displayId || displayId === field?.id) { if (!displayId) {
return [] return []
} }
let defaultMapValue = {} let defaultMapValue = {}

View File

@ -51,6 +51,7 @@ onMounted(() => {
.ai-main { .ai-main {
position: fixed; position: fixed;
border-radius: 5px; border-radius: 5px;
border-top-right-radius: 0;
overflow: hidden; overflow: hidden;
height: 0; height: 0;
bottom: 48px; bottom: 48px;

View File

@ -10,7 +10,7 @@ const setCollapse = () => {
<template> <template>
<div class="de-collapse-bar" @click="setCollapse"> <div class="de-collapse-bar" @click="setCollapse">
<el-icon> <el-icon style="color: #646a73">
<Icon :name="!isCollapse ? 'icon_side-fold_outlined' : 'icon_side-expand_outlined'"></Icon> <Icon :name="!isCollapse ? 'icon_side-fold_outlined' : 'icon_side-expand_outlined'"></Icon>
</el-icon> </el-icon>
{{ !isCollapse ? '收起导航' : '' }} {{ !isCollapse ? '收起导航' : '' }}
@ -29,7 +29,6 @@ const setCollapse = () => {
font-size: 14px; font-size: 14px;
font-weight: 400; font-weight: 400;
line-height: 22px; line-height: 22px;
color: #646a73;
display: flex; display: flex;
align-items: center; align-items: center;

View File

@ -17,7 +17,7 @@ const { start, done } = useNProgress()
const interactiveStore = interactiveStoreWithOut() const interactiveStore = interactiveStoreWithOut()
const { loadStart, loadDone } = usePageLoading() const { loadStart, loadDone } = usePageLoading()
const whiteList = ['/login'] // 不重定向白名单 const whiteList = ['/login', '/panel'] // 不重定向白名单
router.beforeEach(async (to, _, next) => { router.beforeEach(async (to, _, next) => {
start() start()

View File

@ -20,6 +20,7 @@ interface AppearanceState {
foot?: string foot?: string
footContent?: string footContent?: string
loaded: boolean loaded: boolean
showDemoTips?: boolean
} }
const { wsCache } = useCache() const { wsCache } = useCache()
export const useAppearanceStore = defineStore('appearanceStore', { export const useAppearanceStore = defineStore('appearanceStore', {
@ -37,7 +38,8 @@ export const useAppearanceStore = defineStore('appearanceStore', {
name: '', name: '',
foot: 'false', foot: 'false',
footContent: '', footContent: '',
loaded: false loaded: false,
showDemoTips: false
} }
}, },
getters: { getters: {
@ -91,6 +93,9 @@ export const useAppearanceStore = defineStore('appearanceStore', {
}, },
getFootContent(): string { getFootContent(): string {
return this.footContent return this.footContent
},
getShowDemoTips(): boolean {
return this.showDemoTips
} }
}, },
actions: { actions: {
@ -126,6 +131,10 @@ export const useAppearanceStore = defineStore('appearanceStore', {
if (!resData?.length) { if (!resData?.length) {
return return
} }
if (resData.length === 1 && resData[0]?.pkey === 'showDemoTips') {
this.showDemoTips = resData[0].pval
return
}
const data: AppearanceState = { loaded: false } const data: AppearanceState = { loaded: false }
resData.forEach(item => { resData.forEach(item => {
data[item.pkey] = item.pval data[item.pkey] = item.pval

View File

@ -402,3 +402,10 @@ strong {
.ed-picker__popper { .ed-picker__popper {
--ed-datepicker-border-color: #DEE0E3 !important; --ed-datepicker-border-color: #DEE0E3 !important;
} }
.ed-dialog__headerbtn {
top: 21px !important;
display: flex;
align-items: center;
justify-content: center
}

View File

@ -226,6 +226,7 @@ onMounted(() => {
<el-dropdown-item @click.prevent> <el-dropdown-item @click.prevent>
<el-dropdown <el-dropdown
:effect="themes" :effect="themes"
popper-class="data-dropdown_popper_mr9"
placement="right-start" placement="right-start"
style="width: 100%; height: 100%" style="width: 100%; height: 100%"
@command="sort" @command="sort"
@ -305,6 +306,7 @@ onMounted(() => {
<el-dropdown <el-dropdown
:effect="themes" :effect="themes"
placement="right-start" placement="right-start"
popper-class="data-dropdown_popper_mr9"
style="width: 100%; height: 100%" style="width: 100%; height: 100%"
@command="dateStyle" @command="dateStyle"
> >
@ -438,6 +440,7 @@ onMounted(() => {
<el-dropdown <el-dropdown
:effect="themes" :effect="themes"
placement="right-start" placement="right-start"
popper-class="data-dropdown_popper_mr9"
style="width: 100%; height: 100%" style="width: 100%; height: 100%"
@command="datePattern" @command="datePattern"
> >
@ -695,6 +698,9 @@ span {
} }
</style> </style>
<style lang="less"> <style lang="less">
.data-dropdown_popper_mr9 {
margin-left: -9px !important;
}
.menu-item-padding { .menu-item-padding {
span { span {
font-size: 14px; font-size: 14px;

View File

@ -349,6 +349,7 @@ onMounted(() => {
<el-dropdown <el-dropdown
:effect="themes" :effect="themes"
placement="right-start" placement="right-start"
popper-class="data-dropdown_popper_mr9"
style="width: 100%" style="width: 100%"
@command="switchChartType" @command="switchChartType"
> >
@ -403,6 +404,7 @@ onMounted(() => {
<el-dropdown <el-dropdown
:effect="themes" :effect="themes"
placement="right-start" placement="right-start"
popper-class="data-dropdown_popper_mr9"
style="width: 100%; height: 100%" style="width: 100%; height: 100%"
@command="summary" @command="summary"
> >
@ -583,6 +585,7 @@ onMounted(() => {
<el-dropdown <el-dropdown
placement="right-start" placement="right-start"
:effect="themes" :effect="themes"
popper-class="data-dropdown_popper_mr9"
style="width: 100%; height: 100%" style="width: 100%; height: 100%"
@command="quickCalc" @command="quickCalc"
> >
@ -670,6 +673,7 @@ onMounted(() => {
<el-dropdown <el-dropdown
:effect="themes" :effect="themes"
placement="right-start" placement="right-start"
popper-class="data-dropdown_popper_mr9"
style="width: 100%; height: 100%" style="width: 100%; height: 100%"
@command="sort" @command="sort"
> >
@ -958,6 +962,9 @@ span {
} }
</style> </style>
<style lang="less"> <style lang="less">
.data-dropdown_popper_mr9 {
margin-left: -9px !important;
}
.menu-item-padding { .menu-item-padding {
span { span {
font-size: 14px; font-size: 14px;

View File

@ -145,7 +145,7 @@ initCompareType()
>本期数据 - 上期数据</span >本期数据 - 上期数据</span
> >
<span v-else-if="compareItem.compareCalc.resultData === 'percent'" class="exp-style" <span v-else-if="compareItem.compareCalc.resultData === 'percent'" class="exp-style"
>(本期数据 / 上期数据 - 1) * 100%</span >(本期数据 / |上期数据| - 1) * 100%</span
> >
</el-form-item> </el-form-item>
</el-form> </el-form>

View File

@ -15,7 +15,8 @@ import {
import { import {
AntVAbstractChartView, AntVAbstractChartView,
AntVDrawOptions, AntVDrawOptions,
ChartLibraryType ChartLibraryType,
ChartWrapper
} from '@/views/chart/components/js/panel/types' } from '@/views/chart/components/js/panel/types'
import { getEngine } from '@antv/g2/esm/core' import { getEngine } from '@antv/g2/esm/core'
import { handleEmptyDataStrategy } from '../../../util' import { handleEmptyDataStrategy } from '../../../util'
@ -32,6 +33,38 @@ export interface G2PlotDrawOptions<O> extends AntVDrawOptions<O> {
quadrantDefaultBaseline?: (...args: any) => void quadrantDefaultBaseline?: (...args: any) => void
} }
/**
* 图表对象包装类一个图表里面可能有多个对象实例
*/
export class G2PlotWrapper<O extends PickOptions, P extends Plot<O>> extends ChartWrapper<
P | Array<P>
> {
constructor(chartInstance: P | Array<P>) {
super()
this.chartInstance = chartInstance
}
destroy = () => {
if (!this.chartInstance) {
return
}
if (Array.isArray(this.chartInstance)) {
this.chartInstance?.forEach(p => p.destroy())
} else {
this.chartInstance?.destroy()
}
}
render = () => {
if (!this.chartInstance) {
return
}
if (Array.isArray(this.chartInstance)) {
this.chartInstance?.forEach(p => p.render())
} else {
this.chartInstance?.render()
}
}
}
/** /**
* G2Plot 的图表抽象类 * G2Plot 的图表抽象类
*/ */
@ -46,7 +79,7 @@ export abstract class G2PlotChartView<
* @param drawOptions 图表配置参数 * @param drawOptions 图表配置参数
* @return 生成的图表对象类型为 Plot 的子类 * @return 生成的图表对象类型为 Plot 的子类
*/ */
public abstract drawChart(drawOptions: G2PlotDrawOptions<P>): P public abstract drawChart(drawOptions: G2PlotDrawOptions<P>): G2PlotWrapper<O, P> | P
protected configTheme(chart: Chart, options: O): O { protected configTheme(chart: Chart, options: O): O {
const theme = getTheme(chart) const theme = getTheme(chart)

View File

@ -16,7 +16,11 @@ export enum ChartLibraryType {
RICH_TEXT = 'rich-text', RICH_TEXT = 'rich-text',
INDICATOR = 'indicator' INDICATOR = 'indicator'
} }
export abstract class ChartWrapper<O> {
chartInstance: O
abstract render: () => any
abstract destroy: () => any
}
export abstract class AbstractChartView { export abstract class AbstractChartView {
render: ChartRenderType render: ChartRenderType
library: ChartLibraryType library: ChartLibraryType

View File

@ -1,6 +1,5 @@
<script lang="ts" setup> <script lang="ts" setup>
import { ref, onMounted, unref, onBeforeUnmount, computed } from 'vue' import { ref, onMounted, unref, onBeforeUnmount, computed } from 'vue'
import { XpackComponent } from '@/components/plugin'
import { ElMessage, ElMessageBox } from 'element-plus-secondary' import { ElMessage, ElMessageBox } from 'element-plus-secondary'
import MobileBackgroundSelector from './MobileBackgroundSelector.vue' import MobileBackgroundSelector from './MobileBackgroundSelector.vue'
import ComponentWrapper from '@/components/data-visualization/canvas/ComponentWrapper.vue' import ComponentWrapper from '@/components/data-visualization/canvas/ComponentWrapper.vue'
@ -47,18 +46,6 @@ const iframeSrc = computed(() => {
? `${embeddedStore.baseUrl}mobile.html#/panel` ? `${embeddedStore.baseUrl}mobile.html#/panel`
: './mobile.html#/panel' : './mobile.html#/panel'
}) })
const openHandler = ref(null)
const initOpenHandler = newWindow => {
if (openHandler?.value && !!embeddedStore.baseUrl) {
const pm = {
methodName: 'initOpenHandler',
args: newWindow
}
openHandler.value.invokeMethod(pm)
}
}
const handleLoad = () => { const handleLoad = () => {
mobileStatusChange( mobileStatusChange(
'panelInit', 'panelInit',
@ -69,7 +56,8 @@ const handleLoad = () => {
), ),
canvasStyleData: JSON.parse(JSON.stringify(unref(canvasStyleData))), canvasStyleData: JSON.parse(JSON.stringify(unref(canvasStyleData))),
canvasViewInfo: JSON.parse(JSON.stringify(unref(canvasViewInfo))), canvasViewInfo: JSON.parse(JSON.stringify(unref(canvasViewInfo))),
dvInfo: JSON.parse(JSON.stringify(unref(dvInfo))) dvInfo: JSON.parse(JSON.stringify(unref(dvInfo))),
isEmbedded: !!embeddedStore.baseUrl
}) })
) )
) )
@ -79,7 +67,19 @@ const componentDataNotInMobile = computed(() => {
return componentData.value.filter(ele => !ele.inMobile) return componentData.value.filter(ele => !ele.inMobile)
}) })
const newWindow = ref()
const hanedleMessage = event => { const hanedleMessage = event => {
if (event.data?.msgOrigin === 'de-fit2cloud' && !!embeddedStore.token) {
const params = {
embeddedToken: embeddedStore.token
}
params['de-embedded'] = true
const contentWindow = newWindow.value.contentWindow
console.log('call back from dataease!', contentWindow)
contentWindow.postMessage(params, '*')
return
}
if (event.data.type === 'panelInit') { if (event.data.type === 'panelInit') {
loadCanvasData() loadCanvasData()
} }
@ -95,7 +95,7 @@ const hanedleMessage = event => {
}) })
} }
if (event.data.type === 'mobileSaveFromMobile') { if (['mobileSaveFromMobile', 'mobilePatchFromMobile'].includes(event.data.type)) {
componentData.value.forEach(ele => { componentData.value.forEach(ele => {
const com = event.data.value[ele.id] const com = event.data.value[ele.id]
if (!!com) { if (!!com) {
@ -117,8 +117,14 @@ const hanedleMessage = event => {
} }
} }
}) })
}
if (event.data.type === 'mobileSaveFromMobile') {
saveCanvasWithCheckFromMobile() saveCanvasWithCheckFromMobile()
} }
if (event.data.type === 'mobilePatchFromMobile') {
emits('pcMode')
}
} }
const saveCanvasWithCheckFromMobile = () => { const saveCanvasWithCheckFromMobile = () => {
@ -146,7 +152,6 @@ const setMobileStyle = debounce(() => {
transformOrigin: '0 0' transformOrigin: '0 0'
} }
}, 100) }, 100)
const newWindow = ref()
onMounted(() => { onMounted(() => {
window.addEventListener('message', hanedleMessage) window.addEventListener('message', hanedleMessage)
window.addEventListener('resize', setMobileStyle) window.addEventListener('resize', setMobileStyle)
@ -158,9 +163,6 @@ onMounted(() => {
} }
}) })
setMobileStyle() setMobileStyle()
setTimeout(() => {
initOpenHandler(newWindow.value)
}, 300)
}) })
onBeforeUnmount(() => { onBeforeUnmount(() => {
@ -179,7 +181,7 @@ const changeTimes = ref(0)
const activeCollapse = ref('com') const activeCollapse = ref('com')
const handleBack = () => { const handleBack = () => {
if (!changeTimes.value) { if (!changeTimes.value) {
emits('pcMode') mobileStatusChange('mobilePatch', undefined)
return return
} }
ElMessageBox.confirm('当前的更改尚未保存,确定退出吗?', { ElMessageBox.confirm('当前的更改尚未保存,确定退出吗?', {
@ -188,7 +190,9 @@ const handleBack = () => {
autofocus: false, autofocus: false,
showClose: false showClose: false
}).then(() => { }).then(() => {
emits('pcMode') setTimeout(() => {
mobileStatusChange('mobilePatch', undefined)
}, 100)
}) })
} }
@ -274,7 +278,6 @@ const save = () => {
</div> </div>
</div> </div>
</div> </div>
<XpackComponent ref="openHandler" jsname="L2NvbXBvbmVudC9lbWJlZGRlZC1pZnJhbWUvT3BlbkhhbmRsZXI=" />
</template> </template>
<style lang="less" scoped> <style lang="less" scoped>

View File

@ -154,7 +154,7 @@ onMounted(async () => {
} }
let deTemplateData let deTemplateData
if (createType === 'template') { if (createType === 'template') {
const templateParamsApply = JSON.parse(Base64.decode(templateParams + '')) const templateParamsApply = JSON.parse(decodeURIComponent(Base64.decode(templateParams + '')))
await decompressionPre(templateParamsApply, result => { await decompressionPre(templateParamsApply, result => {
deTemplateData = result deTemplateData = result
}) })

View File

@ -261,7 +261,7 @@ onMounted(async () => {
} }
let deTemplateData let deTemplateData
if (createType === 'template') { if (createType === 'template') {
const templateParamsApply = JSON.parse(Base64.decode(templateParams + '')) const templateParamsApply = JSON.parse(decodeURIComponent(Base64.decode(templateParams + '')))
await decompressionPre(templateParamsApply, result => { await decompressionPre(templateParamsApply, result => {
deTemplateData = result deTemplateData = result
}) })

View File

@ -35,12 +35,13 @@ const slogan = ref(null)
const footContent = ref(null) const footContent = ref(null)
const loginErrorMsg = ref('') const loginErrorMsg = ref('')
const xpackLoginHandler = ref() const xpackLoginHandler = ref()
const showDempTips = ref(false)
const demoTips = '账号admin 密码DataEase@123456 每晚 00:00 重置数据'
const state = reactive({ const state = reactive({
loginForm: { loginForm: {
username: '', username: '',
password: '' password: ''
}, },
uiInfo: {},
footContent: '' footContent: ''
}) })
const checkUsername = value => { const checkUsername = value => {
@ -163,6 +164,7 @@ const showLoginErrorMsg = () => {
} }
const loadArrearance = () => { const loadArrearance = () => {
showDempTips.value = appearanceStore.getShowDemoTips
if (appearanceStore.getBg) { if (appearanceStore.getBg) {
loginImageUrl.value = appearanceStore.getBg loginImageUrl.value = appearanceStore.getBg
} }
@ -307,15 +309,8 @@ onMounted(() => {
> >
{{ t('login.btn') }} {{ t('login.btn') }}
</el-button> </el-button>
<div <div v-if="showDempTips" class="demo-tips">
v-if=" <span>{{ demoTips }}</span>
state.uiInfo &&
state.uiInfo['ui.demo.tips'] &&
state.uiInfo['ui.demo.tips'].paramValue
"
class="demo-tips"
>
{{ state.uiInfo['ui.demo.tips'].paramValue }}
</div> </div>
</div> </div>
</div> </div>
@ -426,12 +421,13 @@ onMounted(() => {
} }
.demo-tips { .demo-tips {
margin-top: 20px; position: absolute;
font-size: 18px; font-size: 18px;
color: #f56c6c; color: #f56c6c;
letter-spacing: 0; letter-spacing: 0;
line-height: 18px; line-height: 18px;
text-align: center; text-align: center;
top: 120px;
@media only screen and (max-width: 1280px) { @media only screen and (max-width: 1280px) {
margin-top: 20px; margin-top: 20px;
} }
@ -465,6 +461,7 @@ onMounted(() => {
} }
.login-btn { .login-btn {
position: relative;
margin-bottom: 120px; margin-bottom: 120px;
.submit { .submit {
width: 100%; width: 100%;

View File

@ -1,9 +1,9 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onBeforeMount, ref, onBeforeUnmount } from 'vue' import { onBeforeMount, ref, onBeforeUnmount } from 'vue'
import { useEmitt } from '@/hooks/web/useEmitt' import { useEmitt } from '@/hooks/web/useEmitt'
import { XpackComponent } from '@/components/plugin'
import eventBus from '@/utils/eventBus' import eventBus from '@/utils/eventBus'
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain' import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
import { XpackComponent } from '@/components/plugin'
import DePreviewMobile from './MobileInPc.vue' import DePreviewMobile from './MobileInPc.vue'
const panelInit = ref(false) const panelInit = ref(false)
const dvMainStore = dvMainStoreWithOut() const dvMainStore = dvMainStoreWithOut()
@ -19,7 +19,7 @@ const checkItemPosition = component => {
const hanedleMessage = event => { const hanedleMessage = event => {
if (event.data.type === 'panelInit') { if (event.data.type === 'panelInit') {
const { componentData, canvasStyleData, dvInfo, canvasViewInfo } = event.data.value const { componentData, canvasStyleData, dvInfo, canvasViewInfo, isEmbedded } = event.data.value
componentData.forEach(ele => { componentData.forEach(ele => {
const { mx, my, mSizeX, mSizeY } = ele const { mx, my, mSizeX, mSizeY } = ele
ele.x = mx ele.x = mx
@ -47,6 +47,7 @@ const hanedleMessage = event => {
dvMainStore.updateCurDvInfo(dvInfo) dvMainStore.updateCurDvInfo(dvInfo)
dvMainStore.setCanvasViewInfo(canvasViewInfo) dvMainStore.setCanvasViewInfo(canvasViewInfo)
eventBus.emit('doCanvasInit-canvas-main') eventBus.emit('doCanvasInit-canvas-main')
if (isEmbedded) return
panelInit.value = true panelInit.value = true
} }
@ -61,10 +62,10 @@ const hanedleMessage = event => {
dvMainStore.setCanvasStyle(event.data.value) dvMainStore.setCanvasStyle(event.data.value)
} }
if (event.data.type === 'mobileSave') { if (['mobileSave', 'mobilePatch'].includes(event.data.type)) {
window.top.postMessage( window.parent.postMessage(
{ {
type: 'mobileSaveFromMobile', type: `${event.data.type}FromMobile`,
value: dvMainStore.componentData.reduce((pre, next) => { value: dvMainStore.componentData.reduce((pre, next) => {
const { x, y, sizeX, sizeY, id, component } = next const { x, y, sizeX, sizeY, id, component } = next
pre[id] = { x, y, sizeX, sizeY, component } pre[id] = { x, y, sizeX, sizeY, component }
@ -90,11 +91,15 @@ const hanedleMessage = event => {
} }
} }
let p = null const initIframe = () => {
const XpackLoaded = () => p(true) panelInit.value = false
onBeforeMount(async () => { setTimeout(() => {
await new Promise(r => (p = r)) panelInit.value = true
window.top.postMessage({ type: 'panelInit', value: true }, '*') })
}
onBeforeMount(() => {
window.parent.postMessage({ type: 'panelInit', value: true }, '*')
window.addEventListener('message', hanedleMessage) window.addEventListener('message', hanedleMessage)
useEmitt({ useEmitt({
name: 'onMobileStatusChange', name: 'onMobileStatusChange',
@ -105,7 +110,7 @@ onBeforeMount(async () => {
}) })
const mobileStatusChange = (type, value) => { const mobileStatusChange = (type, value) => {
window.top.postMessage({ type, value }, '*') window.parent.postMessage({ type, value }, '*')
if (type === 'delFromMobile') { if (type === 'delFromMobile') {
eventBus.emit('removeMatrixItemById-canvas-main', value) eventBus.emit('removeMatrixItemById-canvas-main', value)
} }
@ -121,9 +126,8 @@ onBeforeUnmount(() => {
<de-preview-mobile v-if="panelInit"></de-preview-mobile> <de-preview-mobile v-if="panelInit"></de-preview-mobile>
</div> </div>
<XpackComponent <XpackComponent
jsname="L2NvbXBvbmVudC9lbWJlZGRlZC1pZnJhbWUvTmV3V2luZG93SGFuZGxlcg==" @initIframe="initIframe"
@loaded="XpackLoaded" jsname="L2NvbXBvbmVudC9lbWJlZGRlZC1pZnJhbWUvRW50cmFuY2Vz"
@load-fail="XpackLoaded"
/> />
</template> </template>

View File

@ -432,7 +432,7 @@ const apply = template => {
? '#/dvCanvas?opt=create&createType=template' ? '#/dvCanvas?opt=create&createType=template'
: '#/dashboard?opt=create&createType=template') + : '#/dashboard?opt=create&createType=template') +
'&templateParams=' + '&templateParams=' +
Base64.encode(JSON.stringify(templateTemplate)) encodeURIComponent(Base64.encode(JSON.stringify(templateTemplate)))
let newWindow = null let newWindow = null
let embeddedBaseUrl = '' let embeddedBaseUrl = ''
if (isDataEaseBi.value) { if (isDataEaseBi.value) {

View File

@ -235,7 +235,7 @@ const apply = () => {
? '#/dvCanvas?opt=create&createType=template' ? '#/dvCanvas?opt=create&createType=template'
: '#/dashboard?opt=create&createType=template') + : '#/dashboard?opt=create&createType=template') +
'&templateParams=' + '&templateParams=' +
Base64.encode(JSON.stringify(templateTemplate)) encodeURIComponent(Base64.encode(JSON.stringify(templateTemplate)))
let newWindow = null let newWindow = null
let embeddedBaseUrl = '' let embeddedBaseUrl = ''
if (isDataEaseBi.value) { if (isDataEaseBi.value) {

View File

@ -25,7 +25,7 @@
<mybatis-plus.version>3.5.6</mybatis-plus.version> <mybatis-plus.version>3.5.6</mybatis-plus.version>
<h2.version>2.2.220</h2.version> <h2.version>2.2.220</h2.version>
<knife4j.version>4.4.0</knife4j.version> <knife4j.version>4.4.0</knife4j.version>
<calcite-core.version>1.35.7</calcite-core.version> <calcite-core.version>1.35.8</calcite-core.version>
<commons-dbcp2.version>2.6.0</commons-dbcp2.version> <commons-dbcp2.version>2.6.0</commons-dbcp2.version>
<antlr.version>3.5.2</antlr.version> <antlr.version>3.5.2</antlr.version>
<java-jwt.version>3.12.1</java-jwt.version> <java-jwt.version>3.12.1</java-jwt.version>