forked from github/dataease
Merge branch 'dev' of github.com:dataease/dataease into dev
This commit is contained in:
commit
356c20f16f
14
README.md
14
README.md
@ -24,6 +24,20 @@ DataEase 是开源的数据可视化分析工具,帮助用户快速分析数
|
||||
- 秒级响应:集成 Apache Doris,超大数据量下秒级查询返回延时;
|
||||
- 安全分享:支持多种数据分享方式,确保数据安全。
|
||||
|
||||
### DataEase 已支持的数据源:
|
||||
|
||||
- Excel
|
||||
- MySQL
|
||||
- Oracle
|
||||
- SQL Server
|
||||
- PostgreSQL
|
||||
- Elasticsearch
|
||||
- MariaDB
|
||||
- Apache Doris
|
||||
- ClickHouse
|
||||
|
||||
> 更多数据源支持持续增加中...
|
||||
|
||||
## UI 展示
|
||||
|
||||
![de-ui](https://www.fit2cloud.com/dataease/images/screenshot/dataease-v1.gif)
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>backend</artifactId>
|
||||
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
@ -260,11 +261,16 @@
|
||||
<includes>
|
||||
<include>**/*</include>
|
||||
</includes>
|
||||
<filtering>false</filtering>
|
||||
<filtering>true</filtering>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-resources-plugin</artifactId>
|
||||
<version>3.1.0</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
|
@ -19,6 +19,6 @@ public class LoginDto implements Serializable {
|
||||
* 1:ldap登录
|
||||
* 2:单点登录
|
||||
*/
|
||||
@ApiModelProperty(value = "登录方式", required = true, allowableValues = "0, 1, 2")
|
||||
@ApiModelProperty(value = "登录方式{0:普通登录, 1:ldap登录}", required = true, allowableValues = "0, 1")
|
||||
private int loginType;
|
||||
}
|
||||
|
@ -1,9 +1,6 @@
|
||||
package io.dataease.commons.utils;
|
||||
import com.google.gson.Gson;
|
||||
import io.dataease.datasource.dto.TableFiled;
|
||||
import org.apache.poi.hssf.usermodel.HSSFCell;
|
||||
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
|
||||
@ -70,10 +67,10 @@ public class ExcelReaderUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
/* public static void main(String[] args) throws Exception {
|
||||
|
||||
|
||||
String file ="各省市GDP-表格_加内容.xlsx";
|
||||
ExcelReaderUtil.readExcel(file, new FileInputStream("/Users/taojinlong/Desktop/" + file));
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
package io.dataease.config;
|
||||
|
||||
import com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver;
|
||||
import io.dataease.commons.condition.LicStatusCondition;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
||||
import org.springframework.context.annotation.*;
|
||||
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
|
||||
import springfox.documentation.builders.*;
|
||||
@ -12,19 +12,17 @@ import springfox.documentation.service.*;
|
||||
import springfox.documentation.spi.DocumentationType;
|
||||
import springfox.documentation.spi.service.contexts.SecurityContext;
|
||||
import springfox.documentation.spring.web.plugins.Docket;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@EnableOpenApi
|
||||
@Configuration
|
||||
@Import(BeanValidatorPluginsConfiguration.class)
|
||||
public class Knife4jConfiguration {
|
||||
public class Knife4jConfiguration implements BeanPostProcessor{
|
||||
|
||||
private final OpenApiExtensionResolver openApiExtensionResolver;
|
||||
|
||||
@Value("${app.version}")
|
||||
@Value("${version}")
|
||||
private String version;
|
||||
|
||||
|
||||
|
@ -43,8 +43,8 @@ public class IndexController {
|
||||
return "doc.html";
|
||||
default:
|
||||
// DataEaseException.throwException("Invalid License.");
|
||||
return "nolic.html";
|
||||
// return "doc.html";
|
||||
//return "nolic.html";
|
||||
return "doc.html";
|
||||
}
|
||||
// return "index.html";
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ import io.dataease.commons.utils.AuthUtils;
|
||||
import io.dataease.commons.utils.PageUtils;
|
||||
import io.dataease.commons.utils.Pager;
|
||||
import io.dataease.controller.sys.base.BaseGridRequest;
|
||||
import io.dataease.controller.sys.request.LdapAddRequest;
|
||||
import io.dataease.controller.sys.request.SysUserCreateRequest;
|
||||
import io.dataease.controller.sys.request.SysUserPwdRequest;
|
||||
import io.dataease.controller.sys.request.SysUserStateRequest;
|
||||
@ -130,11 +129,11 @@ public class SysUserController {
|
||||
}
|
||||
|
||||
|
||||
@ApiOperation("同步用户")
|
||||
/* @ApiOperation("同步用户")
|
||||
@PostMapping("/sync")
|
||||
public void importLdap(@RequestBody LdapAddRequest request) {
|
||||
sysUserService.saveLdapUsers(request);
|
||||
}
|
||||
} */
|
||||
|
||||
@ApiOperation("已同步用户")
|
||||
@PostMapping("/existLdapUsers")
|
||||
|
@ -34,7 +34,7 @@ knife4j.setting.enableSearch=false
|
||||
knife4j.setting.enableOpenApi=false
|
||||
knife4j.setting.enableAfterScript=false
|
||||
|
||||
app.version=@project.version@
|
||||
version=@project.version@
|
||||
|
||||
logging.file.path=/opt/dataease/logs/${spring.application.name}
|
||||
|
||||
|
120
frontend/src/components/canvas/components/Editor/Hyperlinks.vue
Normal file
120
frontend/src/components/canvas/components/Editor/Hyperlinks.vue
Normal file
@ -0,0 +1,120 @@
|
||||
<template>
|
||||
|
||||
<el-popover
|
||||
ref="popover"
|
||||
width="340"
|
||||
trigger="click"
|
||||
>
|
||||
<el-row>
|
||||
<el-form ref="form" size="mini" label-width="70px">
|
||||
<el-form-item :label="$t('panel.is_enable')">
|
||||
<el-switch v-model="linkInfo.enable" size="mini" />
|
||||
<span v-show="linkInfo.enable" style="color: #909399; font-size: 8px;margin-left: 3px">
|
||||
Tips:{{ $t('panel.link_open_tips') }}
|
||||
</span>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('panel.open_mode')">
|
||||
<el-radio-group v-model="linkInfo.openMode" :disabled="!linkInfo.enable">
|
||||
<el-radio label="_blank">{{ $t('panel.new_window') }}</el-radio>
|
||||
<el-radio label="_self">{{ $t('panel.now_window') }}</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('panel.hyperLinks')">
|
||||
<el-input v-model="linkInfo.content" :disabled="!linkInfo.enable" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="onSubmit">{{ $t('panel.confirm') }}</el-button>
|
||||
<el-button @click="onClose">{{ $t('panel.cancel') }}</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
<i slot="reference" class="icon iconfont icon-chaolianjie" />
|
||||
</el-popover>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import { deepCopy } from '@/components/canvas/utils/utils'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
linkInfo: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
componentType: null,
|
||||
linkageActiveStatus: false,
|
||||
editFilter: [
|
||||
'view',
|
||||
'custom'
|
||||
]
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState([
|
||||
'curComponent'
|
||||
])
|
||||
},
|
||||
methods: {
|
||||
onSubmit() {
|
||||
this.curComponent.hyperlinks = deepCopy(this.linkInfo)
|
||||
this.popoverClose()
|
||||
},
|
||||
onClose() {
|
||||
this.$emit('close')
|
||||
this.popoverClose()
|
||||
},
|
||||
popoverClose() {
|
||||
this.$refs.popover.showPopper = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.slot-class{
|
||||
color: white;
|
||||
}
|
||||
|
||||
.bottom {
|
||||
margin-top: 20px;
|
||||
text-align: center;
|
||||
|
||||
}
|
||||
.ellip{
|
||||
/*width: 100%;*/
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
overflow: hidden;/*超出部分隐藏*/
|
||||
white-space: nowrap;/*不换行*/
|
||||
text-overflow:ellipsis;/*超出部分文字以...显示*/
|
||||
background-color: #f7f8fa;
|
||||
color: #3d4d66;
|
||||
font-size: 12px;
|
||||
line-height: 24px;
|
||||
height: 24px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.select-filed{
|
||||
/*width: 100%;*/
|
||||
margin-left: 10px;
|
||||
margin-right: 10px;
|
||||
overflow: hidden;/*超出部分隐藏*/
|
||||
white-space: nowrap;/*不换行*/
|
||||
text-overflow:ellipsis;/*超出部分文字以...显示*/
|
||||
color: #3d4d66;
|
||||
font-size: 12px;
|
||||
line-height: 35px;
|
||||
height: 35px;
|
||||
border-radius: 3px;
|
||||
}
|
||||
>>>.el-popover{
|
||||
height: 200px;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
</style>
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<el-card class="el-card-main" :style="mainStyle">
|
||||
<div style="position: relative;">
|
||||
<div id="main-attr" style="position: relative;">
|
||||
<div style="width: 100px;float: left;margin-top: 2px;margin-left: 2px;">
|
||||
<el-radio-group v-model="styleInfo.textAlign" size="mini" @change="styleChange">
|
||||
<el-radio-button
|
||||
@ -76,13 +76,23 @@
|
||||
<el-color-picker ref="backgroundColorPicker" v-model="styleInfo.backgroundColor" style="margin-top: 7px;height: 0px" size="mini" @change="styleChange" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="width: 20px;float: left;margin-top: 2px;margin-left: 2px;">
|
||||
<el-tooltip content="超链接">
|
||||
<Hyperlinks :link-info="this.curComponent.hyperlinks" />
|
||||
</el-tooltip>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import Hyperlinks from '@/components/canvas/components/Editor/Hyperlinks'
|
||||
|
||||
export default {
|
||||
components: { Hyperlinks },
|
||||
props: {
|
||||
scrollLeft: {
|
||||
type: Number,
|
||||
@ -96,6 +106,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
innerOpacity: 0,
|
||||
mainWidthOffset: 600,
|
||||
textAlignOptions: [
|
||||
{
|
||||
icon: 'iconfont icon-juzuo',
|
||||
@ -125,6 +136,8 @@ export default {
|
||||
if (this.styleInfo['opacity']) {
|
||||
this.innerOpacity = this.styleInfo['opacity'] * 100
|
||||
}
|
||||
this.mainWidthOffset = document.getElementById('main-attr').offsetWidth - 50
|
||||
// console.log('mainWidthOffset:' + this.mainWidthOffset)
|
||||
},
|
||||
computed: {
|
||||
letterDivColor() {
|
||||
@ -181,7 +194,7 @@ export default {
|
||||
ps = x + 60
|
||||
}
|
||||
// 防止toolbar超出边界
|
||||
const xGap = ps + 565 - this.canvasWidth
|
||||
const xGap = ps + this.mainWidthOffset - this.canvasWidth
|
||||
// console.log('canvasWidth:' + this.canvasWidth + ';xGap:' + xGap)
|
||||
if (xGap > 0) {
|
||||
return ps - xGap
|
||||
@ -213,7 +226,6 @@ export default {
|
||||
.el-card-main {
|
||||
height: 34px;
|
||||
z-index: 10;
|
||||
width: 620px;
|
||||
position: absolute;
|
||||
|
||||
}
|
||||
|
@ -211,7 +211,10 @@ export default {
|
||||
created() {
|
||||
this.refId = uuid.v1
|
||||
// this.filter.filter = this.$store.getters.conditions
|
||||
this.getData(this.element.propValue.viewId)
|
||||
if (this.element && this.element.propValue && this.element.propValue.viewId) {
|
||||
this.getData(this.element.propValue.viewId)
|
||||
}
|
||||
|
||||
// this.initAreas()
|
||||
},
|
||||
mounted() {
|
||||
|
@ -18,7 +18,7 @@
|
||||
<div v-if="!canEdit" :style="{ verticalAlign: element.style.verticalAlign }" @dblclick="setEdit" v-html="element.propValue" />
|
||||
</div>
|
||||
<div v-else class="v-text">
|
||||
<div :style="{ verticalAlign: element.style.verticalAlign }" v-html="element.propValue" />
|
||||
<div :style="{ verticalAlign: element.style.verticalAlign }" v-html="textInfo" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -56,6 +56,13 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
textInfo() {
|
||||
if (this.element && this.element.hyperlinks && this.element.hyperlinks.enable) {
|
||||
return "<a target='" + this.element.hyperlinks.openMode + "' href='" + this.element.hyperlinks.content + "'>" + this.element.propValue + '</a>'
|
||||
} else {
|
||||
return this.element.propValue
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
@ -123,9 +130,9 @@ export default {
|
||||
selectText(element) {
|
||||
const selection = window.getSelection()
|
||||
const range = document.createRange()
|
||||
range.selectNodeContents(element)
|
||||
selection.removeAllRanges()
|
||||
selection.addRange(range)
|
||||
// range.selectNodeContents(element)
|
||||
// selection.removeAllRanges()
|
||||
// selection.addRange(range)
|
||||
},
|
||||
|
||||
removeSelectText() {
|
||||
|
@ -11,6 +11,13 @@ export const commonAttr = {
|
||||
isLock: false // 是否锁定组件
|
||||
}
|
||||
|
||||
// 超链接配置
|
||||
export const HYPERLINKS = {
|
||||
openMode: '_blank',
|
||||
enable: false,
|
||||
content: 'http://'
|
||||
}
|
||||
|
||||
export const assistList = [
|
||||
{
|
||||
id: '10001',
|
||||
@ -71,6 +78,7 @@ const list = [
|
||||
backgroundColor: '#ffffff',
|
||||
borderRadius: 0
|
||||
},
|
||||
hyperlinks: HYPERLINKS,
|
||||
x: 1,
|
||||
y: 1,
|
||||
sizex: 10,
|
||||
|
@ -10,13 +10,17 @@
|
||||
:placeholder="$t(options.attrs.placeholder)"
|
||||
:popper-append-to-body="inScreen"
|
||||
@change="changeValue"
|
||||
@focus="setOptionWidth"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in options.attrs.datas"
|
||||
:key="item[options.attrs.key]"
|
||||
:style="{width:selectOptionWidth}"
|
||||
:label="item[options.attrs.label]"
|
||||
:value="item[options.attrs.value]"
|
||||
/>
|
||||
>
|
||||
<span :title="item[options.attrs.label]" style="display:inline-block;width:100%;white-space:nowrap;text-overflow:ellipsis;overflow:hidden;">{{ item[options.attrs.label] }}</span>
|
||||
</el-option>
|
||||
</el-select>
|
||||
|
||||
</template>
|
||||
@ -43,7 +47,8 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
options: null,
|
||||
showNumber: false
|
||||
showNumber: false,
|
||||
selectOptionWidth: 0
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -119,6 +124,12 @@ export default {
|
||||
text: item
|
||||
}
|
||||
})
|
||||
},
|
||||
setOptionWidth(event) {
|
||||
// 下拉框弹出时,设置弹框的宽度
|
||||
this.$nextTick(() => {
|
||||
this.selectOptionWidth = event.srcElement.offsetWidth + 'px'
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -35,7 +35,7 @@
|
||||
</span>
|
||||
|
||||
<div v-if="activeTabName === item.name" class="de-tab-content">
|
||||
<user-view v-if="item.content" :ref="item.name" :element="item.content" :out-style="outStyle" />
|
||||
<user-view v-if="item.content && item.content.propValue && item.content.propValue.viewId" :ref="item.name" :element="item.content" :out-style="outStyle" />
|
||||
</div>
|
||||
|
||||
</el-tab-pane>
|
||||
|
@ -1319,7 +1319,13 @@ export default {
|
||||
suspension: 'suspension',
|
||||
new_element_distribution: 'New element Distribution',
|
||||
subject_no_edit: 'System Subject Can Not Edit',
|
||||
subject_name_not_null: 'Subject Name Can Not Be Null And Less Than 20 charts'
|
||||
subject_name_not_null: 'Subject Name Can Not Be Null And Less Than 20 charts',
|
||||
is_enable: 'Enable',
|
||||
open_mode: 'Open Model',
|
||||
new_window: 'New Window',
|
||||
now_window: 'Now Window',
|
||||
hyperLinks: 'hyperlinks',
|
||||
link_open_tips: 'Open When Panel Not In Edit Status'
|
||||
},
|
||||
plugin: {
|
||||
local_install: 'Local installation',
|
||||
|
@ -1322,7 +1322,13 @@ export default {
|
||||
suspension: '悬浮',
|
||||
new_element_distribution: '当前元素移入分布方式',
|
||||
subject_no_edit: '系统主题不能修改',
|
||||
subject_name_not_null: '主题名称需要1~20字符'
|
||||
subject_name_not_null: '主题名称需要1~20字符',
|
||||
is_enable: '是否启用',
|
||||
open_mode: '打开方式',
|
||||
new_window: '新窗口',
|
||||
now_window: '当前窗口',
|
||||
hyperLinks: '超链接',
|
||||
link_open_tips: '仪表板非编辑状态可打开链接'
|
||||
},
|
||||
plugin: {
|
||||
local_install: '本地安裝',
|
||||
|
@ -1327,7 +1327,13 @@ export default {
|
||||
suspension: '悬浮',
|
||||
new_element_distribution: '当前元素移入分布方式',
|
||||
subject_no_edit: '系统主题不能修改',
|
||||
subject_name_not_null: '主题名称需要1~20字符'
|
||||
subject_name_not_null: '主题名称需要1~20字符',
|
||||
is_enable: '是否启用',
|
||||
open_mode: '打开方式',
|
||||
new_window: '新窗口',
|
||||
now_window: '当前窗口',
|
||||
hyperLinks: '超链接',
|
||||
link_open_tips: '仪表板非编辑状态可打开链接'
|
||||
},
|
||||
plugin: {
|
||||
local_install: '本地安装',
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,8 +1,8 @@
|
||||
@font-face {
|
||||
font-family: "iconfont"; /* Project id 2459092 */
|
||||
src: url('iconfont.woff2?t=1633678290478') format('woff2'),
|
||||
url('iconfont.woff?t=1633678290478') format('woff'),
|
||||
url('iconfont.ttf?t=1633678290478') format('truetype');
|
||||
src: url('iconfont.woff2?t=1634191971474') format('woff2'),
|
||||
url('iconfont.woff?t=1634191971474') format('woff'),
|
||||
url('iconfont.ttf?t=1634191971474') format('truetype');
|
||||
}
|
||||
|
||||
.iconfont {
|
||||
@ -13,6 +13,14 @@
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-chaolianjie:before {
|
||||
content: "\e9b2";
|
||||
}
|
||||
|
||||
.icon-kexuejishu:before {
|
||||
content: "\e60f";
|
||||
}
|
||||
|
||||
.icon-shujujuzhen:before {
|
||||
content: "\e69c";
|
||||
}
|
||||
|
File diff suppressed because one or more lines are too long
@ -5,6 +5,20 @@
|
||||
"css_prefix_text": "icon-",
|
||||
"description": "",
|
||||
"glyphs": [
|
||||
{
|
||||
"icon_id": "3229030",
|
||||
"name": "超链接",
|
||||
"font_class": "chaolianjie",
|
||||
"unicode": "e9b2",
|
||||
"unicode_decimal": 59826
|
||||
},
|
||||
{
|
||||
"icon_id": "23880814",
|
||||
"name": "科学技术",
|
||||
"font_class": "kexuejishu",
|
||||
"unicode": "e60f",
|
||||
"unicode_decimal": 58895
|
||||
},
|
||||
{
|
||||
"icon_id": "1766500",
|
||||
"name": "符号-数据矩阵",
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user