Merge remote-tracking branch 'origin/dev-v2' into dev-v2

This commit is contained in:
wangjiahao 2024-01-22 18:29:38 +08:00
commit c56d811259
24 changed files with 364 additions and 256 deletions

View File

@ -7,4 +7,7 @@ assignees: xuwei-fit2cloud, yayanpei-fit2cloud
---
DataEase 版本:
**请描述您的需求或者改进建议.**

View File

@ -3,7 +3,7 @@ name: Bug 提交
about: 提交产品缺陷帮助我们更好的改进
title: "[Bug]"
labels: 状态:待处理
assignees: BBchicken-9527, Shenguobin0102, zrfit
assignees: BBchicken-9527, Shenguobin0102
---

View File

@ -6,7 +6,6 @@ import io.dataease.api.dataset.dto.DatasetTableDTO;
import io.dataease.api.dataset.dto.SqlVariableDetails;
import io.dataease.api.dataset.union.DatasetGroupInfoDTO;
import io.dataease.api.dataset.vo.DataSetBarVO;
import io.dataease.commons.constants.OptConstants;
import io.dataease.constant.LogOT;
import io.dataease.constant.LogST;
import io.dataease.dataset.manage.DatasetGroupManage;
@ -44,11 +43,13 @@ public class DatasetTreeServer implements DatasetTreeApi {
return datasetGroupManage.save(dto, false);
}
@DeLog(id = "#p0.id", ot = LogOT.MODIFY, st = LogST.DATASET)
@Override
public DatasetNodeDTO move(DatasetGroupInfoDTO dto) throws Exception {
return datasetGroupManage.move(dto);
}
@DeLog(id = "#p0", ot = LogOT.DELETE, st = LogST.DATASET)
@Override
public void delete(Long id) {
datasetGroupManage.delete(id);

View File

@ -5,6 +5,8 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import io.dataease.api.ds.vo.DatasourceDTO;
import io.dataease.commons.constants.OptConstants;
import io.dataease.constant.DataSourceType;
import io.dataease.constant.LogOT;
import io.dataease.constant.LogST;
import io.dataease.datasource.dao.auto.entity.CoreDatasource;
import io.dataease.datasource.dao.auto.mapper.CoreDatasourceMapper;
import io.dataease.datasource.dao.ext.mapper.DataSourceExtMapper;
@ -12,6 +14,7 @@ import io.dataease.datasource.dao.ext.po.DataSourceNodePO;
import io.dataease.datasource.dto.DatasourceNodeBO;
import io.dataease.exception.DEException;
import io.dataease.license.config.XpackInteract;
import io.dataease.log.DeLog;
import io.dataease.model.BusiNodeRequest;
import io.dataease.model.BusiNodeVO;
import io.dataease.operation.manage.CoreOptRecentManage;
@ -25,7 +28,6 @@ import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Component
public class DataSourceManage {
@ -71,12 +73,14 @@ public class DataSourceManage {
return TreeUtils.mergeTree(nodes, BusiNodeVO.class, false);
}
@DeLog(id = "#p0.id", pid = "#p0.pid", ot = LogOT.CREATE, st = LogST.DATASOURCE)
@XpackInteract(value = "datasourceResourceTree", before = false)
public void innerSave(CoreDatasource coreDatasource) {
coreDatasourceMapper.insert(coreDatasource);
coreOptRecentManage.saveOpt(coreDatasource.getId(), OptConstants.OPT_RESOURCE_TYPE.DATASOURCE,OptConstants.OPT_TYPE.NEW);
coreOptRecentManage.saveOpt(coreDatasource.getId(), OptConstants.OPT_RESOURCE_TYPE.DATASOURCE, OptConstants.OPT_TYPE.NEW);
}
@DeLog(id = "#p0.id", ot = LogOT.MODIFY, st = LogST.DATASOURCE)
@XpackInteract(value = "datasourceResourceTree", before = false)
public void innerEdit(CoreDatasource coreDatasource) {
UpdateWrapper<CoreDatasource> updateWrapper = new UpdateWrapper<>();
@ -84,9 +88,10 @@ public class DataSourceManage {
coreDatasource.setUpdateTime(System.currentTimeMillis());
coreDatasource.setUpdateBy(AuthUtils.getUser().getUserId());
coreDatasourceMapper.update(coreDatasource, updateWrapper);
coreOptRecentManage.saveOpt(coreDatasource.getId(), OptConstants.OPT_RESOURCE_TYPE.DATASOURCE,OptConstants.OPT_TYPE.UPDATE);
coreOptRecentManage.saveOpt(coreDatasource.getId(), OptConstants.OPT_RESOURCE_TYPE.DATASOURCE, OptConstants.OPT_TYPE.UPDATE);
}
@DeLog(id = "#p0.id", ot = LogOT.MODIFY, st = LogST.DATASOURCE)
@XpackInteract(value = "datasourceResourceTree", before = false)
public void innerEditStatus(CoreDatasource coreDatasource) {
UpdateWrapper<CoreDatasource> updateWrapper = new UpdateWrapper<>();
@ -94,6 +99,7 @@ public class DataSourceManage {
coreDatasourceMapper.update(coreDatasource, updateWrapper);
}
@DeLog(id = "#p0.id", ot = LogOT.MODIFY, st = LogST.DATASOURCE)
@XpackInteract(value = "datasourceResourceTree", before = false)
public void move(DatasourceDTO dataSourceDTO) {
Long id = dataSourceDTO.getId();
@ -106,6 +112,6 @@ public class DataSourceManage {
sourceData.setPid(dataSourceDTO.getPid());
sourceData.setName(dataSourceDTO.getName());
coreDatasourceMapper.updateById(sourceData);
coreOptRecentManage.saveOpt(sourceData.getId(), OptConstants.OPT_RESOURCE_TYPE.DATASOURCE,OptConstants.OPT_TYPE.UPDATE);
coreOptRecentManage.saveOpt(sourceData.getId(), OptConstants.OPT_RESOURCE_TYPE.DATASOURCE, OptConstants.OPT_TYPE.UPDATE);
}
}

View File

@ -14,6 +14,8 @@ import io.dataease.api.ds.vo.*;
import io.dataease.commons.constants.TaskStatus;
import io.dataease.commons.utils.CommonThreadPool;
import io.dataease.constant.DataSourceType;
import io.dataease.constant.LogOT;
import io.dataease.constant.LogST;
import io.dataease.dataset.dto.DatasourceSchemaDTO;
import io.dataease.dataset.manage.DatasetDataManage;
import io.dataease.dataset.utils.TableUtils;
@ -35,6 +37,7 @@ import io.dataease.i18n.Translator;
import io.dataease.job.sechedule.CheckDsStatusJob;
import io.dataease.job.sechedule.ScheduleManager;
import io.dataease.license.config.XpackInteract;
import io.dataease.log.DeLog;
import io.dataease.model.BusiNodeRequest;
import io.dataease.model.BusiNodeVO;
import io.dataease.system.dao.auto.entity.CoreSysSetting;
@ -136,7 +139,7 @@ public class DatasourceServer implements DatasourceApi {
dataSourceManage.move(dataSourceDTO);
}
case "rename" -> {
if(StringUtils.isEmpty(dataSourceDTO.getName())){
if (StringUtils.isEmpty(dataSourceDTO.getName())) {
DEException.throwException("名称不能为空!");
}
CoreDatasource datasource = datasourceMapper.selectById(dataSourceDTO.getId());
@ -550,6 +553,7 @@ public class DatasourceServer implements DatasourceApi {
return datasourceDTO;
}
@DeLog(id = "#p0", ot = LogOT.DELETE, st = LogST.DATASOURCE)
@Override
@XpackInteract(value = "datasourceResourceTree", before = false)
public void delete(Long datasourceId) throws DEException {

View File

@ -17,8 +17,10 @@ import io.dataease.chart.manage.ChartViewManege;
import io.dataease.commons.constants.DataVisualizationConstants;
import io.dataease.commons.constants.OptConstants;
import io.dataease.constant.CommonConstants;
import io.dataease.constant.LogOT;
import io.dataease.exception.DEException;
import io.dataease.license.config.XpackInteract;
import io.dataease.log.DeLog;
import io.dataease.model.BusiNodeRequest;
import io.dataease.model.BusiNodeVO;
import io.dataease.operation.manage.CoreOptRecentManage;
@ -89,6 +91,7 @@ public class DataVisualizationServer implements DataVisualizationApi {
@Resource
private VisualizationWatermarkMapper watermarkMapper;
@DeLog(id = "#p0", ot = LogOT.READ, stExp = "#p1")
@Override
public DataVisualizationVO findCopyResource(Long dvId, String busiFlag) {
DataVisualizationVO result = findById(dvId, busiFlag);
@ -121,6 +124,7 @@ public class DataVisualizationServer implements DataVisualizationApi {
return null;
}
@DeLog(id = "#p0.id", pid = "#p0.pid", ot = LogOT.CREATE, stExp = "#p0.type")
@Override
@Transactional
public String saveCanvas(DataVisualizationBaseRequest request) {
@ -133,11 +137,13 @@ public class DataVisualizationServer implements DataVisualizationApi {
visualizationInfo.setSelfWatermarkStatus(0);
}
Long newDvId = coreVisualizationManage.innerSave(visualizationInfo);
request.setId(newDvId);
//保存视图信
chartDataManage.saveChartViewFromVisualization(request.getComponentData(), newDvId, request.getCanvasViewInfo());
return newDvId.toString();
}
@DeLog(id = "#p0.id", ot = LogOT.MODIFY, stExp = "#p0.type")
@Override
@Transactional
public void updateCanvas(DataVisualizationBaseRequest request) {
@ -178,6 +184,7 @@ public class DataVisualizationServer implements DataVisualizationApi {
* @Description: 更新基础信息
* 为什么单独接口1.基础信息更新频繁数据且数据载量较小2.防止出现更新过多信息的情况造成视图的误删等操作
*/
@DeLog(id = "#p0.id", ot = LogOT.MODIFY, stExp = "#p0.type")
@Override
@Transactional
public void updateBase(DataVisualizationBaseRequest request) {
@ -191,6 +198,7 @@ public class DataVisualizationServer implements DataVisualizationApi {
/**
* @Description: 逻辑删除可视化信息将delete_flag 置为0
*/
@DeLog(id = "#p0", ot = LogOT.DELETE, stExp = "#p1")
@Transactional
@Override
public void deleteLogic(Long dvId, String busiFlag) {
@ -203,6 +211,7 @@ public class DataVisualizationServer implements DataVisualizationApi {
return coreVisualizationManage.tree(request);
}
@DeLog(id = "#p0.id", pid = "#p0.pid", ot = LogOT.MODIFY, stExp = "#p0.type")
@Transactional
@Override
public void move(DataVisualizationBaseRequest request) {

View File

@ -24,7 +24,7 @@
"axios": "^1.3.3",
"crypto-js": "^4.1.1",
"dayjs": "^1.11.9",
"element-plus-secondary": "^0.4.15",
"element-plus-secondary": "^0.4.16",
"element-resize-detector": "^1.2.4",
"file-saver": "^2.0.5",
"html-to-image": "^1.11.11",

View File

@ -194,6 +194,8 @@ const indicatorSuffixClass = ref<CSSProperties>({
'font-synthesis': 'weight style'
})
const showSuffix = ref<boolean>(DEFAULT_INDICATOR_STYLE.suffixEnable)
const suffixContent = ref('')
const indicatorNameShow = ref(false)
@ -293,6 +295,7 @@ const renderChart = async view => {
'font-synthesis': 'weight style'
}
showSuffix.value = customAttr.indicator.suffixEnable
suffixContent.value = defaultTo(customAttr.indicator.suffix, '')
}
if (customAttr.indicatorName && customAttr.indicatorName.show) {
@ -359,7 +362,7 @@ defineExpose({
<div :style="contentStyle">
<div>
<span :style="indicatorClass">{{ formattedResult }}</span>
<span :style="indicatorSuffixClass">{{ suffixContent }}</span>
<span :style="indicatorSuffixClass" v-if="showSuffix">{{ suffixContent }}</span>
</div>
<div v-if="indicatorNameShow">
<span :style="indicatorNameClass">{{ resultName }}</span>

View File

@ -5,6 +5,7 @@ import { type DatePickType } from 'element-plus-secondary'
import { getCustomTime } from './time-format'
interface SelectConfig {
timeType: string
timeGranularityMultiple: DatePickType
defaultValue: [Date, Date]
selectValue: [Date, Date]
defaultValueCheck: boolean
@ -25,6 +26,7 @@ const props = defineProps({
type: Object as PropType<SelectConfig>,
default: () => {
return {
timeGranularityMultiple: 'datetimerange',
defaultValue: [],
selectValue: [],
timeType: 'fixed',
@ -136,14 +138,19 @@ const init = () => {
onBeforeMount(() => {
init()
})
const formatDate = computed(() => {
return (config.value.timeGranularityMultiple as string) === 'yearrange' ? 'YYYY' : undefined
})
</script>
<template>
<el-date-picker
disabled
v-model="selectValue"
type="datetimerange"
:type="config.timeGranularityMultiple"
:prefix-icon="Calendar"
:format="formatDate"
:range-separator="$t('cron.to')"
:start-placeholder="$t('datasource.start_time')"
:end-placeholder="$t('datasource.end_time')"

View File

@ -197,6 +197,12 @@ const setTypeChange = () => {
nextTick(() => {
curComponent.value.field.id = ''
inputCom.value?.displayTypeChange?.()
if (
+curComponent.value.displayType === 7 &&
['yearrange', 'monthrange', 'datetimerange'].includes(curComponent.value.timeGranularity)
) {
curComponent.value.timeGranularityMultiple = curComponent.value.timeGranularity
}
})
}
@ -635,6 +641,13 @@ const dynamicTime = computed(() => {
const relativeToCurrentTypeList = computed(() => {
if (!curComponent.value) return []
let index = ['year', 'month', 'date', 'datetime'].indexOf(curComponent.value.timeGranularity) + 1
if (+curComponent.value.displayType === 7) {
index =
['yearrange', 'monthrange', 'datetimerange'].indexOf(
curComponent.value.timeGranularityMultiple
) + 1
}
return [
{
label: '年',
@ -648,7 +661,7 @@ const relativeToCurrentTypeList = computed(() => {
label: '日',
value: 'date'
}
].slice(0, ['year', 'month', 'date', 'datetime'].indexOf(curComponent.value.timeGranularity) + 1)
].slice(0, index)
})
const timeGranularityChange = (val: string) => {
@ -662,6 +675,15 @@ const timeGranularityChange = (val: string) => {
curComponent.value.relativeToCurrent = relativeToCurrentList.value[0]?.value
}
}
const timeGranularityMultipleChange = (val: string) => {
if (
['yearrange', 'monthrange', 'datetimerange'].indexOf(val) <
['year', 'month', 'date'].indexOf(curComponent.value.relativeToCurrentType)
) {
curComponent.value.relativeToCurrentType = 'year'
}
}
const aroundList = [
{
label: '前',
@ -968,9 +990,12 @@ defineExpose({
<div class="value">
<template v-if="curComponent.displayType === '7'">
<el-select
@change="timeGranularityMultipleChange"
placeholder="请选择时间粒度"
v-model="curComponent.timeGranularityMultiple"
>
<el-option label="年" value="yearrange" />
<el-option label="年月" value="monthrange" />
<el-option label="年月日时分秒" value="datetimerange" />
</el-select>
</template>
@ -1284,7 +1309,13 @@ defineExpose({
</div>
</template>
<template v-else-if="dynamicTime && curComponent.displayType === '7'">
<div class="setting">
<div
class="setting"
:class="
['yearrange', 'monthrange'].includes(curComponent.timeGranularityMultiple) &&
'is-year-month-range'
"
>
<div class="setting-label">开始时间</div>
<div class="setting-input with-date range">
<el-input-number
@ -1311,7 +1342,13 @@ defineExpose({
<el-time-picker v-model="curComponent.arbitraryTime" />
</div>
</div>
<div class="setting">
<div
class="setting"
:class="
['yearrange', 'monthrange'].includes(curComponent.timeGranularityMultiple) &&
'is-year-month-range'
"
>
<div class="setting-label">结束时间</div>
<div class="setting-input with-date range">
<el-input-number
@ -1651,6 +1688,7 @@ defineExpose({
padding-left: 24px;
display: flex;
flex-wrap: wrap;
.range-title,
.params-start,
.params-end {
@ -1729,6 +1767,20 @@ defineExpose({
}
}
}
&.is-year-month-range {
.setting-input {
&.with-date {
.ed-input-number,
.ed-select {
width: 103px;
}
}
.ed-date-editor.ed-input {
display: none;
}
}
}
}
}
}

View File

@ -121,6 +121,10 @@ onBeforeMount(() => {
defineExpose({
displayTypeChange
})
const formatDate = computed(() => {
return (config.value.timeGranularityMultiple as string) === 'yearrange' ? 'YYYY' : undefined
})
</script>
<template>
@ -128,6 +132,7 @@ defineExpose({
v-model="selectValue"
:type="config.timeGranularityMultiple"
:style="selectStyle"
:format="formatDate"
v-if="multiple"
@change="handleValueChange"
:prefix-icon="Calendar"

View File

@ -1102,7 +1102,7 @@ export default {
select_year: '选择年',
sql_variable_limit_1: '1SQL 变量只能在 WHERE 条件中使用',
sql_variable_limit_2:
"2、示例select * from table_name where column_name1='${'{'}param_name1{'}'}' and column_name2 in ( ${'{'}param_name2{'}'} ) ",
"2、示例select * from table_name where column_name1='${'{'}param_name1{'}'}' and column_name2 in (${'{'}param_name2{'}'})",
select_month: '选择月',
select_date: '选择日期',
select_time: '选择时间',

View File

@ -44,6 +44,7 @@ declare interface ChartIndicatorStyle {
letterSpace: string
fontShadow: boolean
suffixEnable: boolean
suffix: string
suffixFontSize: string
suffixColor: string

View File

@ -149,6 +149,7 @@ watch(
<el-form-item class="form-item" :class="'form-item-' + themes" style="padding-left: 4px">
<el-select
size="small"
:effect="themes"
v-model="state.indicatorNameForm.letterSpace"
:placeholder="t('chart.quota_letter_space')"

View File

@ -360,152 +360,170 @@ watch(
<el-divider class="m-divider" :class="{ 'divider-dark': themes === 'dark' }" />
<el-form-item
class="form-item"
:class="'form-item-' + themes"
:label="t('chart.indicator_suffix')"
>
<el-input
v-model="state.indicatorValueForm.suffix"
:placeholder="t('chart.indicator_suffix_placeholder')"
maxlength="10"
@change="changeTitleStyle('suffix')"
/>
</el-form-item>
<el-form-item class="form-item" :class="'form-item-' + themes" :effect="themes">
<el-select
<el-form-item class="form-item" :class="'form-item-' + themes">
<el-checkbox
size="small"
:effect="themes"
v-model="state.indicatorValueForm.suffixFontFamily"
:placeholder="t('chart.font_family')"
@change="changeTitleStyle('suffixFontFamily')"
v-model="state.indicatorValueForm.suffixEnable"
@change="changeTitleStyle('suffixEnable')"
>
<el-option
v-for="option in fontFamily"
:key="option.value"
:label="option.name"
:value="option.value"
/>
</el-select>
{{ t('chart.indicator_suffix') }}
</el-checkbox>
</el-form-item>
<div style="display: flex">
<el-form-item class="form-item" :class="'form-item-' + themes" style="padding-right: 4px">
<el-color-picker
:effect="themes"
v-model="state.indicatorValueForm.suffixColor"
class="color-picker-style"
:predefine="predefineColors"
@change="changeTitleStyle('suffixColor')"
is-custom
<div style="padding-left: 22px">
<el-form-item class="form-item" :class="'form-item-' + themes">
<el-input
:disabled="!state.indicatorValueForm.suffixEnable"
v-model="state.indicatorValueForm.suffix"
:placeholder="t('chart.indicator_suffix_placeholder')"
maxlength="10"
@change="changeTitleStyle('suffix')"
/>
</el-form-item>
<el-form-item class="form-item" :class="'form-item-' + themes" style="padding: 0 4px">
<el-tooltip content="字号" :effect="toolTip" placement="top">
<el-select
style="width: 56px"
:effect="themes"
v-model="state.indicatorValueForm.suffixFontSize"
:placeholder="t('chart.text_fontsize')"
size="small"
@change="changeTitleStyle('suffixFontSize')"
>
<el-option
v-for="option in fontSizeList"
:key="option.value"
:label="option.name"
:value="option.value"
/>
</el-select>
</el-tooltip>
</el-form-item>
<el-form-item class="form-item" :class="'form-item-' + themes" style="padding-left: 4px">
<el-form-item class="form-item" :class="'form-item-' + themes" :effect="themes">
<el-select
:disabled="!state.indicatorValueForm.suffixEnable"
:effect="themes"
v-model="state.indicatorValueForm.suffixLetterSpace"
:placeholder="t('chart.quota_letter_space')"
@change="changeTitleStyle('suffixLetterSpace')"
v-model="state.indicatorValueForm.suffixFontFamily"
:placeholder="t('chart.font_family')"
@change="changeTitleStyle('suffixFontFamily')"
>
<template #prefix>
<el-icon>
<Icon name="icon_letter-spacing_outlined" />
</el-icon>
</template>
<el-option
v-for="option in fontLetterSpace"
v-for="option in fontFamily"
:key="option.value"
:label="option.name"
:value="option.value"
/>
</el-select>
</el-form-item>
<div style="display: flex">
<el-form-item class="form-item" :class="'form-item-' + themes" style="padding-right: 4px">
<el-color-picker
:disabled="!state.indicatorValueForm.suffixEnable"
:effect="themes"
v-model="state.indicatorValueForm.suffixColor"
class="color-picker-style"
:predefine="predefineColors"
@change="changeTitleStyle('suffixColor')"
is-custom
/>
</el-form-item>
<el-form-item class="form-item" :class="'form-item-' + themes" style="padding: 0 4px">
<el-tooltip content="字号" :effect="toolTip" placement="top">
<el-select
:disabled="!state.indicatorValueForm.suffixEnable"
style="width: 56px"
:effect="themes"
v-model="state.indicatorValueForm.suffixFontSize"
:placeholder="t('chart.text_fontsize')"
size="small"
@change="changeTitleStyle('suffixFontSize')"
>
<el-option
v-for="option in fontSizeList"
:key="option.value"
:label="option.name"
:value="option.value"
/>
</el-select>
</el-tooltip>
</el-form-item>
<el-form-item class="form-item" :class="'form-item-' + themes" style="padding-left: 4px">
<el-select
size="small"
:disabled="!state.indicatorValueForm.suffixEnable"
:effect="themes"
v-model="state.indicatorValueForm.suffixLetterSpace"
:placeholder="t('chart.quota_letter_space')"
@change="changeTitleStyle('suffixLetterSpace')"
>
<template #prefix>
<el-icon>
<Icon name="icon_letter-spacing_outlined" />
</el-icon>
</template>
<el-option
v-for="option in fontLetterSpace"
:key="option.value"
:label="option.name"
:value="option.value"
/>
</el-select>
</el-form-item>
</div>
<el-space>
<el-form-item class="form-item" :class="'form-item-' + themes">
<el-checkbox
:disabled="!state.indicatorValueForm.suffixEnable"
:effect="themes"
class="icon-checkbox"
v-model="state.indicatorValueForm.suffixIsBolder"
@change="changeTitleStyle('suffixIsBolder')"
>
<el-tooltip :effect="toolTip" placement="top">
<template #content>
{{ t('chart.bolder') }}
</template>
<div
class="icon-btn"
:class="{
dark: themes === 'dark',
active: state.indicatorValueForm.suffixIsBolder
}"
>
<el-icon>
<Icon name="icon_bold_outlined" />
</el-icon>
</div>
</el-tooltip>
</el-checkbox>
</el-form-item>
<el-form-item class="form-item" :class="'form-item-' + themes">
<el-checkbox
:disabled="!state.indicatorValueForm.suffixEnable"
:effect="themes"
class="icon-checkbox"
v-model="state.indicatorValueForm.suffixIsItalic"
@change="changeTitleStyle('suffixIsItalic')"
>
<el-tooltip :effect="toolTip" placement="top">
<template #content>
{{ t('chart.italic') }}
</template>
<div
class="icon-btn"
:class="{
dark: themes === 'dark',
active: state.indicatorValueForm.suffixIsItalic
}"
>
<el-icon>
<Icon name="icon_italic_outlined" />
</el-icon>
</div>
</el-tooltip>
</el-checkbox>
</el-form-item>
</el-space>
<el-form-item class="form-item" :class="'form-item-' + themes">
<el-checkbox
:disabled="!state.indicatorValueForm.suffixEnable"
size="small"
:effect="themes"
v-model="state.indicatorValueForm.suffixFontShadow"
@change="changeTitleStyle('suffixFontShadow')"
>
{{ t('chart.font_shadow') }}
</el-checkbox>
</el-form-item>
</div>
<el-space>
<el-form-item class="form-item" :class="'form-item-' + themes">
<el-checkbox
:effect="themes"
class="icon-checkbox"
v-model="state.indicatorValueForm.suffixIsBolder"
@change="changeTitleStyle('suffixIsBolder')"
>
<el-tooltip :effect="toolTip" placement="top">
<template #content>
{{ t('chart.bolder') }}
</template>
<div
class="icon-btn"
:class="{
dark: themes === 'dark',
active: state.indicatorValueForm.suffixIsBolder
}"
>
<el-icon>
<Icon name="icon_bold_outlined" />
</el-icon>
</div>
</el-tooltip>
</el-checkbox>
</el-form-item>
<el-form-item class="form-item" :class="'form-item-' + themes">
<el-checkbox
:effect="themes"
class="icon-checkbox"
v-model="state.indicatorValueForm.suffixIsItalic"
@change="changeTitleStyle('suffixIsItalic')"
>
<el-tooltip :effect="toolTip" placement="top">
<template #content>
{{ t('chart.italic') }}
</template>
<div
class="icon-btn"
:class="{
dark: themes === 'dark',
active: state.indicatorValueForm.suffixIsItalic
}"
>
<el-icon>
<Icon name="icon_italic_outlined" />
</el-icon>
</div>
</el-tooltip>
</el-checkbox>
</el-form-item>
</el-space>
<el-form-item class="form-item" :class="'form-item-' + themes">
<el-checkbox
size="small"
:effect="themes"
v-model="state.indicatorValueForm.suffixFontShadow"
@change="changeTitleStyle('suffixFontShadow')"
>
{{ t('chart.font_shadow') }}
</el-checkbox>
</el-form-item>
</el-form>
</div>
</template>

View File

@ -359,6 +359,7 @@ export const DEFAULT_INDICATOR_STYLE: ChartIndicatorStyle = {
letterSpace: '0',
fontShadow: false,
suffixEnable: true,
suffix: '',
suffixFontSize: '14',
suffixColor: '#5470C6',

View File

@ -607,7 +607,7 @@ const iconSize = computed<string>(() => {
</template>
<div
class="icons-container"
:class="{ 'is-editing': titleEditStatus }"
:class="{ 'is-editing': titleEditStatus, 'icons-container__dark': themes === 'dark' }"
v-if="trackMenu.length > 0 || state.title_remark.show"
>
<el-tooltip :effect="toolTip" placement="top" v-if="state.title_remark.show">
@ -712,6 +712,10 @@ const iconSize = computed<string>(() => {
color: #646a73;
&.icons-container__dark {
color: #a6a6a6;
}
&.is-editing {
gap: 6px;
}

View File

@ -759,10 +759,6 @@ const getMenuList = (val: boolean) => {
height: calc(100vh - 56px);
overflow: auto;
position: relative;
&.h100 {
height: 100%;
}
}
.dataset-content {

View File

@ -1576,8 +1576,6 @@ const getMenuList = (val: boolean) => {
overflow: auto;
position: relative;
&.h100 {
height: 100%;
.datasource-table {
height: calc(100% - 140px);
}

@ -1 +1 @@
Subproject commit 2012e4fb3c3169330cc70b09e4e77d144b22031b
Subproject commit 19d1cc14aaa7ff5297ebe8f3b8ea3c706f164cc3

View File

@ -7,6 +7,9 @@ DE_RUNNING_BASE=${DE_BASE}/dataease2.0
need_init_apisix=false
compose_files="-f docker-compose.yml"
compose_cmd="docker-compose"
server_url=""
current_version=""
latest_version=""
set -a
source ${DE_RUNNING_BASE}/.env
@ -107,7 +110,84 @@ function _healthcheck() {
}
function _get_current_version() {
de_current_version=$(grep "^ image:.*dataease:" ${DE_RUNNING_BASE}/docker-compose.yml | awk -F'dataease:' '{print $2}')
echo $de_current_version
if test -z $de_current_version; then
echo "获取当前版本失败,请检查当前版本是否正确"
exit 1
fi
current_version=$de_current_version
}
function _get_available_server() {
git_urls=('github.com')
for git_url in ${git_urls[*]}; do
echo -ne "检测 ${git_url} ... "
curl -m 5 -kIs https://${git_url} >/dev/null
if [ $? != 0 ]; then
echo "failed"
else
echo "ok"
server_url=${git_url}
break
fi
done
}
function _get_latest_version() {
rm -f /tmp/de_latest_release
_get_available_server
if [[ "x${server_url}" == "x" ]];then
echo "无法连接版本服务器,请稍候重试"
exit 1
fi
if [[ -x "$(command -v python)" ]]; then
py_cmd='python'
elif [[ -x "$(command -v python3)" ]]; then
py_cmd='python3'
fi
$py_cmd - <<EOF
# -*- coding: UTF-8 -*-
import os
import json
import re
latest_release=""
release_pattern="v2\.\d+\.\d+$"
def get_releases(page):
try:
releases=os.popen("curl -s https://api.github.com/repos/dataease/dataease/releases?page=%d" % (page)).read()
releases=[ x["name"] for x in json.loads(releases) if x["prerelease"] == False ]
except Exception as e:
print(str(e))
print("Failed to obtain Release information, please check the network.")
exit(1)
else:
for release in releases:
if re.search(release_pattern,release) != None:
return release
page = 1
while (page <= 3):
latest_release = get_releases(page)
if (latest_release != "" and latest_release != None):
break
page += 1
if latest_release == None or latest_release == "":
print("Failed to obtain latest version, please try again.")
exit(1)
# 记录最新版本号
os.popen("echo "+latest_release+" > /tmp/de_latest_release")
EOF
if [ ! -f /tmp/de_latest_release ]; then
echo "获取最新版本失败,请检查网络连接是否正常"
exit 1
fi
latest_version=$(cat /tmp/de_latest_release)
}
function status() {
echo
@ -164,117 +244,26 @@ function reload() {
function version() {
echo
_get_current_version
_get_latest_version
echo "current version is $current_version"
echo "latest version is $latest_version"
}
function upgrade() {
echo
git_urls=('github.com')
if [[ -x "$(command -v python)" ]]; then
py_cmd='python'
elif [[ -x "$(command -v python3)" ]]; then
py_cmd='python3'
fi
version
for git_url in ${git_urls[*]}; do
success="true"
for i in {1..3}; do
echo -ne "检测 ${git_url} ... ${i} "
curl -m 5 -kIs https://${git_url} >/dev/null
if [ $? != 0 ]; then
echo "failed"
success="false"
break
else
echo "ok"
fi
done
if [[ ${success} == "true" ]]; then
server_url=${git_url}
break
fi
done
if [[ "x${server_url}" == "x" ]]; then
echo "没有找到稳定的下载服务器,请访问 https://community.fit2cloud.com/#/products/dataease/downloads 下载离线安装包"
exit 1
fi
if [[ "${server_url}" == "gitee.com" ]]; then
owner='fit2cloud-feizhiyun'
repo='DataEase'
else
owner='dataease'
repo='dataease'
fi
export DE_VERSION=$(_get_current_version)
if test -z $DE_VERSION; then
echo "获取当前版本失败,请检查当前版本是否正确"
exit 1
fi
echo "检测当前版本为${DE_VERSION}"
rm -f /tmp/de_latest_release
$py_cmd - <<EOF
# -*- coding: UTF-8 -*-
import os
import json
import re
latest_release=""
release_pattern=""
current_version="$DE_VERSION"
server_url="$server_url"
release_pattern="v2\.\d+\.\d+$"
def get_releases(page):
try:
if server_url == "gitee.com":
releases=os.popen("curl -s https://gitee.com/api/v5/repos/fit2cloud-feizhiyun/DataEase/releases?direction=desc&page=%d" % (page)).read()
else:
releases=os.popen("curl -s https://api.github.com/repos/dataease/dataease/releases?page=%d" % (page)).read()
releases=[ x["name"] for x in json.loads(releases) if x["prerelease"] == False ]
except Exception as e:
print(str(e))
print("Failed to obtain Release information, please check the network.")
exit(1)
else:
for release in releases:
if re.search(release_pattern,release) != None:
return release
page = 1
while (page <= 3):
latest_release = get_releases(page)
if (latest_release != "" and latest_release != None):
break
page += 1
if latest_release == None or latest_release == "":
print("Failed to obtain latest version, please try again.")
exit(1)
else:
print("latest version is %s" % (latest_release))
# 记录最新版本号
os.popen("echo "+latest_release+" > /tmp/de_latest_release")
EOF
if [ ! -f /tmp/de_latest_release ]; then
echo "获取最新版本失败,请检查网络连接是否正常"
exit 1
fi
latest_version=$(cat /tmp/de_latest_release)
if [ "${latest_version}" = "" ]; then
echo "未获取到最新版本"
exit 1
elif [ "${latest_version}" = "${DE_VERSION}" ]; then
elif [ "${latest_version}" = "${current_version}" ]; then
echo "最新版本与当前版本一致,退出升级过程"
exit 0
else
echo "检测到 ${server_url} 上最新版本为 ${latest_version} 即将执行在线升级..."
if [[ ! "$latest_version" =~ ^v2.* ]];then
echo "获取到的最新版本与当前版本不匹配,请访问 https://community.fit2cloud.com/#/products/dataease/downloads 下载离线安装包"
exit 1
else
echo "检测到 ${server_url} 上最新版本为 ${latest_version} 即将执行在线升级..."
fi
fi
sleep 2
@ -283,11 +272,11 @@ EOF
cd /tmp
installer_file="dataease-online-installer-${latest_version}.tar.gz"
download_url="https://${server_url}/${owner}/${repo}/releases/download/${latest_version}/$installer_file"
download_url="https://${server_url}/dataease/dataease/releases/download/${latest_version}/$installer_file"
curl -LOk -m 60 -o $installer_file $download_url
if [ $? -ne 0 ]; then
echo -e "\e[31m升级失败:连接下载服务器超时!\n可手动下载升级包然后执行\e[1;33m /bin/bash install.sh \e[0;31m离线升级也可以重新执行一次 dectl upgrade 命令。\e[0m"
return 2
exit 1
fi
if [ ! -f $installer_file ]; then

View File

@ -16,4 +16,8 @@ public class LogGridVO implements Serializable {
private String ip;
private Long time;
private boolean success;
private String msg;
}

View File

@ -152,4 +152,8 @@ public interface UserApi {
@Hidden
@GetMapping("/firstEchelon/{limit}")
List<Long> firstEchelon(@PathVariable("limit") Long limit);
@Hidden
@GetMapping("/queryByAccount")
CurUserVO queryByAccount(String account);
}

View File

@ -13,7 +13,9 @@ public @interface DeLog {
String pid() default "";
LogST st();
LogST st() default LogST.PANEL;
LogOT ot();
String stExp() default "";
}