@@ -125,6 +148,7 @@ watch(
:predefine="predefineColors"
@change="changeTitleStyle('color')"
is-custom
+ show-alpha
/>
diff --git a/core/core-frontend/src/views/chart/components/editor/editor-style/components/IndicatorValueSelector.vue b/core/core-frontend/src/views/chart/components/editor/editor-style/components/IndicatorValueSelector.vue
index 6cd2ffc63e..9f2e6cea22 100644
--- a/core/core-frontend/src/views/chart/components/editor/editor-style/components/IndicatorValueSelector.vue
+++ b/core/core-frontend/src/views/chart/components/editor/editor-style/components/IndicatorValueSelector.vue
@@ -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 })
@@ -125,6 +150,7 @@ watch(
class="color-picker-style"
:predefine="predefineColors"
@change="changeTitleStyle('color')"
+ show-alpha
is-custom
/>
@@ -410,6 +436,7 @@ watch(
:predefine="predefineColors"
@change="changeTitleStyle('suffixColor')"
is-custom
+ show-alpha
/>
diff --git a/core/core-frontend/src/views/chart/components/editor/index.vue b/core/core-frontend/src/views/chart/components/editor/index.vue
index 77b3e2ecd2..dbda67309d 100644
--- a/core/core-frontend/src/views/chart/components/editor/index.vue
+++ b/core/core-frontend/src/views/chart/components/editor/index.vue
@@ -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)
}
diff --git a/core/core-frontend/src/views/chart/components/editor/util/chart.ts b/core/core-frontend/src/views/chart/components/editor/util/chart.ts
index d3d71ecb7a..590bab5478 100644
--- a/core/core-frontend/src/views/chart/components/editor/util/chart.ts
+++ b/core/core-frontend/src/views/chart/components/editor/util/chart.ts
@@ -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',
diff --git a/core/core-frontend/src/views/chart/components/js/panel/charts/table/table-pivot.ts b/core/core-frontend/src/views/chart/components/js/panel/charts/table/table-pivot.ts
index 06664323b7..69bd521738 100644
--- a/core/core-frontend/src/views/chart/components/js/panel/charts/table/table-pivot.ts
+++ b/core/core-frontend/src/views/chart/components/js/panel/charts/table/table-pivot.ts
@@ -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) => {
diff --git a/core/core-frontend/src/views/share/link/pwd.vue b/core/core-frontend/src/views/share/link/pwd.vue
index 327c71d8a1..a9ad6eb164 100644
--- a/core/core-frontend/src/views/share/link/pwd.vue
+++ b/core/core-frontend/src/views/share/link/pwd.vue
@@ -30,7 +30,7 @@
- {{
+ {{
t('pblink.sure_bt')
}}
@@ -71,20 +71,30 @@ const rule = reactive({
]
})
-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)
}
})
}
diff --git a/core/core-frontend/src/views/share/share/ShareHandler.vue b/core/core-frontend/src/views/share/share/ShareHandler.vue
index 0d2892c9dd..eefb40c500 100644
--- a/core/core-frontend/src/views/share/share/ShareHandler.vue
+++ b/core/core-frontend/src/views/share/share/ShareHandler.vue
@@ -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
}
diff --git a/core/core-frontend/src/views/share/share/ShareVisualHead.vue b/core/core-frontend/src/views/share/share/ShareVisualHead.vue
index 5de4706a9c..95c47cff67 100644
--- a/core/core-frontend/src/views/share/share/ShareVisualHead.vue
+++ b/core/core-frontend/src/views/share/share/ShareVisualHead.vue
@@ -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
}
diff --git a/core/core-frontend/src/views/system/parameter/basic/BasicEdit.vue b/core/core-frontend/src/views/system/parameter/basic/BasicEdit.vue
index be9875c849..f992312be3 100644
--- a/core/core-frontend/src/views/system/parameter/basic/BasicEdit.vue
+++ b/core/core-frontend/src/views/system/parameter/basic/BasicEdit.vue
@@ -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"
/>
+
+
+
@@ -215,6 +237,9 @@ defineExpose({
.is-error {
margin-bottom: 40px !important;
}
+ .edit-all-line {
+ width: 552px !important;
+ }
}
.setting-hidden-item {
display: none !important;
diff --git a/core/core-frontend/src/views/system/parameter/basic/BasicInfo.vue b/core/core-frontend/src/views/system/parameter/basic/BasicInfo.vue
index 91c30d073d..4c89aee153 100644
--- a/core/core-frontend/src/views/system/parameter/basic/BasicInfo.vue
+++ b/core/core-frontend/src/views/system/parameter/basic/BasicInfo.vue
@@ -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()
diff --git a/de-xpack b/de-xpack
index 4889ffa0fc..25c0bb1ec2 160000
--- a/de-xpack
+++ b/de-xpack
@@ -1 +1 @@
-Subproject commit 4889ffa0fcdfebe2755f5f1ce3b371e858abc981
+Subproject commit 25c0bb1ec2569f54aed498da03732637cbdda727
diff --git a/installer/dataease/bin/dataease/dataease.service b/installer/dataease/bin/dataease/dataease.service
index 6364c0a46c..2752d16200 100644
--- a/installer/dataease/bin/dataease/dataease.service
+++ b/installer/dataease/bin/dataease/dataease.service
@@ -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
\ No newline at end of file
diff --git a/installer/dectl b/installer/dectl
index 4490f559f1..245a189349 100644
--- a/installer/dectl
+++ b/installer/dectl
@@ -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
;;
diff --git a/installer/install.sh b/installer/install.sh
index 7111eff777..d71fd06efd 100644
--- a/installer/install.sh
+++ b/installer/install.sh
@@ -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
\ No newline at end of file
+echo -e "系统登录信息如下:\n\t访问地址: http://服务器IP:$access_port\n\t用户名: admin\n\t初始密码: DataEase@123456" 2>&1 | tee -a ${CURRENT_DIR}/install.log
\ No newline at end of file
diff --git a/installer/quick_start.sh b/installer/quick_start.sh
new file mode 100644
index 0000000000..2279bd5cae
--- /dev/null
+++ b/installer/quick_start.sh
@@ -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 - < /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
\ No newline at end of file
diff --git a/installer/uninstall.sh b/installer/uninstall.sh
index 433f478122..d27daf96e8 100644
--- a/installer/uninstall.sh
+++ b/installer/uninstall.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
\ No newline at end of file
+rm -rf ${DE_BASE}/dataease2.0 /usr/bin/dectl
+
+echo "DataEase 服务卸载完成"
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 60fa8cd8ca..9a5794c0c6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -25,7 +25,7 @@
3.5.3.1
2.2.220
4.4.0
- 1.35.2
+ 1.35.3
2.6.0
3.5.2
3.12.1
diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/dingtalk/api/DingtalkApi.java b/sdk/api/api-base/src/main/java/io/dataease/api/dingtalk/api/DingtalkApi.java
new file mode 100644
index 0000000000..d4be6fb768
--- /dev/null
+++ b/sdk/api/api-base/src/main/java/io/dataease/api/dingtalk/api/DingtalkApi.java
@@ -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);
+}
diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/dingtalk/dto/DingtalkEnableEditor.java b/sdk/api/api-base/src/main/java/io/dataease/api/dingtalk/dto/DingtalkEnableEditor.java
new file mode 100644
index 0000000000..efcc62563e
--- /dev/null
+++ b/sdk/api/api-base/src/main/java/io/dataease/api/dingtalk/dto/DingtalkEnableEditor.java
@@ -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;
+}
diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/dingtalk/dto/DingtalkSettingCreator.java b/sdk/api/api-base/src/main/java/io/dataease/api/dingtalk/dto/DingtalkSettingCreator.java
new file mode 100644
index 0000000000..09ee809e15
--- /dev/null
+++ b/sdk/api/api-base/src/main/java/io/dataease/api/dingtalk/dto/DingtalkSettingCreator.java
@@ -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;
+}
diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/dingtalk/dto/DingtalkTokenRequest.java b/sdk/api/api-base/src/main/java/io/dataease/api/dingtalk/dto/DingtalkTokenRequest.java
new file mode 100644
index 0000000000..2bae3204c5
--- /dev/null
+++ b/sdk/api/api-base/src/main/java/io/dataease/api/dingtalk/dto/DingtalkTokenRequest.java
@@ -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;
+}
diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/dingtalk/vo/DingtalkInfoVO.java b/sdk/api/api-base/src/main/java/io/dataease/api/dingtalk/vo/DingtalkInfoVO.java
new file mode 100644
index 0000000000..428d4f7b14
--- /dev/null
+++ b/sdk/api/api-base/src/main/java/io/dataease/api/dingtalk/vo/DingtalkInfoVO.java
@@ -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;
+
+}
diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/wecom/api/WecomApi.java b/sdk/api/api-base/src/main/java/io/dataease/api/wecom/api/WecomApi.java
new file mode 100644
index 0000000000..04a2ed72dd
--- /dev/null
+++ b/sdk/api/api-base/src/main/java/io/dataease/api/wecom/api/WecomApi.java
@@ -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);
+}
diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/wecom/dto/WecomCreator.java b/sdk/api/api-base/src/main/java/io/dataease/api/wecom/dto/WecomCreator.java
new file mode 100644
index 0000000000..581dcd1215
--- /dev/null
+++ b/sdk/api/api-base/src/main/java/io/dataease/api/wecom/dto/WecomCreator.java
@@ -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;
+}
diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/wecom/dto/WecomEnableEditor.java b/sdk/api/api-base/src/main/java/io/dataease/api/wecom/dto/WecomEnableEditor.java
new file mode 100644
index 0000000000..bf53b7f88f
--- /dev/null
+++ b/sdk/api/api-base/src/main/java/io/dataease/api/wecom/dto/WecomEnableEditor.java
@@ -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;
+}
diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/wecom/dto/WecomTokenRequest.java b/sdk/api/api-base/src/main/java/io/dataease/api/wecom/dto/WecomTokenRequest.java
new file mode 100644
index 0000000000..93697a6a0d
--- /dev/null
+++ b/sdk/api/api-base/src/main/java/io/dataease/api/wecom/dto/WecomTokenRequest.java
@@ -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;
+}
diff --git a/sdk/api/api-base/src/main/java/io/dataease/api/wecom/vo/WecomInfoVO.java b/sdk/api/api-base/src/main/java/io/dataease/api/wecom/vo/WecomInfoVO.java
new file mode 100644
index 0000000000..7f6415ef3a
--- /dev/null
+++ b/sdk/api/api-base/src/main/java/io/dataease/api/wecom/vo/WecomInfoVO.java
@@ -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;
+}
diff --git a/sdk/api/api-permissions/src/main/java/io/dataease/api/permissions/org/dto/OrgCreator.java b/sdk/api/api-permissions/src/main/java/io/dataease/api/permissions/org/dto/OrgCreator.java
index c53d772ac9..4eb01bd47b 100644
--- a/sdk/api/api-permissions/src/main/java/io/dataease/api/permissions/org/dto/OrgCreator.java
+++ b/sdk/api/api-permissions/src/main/java/io/dataease/api/permissions/org/dto/OrgCreator.java
@@ -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")
diff --git a/sdk/api/api-permissions/src/main/java/io/dataease/api/permissions/setting/api/PerSettingApi.java b/sdk/api/api-permissions/src/main/java/io/dataease/api/permissions/setting/api/PerSettingApi.java
index 6244cae083..c90ab08465 100644
--- a/sdk/api/api-permissions/src/main/java/io/dataease/api/permissions/setting/api/PerSettingApi.java
+++ b/sdk/api/api-permissions/src/main/java/io/dataease/api/permissions/setting/api/PerSettingApi.java
@@ -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