forked from github/dataease
Merge remote-tracking branch 'origin/dev-v2' into dev-v2
This commit is contained in:
commit
c56d811259
3
.github/ISSUE_TEMPLATE/----.md
vendored
3
.github/ISSUE_TEMPLATE/----.md
vendored
@ -7,4 +7,7 @@ assignees: xuwei-fit2cloud, yayanpei-fit2cloud
|
||||
|
||||
---
|
||||
|
||||
DataEase 版本:
|
||||
|
||||
|
||||
**请描述您的需求或者改进建议.**
|
||||
|
2
.github/ISSUE_TEMPLATE/bug---.md
vendored
2
.github/ISSUE_TEMPLATE/bug---.md
vendored
@ -3,7 +3,7 @@ name: Bug 提交
|
||||
about: 提交产品缺陷帮助我们更好的改进
|
||||
title: "[Bug]"
|
||||
labels: 状态:待处理
|
||||
assignees: BBchicken-9527, Shenguobin0102, zrfit
|
||||
assignees: BBchicken-9527, Shenguobin0102
|
||||
|
||||
---
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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",
|
||||
|
@ -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>
|
||||
|
@ -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')"
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -1102,7 +1102,7 @@ export default {
|
||||
select_year: '选择年',
|
||||
sql_variable_limit_1: '1、SQL 变量只能在 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: '选择时间',
|
||||
|
@ -44,6 +44,7 @@ declare interface ChartIndicatorStyle {
|
||||
letterSpace: string
|
||||
fontShadow: boolean
|
||||
|
||||
suffixEnable: boolean
|
||||
suffix: string
|
||||
suffixFontSize: string
|
||||
suffixColor: string
|
||||
|
@ -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')"
|
||||
|
@ -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>
|
||||
|
@ -359,6 +359,7 @@ export const DEFAULT_INDICATOR_STYLE: ChartIndicatorStyle = {
|
||||
letterSpace: '0',
|
||||
fontShadow: false,
|
||||
|
||||
suffixEnable: true,
|
||||
suffix: '',
|
||||
suffixFontSize: '14',
|
||||
suffixColor: '#5470C6',
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -759,10 +759,6 @@ const getMenuList = (val: boolean) => {
|
||||
height: calc(100vh - 56px);
|
||||
overflow: auto;
|
||||
position: relative;
|
||||
|
||||
&.h100 {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.dataset-content {
|
||||
|
@ -1576,8 +1576,6 @@ const getMenuList = (val: boolean) => {
|
||||
overflow: auto;
|
||||
position: relative;
|
||||
&.h100 {
|
||||
height: 100%;
|
||||
|
||||
.datasource-table {
|
||||
height: calc(100% - 140px);
|
||||
}
|
||||
|
2
de-xpack
2
de-xpack
@ -1 +1 @@
|
||||
Subproject commit 2012e4fb3c3169330cc70b09e4e77d144b22031b
|
||||
Subproject commit 19d1cc14aaa7ff5297ebe8f3b8ea3c706f164cc3
|
199
installer/dectl
199
installer/dectl
@ -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
|
||||
|
@ -16,4 +16,8 @@ public class LogGridVO implements Serializable {
|
||||
private String ip;
|
||||
|
||||
private Long time;
|
||||
|
||||
private boolean success;
|
||||
|
||||
private String msg;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -13,7 +13,9 @@ public @interface DeLog {
|
||||
|
||||
String pid() default "";
|
||||
|
||||
LogST st();
|
||||
LogST st() default LogST.PANEL;
|
||||
|
||||
LogOT ot();
|
||||
|
||||
String stExp() default "";
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user