forked from github/dataease
Merge branch 'dev-v2' into pr@dev-v2_query_com
This commit is contained in:
commit
918da1e1ef
@ -43,10 +43,9 @@ public class SqlparserUtils {
|
||||
}
|
||||
|
||||
SqlParser.Config config =
|
||||
SqlParser.configBuilder()
|
||||
.setLex(Lex.JAVA)
|
||||
.setIdentifierMaxLength(256)
|
||||
.build();
|
||||
SqlParser.config()
|
||||
.withLex(Lex.JAVA)
|
||||
.withIdentifierMaxLength(256);
|
||||
SqlParser sqlParser = SqlParser.create(tmpSql, config);
|
||||
SqlNode sqlNode;
|
||||
try {
|
||||
|
@ -21,10 +21,9 @@ public class SqlUtils {
|
||||
}
|
||||
|
||||
SqlParser.Config config =
|
||||
SqlParser.configBuilder()
|
||||
.setLex(Lex.JAVA)
|
||||
.setIdentifierMaxLength(256)
|
||||
.build();
|
||||
SqlParser.config()
|
||||
.withLex(Lex.JAVA)
|
||||
.withIdentifierMaxLength(256);
|
||||
// 创建解析器
|
||||
SqlParser sqlParser = SqlParser
|
||||
.create(sql, config);
|
||||
|
@ -73,7 +73,7 @@ public class SQLConstants {
|
||||
|
||||
public static final String DEFAULT_INT_FORMAT = "DECIMAL(18,0)";
|
||||
|
||||
public static final String DEFAULT_FLOAT_FORMAT = "DECIMAL(27,8)";
|
||||
public static final String DEFAULT_FLOAT_FORMAT = "DECIMAL(26,8)";
|
||||
|
||||
public static final String WHERE_VALUE_NULL = "(NULL,'')";
|
||||
|
||||
|
@ -101,6 +101,7 @@ public class DataVisualizationServer implements DataVisualizationApi {
|
||||
}
|
||||
}
|
||||
|
||||
@DeLog(id = "#p0", ot = LogOT.READ, stExp = "#p1")
|
||||
@Override
|
||||
@XpackInteract(value = "dataVisualizationServer", original = true)
|
||||
public DataVisualizationVO findById(Long dvId, String busiFlag) {
|
||||
|
@ -1,3 +1,3 @@
|
||||
# 接口前缀
|
||||
VITE_API_BASEPATH="/de2api"
|
||||
VITE_API_BASEPATH="./de2api"
|
||||
VITE_VERSION="0.0.0"
|
||||
|
@ -232,6 +232,7 @@ const {
|
||||
} = toRefs(props)
|
||||
const domId = ref('shape-id-' + element.value.id)
|
||||
const pointList = ['lt', 't', 'rt', 'r', 'rb', 'b', 'lb', 'l']
|
||||
const pointCorner = ['lt', 'rt', 'rb', 'lb']
|
||||
const pointList2 = ['r', 'l']
|
||||
const initialAngle = {
|
||||
// 每个点对应的初始角度
|
||||
@ -608,6 +609,7 @@ const handleMouseDownOnPoint = (point, e) => {
|
||||
let isFirst = true
|
||||
|
||||
const needLockProportion = isNeedLockProportion()
|
||||
const originRadio = curComponent.value.style.width / curComponent.value.style.height
|
||||
const move = moveEvent => {
|
||||
// 第一次点击时也会触发 move,所以会有“刚点击组件但未移动,组件的大小却改变了”的情况发生
|
||||
// 因此第一次点击时不触发 move 事件
|
||||
@ -628,6 +630,27 @@ const handleMouseDownOnPoint = (point, e) => {
|
||||
})
|
||||
//Temp dataV坐标偏移
|
||||
offsetDataVAdaptor(style, point)
|
||||
// 保持宽搞比例调整
|
||||
if (curComponent.value.maintainRadio) {
|
||||
// 高度偏移量
|
||||
const heightOffset = style.height - defaultStyle.value.height
|
||||
// 宽度偏移量
|
||||
const widthOffset = style.width - defaultStyle.value.width
|
||||
// 保持宽高比例是相对宽度偏移量
|
||||
const adaptorWidthOffset = heightOffset * originRadio
|
||||
// 保持宽高比例是相对高度偏移量
|
||||
const adaptorHeightOffset = widthOffset / originRadio
|
||||
if (pointCorner.includes(point)) {
|
||||
style.height = defaultStyle.value.height + adaptorHeightOffset
|
||||
} else if (Math.abs(widthOffset) > Math.abs(adaptorWidthOffset)) {
|
||||
// 调整高度
|
||||
style.height = defaultStyle.value.height + adaptorHeightOffset
|
||||
} else {
|
||||
// 调整宽度
|
||||
style.width = defaultStyle.value.width + adaptorWidthOffset
|
||||
}
|
||||
}
|
||||
|
||||
dvMainStore.setShapeStyle(style)
|
||||
// 矩阵逻辑 如果当前是仪表板(矩阵模式)则要进行矩阵重排
|
||||
dashboardActive.value && emit('onResizing', moveEvent)
|
||||
|
@ -17,6 +17,17 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-form-item class="form-item" :class="'form-item-' + themes">
|
||||
<el-checkbox
|
||||
v-if="curComponent"
|
||||
size="small"
|
||||
:effect="themes"
|
||||
v-model="curComponent['maintainRadio']"
|
||||
@change="maintainRadioChange"
|
||||
>
|
||||
保持宽高比
|
||||
</el-checkbox>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
|
||||
@ -71,9 +82,19 @@ const onPositionChange = key => {
|
||||
if (!positionMounted.value[key]) {
|
||||
positionMounted.value[key] = 0
|
||||
}
|
||||
const originRadio = curComponent.value.style.width / curComponent.value.style.height
|
||||
curComponent.value.style[key] = Math.round(
|
||||
(positionMounted.value[key] * canvasStyleData.value.scale) / 100
|
||||
)
|
||||
if (curComponent.value.maintainRadio) {
|
||||
if (key === 'width') {
|
||||
curComponent.value.style['height'] = curComponent.value.style['width'] / originRadio
|
||||
positionMounted.value['height'] = Math.round(positionMounted.value['width'] / originRadio)
|
||||
} else if (key === 'height') {
|
||||
curComponent.value.style['width'] = curComponent.value.style['height'] * originRadio
|
||||
positionMounted.value['width'] = Math.round(positionMounted.value['height'] * originRadio)
|
||||
}
|
||||
}
|
||||
|
||||
if (curComponent.value.component === 'Group') {
|
||||
//如果当前组件是Group分组 则要进行内部组件深度计算
|
||||
@ -84,6 +105,10 @@ const onPositionChange = key => {
|
||||
snapshotStore.recordSnapshotCache()
|
||||
}
|
||||
|
||||
const maintainRadioChange = () => {
|
||||
snapshotStore.recordSnapshotCache()
|
||||
}
|
||||
|
||||
const positionInit = () => {
|
||||
if (curComponent.value) {
|
||||
Object.keys(positionMounted.value).forEach(key => {
|
||||
|
@ -104,7 +104,7 @@ service.interceptors.request.use(
|
||||
config.data = qs.stringify(config.data)
|
||||
}
|
||||
if (embeddedStore.baseUrl) {
|
||||
config.baseURL = embeddedStore.baseUrl + 'de2api/'
|
||||
config.baseURL = PATH_URL
|
||||
}
|
||||
|
||||
if (linkStore.getLinkToken) {
|
||||
|
@ -58,6 +58,7 @@ export const commonAttr = {
|
||||
events: {},
|
||||
groupStyle: {}, // 当一个组件成为 Group 的子组件时使用
|
||||
isLock: false, // 是否锁定组件
|
||||
maintainRadio: false, // 布局时保持宽高比例
|
||||
isShow: true, // 是否显示组件
|
||||
collapseName: ['position', 'background', 'style', 'picture'], // 编辑组件时记录当前使用的是哪个折叠面板,再次回来时恢复上次打开的折叠面板,优化用户体验
|
||||
linkage: {
|
||||
|
@ -12,6 +12,7 @@ import {
|
||||
DEFAULT_INDICATOR_STYLE
|
||||
} from '@/views/chart/components/editor/util/chart'
|
||||
import { valueFormatter } from '@/views/chart/components/js/formatter'
|
||||
import { hexColorToRGBA } from '@/views/chart/components/js/util'
|
||||
|
||||
const props = defineProps({
|
||||
view: {
|
||||
@ -222,15 +223,21 @@ const renderChart = async view => {
|
||||
if (!view) {
|
||||
return
|
||||
}
|
||||
|
||||
const TEMP_DEFAULT_CHART = cloneDeep(BASE_VIEW_CONFIG)
|
||||
delete TEMP_DEFAULT_CHART.customAttr.basicStyle.alpha
|
||||
|
||||
const chart = deepCopy({
|
||||
...defaultsDeep(view, cloneDeep(BASE_VIEW_CONFIG)),
|
||||
...defaultsDeep(view, TEMP_DEFAULT_CHART),
|
||||
data: chartData.value
|
||||
})
|
||||
|
||||
recursionTransObj(customAttrTrans, chart.customAttr, scale.value, terminal.value)
|
||||
recursionTransObj(customStyleTrans, chart.customStyle, scale.value, terminal.value)
|
||||
|
||||
if (chart.customAttr) {
|
||||
const customAttr = chart.customAttr
|
||||
|
||||
if (customAttr.indicator) {
|
||||
switch (customAttr.indicator.hPosition) {
|
||||
case 'left':
|
||||
@ -254,6 +261,15 @@ const renderChart = async view => {
|
||||
}
|
||||
|
||||
indicatorColor.value = customAttr.indicator.color
|
||||
let suffixColor = customAttr.indicator.suffixColor
|
||||
|
||||
if (customAttr.basicStyle && customAttr.basicStyle.alpha !== undefined) {
|
||||
indicatorColor.value = hexColorToRGBA(
|
||||
customAttr.basicStyle.colors[0],
|
||||
customAttr.basicStyle.alpha
|
||||
)
|
||||
suffixColor = hexColorToRGBA(customAttr.basicStyle.colors[1], customAttr.basicStyle.alpha)
|
||||
}
|
||||
|
||||
indicatorClass.value = {
|
||||
color: thresholdColor.value,
|
||||
@ -270,7 +286,7 @@ const renderChart = async view => {
|
||||
}
|
||||
|
||||
indicatorSuffixClass.value = {
|
||||
color: customAttr.indicator.suffixColor,
|
||||
color: suffixColor,
|
||||
'font-size': customAttr.indicator.suffixFontSize + 'px',
|
||||
'font-family': defaultTo(
|
||||
CHART_CONT_FAMILY_MAP[customAttr.indicator.suffixFontFamily],
|
||||
@ -287,9 +303,15 @@ const renderChart = async view => {
|
||||
suffixContent.value = defaultTo(customAttr.indicator.suffix, '')
|
||||
}
|
||||
if (customAttr.indicatorName && customAttr.indicatorName.show) {
|
||||
let nameColor = customAttr.indicatorName.color
|
||||
|
||||
if (customAttr.basicStyle && customAttr.basicStyle.alpha !== undefined) {
|
||||
nameColor = hexColorToRGBA(customAttr.basicStyle.colors[2], customAttr.basicStyle.alpha)
|
||||
}
|
||||
|
||||
indicatorNameShow.value = true
|
||||
indicatorNameClass.value = {
|
||||
color: customAttr.indicatorName.color,
|
||||
color: nameColor,
|
||||
'font-size': customAttr.indicatorName.fontSize + 'px',
|
||||
'font-family': defaultTo(
|
||||
CHART_CONT_FAMILY_MAP[customAttr.indicatorName.fontFamily],
|
||||
|
@ -44,7 +44,7 @@ onMounted(() => {
|
||||
popper-class="toolbox-top-popover"
|
||||
placement="bottom-end"
|
||||
width="208"
|
||||
trigger="click"
|
||||
trigger="hover"
|
||||
>
|
||||
<top-doc-card
|
||||
:span="12"
|
||||
|
@ -2133,7 +2133,8 @@ export default {
|
||||
autoCreateUser: '第三方自动创建用户',
|
||||
dsIntervalTime: '数据源检测时间间隔',
|
||||
dsExecuteTime: '数据源检测频率',
|
||||
frontTimeOut: '请求超时时间(秒)'
|
||||
frontTimeOut: '请求超时时间(秒)',
|
||||
logLiveTime: '日志保留时间(天)'
|
||||
},
|
||||
template_manage: {
|
||||
name_already_exists_type: '分类名称已存在',
|
||||
|
@ -115,6 +115,7 @@ export function initCanvasDataPrepare(dvId, busiFlag, callBack) {
|
||||
if (componentItem.component === 'Group') {
|
||||
componentItem.expand = componentItem.expand || false
|
||||
}
|
||||
componentItem['maintainRadio'] = componentItem['maintainRadio'] || false
|
||||
})
|
||||
const curPreviewGap =
|
||||
dvInfo.type === 'dashboard' && canvasStyleResult['dashboard'].gap === 'yes'
|
||||
|
@ -1,6 +1,6 @@
|
||||
<script lang="ts" setup>
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { PropType, toRefs, nextTick, watch } from 'vue'
|
||||
import { PropType, toRefs, nextTick, watch, ref } from 'vue'
|
||||
import MiscSelector from '@/views/chart/components/editor/editor-style/components/MiscSelector.vue'
|
||||
import LabelSelector from '@/views/chart/components/editor/editor-style/components/LabelSelector.vue'
|
||||
import TooltipSelector from '@/views/chart/components/editor/editor-style/components/TooltipSelector.vue'
|
||||
@ -90,6 +90,9 @@ const emit = defineEmits([
|
||||
'onIndicatorNameChange'
|
||||
])
|
||||
|
||||
const indicatorValueRef = ref()
|
||||
const indicatorNameRef = ref()
|
||||
|
||||
const showProperties = (property: EditorProperty) => properties.value?.includes(property)
|
||||
|
||||
const onMiscChange = (val, prop) => {
|
||||
@ -117,11 +120,19 @@ const onTextChange = (val, prop) => {
|
||||
}
|
||||
|
||||
const onIndicatorChange = (val, prop) => {
|
||||
state.initReady && emit('onIndicatorChange', val, prop)
|
||||
const value = { indicatorValue: val, indicatorName: undefined }
|
||||
if (prop === 'color' || prop === 'suffixColor') {
|
||||
value.indicatorName = indicatorNameRef.value?.getFormData()
|
||||
}
|
||||
state.initReady && emit('onIndicatorChange', value, prop)
|
||||
}
|
||||
|
||||
const onIndicatorNameChange = (val, prop) => {
|
||||
state.initReady && emit('onIndicatorNameChange', val, prop)
|
||||
const value = { indicatorName: val, indicatorValue: undefined }
|
||||
if (prop === 'color') {
|
||||
value.indicatorValue = indicatorValueRef.value?.getFormData()
|
||||
}
|
||||
state.initReady && emit('onIndicatorNameChange', value, prop)
|
||||
}
|
||||
|
||||
const onLegendChange = (val, prop) => {
|
||||
@ -243,6 +254,7 @@ watch(
|
||||
title="指标值"
|
||||
>
|
||||
<indicator-value-selector
|
||||
ref="indicatorValueRef"
|
||||
:property-inner="propertyInnerAll['indicator-value-selector']"
|
||||
:themes="themes"
|
||||
class="attr-selector"
|
||||
@ -261,6 +273,7 @@ watch(
|
||||
name="indicator-name"
|
||||
>
|
||||
<indicator-name-selector
|
||||
ref="indicatorNameRef"
|
||||
:property-inner="propertyInnerAll['indicator-name-selector']"
|
||||
:themes="themes"
|
||||
class="attr-selector"
|
||||
|
@ -5,13 +5,15 @@ import {
|
||||
COLOR_PANEL,
|
||||
CHART_FONT_FAMILY,
|
||||
CHART_FONT_LETTER_SPACE,
|
||||
DEFAULT_INDICATOR_NAME_STYLE
|
||||
DEFAULT_INDICATOR_NAME_STYLE,
|
||||
DEFAULT_BASIC_STYLE
|
||||
} from '@/views/chart/components/editor/util/chart'
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { cloneDeep, defaultsDeep } from 'lodash-es'
|
||||
import { ElButton, ElIcon } from 'element-plus-secondary'
|
||||
import Icon from '@/components/icon-custom/src/Icon.vue'
|
||||
import { hexColorToRGBA } from '@/views/chart/components/js/util'
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const { batchOptStatus } = storeToRefs(dvMainStore)
|
||||
|
||||
@ -40,7 +42,8 @@ const fontFamily = CHART_FONT_FAMILY
|
||||
const fontLetterSpace = CHART_FONT_LETTER_SPACE
|
||||
|
||||
const state = reactive({
|
||||
indicatorNameForm: JSON.parse(JSON.stringify(DEFAULT_INDICATOR_NAME_STYLE))
|
||||
indicatorNameForm: JSON.parse(JSON.stringify(DEFAULT_INDICATOR_NAME_STYLE)),
|
||||
basicStyleForm: {} as ChartBasicStyle
|
||||
})
|
||||
|
||||
const { chart } = toRefs(props)
|
||||
@ -61,11 +64,25 @@ const changeTitleStyle = prop => {
|
||||
}
|
||||
|
||||
const init = () => {
|
||||
const TEMP_DEFAULT_BASIC_STYLE = cloneDeep(DEFAULT_BASIC_STYLE)
|
||||
delete TEMP_DEFAULT_BASIC_STYLE.alpha
|
||||
|
||||
state.basicStyleForm = defaultsDeep(
|
||||
cloneDeep(props.chart?.customAttr?.basicStyle),
|
||||
cloneDeep(TEMP_DEFAULT_BASIC_STYLE)
|
||||
)
|
||||
|
||||
const customText = defaultsDeep(
|
||||
cloneDeep(props.chart?.customAttr?.indicatorName),
|
||||
cloneDeep(DEFAULT_INDICATOR_NAME_STYLE)
|
||||
)
|
||||
|
||||
if (state.basicStyleForm.alpha !== undefined) {
|
||||
const color = hexColorToRGBA(state.basicStyleForm.colors[2], state.basicStyleForm.alpha)
|
||||
|
||||
customText.color = color
|
||||
}
|
||||
|
||||
state.indicatorNameForm = cloneDeep(customText)
|
||||
|
||||
//第一次颜色可能赋值失败,单独赋值一次
|
||||
@ -85,6 +102,12 @@ watch(
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
function getFormData() {
|
||||
return state.indicatorNameForm
|
||||
}
|
||||
|
||||
defineExpose({ getFormData })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -125,6 +148,7 @@ watch(
|
||||
:predefine="predefineColors"
|
||||
@change="changeTitleStyle('color')"
|
||||
is-custom
|
||||
show-alpha
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="form-item" :class="'form-item-' + themes" style="padding: 0 4px">
|
||||
|
@ -5,13 +5,15 @@ import {
|
||||
COLOR_PANEL,
|
||||
CHART_FONT_FAMILY,
|
||||
CHART_FONT_LETTER_SPACE,
|
||||
DEFAULT_INDICATOR_STYLE
|
||||
DEFAULT_INDICATOR_STYLE,
|
||||
DEFAULT_BASIC_STYLE
|
||||
} from '@/views/chart/components/editor/util/chart'
|
||||
import { dvMainStoreWithOut } from '@/store/modules/data-visualization/dvMain'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { cloneDeep, defaultsDeep } from 'lodash-es'
|
||||
import { ElButton, ElIcon, ElInput } from 'element-plus-secondary'
|
||||
import Icon from '@/components/icon-custom/src/Icon.vue'
|
||||
import { hexColorToRGBA } from '@/views/chart/components/js/util'
|
||||
const dvMainStore = dvMainStoreWithOut()
|
||||
const { batchOptStatus } = storeToRefs(dvMainStore)
|
||||
|
||||
@ -31,7 +33,7 @@ const props = defineProps({
|
||||
}
|
||||
})
|
||||
|
||||
const emit = defineEmits(['onIndicatorChange'])
|
||||
const emit = defineEmits(['onIndicatorChange', 'onBasicStyleChange'])
|
||||
const toolTip = computed(() => {
|
||||
return props.themes === 'dark' ? 'ndark' : 'dark'
|
||||
})
|
||||
@ -40,7 +42,8 @@ const fontFamily = CHART_FONT_FAMILY
|
||||
const fontLetterSpace = CHART_FONT_LETTER_SPACE
|
||||
|
||||
const state = reactive({
|
||||
indicatorValueForm: JSON.parse(JSON.stringify(DEFAULT_INDICATOR_STYLE))
|
||||
indicatorValueForm: JSON.parse(JSON.stringify(DEFAULT_INDICATOR_STYLE)),
|
||||
basicStyleForm: {} as ChartBasicStyle
|
||||
})
|
||||
|
||||
const { chart } = toRefs(props)
|
||||
@ -61,11 +64,27 @@ const changeTitleStyle = prop => {
|
||||
}
|
||||
|
||||
const init = () => {
|
||||
const TEMP_DEFAULT_BASIC_STYLE = cloneDeep(DEFAULT_BASIC_STYLE)
|
||||
delete TEMP_DEFAULT_BASIC_STYLE.alpha
|
||||
|
||||
state.basicStyleForm = defaultsDeep(
|
||||
cloneDeep(props.chart?.customAttr?.basicStyle),
|
||||
cloneDeep(TEMP_DEFAULT_BASIC_STYLE)
|
||||
)
|
||||
|
||||
const customText = defaultsDeep(
|
||||
cloneDeep(props.chart?.customAttr?.indicator),
|
||||
cloneDeep(DEFAULT_INDICATOR_STYLE)
|
||||
)
|
||||
|
||||
if (state.basicStyleForm.alpha !== undefined) {
|
||||
const color = hexColorToRGBA(state.basicStyleForm.colors[0], state.basicStyleForm.alpha)
|
||||
const suffixColor = hexColorToRGBA(state.basicStyleForm.colors[1], state.basicStyleForm.alpha)
|
||||
|
||||
customText.color = color
|
||||
customText.suffixColor = suffixColor
|
||||
}
|
||||
|
||||
state.indicatorValueForm = cloneDeep(customText)
|
||||
|
||||
//第一次颜色可能赋值失败,单独赋值一次
|
||||
@ -86,6 +105,12 @@ watch(
|
||||
},
|
||||
{ deep: true }
|
||||
)
|
||||
|
||||
function getFormData() {
|
||||
return state.indicatorValueForm
|
||||
}
|
||||
|
||||
defineExpose({ getFormData })
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -125,6 +150,7 @@ watch(
|
||||
class="color-picker-style"
|
||||
:predefine="predefineColors"
|
||||
@change="changeTitleStyle('color')"
|
||||
show-alpha
|
||||
is-custom
|
||||
/>
|
||||
</el-form-item>
|
||||
@ -410,6 +436,7 @@ watch(
|
||||
:predefine="predefineColors"
|
||||
@change="changeTitleStyle('suffixColor')"
|
||||
is-custom
|
||||
show-alpha
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item class="form-item" :class="'form-item-' + themes" style="padding: 0 4px">
|
||||
|
@ -691,13 +691,25 @@ const onLabelChange = val => {
|
||||
renderChart(view.value)
|
||||
}
|
||||
|
||||
const onIndicatorChange = val => {
|
||||
view.value.customAttr.indicator = val
|
||||
const onIndicatorChange = (val, prop) => {
|
||||
if (prop === 'color' || prop === 'suffixColor') {
|
||||
view.value.customAttr.basicStyle.alpha = undefined
|
||||
if (val.indicatorName !== undefined) {
|
||||
view.value.customAttr.indicatorName = val.indicatorName
|
||||
}
|
||||
}
|
||||
view.value.customAttr.indicator = val.indicatorValue
|
||||
renderChart(view.value)
|
||||
}
|
||||
|
||||
const onIndicatorNameChange = val => {
|
||||
view.value.customAttr.indicatorName = val
|
||||
const onIndicatorNameChange = (val, prop) => {
|
||||
if (prop === 'color') {
|
||||
view.value.customAttr.basicStyle.alpha = undefined
|
||||
if (val.indicatorValue !== undefined) {
|
||||
view.value.customAttr.indicator = val.indicatorValue
|
||||
}
|
||||
}
|
||||
view.value.customAttr.indicatorName = val.indicatorName
|
||||
renderChart(view.value)
|
||||
}
|
||||
|
||||
|
@ -354,7 +354,7 @@ export const DEFAULT_TITLE_STYLE: ChartTextStyle = {
|
||||
export const DEFAULT_INDICATOR_STYLE: ChartIndicatorStyle = {
|
||||
show: true,
|
||||
fontSize: '20',
|
||||
color: '#5470C6',
|
||||
color: '#5470C6ff',
|
||||
hPosition: 'center',
|
||||
vPosition: 'center',
|
||||
isItalic: false,
|
||||
@ -366,7 +366,7 @@ export const DEFAULT_INDICATOR_STYLE: ChartIndicatorStyle = {
|
||||
suffixEnable: true,
|
||||
suffix: '',
|
||||
suffixFontSize: '14',
|
||||
suffixColor: '#5470C6',
|
||||
suffixColor: '#5470C6ff',
|
||||
suffixIsItalic: false,
|
||||
suffixIsBolder: true,
|
||||
suffixFontFamily: 'Microsoft YaHei',
|
||||
@ -376,7 +376,7 @@ export const DEFAULT_INDICATOR_STYLE: ChartIndicatorStyle = {
|
||||
export const DEFAULT_INDICATOR_NAME_STYLE: ChartIndicatorNameStyle = {
|
||||
show: true,
|
||||
fontSize: '18',
|
||||
color: '#ffffff',
|
||||
color: '#ffffffff',
|
||||
isItalic: false,
|
||||
isBolder: true,
|
||||
fontFamily: 'Microsoft YaHei',
|
||||
|
@ -319,13 +319,13 @@ function customCalcFunc(query, data, totalCfgMap) {
|
||||
const result = minBy(data, n => {
|
||||
return n[query[EXTRA_FIELD]]
|
||||
})
|
||||
return result[query[EXTRA_FIELD]]
|
||||
return result?.[query[EXTRA_FIELD]]
|
||||
}
|
||||
case 'MAX': {
|
||||
const result = maxBy(data, n => {
|
||||
return n[query[EXTRA_FIELD]]
|
||||
})
|
||||
return result[query[EXTRA_FIELD]]
|
||||
return result?.[query[EXTRA_FIELD]]
|
||||
}
|
||||
default: {
|
||||
return data.reduce((p, n) => {
|
||||
|
@ -30,7 +30,7 @@
|
||||
</div>
|
||||
|
||||
<div class="auth-root-class">
|
||||
<el-button size="small" type="primary" @click="refresh">{{
|
||||
<el-button size="small" type="primary" @click="refresh(pwdForm)">{{
|
||||
t('pblink.sure_bt')
|
||||
}}</el-button>
|
||||
</div>
|
||||
@ -71,20 +71,30 @@ const rule = reactive<FormRules>({
|
||||
]
|
||||
})
|
||||
|
||||
const refresh = () => {
|
||||
const curLocation = window.location.href
|
||||
const paramIndex = curLocation.indexOf('?')
|
||||
const uuidIndex = curLocation.indexOf('de-link/') + 8
|
||||
const uuid = curLocation.substring(uuidIndex, paramIndex !== -1 ? paramIndex : curLocation.length)
|
||||
const pwd = form.value.password
|
||||
const text = uuid + pwd
|
||||
const ciphertext = rsaEncryp(text)
|
||||
request.post({ url: '/share/validate', data: { ciphertext } }).then(res => {
|
||||
if (res.data) {
|
||||
wsCache.set(`link-${uuid}`, ciphertext)
|
||||
window.location.reload()
|
||||
const refresh = async (formEl: FormInstance | undefined) => {
|
||||
if (!formEl) return
|
||||
await formEl.validate((valid, fields) => {
|
||||
if (valid) {
|
||||
const curLocation = window.location.href
|
||||
const paramIndex = curLocation.indexOf('?')
|
||||
const uuidIndex = curLocation.indexOf('de-link/') + 8
|
||||
const uuid = curLocation.substring(
|
||||
uuidIndex,
|
||||
paramIndex !== -1 ? paramIndex : curLocation.length
|
||||
)
|
||||
const pwd = form.value.password
|
||||
const text = uuid + pwd
|
||||
const ciphertext = rsaEncryp(text)
|
||||
request.post({ url: '/share/validate', data: { ciphertext } }).then(res => {
|
||||
if (res.data) {
|
||||
wsCache.set(`link-${uuid}`, ciphertext)
|
||||
window.location.reload()
|
||||
} else {
|
||||
msg.value = '密码错误'
|
||||
}
|
||||
})
|
||||
} else {
|
||||
msg.value = '密码错误'
|
||||
console.error('error submit!', fields)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -186,8 +186,13 @@ const enableSwitcher = () => {
|
||||
}
|
||||
|
||||
const formatLinkAddr = () => {
|
||||
const href = window.location.href
|
||||
const prefix = href.substring(0, href.indexOf('#') + 1)
|
||||
let prefix = '/'
|
||||
if (window.DataEaseBi?.baseUrl) {
|
||||
prefix = window.DataEaseBi.baseUrl + '#'
|
||||
} else {
|
||||
const href = window.location.href
|
||||
prefix = href.substring(0, href.indexOf('#') + 1)
|
||||
}
|
||||
linkAddr.value = prefix + SHARE_BASE + state.detailInfo.uuid
|
||||
}
|
||||
|
||||
|
@ -190,8 +190,13 @@ const enableSwitcher = () => {
|
||||
}
|
||||
|
||||
const formatLinkAddr = () => {
|
||||
const href = window.location.href
|
||||
const prefix = href.substring(0, href.indexOf('#') + 1)
|
||||
let prefix = '/'
|
||||
if (window.DataEaseBi?.baseUrl) {
|
||||
prefix = window.DataEaseBi.baseUrl + '#'
|
||||
} else {
|
||||
const href = window.location.href
|
||||
prefix = href.substring(0, href.indexOf('#') + 1)
|
||||
}
|
||||
linkAddr.value = prefix + SHARE_BASE + state.detailInfo.uuid
|
||||
}
|
||||
|
||||
|
@ -102,6 +102,15 @@ const closeLoading = () => {
|
||||
const edit = list => {
|
||||
state.settingList = list.map(item => {
|
||||
const pkey = item.pkey
|
||||
if (pkey === 'basic.logLiveTime') {
|
||||
rule[pkey.split('.')[1]] = [
|
||||
{
|
||||
required: true,
|
||||
message: t('common.require'),
|
||||
trigger: ['blur', 'change']
|
||||
}
|
||||
]
|
||||
}
|
||||
item['label'] = `setting_${pkey}`
|
||||
item['pkey'] = pkey.split('.')[1]
|
||||
let pval = item.pval
|
||||
@ -171,13 +180,26 @@ defineExpose({
|
||||
v-model="state.form.frontTimeOut"
|
||||
autocomplete="off"
|
||||
step-strictly
|
||||
class="text-left"
|
||||
class="text-left edit-all-line"
|
||||
:min="1"
|
||||
:placeholder="t('common.inputText')"
|
||||
controls-position="right"
|
||||
type="number"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="item.pkey === 'logLiveTime'">
|
||||
<el-input-number
|
||||
v-model="state.form[item.pkey]"
|
||||
autocomplete="off"
|
||||
step-strictly
|
||||
class="text-left edit-all-line"
|
||||
:min="1"
|
||||
:max="4000"
|
||||
:placeholder="t('common.inputText')"
|
||||
controls-position="right"
|
||||
type="number"
|
||||
/>
|
||||
</div>
|
||||
<v-else />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
@ -215,6 +237,9 @@ defineExpose({
|
||||
.is-error {
|
||||
margin-bottom: 40px !important;
|
||||
}
|
||||
.edit-all-line {
|
||||
width: 552px !important;
|
||||
}
|
||||
}
|
||||
.setting-hidden-item {
|
||||
display: none !important;
|
||||
|
@ -45,7 +45,6 @@ const search = cb => {
|
||||
item.pval = item.pval
|
||||
}
|
||||
item.pkey = 'setting_' + item.pkey
|
||||
console.log(item.pkey)
|
||||
state.templateList.push(item)
|
||||
}
|
||||
cb && cb()
|
||||
|
2
de-xpack
2
de-xpack
@ -1 +1 @@
|
||||
Subproject commit 4889ffa0fcdfebe2755f5f1ce3b371e858abc981
|
||||
Subproject commit 25c0bb1ec2569f54aed498da03732637cbdda727
|
@ -1,43 +1,17 @@
|
||||
#!/bin/bash
|
||||
# chkconfig: 2345 10 90
|
||||
# description: DATAEASE service
|
||||
[Unit]
|
||||
Description=DataEase Service
|
||||
After=docker.service
|
||||
Requires=docker.service
|
||||
|
||||
function startDATAEASE
|
||||
{
|
||||
dectl start
|
||||
}
|
||||
[Service]
|
||||
User=root
|
||||
Group=root
|
||||
|
||||
function stopDATAEASE
|
||||
{
|
||||
dectl stop
|
||||
}
|
||||
Type=oneshot
|
||||
RemainAfterExit=yes
|
||||
ExecStart=/usr/bin/dectl start
|
||||
ExecStop=/usr/bin/dectl stop
|
||||
ExecReload=/usr/bin/dectl reload
|
||||
|
||||
function restartDATAEASE
|
||||
{
|
||||
stopDATAEASE
|
||||
startDATAEASE
|
||||
}
|
||||
|
||||
function statusDATAEASE
|
||||
{
|
||||
dectl status
|
||||
}
|
||||
|
||||
export HOSTNAME=$HOSTNAME
|
||||
case "$1" in
|
||||
start)
|
||||
startDATAEASE
|
||||
;;
|
||||
stop)
|
||||
stopDATAEASE
|
||||
;;
|
||||
restart)
|
||||
restartDATAEASE
|
||||
;;
|
||||
status)
|
||||
statusDATAEASE
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 {start|stop|restart|status}"
|
||||
;;
|
||||
esac
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
@ -36,18 +36,20 @@ function usage() {
|
||||
echo " ./dectl --help"
|
||||
echo
|
||||
echo "Commands: "
|
||||
echo " status 查看 DATAEASE 服务运行状态"
|
||||
echo " start 启动 DATAEASE 服务"
|
||||
echo " stop 停止 DATAEASE 服务"
|
||||
echo " restart 重启 DATAEASE 服务"
|
||||
echo " reload 重新加载 DATAEASE 服务"
|
||||
echo " upgrade 升级 DATAEASE 服务"
|
||||
echo " clear-images 清理 DATAEASE 旧版本的相关镜像"
|
||||
echo " version 查看 DATAEASE 版本"
|
||||
echo " status 查看 DATAEASE 服务运行状态"
|
||||
echo " start 启动 DATAEASE 服务"
|
||||
echo " stop 停止 DATAEASE 服务"
|
||||
echo " restart 重启 DATAEASE 服务"
|
||||
echo " reload 重新加载 DATAEASE 服务"
|
||||
echo " upgrade 升级 DATAEASE 服务"
|
||||
echo " backup 备份 DATAEASE 服务"
|
||||
echo " restore xxx.tar.gz 还原 DATAEASE 服务"
|
||||
echo " clear-images 清理 DATAEASE 旧版本的相关镜像"
|
||||
echo " version 查看 DATAEASE 版本"
|
||||
}
|
||||
function _generate_compose_file_args() {
|
||||
if [[ $DE_INSTALL_MODE != "community" ]];then
|
||||
compose_files="${compose_files} -f docker-compose-apisix.yml"
|
||||
compose_files="${compose_files} -f docker-compose-apisix.yml -f docker-compose-task.yml"
|
||||
fi
|
||||
}
|
||||
function _check_apisix_init() {
|
||||
@ -55,14 +57,6 @@ function _check_apisix_init() {
|
||||
_prepare_apisix
|
||||
fi
|
||||
}
|
||||
function _check_task_init() {
|
||||
if [[ $DE_INSTALL_MODE != "community" ]];then
|
||||
_prepare_task
|
||||
fi
|
||||
}
|
||||
function _prepare_task() {
|
||||
compose_files="${compose_files} -f docker-compose-task.yml"
|
||||
}
|
||||
function _prepare_apisix() {
|
||||
if [[ -z $DE_APISIX_KEY ]];then
|
||||
need_init_apisix=true
|
||||
@ -73,7 +67,6 @@ function _prepare_apisix() {
|
||||
sed -i -e "s/DE_APISIX_KEY/${DE_APISIX_KEY}/g" $DE_RUNNING_BASE/apisix/apisix_conf/config.yaml
|
||||
sed -i -e "s/DE_APISIX_KEY/${DE_APISIX_KEY}/g" $DE_RUNNING_BASE/conf/application.yml
|
||||
fi
|
||||
compose_files="${compose_files} -f docker-compose-apisix.yml"
|
||||
}
|
||||
function _init_apisix() {
|
||||
DE_APISIX_KEY=$DE_APISIX_KEY sh $DE_RUNNING_BASE/bin/apisix/init.sh
|
||||
@ -220,7 +213,7 @@ function status() {
|
||||
function start() {
|
||||
echo
|
||||
_check_apisix_init
|
||||
_check_task_init
|
||||
_generate_compose_file_args
|
||||
cd ${DE_RUNNING_BASE}
|
||||
${compose_cmd} ${compose_files} up -d
|
||||
_healthcheck
|
||||
@ -284,7 +277,7 @@ function upgrade() {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tar zxvf $installer_file
|
||||
tar zxf $installer_file
|
||||
if [ $? != 0 ]; then
|
||||
echo "下载在线安装包失败,请试试重新执行一次安装命令。"
|
||||
rm -f $installer_file
|
||||
@ -323,6 +316,33 @@ function clear_images() {
|
||||
echo "清理完毕"
|
||||
fi
|
||||
}
|
||||
function backup() {
|
||||
backup_file_name=dataease-backup-$(date +%Y%m%d)_$(date +%H%M%S).tar.gz
|
||||
tar --exclude=logs/dataease -zcf $backup_file_name -C $DE_RUNNING_BASE .
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "备份失败"
|
||||
exit 1
|
||||
else
|
||||
echo "备份成功,备份文件 : $backup_file_name"
|
||||
fi
|
||||
}
|
||||
function restore() {
|
||||
if [[ -z $target ]];then
|
||||
echo "未指定需要恢复的备份文件!"
|
||||
exit 1
|
||||
elif [[ -f $target ]];then
|
||||
service dataease stop
|
||||
if [[ ! -d $DE_RUNNING_BASE ]];then
|
||||
mkdir -p $DE_RUNNING_BASE
|
||||
fi
|
||||
echo "恢复备份 $target"
|
||||
tar -zxf $target --directory=$DE_RUNNING_BASE
|
||||
service dataease start
|
||||
else
|
||||
echo "未找到备份文件 $target!"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
function main() {
|
||||
case "${action}" in
|
||||
status)
|
||||
@ -343,6 +363,12 @@ function main() {
|
||||
upgrade)
|
||||
upgrade
|
||||
;;
|
||||
backup)
|
||||
backup
|
||||
;;
|
||||
restore)
|
||||
restore $target
|
||||
;;
|
||||
clear-images)
|
||||
clear_images
|
||||
;;
|
||||
|
@ -5,6 +5,8 @@ CURRENT_DIR=$(
|
||||
pwd
|
||||
)
|
||||
|
||||
echo "$(date)" | tee -a ${CURRENT_DIR}/install.log
|
||||
|
||||
function log() {
|
||||
message="[DATAEASE Log]: $1 "
|
||||
echo -e "${message}" 2>&1 | tee -a ${CURRENT_DIR}/install.log
|
||||
@ -28,7 +30,7 @@ if [ -f /usr/bin/dectl ]; then
|
||||
fi
|
||||
|
||||
set -a
|
||||
if [[ $DE_BASE ]] && [[ -f $DE_BASE/dataease2.0/.env ]]; then
|
||||
if [[ -d $DE_BASE ]] && [[ -f $DE_BASE/dataease2.0/.env ]]; then
|
||||
source $DE_BASE/dataease2.0/.env
|
||||
INSTALL_TYPE='upgrade'
|
||||
else
|
||||
@ -48,7 +50,7 @@ DE_RUN_BASE=$DE_BASE/dataease2.0
|
||||
conf_folder=${DE_RUN_BASE}/conf
|
||||
templates_folder=${DE_RUN_BASE}/templates
|
||||
|
||||
if [[ $DE_RUN_BASE ]];then
|
||||
if [[ -d $DE_RUN_BASE ]];then
|
||||
for image in $(grep "image: " $DE_RUN_BASE/docker*.yml | awk -F 'image:' '{print $2}'); do
|
||||
image_path=$(eval echo $image)
|
||||
image_name=$(echo $image_path | awk -F "[/]" '{print $3}')
|
||||
@ -102,9 +104,7 @@ if [ ! -f /usr/bin/dectl ]; then
|
||||
ln -s /usr/local/bin/dectl /usr/bin/dectl 2>/dev/null
|
||||
fi
|
||||
|
||||
echo "time: $(date)"
|
||||
|
||||
if which getenforce && [ $(getenforce) == "Enforcing" ];then
|
||||
if which getenforce >/dev/null 2>&1 && [ $(getenforce) == "Enforcing" ];then
|
||||
log "... 关闭 SELINUX"
|
||||
setenforce 0
|
||||
sed -i "s/SELINUX=enforcing/SELINUX=disabled/g" /etc/selinux/config
|
||||
@ -115,14 +115,14 @@ fi
|
||||
if which docker >/dev/null 2>&1; then
|
||||
log "检测到 Docker 已安装,跳过安装步骤"
|
||||
log "启动 Docker "
|
||||
service docker start 2>&1 | tee -a ${CURRENT_DIR}/install.log
|
||||
service docker start >/dev/null 2>&1 | tee -a ${CURRENT_DIR}/install.log
|
||||
else
|
||||
if [[ -d docker ]]; then
|
||||
log "... 离线安装 docker"
|
||||
cp docker/bin/* /usr/bin/
|
||||
cp docker/service/docker.service /etc/systemd/system/
|
||||
chmod +x /usr/bin/docker*
|
||||
chmod 754 /etc/systemd/system/docker.service
|
||||
chmod 644 /etc/systemd/system/docker.service
|
||||
log "... 启动 docker"
|
||||
systemctl enable docker; systemctl daemon-reload; service docker start 2>&1 | tee -a ${CURRENT_DIR}/install.log
|
||||
else
|
||||
@ -203,21 +203,20 @@ else
|
||||
cd -
|
||||
fi
|
||||
|
||||
log "配置 dataease Service"
|
||||
cp ${DE_RUN_BASE}/bin/dataease/dataease.service /etc/init.d/dataease
|
||||
chmod a+x /etc/init.d/dataease
|
||||
if which chkconfig;then
|
||||
chkconfig --add dataease
|
||||
fi
|
||||
|
||||
if [ -f /etc/rc.d/rc.local ];then
|
||||
dataeaseService=$(grep "service dataease start" /etc/rc.d/rc.local | wc -l)
|
||||
if [ "$dataeaseService" -eq 0 ]; then
|
||||
echo "sleep 10" >> /etc/rc.d/rc.local
|
||||
echo "service dataease start" >> /etc/rc.d/rc.local
|
||||
if which chkconfig >/dev/null 2>&1;then
|
||||
chkconfig dataease >/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
chkconfig --del dataease
|
||||
fi
|
||||
chmod +x /etc/rc.d/rc.local
|
||||
fi
|
||||
if [[ -f /etc/init.d/dataease ]];then
|
||||
rm -f /etc/init.d/dataease
|
||||
fi
|
||||
log "配置 dataease Service"
|
||||
cp ${DE_RUN_BASE}/bin/dataease/dataease.service /etc/systemd/system/
|
||||
chmod 644 /etc/systemd/system/dataease.service
|
||||
log "配置开机自启动"
|
||||
systemctl enable dataease >/dev/null 2>&1; systemctl daemon-reload | tee -a ${CURRENT_DIR}/install.log
|
||||
|
||||
if [[ $(grep "vm.max_map_count" /etc/sysctl.conf | wc -l) -eq 0 ]];then
|
||||
sysctl -w vm.max_map_count=2000000
|
||||
@ -234,7 +233,7 @@ else
|
||||
sed -i 's/^net\.ipv4\.ip_forward.*/net\.ipv4\.ip_forward=1/' /etc/sysctl.conf
|
||||
fi
|
||||
|
||||
if which firewall-cmd >/dev/null; then
|
||||
if which firewall-cmd >/dev/null 2>&1; then
|
||||
if systemctl is-active firewalld &>/dev/null ;then
|
||||
log "防火墙端口开放"
|
||||
firewall-cmd --zone=public --add-port=${DE_PORT}/tcp --permanent
|
||||
@ -251,12 +250,11 @@ if [[ $http_code == 200 ]];then
|
||||
fi
|
||||
|
||||
log "启动服务"
|
||||
dectl start | tee -a ${CURRENT_DIR}/install.log
|
||||
dectl status 2>&1 | tee -a ${CURRENT_DIR}/install.log
|
||||
systemctl start dataease 2>&1 | tee -a ${CURRENT_DIR}/install.log
|
||||
|
||||
access_port=$DE_PORT
|
||||
if [[ $DE_INSTALL_MODE != "community" ]];then
|
||||
access_port=9080
|
||||
fi
|
||||
echo -e "======================= 安装完成 =======================\n" 2>&1 | tee -a ${CURRENT_DIR}/install.log
|
||||
echo -e "系统登录信息如下:\n 访问地址: http://服务器IP:$access_port\n 用户名: admin\n 初始密码: DataEase@123456" 2>&1 | tee -a ${CURRENT_DIR}/install.log
|
||||
echo -e "系统登录信息如下:\n\t访问地址: http://服务器IP:$access_port\n\t用户名: admin\n\t初始密码: DataEase@123456" 2>&1 | tee -a ${CURRENT_DIR}/install.log
|
86
installer/quick_start.sh
Normal file
86
installer/quick_start.sh
Normal file
@ -0,0 +1,86 @@
|
||||
|
||||
if [[ -x "$(command -v python)" ]];then
|
||||
py_cmd='python'
|
||||
elif [[ -x "$(command -v python3)" ]]; then
|
||||
py_cmd='python3'
|
||||
fi
|
||||
|
||||
server_url="github.com"
|
||||
|
||||
echo -ne "检测 ${server_url} ... "
|
||||
curl -m 5 -kIs https://${server_url} >/dev/null
|
||||
|
||||
if [ $? != 0 ];then
|
||||
echo "failed"
|
||||
echo "没有找到稳定的下载服务器,请稍候重试"
|
||||
exit 1
|
||||
else
|
||||
echo "ok"
|
||||
fi
|
||||
|
||||
rm -f /tmp/de_latest_release
|
||||
|
||||
$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)
|
||||
|
||||
echo "开始下载 DataEase ${latest_version} 版本在线安装包"
|
||||
|
||||
installer_file="dataease-online-installer-${latest_version}.tar.gz"
|
||||
download_url="https://${server_url}/dataease/dataease/releases/download/${latest_version}/$installer_file"
|
||||
echo "下载地址: ${download_url}"
|
||||
curl -LOk -m 60 -o $installer_file $download_url
|
||||
|
||||
if [ ! -f ${installer_file} ];then
|
||||
echo "下载在线安装包失败,请试试重新执行一次安装命令。"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tar zxvf ${installer_file}
|
||||
if [ $? != 0 ];then
|
||||
echo "下载在线安装包失败,请试试重新执行一次安装命令。"
|
||||
rm -f ${installer_file}
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd ${installer_file%.tar.gz}
|
||||
/bin/bash install.sh
|
@ -2,6 +2,7 @@
|
||||
|
||||
DE_BASE=/opt
|
||||
|
||||
echo "如需备份 DataEase 数据,请执行 dectl backup 进行备份。如您的 dectl 命令不支持 backup 命令,请升级版本。"
|
||||
read -r -p "即将卸载 DataEase 服务,包括删除运行目录、数据及相关镜像,是否继续? [Y/n] " input
|
||||
|
||||
case $input in
|
||||
@ -18,14 +19,30 @@ case $input in
|
||||
;;
|
||||
esac
|
||||
|
||||
echo "停止 DataEase 服务"
|
||||
service dataease stop >/dev/null 2>&1
|
||||
|
||||
echo "移除 DataEase 服务"
|
||||
if which chkconfig >/dev/null 2>&1;then
|
||||
chkconfig dataease >/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
chkconfig --del dataease >/dev/null 2>&1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -f /etc/systemd/system/dataease.service ];then
|
||||
systemctl disable dataease >/dev/null 2>&1
|
||||
rm -f /etc/systemd/system/dataease.service
|
||||
systemctl daemon-reload
|
||||
elif [[ -f /etc/init.d/dataease ]];then
|
||||
rm -f /etc/init.d/dataease
|
||||
fi
|
||||
|
||||
if [ -f /usr/bin/dectl ]; then
|
||||
# 获取已安装的 DataEase 的运行目录
|
||||
DE_BASE=$(grep "^DE_BASE=" /usr/bin/dectl | cut -d'=' -f2)
|
||||
fi
|
||||
|
||||
echo "停止 DataEase 服务"
|
||||
dectl stop
|
||||
|
||||
# 清理 DataEase 相关镜像
|
||||
if test ! -z "$(docker images -f dangling=true -q)"; then
|
||||
echo "清理虚悬镜像"
|
||||
@ -38,4 +55,6 @@ if test -n "$(docker images | grep 'registry.cn-qingdao.aliyuncs.com/dataease')"
|
||||
fi
|
||||
|
||||
# 清理 DataEase 运行目录及命令行工具 dectl
|
||||
rm -rf ${DE_BASE}/dataease2.0 /usr/bin/dectl
|
||||
rm -rf ${DE_BASE}/dataease2.0 /usr/bin/dectl
|
||||
|
||||
echo "DataEase 服务卸载完成"
|
2
pom.xml
2
pom.xml
@ -25,7 +25,7 @@
|
||||
<mybatis-plus.version>3.5.3.1</mybatis-plus.version>
|
||||
<h2.version>2.2.220</h2.version>
|
||||
<knife4j.version>4.4.0</knife4j.version>
|
||||
<calcite-core.version>1.35.2</calcite-core.version>
|
||||
<calcite-core.version>1.35.3</calcite-core.version>
|
||||
<commons-dbcp2.version>2.6.0</commons-dbcp2.version>
|
||||
<antlr.version>3.5.2</antlr.version>
|
||||
<java-jwt.version>3.12.1</java-jwt.version>
|
||||
|
@ -0,0 +1,37 @@
|
||||
package io.dataease.api.dingtalk.api;
|
||||
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.dataease.api.dingtalk.dto.DingtalkEnableEditor;
|
||||
import io.dataease.api.dingtalk.dto.DingtalkSettingCreator;
|
||||
import io.dataease.api.dingtalk.dto.DingtalkTokenRequest;
|
||||
import io.dataease.api.dingtalk.vo.DingtalkInfoVO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
@Tag(name = "钉钉设置")
|
||||
@ApiSupport(order = 899)
|
||||
public interface DingtalkApi {
|
||||
|
||||
@Operation(summary = "查询钉钉信息")
|
||||
@GetMapping("/info")
|
||||
DingtalkInfoVO info();
|
||||
|
||||
@Operation(summary = "保存")
|
||||
@PostMapping("/create")
|
||||
void save(@RequestBody DingtalkSettingCreator creator);
|
||||
|
||||
@Operation(summary = "钉钉token", hidden = true)
|
||||
@PostMapping("/token")
|
||||
String dingtalkToken(@RequestBody DingtalkTokenRequest request);
|
||||
|
||||
@Operation(summary = "切换开启状态")
|
||||
@PostMapping("/switchEnable")
|
||||
void switchEnable(@RequestBody DingtalkEnableEditor editor);
|
||||
|
||||
@Operation(summary = "验证可用性")
|
||||
@PostMapping("/validate")
|
||||
void validate(@RequestBody DingtalkSettingCreator creator);
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package io.dataease.api.dingtalk.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Schema(description = "开启状态切换器")
|
||||
@Data
|
||||
public class DingtalkEnableEditor implements Serializable {
|
||||
|
||||
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private boolean enable;
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package io.dataease.api.dingtalk.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Schema(description = "钉钉设置构造器")
|
||||
@Data
|
||||
public class DingtalkSettingCreator implements Serializable {
|
||||
@Schema(description = "agentId", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String agentId;
|
||||
@Schema(description = "appKey", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String appKey;
|
||||
@Schema(description = "appSecret", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String appSecret;
|
||||
@Schema(description = "回调域名", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String callBack;
|
||||
@Schema(description = "是否可用", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Boolean enable;
|
||||
@Schema(description = "是否有效")
|
||||
private Boolean valid;
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package io.dataease.api.dingtalk.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class DingtalkTokenRequest implements Serializable {
|
||||
|
||||
private String code;
|
||||
|
||||
private String state;
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package io.dataease.api.dingtalk.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Schema(description = "钉钉信息")
|
||||
@Data
|
||||
public class DingtalkInfoVO implements Serializable {
|
||||
@Schema(description = "agentId")
|
||||
private String agentId;
|
||||
@Schema(description = "appKey")
|
||||
private String appKey;
|
||||
@Schema(description = "appSecret")
|
||||
private String appSecret;
|
||||
@Schema(description = "回调域名")
|
||||
private String callBack;
|
||||
@Schema(description = "是否开启")
|
||||
private Boolean enable = false;
|
||||
@Schema(description = "是否可用")
|
||||
private Boolean valid = false;
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package io.dataease.api.wecom.api;
|
||||
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
|
||||
import io.dataease.api.wecom.dto.WecomCreator;
|
||||
import io.dataease.api.wecom.dto.WecomEnableEditor;
|
||||
import io.dataease.api.wecom.dto.WecomTokenRequest;
|
||||
import io.dataease.api.wecom.vo.WecomInfoVO;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
@Tag(name = "企微设置")
|
||||
@ApiSupport(order = 899)
|
||||
public interface WecomApi {
|
||||
|
||||
@Operation(summary = "查询企微信息")
|
||||
@GetMapping("/info")
|
||||
WecomInfoVO info();
|
||||
|
||||
@Operation(summary = "保存")
|
||||
@PostMapping("/create")
|
||||
void save(@RequestBody WecomCreator creator);
|
||||
|
||||
@Operation(summary = "企微token", hidden = true)
|
||||
@PostMapping("/token")
|
||||
String wecomToken(@RequestBody WecomTokenRequest request);
|
||||
|
||||
@Operation(summary = "切换开启状态")
|
||||
@PostMapping("/switchEnable")
|
||||
void switchEnable(@RequestBody WecomEnableEditor editor);
|
||||
|
||||
@Operation(summary = "验证可用性")
|
||||
@PostMapping("/validate")
|
||||
void validate(@RequestBody WecomCreator creator);
|
||||
}
|
@ -0,0 +1,22 @@
|
||||
package io.dataease.api.wecom.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class WecomCreator implements Serializable {
|
||||
@Schema(description = "corpId", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String corpId;
|
||||
@Schema(description = "agentId", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String agentId;
|
||||
@Schema(description = "appSecret", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String appSecret;
|
||||
@Schema(description = "回调域名", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private String callBack;
|
||||
@Schema(description = "是否开启", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Boolean enable = false;
|
||||
@Schema(description = "是否可用", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private Boolean valid = false;
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package io.dataease.api.wecom.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Schema(description = "开启状态切换器")
|
||||
@Data
|
||||
public class WecomEnableEditor implements Serializable {
|
||||
|
||||
@Schema(description = "状态", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
private boolean enable;
|
||||
}
|
@ -0,0 +1,13 @@
|
||||
package io.dataease.api.wecom.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Data
|
||||
public class WecomTokenRequest implements Serializable {
|
||||
|
||||
private String code;
|
||||
|
||||
private String state;
|
||||
}
|
@ -0,0 +1,23 @@
|
||||
package io.dataease.api.wecom.vo;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
@Schema(description = "企微信息")
|
||||
@Data
|
||||
public class WecomInfoVO implements Serializable {
|
||||
@Schema(description = "corpId")
|
||||
private String corpId;
|
||||
@Schema(description = "agentId")
|
||||
private String agentId;
|
||||
@Schema(description = "appSecret")
|
||||
private String appSecret;
|
||||
@Schema(description = "回调域名")
|
||||
private String callBack;
|
||||
@Schema(description = "是否开启")
|
||||
private Boolean enable = false;
|
||||
@Schema(description = "是否可用")
|
||||
private Boolean valid = false;
|
||||
}
|
@ -12,6 +12,8 @@ public class OrgCreator implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = -4246980891732805368L;
|
||||
|
||||
private Long id;
|
||||
@Schema(description = "组织名称")
|
||||
private String name;
|
||||
@Schema(description = "上级ID")
|
||||
|
@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.Hidden;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
|
||||
@ -22,4 +23,8 @@ public interface PerSettingApi {
|
||||
@Operation(summary = "保存设置")
|
||||
@PostMapping("/baisc/save")
|
||||
void saveBasic(@RequestBody List<Object> settings);
|
||||
|
||||
@Hidden
|
||||
@GetMapping("/baisc/single/{key}")
|
||||
String singleValue(@PathVariable("key") String key);
|
||||
}
|
||||
|
@ -26,11 +26,9 @@ import static io.dataease.constant.AuthResourceEnum.SYNC_DATASOURCE;
|
||||
@DeApiPath(value = "/sync/datasource", rt = SYNC_DATASOURCE)
|
||||
public interface SyncDatasourceApi {
|
||||
|
||||
@DePermit("m:read")
|
||||
@PostMapping("/source/pager/{goPage}/{pageSize}")
|
||||
IPage<SyncDatasourceVO> sourcePager(@PathVariable("goPage") int goPage, @PathVariable("pageSize") int pageSize, @RequestBody BaseGridRequest request);
|
||||
|
||||
@DePermit("m:read")
|
||||
@PostMapping("/target/pager/{goPage}/{pageSize}")
|
||||
IPage<SyncDatasourceVO> targetPager(@PathVariable("goPage") int goPage, @PathVariable("pageSize") int pageSize, @RequestBody BaseGridRequest request);
|
||||
|
||||
@ -52,7 +50,6 @@ public interface SyncDatasourceApi {
|
||||
@PostMapping("/getSchema")
|
||||
List<String> getSchema(@RequestBody SyncDatasourceDTO dataSourceDTO) throws DEException;
|
||||
|
||||
@DePermit({"#p0+':manage'"})
|
||||
@GetMapping("/validate/{datasourceId}")
|
||||
SyncDatasourceDTO validate(@PathVariable("datasourceId") String datasourceId) throws DEException;
|
||||
|
||||
|
@ -17,9 +17,7 @@ public class GetDatasourceRequest extends SyncDatasourceDTO {
|
||||
* 表格的抽取数据方式
|
||||
*/
|
||||
private boolean tableExtract;
|
||||
/**
|
||||
* 不为空时,获取源数据库表字段,将转换为doris的数据类型
|
||||
*/
|
||||
private String targetDbType;
|
||||
|
||||
private String targetDbId;
|
||||
|
||||
}
|
||||
|
@ -7,13 +7,13 @@ import io.dataease.auth.DeApiPath;
|
||||
import io.dataease.request.BaseGridRequest;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import static io.dataease.constant.AuthResourceEnum.TASK_LOG;
|
||||
import static io.dataease.constant.AuthResourceEnum.TASK;
|
||||
|
||||
/**
|
||||
* @author fit2cloud
|
||||
* @date 2023/12/4 12:43
|
||||
**/
|
||||
@DeApiPath(value = "/sync/task/log", rt = TASK_LOG)
|
||||
@DeApiPath(value = "/sync/task/log", rt = TASK)
|
||||
public interface TaskLogApi {
|
||||
@PostMapping("/pager/{goPage}/{pageSize}")
|
||||
IPage<TaskLogVO> pager(@PathVariable("goPage") int goPage, @PathVariable("pageSize") int pageSize, @RequestBody BaseGridRequest request);
|
||||
|
@ -2,7 +2,7 @@ package io.dataease.constant;
|
||||
|
||||
public enum AuthResourceEnum {
|
||||
|
||||
PANEL(2, 1), SCREEN(3, 2), DATASET(5, 3), DATASOURCE(6, 4), SYSTEM(7, 0), USER(8, 5), ROLE(8, 6), ORG(9, 7), SYNC_DATASOURCE(10, 8), TASK(11, 9),TASK_LOG(12, 10), SUMMARY(13, 11);
|
||||
PANEL(2, 1), SCREEN(3, 2), DATASET(5, 3), DATASOURCE(6, 4), SYSTEM(7, 0), USER(8, 5), ROLE(8, 6), ORG(9, 7), SYNC_DATASOURCE(23, 8), TASK(24, 9), SUMMARY(22, 10);
|
||||
|
||||
private long menuId;
|
||||
|
||||
|
@ -3,5 +3,6 @@ package io.dataease.constant;
|
||||
public class XpackSettingConstants {
|
||||
|
||||
public static final String AUTO_CREATE_USER = "basic.autoCreateUser";
|
||||
public static final String LOG_LIVE_TIME = "basic.logLiveTime";
|
||||
public static final String Front_Time_Out = "basic.frontTimeOut";
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ public class SystemSettingUtils {
|
||||
|
||||
public static boolean xpackSetting(String pkey) {
|
||||
|
||||
List<String> xpackSettingList = List.of(XpackSettingConstants.AUTO_CREATE_USER);
|
||||
List<String> xpackSettingList = List.of(XpackSettingConstants.AUTO_CREATE_USER, XpackSettingConstants.LOG_LIVE_TIME);
|
||||
return xpackSettingList.contains(pkey);
|
||||
}
|
||||
}
|
||||
|
@ -2,11 +2,23 @@ package io.dataease.utils;
|
||||
|
||||
import io.dataease.constant.AuthConstant;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.core.env.Environment;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class WhitelistUtils {
|
||||
|
||||
private static String contextPath;
|
||||
|
||||
|
||||
public static String getContextPath() {
|
||||
if (StringUtils.isBlank(contextPath)) {
|
||||
contextPath = Objects.requireNonNull(CommonBeanFactory.getBean(Environment.class)).getProperty("server.servlet.context-path", String.class);
|
||||
}
|
||||
return contextPath;
|
||||
}
|
||||
|
||||
public static List<String> WHITE_PATH = List.of(
|
||||
"/login/localLogin",
|
||||
"/apisix/check",
|
||||
@ -18,11 +30,16 @@ public class WhitelistUtils {
|
||||
"/panel.html",
|
||||
"/lark/info",
|
||||
"/lark/token",
|
||||
"/dingtalk/info",
|
||||
"/dingtalk/token",
|
||||
"/sysParameter/requestTimeOut",
|
||||
"/setting/authentication/status",
|
||||
"/");
|
||||
|
||||
public static boolean match(String requestURI) {
|
||||
if (StringUtils.startsWith(requestURI, getContextPath())) {
|
||||
requestURI = requestURI.replaceFirst(getContextPath(), "");
|
||||
}
|
||||
if (StringUtils.startsWith(requestURI, AuthConstant.DE_API_PREFIX)) {
|
||||
requestURI = requestURI.replaceFirst(AuthConstant.DE_API_PREFIX, "");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user