@ -38,6 +38,7 @@ DataEase 是开源的数据可视化分析工具,帮助用户快速分析数
|
||||
- MongoDB
|
||||
- Amazon Redshift
|
||||
- Hive
|
||||
- DB2
|
||||
|
||||
> 更多数据源支持持续增加中...
|
||||
|
||||
|
@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Api(tags = "首页")
|
||||
@ -24,7 +25,7 @@ public class ReptileController {
|
||||
|
||||
@GetMapping("lastActive")
|
||||
@ApiOperation("获取官方Blog最新动态")
|
||||
public Map<String, String> lastActive() {
|
||||
public List lastActive() {
|
||||
return reptileService.lastActive();
|
||||
}
|
||||
}
|
||||
|
@ -7,8 +7,7 @@ import org.jsoup.nodes.Element;
|
||||
import org.jsoup.select.Elements;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Author: wangjiahao
|
||||
@ -18,27 +17,33 @@ import java.util.Map;
|
||||
@Service
|
||||
public class ReptileService {
|
||||
String blogUrl = "https://blog.fit2cloud.com/?cat=321";
|
||||
//获取最新的前几条数据
|
||||
private static int infoCount=1;
|
||||
|
||||
public Map<String, String> lastActive() {
|
||||
Map<String, String> result = new HashMap();
|
||||
public List lastActive() {
|
||||
List result = new ArrayList();
|
||||
try {
|
||||
//爬取最新数据
|
||||
Document doc = Jsoup.parse(HttpClientUtil.get(blogUrl, null));
|
||||
Elements elementsContent = doc.getElementsByAttributeValue("rel", "bookmark");
|
||||
Elements elementsTime = doc.getElementsByTag("time");
|
||||
Element lastInfo = elementsContent.get(0);
|
||||
result.put("title",lastInfo.attr("title"));
|
||||
result.put("href",lastInfo.attr("href"));
|
||||
result.put("time",elementsTime.get(0).childNode(0).outerHtml());
|
||||
for(int i = 0;i<infoCount;i++){
|
||||
Element info = elementsContent.get(i*3);
|
||||
Map<String, String> infoMap = new HashMap();
|
||||
infoMap.put("title",info.attr("title"));
|
||||
infoMap.put("href",info.attr("href"));
|
||||
infoMap.put("time",elementsTime.get(i).childNode(0).outerHtml());
|
||||
result.add(infoMap);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
//ignore
|
||||
result.put("title","支持移动端展示,数据源新增对DB2的支持,DataEase开源数据可视化分析平台v1.6.0发布");
|
||||
result.put("href","https://blog.fit2cloud.com/?p=3200");
|
||||
result.put("time","2022年1月10日");
|
||||
Map<String, String> infoMap = new HashMap();
|
||||
infoMap.put("title","支持移动端展示,数据源新增对DB2的支持,DataEase开源数据可视化分析平台v1.6.0发布");
|
||||
infoMap.put("href","https://blog.fit2cloud.com/?p=3200");
|
||||
infoMap.put("time","2022年1月10日");
|
||||
result.add(infoMap);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
BIN
frontend/src/assets/DataEase-0.jpg
Normal file
After Width: | Height: | Size: 99 KiB |
BIN
frontend/src/assets/DataEase-1.jpg
Normal file
After Width: | Height: | Size: 88 KiB |
BIN
frontend/src/assets/DataEase-2.jpg
Normal file
After Width: | Height: | Size: 83 KiB |
BIN
frontend/src/assets/DataEase-3.jpg
Normal file
After Width: | Height: | Size: 85 KiB |
BIN
frontend/src/assets/DataEase-4.jpg
Normal file
After Width: | Height: | Size: 104 KiB |
BIN
frontend/src/assets/DataEase-5.jpg
Normal file
After Width: | Height: | Size: 125 KiB |
BIN
frontend/src/assets/banner.png
Normal file
After Width: | Height: | Size: 30 KiB |
@ -118,9 +118,10 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
filterInit: false, // 标记是否已经通过watch.filters 进行初始化,如果filterInit=true 则create放弃数据初始化防止数据覆盖
|
||||
refId: null,
|
||||
chart: BASE_CHART_STRING,
|
||||
requestStatus: 'waiting',
|
||||
requestStatus: 'success',
|
||||
message: null,
|
||||
drillClickDimensionList: [],
|
||||
drillFilters: [],
|
||||
@ -242,7 +243,10 @@ export default {
|
||||
|
||||
watch: {
|
||||
'filters': function(val1, val2) {
|
||||
isChange(val1, val2) && this.getData(this.element.propValue.viewId)
|
||||
if (isChange(val1, val2)) {
|
||||
this.filterInit = true
|
||||
this.getData(this.element.propValue.viewId)
|
||||
}
|
||||
},
|
||||
linkageFilters: {
|
||||
handler(newVal, oldVal) {
|
||||
@ -313,8 +317,8 @@ export default {
|
||||
created() {
|
||||
this.refId = uuid.v1
|
||||
if (this.element && this.element.propValue && this.element.propValue.viewId) {
|
||||
const hasFilter = this.componentData.filter(item => item.type === 'custom').some(item => item.options.value && !(item.options.value instanceof Object) || (item.options.attrs && item.options.attrs.default && item.options.attrs.default.isDynamic))
|
||||
if (!hasFilter || this.filters.length > 0) { this.getData(this.element.propValue.viewId, false) }
|
||||
// 如果watch.filters 已经进行数据初始化时候,此处放弃数据初始化
|
||||
!this.filterInit && this.getData(this.element.propValue.viewId, false)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -1269,6 +1269,9 @@ export default {
|
||||
get_schema: 'Get Schema',
|
||||
schema: 'Database Schema',
|
||||
please_choose_schema: 'Please select Schema',
|
||||
edit_datasource_msg: 'Modifying the data source information may make the data set under the modified data source unavailable. Confirm the modification?',
|
||||
repeat_datasource_msg: 'Data source information with the same configuration already exists, ',
|
||||
confirm_save: 'Confirm save?',
|
||||
in_valid: 'Invalid datasource',
|
||||
initial_pool_size: 'Initial connections',
|
||||
min_pool_size: 'Minimum of connections',
|
||||
@ -1500,7 +1503,10 @@ export default {
|
||||
timeout_refresh: 'Timeout,Will Refresh...',
|
||||
mobile_layout: 'Mobile Layout',
|
||||
component_hidden: 'Component Hidden',
|
||||
public_link_tips: 'New Is Public Link,The Target Panel Have Not Set Public Link,Can Not Jump'
|
||||
public_link_tips: 'New Is Public Link,The Target Panel Have Not Set Public Link,Can Not Jump',
|
||||
input_title: 'Input Title',
|
||||
show_title: 'Show Title',
|
||||
default_settings: 'Default Settings'
|
||||
},
|
||||
plugin: {
|
||||
local_install: 'Local installation',
|
||||
@ -1815,6 +1821,9 @@ export default {
|
||||
open_source_community: 'Open source community',
|
||||
click_show: 'Click To View',
|
||||
show_more: 'Show More',
|
||||
click_inner: 'Click To Enter'
|
||||
click_inner: 'Click To Enter',
|
||||
email: 'Email:',
|
||||
tel: 'Tel:',
|
||||
web: 'Web:'
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,8 @@ import fuZh from 'fit2cloud-ui/src/locale/lang/zh-CN' // 加载fit2cloud的内
|
||||
|
||||
import fuEn from 'fit2cloud-ui/src/locale/lang/en_US' // 加载fit2cloud的内容
|
||||
|
||||
import fuTW from 'fit2cloud-ui/src/locale/lang/zh-TW' // 加载fit2cloud的内容
|
||||
|
||||
Vue.use(VueI18n)
|
||||
|
||||
const messages = {
|
||||
@ -28,7 +30,8 @@ const messages = {
|
||||
},
|
||||
zh_TW: {
|
||||
...twLocale,
|
||||
...elementTWLocale
|
||||
...elementTWLocale,
|
||||
...fuTW
|
||||
}
|
||||
}
|
||||
export function getLanguage() {
|
||||
|
@ -1271,6 +1271,8 @@ export default {
|
||||
schema: '數據庫 Schema',
|
||||
please_choose_schema: '請選擇數據庫 Schema',
|
||||
edit_datasource_msg: '修改數據源信息,可能會導致改數據源下的數據集不可用,確認修改?',
|
||||
repeat_datasource_msg: '已經存在相同配置的數據源信息,',
|
||||
confirm_save: '確認保存?',
|
||||
in_valid: '無效數據源',
|
||||
initial_pool_size: '初始連接數',
|
||||
min_pool_size: '最小連接數',
|
||||
@ -1502,7 +1504,10 @@ export default {
|
||||
timeout_refresh: '請求超時,稍後刷新...',
|
||||
mobile_layout: '移動端佈局',
|
||||
component_hidden: '隱藏的組件',
|
||||
public_link_tips: '當前是公共鏈接模式,目標儀錶闆未設置公共鏈接,無法跳轉'
|
||||
public_link_tips: '當前是公共鏈接模式,目標儀錶闆未設置公共鏈接,無法跳轉',
|
||||
input_title: '請輸入標題',
|
||||
show_title: '顯示標題',
|
||||
default_settings: '默認值設置'
|
||||
},
|
||||
plugin: {
|
||||
local_install: '本地安裝',
|
||||
@ -1825,6 +1830,9 @@ export default {
|
||||
open_source_community: '開源社區',
|
||||
click_show: '點擊查看',
|
||||
show_more: '查看更多',
|
||||
click_inner: '點擊進入'
|
||||
click_inner: '點擊進入',
|
||||
email: '邮箱:',
|
||||
tel: '电话:',
|
||||
web: '网址:'
|
||||
}
|
||||
}
|
||||
|
@ -1275,6 +1275,8 @@ export default {
|
||||
schema: '数据库 Schema',
|
||||
please_choose_schema: '请选择数据库 Schema',
|
||||
edit_datasource_msg: '修改数据源信息,可能会导致该数据源下的数据集不可用,确认修改?',
|
||||
repeat_datasource_msg: '已经存在相同配置的数据源信息, ',
|
||||
confirm_save: '确认保存?',
|
||||
in_valid: '无效数据源',
|
||||
initial_pool_size: '初始连接数',
|
||||
min_pool_size: '最小连接数',
|
||||
@ -1511,7 +1513,10 @@ export default {
|
||||
timeout_refresh: '请求超时,稍后刷新...',
|
||||
mobile_layout: '移动端布局',
|
||||
component_hidden: '隐藏的组件',
|
||||
public_link_tips: '当前是公共链接模式,目标仪表板未设置公共链接,无法跳转'
|
||||
public_link_tips: '当前是公共链接模式,目标仪表板未设置公共链接,无法跳转',
|
||||
input_title: '请输入标题',
|
||||
show_title: '显示标题',
|
||||
default_settings: '默认值设置'
|
||||
},
|
||||
plugin: {
|
||||
local_install: '本地安装',
|
||||
@ -1835,6 +1840,8 @@ export default {
|
||||
open_source_community: '开源社区',
|
||||
click_show: '点击查看',
|
||||
show_more: '查看更多',
|
||||
click_inner: '点击进入'
|
||||
email: '邮箱:',
|
||||
tel: '电话:',
|
||||
web: '网址:'
|
||||
}
|
||||
}
|
||||
|
@ -14,11 +14,11 @@
|
||||
<el-col :span="16">
|
||||
<div class="filter-options-right">
|
||||
<span style="padding-right: 10px;">
|
||||
<el-checkbox v-model="attrs.showTitle" @change="showTitleChange">显示标题
|
||||
<el-checkbox v-model="attrs.showTitle" @change="showTitleChange">{{ $t('panel.show_title') }}
|
||||
</el-checkbox>
|
||||
<el-popover v-model="titlePopovervisible" placement="bottom-end" :disabled="!attrs.showTitle" width="200">
|
||||
<div style="width: 100%;overflow-y: auto;overflow-x: hidden;word-break: break-all;position: relative;">
|
||||
<el-input v-model="attrs.title" placeholder="请输入标题" type="textarea" maxlength="15" show-word-limit />
|
||||
<el-input v-model="attrs.title" :placeholder="$t('panel.input_title')" type="textarea" maxlength="15" show-word-limit />
|
||||
</div>
|
||||
|
||||
<i
|
||||
|
@ -4,7 +4,7 @@
|
||||
<ds-tree ref="dsTree" :datasource="datasource" @switch-main="switchMain"/>
|
||||
</de-aside-container>
|
||||
<de-main-container>
|
||||
<component :is="component" v-if="!!component" :params="param" @refresh-type="refreshType"
|
||||
<component :is="component" v-if="!!component" :params="param" :tData="tData" @refresh-type="refreshType"
|
||||
@switch-component="switchMain"/>
|
||||
</de-main-container>
|
||||
</de-container>
|
||||
@ -25,7 +25,8 @@ export default {
|
||||
return {
|
||||
component: DataHome,
|
||||
datasource: {},
|
||||
param: null
|
||||
param: null,
|
||||
tData: null
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
@ -36,7 +37,8 @@ export default {
|
||||
methods: {
|
||||
// 切换main区内容
|
||||
switchMain(param) {
|
||||
const {component, componentParam} = param
|
||||
console.log(param)
|
||||
const {component, componentParam, tData} = param
|
||||
this.component = DataHome
|
||||
this.param = null
|
||||
this.$nextTick(() => {
|
||||
@ -44,6 +46,7 @@ export default {
|
||||
case 'DsForm':
|
||||
this.component = DsForm
|
||||
this.param = componentParam
|
||||
this.tData = tData
|
||||
break
|
||||
default:
|
||||
this.component = DataHome
|
||||
|
@ -216,10 +216,10 @@ export default {
|
||||
},
|
||||
|
||||
addFolder() {
|
||||
this.switchMain('DsForm')
|
||||
this.switchMain('DsForm', {}, this.tData)
|
||||
},
|
||||
addFolderWithType(data) {
|
||||
this.switchMain('DsForm', {type: data.id})
|
||||
this.switchMain('DsForm', {type: data.id}, this.tData)
|
||||
},
|
||||
nodeClick(node, data) {
|
||||
if (node.type === 'folder') return
|
||||
@ -243,11 +243,11 @@ export default {
|
||||
return {optType, data, node}
|
||||
},
|
||||
edit(row) {
|
||||
this.switchMain('DsForm', row)
|
||||
this.switchMain('DsForm', row, this.tData)
|
||||
},
|
||||
showInfo(row) {
|
||||
const param = {...row.data, ...{showModel: 'show'}}
|
||||
this.switchMain('DsForm', param)
|
||||
this.switchMain('DsForm', param, this.tData)
|
||||
},
|
||||
_handleDelete(datasource) {
|
||||
this.$confirm(this.$t('datasource.delete_warning'), '', {
|
||||
@ -257,7 +257,7 @@ export default {
|
||||
}).then(() => {
|
||||
delDs(datasource.id).then(res => {
|
||||
this.$success(this.$t('commons.delete_success'))
|
||||
this.switchMain('DataHome')
|
||||
this.switchMain('DataHome', {}, this.tData)
|
||||
this.refreshType(datasource)
|
||||
})
|
||||
}).catch(() => {
|
||||
@ -267,10 +267,12 @@ export default {
|
||||
})
|
||||
})
|
||||
},
|
||||
switchMain(component, componentParam) {
|
||||
switchMain(component, componentParam, tData) {
|
||||
console.log(tData)
|
||||
this.$emit('switch-main', {
|
||||
component,
|
||||
componentParam
|
||||
componentParam,
|
||||
tData
|
||||
})
|
||||
},
|
||||
markInvalid(msgParam) {
|
||||
|
@ -192,6 +192,10 @@ export default {
|
||||
params: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
tData: {
|
||||
type: Array,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@ -346,29 +350,81 @@ export default {
|
||||
this.$message.error(i18n.t('datasource.no_less_then_0'))
|
||||
return
|
||||
}
|
||||
let repeat = false
|
||||
let repeatDsName = ''
|
||||
this.tData.forEach(item => {
|
||||
if(item.id === this.form.type){
|
||||
item.children.forEach(child => {
|
||||
let configuration = JSON.parse(child.configuration)
|
||||
switch (this.form.type) {
|
||||
case 'mysql':
|
||||
case 'hive':
|
||||
case 'mariadb':
|
||||
case 'ds_doris':
|
||||
case 'ck':
|
||||
case 'mongo':
|
||||
case 'mariadb':
|
||||
if(configuration.host == this.form.configuration.host && configuration.dataBase == this.form.configuration.dataBase && configuration.port == this.form.configuration.port){
|
||||
repeat = true
|
||||
repeatDsName = child.name
|
||||
}
|
||||
break
|
||||
case 'pg':
|
||||
case 'sqlServer':
|
||||
case 'redshift':
|
||||
case 'oracle':
|
||||
case 'db2':
|
||||
if(configuration.host == this.form.configuration.host && configuration.dataBase == this.form.configuration.dataBase && configuration.port == this.form.configuration.port && configuration.schema == this.form.configuration.schema){
|
||||
repeat = true
|
||||
}
|
||||
break
|
||||
case 'es':
|
||||
if(configuration.url == this.form.configuration.url){
|
||||
repeat = true
|
||||
}
|
||||
break
|
||||
default:
|
||||
break
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
this.$refs.dsForm.validate(valid => {
|
||||
if (valid) {
|
||||
const method = this.formType === 'add' ? addDs : editDs
|
||||
const form = JSON.parse(JSON.stringify(this.form))
|
||||
form.configuration = JSON.stringify(form.configuration)
|
||||
if (this.formType !== 'add' && this.originConfiguration !== form.configuration) {
|
||||
$confirm(i18n.t('datasource.edit_datasource_msg'), () => {
|
||||
method(form).then(res => {
|
||||
this.$success(i18n.t('commons.save_success'))
|
||||
this.refreshType(form)
|
||||
this.backToList()
|
||||
})
|
||||
})
|
||||
} else {
|
||||
method(form).then(res => {
|
||||
this.$success(i18n.t('commons.save_success'))
|
||||
this.refreshType(form)
|
||||
this.backToList()
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (!valid) {
|
||||
return false
|
||||
}
|
||||
const method = this.formType === 'add' ? addDs : editDs
|
||||
const form = JSON.parse(JSON.stringify(this.form))
|
||||
form.configuration = JSON.stringify(form.configuration)
|
||||
if (this.formType === 'modify' && this.originConfiguration !== form.configuration) {
|
||||
if(repeat){
|
||||
$confirm(i18n.t('datasource.repeat_datasource_msg') + '[' + repeatDsName + '], ' + i18n.t('datasource.confirm_save'), () => {
|
||||
$confirm(i18n.t('datasource.edit_datasource_msg'), () => {
|
||||
this.method(method, form)
|
||||
})
|
||||
})
|
||||
}else {
|
||||
$confirm(i18n.t('datasource.edit_datasource_msg'), () => {
|
||||
this.method(method, form)
|
||||
})
|
||||
}
|
||||
return
|
||||
}
|
||||
if(repeat){
|
||||
$confirm(i18n.t('datasource.repeat_datasource_msg') + '[' + repeatDsName + '], ' + i18n.t('datasource.confirm_save'), () => {
|
||||
this.method(method, form)
|
||||
})
|
||||
}else {
|
||||
this.method(method, form)
|
||||
}
|
||||
})
|
||||
},
|
||||
method(method, form){
|
||||
method(form).then(res => {
|
||||
this.$success(i18n.t('commons.save_success'))
|
||||
this.refreshType(form)
|
||||
this.backToList()
|
||||
})
|
||||
},
|
||||
getSchema() {
|
||||
|
@ -54,7 +54,7 @@ export default {
|
||||
border: lightgray solid 1px;
|
||||
border-radius: 0px 5px 5px 5px;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
90
frontend/src/views/wizard/details/CardDetail.vue
Normal file
@ -0,0 +1,90 @@
|
||||
<template>
|
||||
<el-row
|
||||
class="demo_main"
|
||||
>
|
||||
<div class="demo_title">
|
||||
<a target="_blank" :href="details.href">
|
||||
<img
|
||||
:src="require('../../../assets/DataEase-' +imgIndex + '.jpg')"
|
||||
height="100%"
|
||||
>
|
||||
</a>
|
||||
</div>
|
||||
<div class="demo_content">
|
||||
<el-row class="head">
|
||||
<span>{{ details.head }}</span>
|
||||
</el-row>
|
||||
<el-row class="content">
|
||||
<span v-html="details.content" />
|
||||
</el-row>
|
||||
<el-row class="bottom">
|
||||
<span class="span-box">{{ details.bottom }}</span>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'CardDetail',
|
||||
props: {
|
||||
imgIndex: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
details: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
imgSrc: '../../../assets/DataEase-' + this.imgIndex + '.jpg'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
::v-deep a:hover{color:blue;}
|
||||
.demo_main{
|
||||
height: 100%;
|
||||
}
|
||||
.demo_title{
|
||||
float: left;
|
||||
height: 100%;
|
||||
}
|
||||
.demo_content{
|
||||
margin: auto;
|
||||
padding-left: 15px;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
.head{
|
||||
padding-top: 24px;
|
||||
color: var(--TopTextColor, #000000);
|
||||
}
|
||||
.content{
|
||||
height: 50%;
|
||||
padding-top: 15px;
|
||||
padding-right: 10px;
|
||||
color: var(--TextPrimary, #6D6D6D);
|
||||
font-size: 12px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.bottom{
|
||||
height: 25%;
|
||||
.span-box{
|
||||
color: var(--TextPrimary, #6D6D6D);
|
||||
font-size: 12px;
|
||||
position: absolute;
|
||||
bottom: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
@ -1,13 +1,26 @@
|
||||
<template>
|
||||
<el-row class="demo_main">
|
||||
<el-row class="demo_content">
|
||||
<a :href="href" target="_blank">{{ title }}</a>
|
||||
<br>
|
||||
<span style="color: lightgray">{{ time }}</span>
|
||||
</el-row>
|
||||
<el-row class="demo_bottom">
|
||||
<a href="https://blog.fit2cloud.com/?cat=321" target="_blank">{{ $t('wizard.show_more') }}</a>
|
||||
</el-row>
|
||||
<el-row
|
||||
class="demo_main"
|
||||
>
|
||||
<div class="demo_title">
|
||||
<a target="_blank" :href="details.href">
|
||||
<img
|
||||
:src="require('../../../assets/DataEase-' +imgIndex + '.jpg')"
|
||||
height="100%"
|
||||
>
|
||||
</a>
|
||||
</div>
|
||||
<div class="demo_content">
|
||||
<el-row class="head">
|
||||
<span>{{ details.head }}</span>
|
||||
</el-row>
|
||||
<el-row class="content">
|
||||
<span v-html="details.content" />
|
||||
</el-row>
|
||||
<el-row class="bottom">
|
||||
<span class="span-box">{{ details.bottom }}</span>
|
||||
</el-row>
|
||||
</div>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
@ -16,13 +29,25 @@
|
||||
import { blogLastActive } from '@/api/wizard/wizard'
|
||||
|
||||
export default {
|
||||
name: 'LatestDevelopments',
|
||||
name: 'CardDetail',
|
||||
props: {
|
||||
imgIndex: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
details: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
title: '',
|
||||
href: '',
|
||||
time: ''
|
||||
blogsInfo: {},
|
||||
imgSrc: '../../../assets/DataEase-' + this.imgIndex + '.jpg'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
||||
},
|
||||
mounted() {
|
||||
this.init()
|
||||
@ -30,9 +55,7 @@ export default {
|
||||
methods: {
|
||||
init() {
|
||||
blogLastActive().then(res => {
|
||||
this.title = res.data.title
|
||||
this.href = res.data.href
|
||||
this.time = res.data.time
|
||||
this.blogsInfo = res.data[0]
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -43,23 +66,37 @@ export default {
|
||||
<style lang="scss" scoped>
|
||||
.demo_main{
|
||||
height: 100%;
|
||||
padding: 10px 20px 10px 20px;
|
||||
}
|
||||
.demo_title{
|
||||
float: left;
|
||||
height: 100%;
|
||||
}
|
||||
.demo_content{
|
||||
padding-left: 10px;
|
||||
float: left;
|
||||
font-weight: 500;
|
||||
color: var(--MenuActiveBG, #409EFF);
|
||||
max-height: 80%;
|
||||
margin: auto;
|
||||
padding-left: 15px;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.demo_bottom{
|
||||
position: absolute;
|
||||
left: 30px;
|
||||
bottom: 10px;
|
||||
font-weight: 500;
|
||||
color: var(--MenuActiveBG, #409EFF);
|
||||
.head{
|
||||
padding-top: 24px;
|
||||
color: var(--TopTextColor, #000000);
|
||||
}
|
||||
.content{
|
||||
height: 50%;
|
||||
padding-top: 15px;
|
||||
padding-right: 20px;
|
||||
color: var(--TextPrimary, #6D6D6D);
|
||||
font-size: 12px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.bottom{
|
||||
height: 25%;
|
||||
.span-box{
|
||||
color: var(--TextPrimary, #6D6D6D);
|
||||
font-size: 12px;
|
||||
position: absolute;
|
||||
bottom: 5px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
|
63
frontend/src/views/wizard/details/LatestDevelopmentsBack.vue
Normal file
@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<el-row class="demo_main">
|
||||
<el-row class="demo_content">
|
||||
<el-row v-for="(details,index) in blogsInfo" :key="index">
|
||||
<a :href="details.href" target="_blank">{{ details.title }}</a>
|
||||
<br>
|
||||
<span style="color: lightgray">{{ details.time }}</span>
|
||||
</el-row>
|
||||
</el-row>
|
||||
<el-row class="demo_bottom">
|
||||
<a href="https://blog.fit2cloud.com/?cat=321" target="_blank">{{ $t('wizard.show_more') }}</a>
|
||||
</el-row>
|
||||
</el-row>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import { blogLastActive } from '@/api/wizard/wizard'
|
||||
|
||||
export default {
|
||||
name: 'LatestDevelopments',
|
||||
data() {
|
||||
return {
|
||||
blogsInfo: []
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
blogLastActive().then(res => {
|
||||
this.blogsInfo = res.data
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.demo_main{
|
||||
height: 100%;
|
||||
padding: 10px 20px 10px 20px;
|
||||
}
|
||||
.demo_content{
|
||||
padding-left: 10px;
|
||||
float: left;
|
||||
font-weight: 500;
|
||||
color: var(--MenuActiveBG, #409EFF);
|
||||
max-height: 80%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.demo_bottom{
|
||||
position: absolute;
|
||||
left: 30px;
|
||||
bottom: 10px;
|
||||
font-weight: 500;
|
||||
color: var(--MenuActiveBG, #409EFF);
|
||||
}
|
||||
|
||||
</style>
|
@ -5,9 +5,9 @@
|
||||
<span class="hint_content">{{ $t('wizard.welcome_hint') }}</span>
|
||||
</el-row>
|
||||
<el-row class="card_container">
|
||||
<card v-for="(cardDetail,index) in cardList" :key="index" :head-info="cardDetail.headInfo">
|
||||
<component :is="cardDetail.component" />
|
||||
</card>
|
||||
<info-card v-for="(cardDetail,index) in cardList" :key="index">
|
||||
<component :is="cardDetail.component" :img-index="index" :details="cardDetail" />
|
||||
</info-card>
|
||||
</el-row>
|
||||
</el-row>
|
||||
</template>
|
||||
@ -21,38 +21,72 @@ import LatestDevelopments from '@/views/wizard/details/LatestDevelopments'
|
||||
import TeachingVideo from '@/views/wizard/details/TeachingVideo'
|
||||
import EnterpriseEdition from '@/views/wizard/details/EnterpriseEdition'
|
||||
import ContactUs from '@/views/wizard/details/ContactUs'
|
||||
import InfoCard from '@/views/wizard/infoCard'
|
||||
import CardDetail from '@/views/wizard/details/CardDetail'
|
||||
import { blogLastActive } from '@/api/wizard/wizard'
|
||||
|
||||
export default {
|
||||
name: 'Wizard',
|
||||
components: { Card, DemoVideo, OnlineDocument, LatestDevelopments, TeachingVideo, EnterpriseEdition, ContactUs },
|
||||
components: { InfoCard, Card, DemoVideo, OnlineDocument, LatestDevelopments, TeachingVideo, EnterpriseEdition, ContactUs, CardDetail },
|
||||
data() {
|
||||
return {
|
||||
cardList: [
|
||||
{
|
||||
headInfo: this.$t('wizard.demo_video'),
|
||||
component: 'DemoVideo'
|
||||
head: this.$t('wizard.demo_video'),
|
||||
content: this.$t('wizard.demo_video_hint'),
|
||||
bottom: '',
|
||||
href: 'https://www.bilibili.com/video/BV1UB4y1K7jA',
|
||||
component: 'CardDetail'
|
||||
},
|
||||
{
|
||||
headInfo: this.$t('wizard.online_document'),
|
||||
component: 'OnlineDocument'
|
||||
head: this.$t('wizard.online_document'),
|
||||
content: this.$t('wizard.online_document_hint'),
|
||||
bottom: '',
|
||||
href: 'https://dataease.io/docs/dev_manual/dev_manual/',
|
||||
component: 'CardDetail'
|
||||
},
|
||||
{
|
||||
headInfo: this.$t('wizard.latest_developments'),
|
||||
component: 'LatestDevelopments'
|
||||
head: this.$t('wizard.latest_developments'),
|
||||
content: '',
|
||||
bottom: '',
|
||||
href: 'https://blog.fit2cloud.com/?cat=321',
|
||||
component: 'CardDetail'
|
||||
},
|
||||
{
|
||||
headInfo: this.$t('wizard.teaching_video'),
|
||||
component: 'TeachingVideo'
|
||||
head: this.$t('wizard.teaching_video'),
|
||||
content: '<a href="https://live.vhall.com/v3/lives/subscribe/533874762" target="_blank"><span style="line-height: 30px">40分钟带你玩转 DataEase </span></a><br><a href="https://live.vhall.com/v3/lives/subscribe/903960272" target="_blank">用DataEase开源工具可视化 ClickHouse数据</a>',
|
||||
bottom: '',
|
||||
href: 'https://e.vhall.com/v3/user/home/45637107',
|
||||
component: 'CardDetail'
|
||||
},
|
||||
{
|
||||
headInfo: this.$t('wizard.enterprise_edition'),
|
||||
component: 'EnterpriseEdition'
|
||||
head: this.$t('wizard.enterprise_edition'),
|
||||
content: this.$t('wizard.enterprise_edition_hint1') + '<br>' + this.$t('wizard.enterprise_edition_hint2') + '<br>' + this.$t('wizard.enterprise_edition_hint3'),
|
||||
bottom: '',
|
||||
href: 'https://jinshuju.net/f/TK5TTd',
|
||||
component: 'CardDetail'
|
||||
},
|
||||
{
|
||||
headInfo: this.$t('wizard.contact_us'),
|
||||
component: 'ContactUs'
|
||||
head: this.$t('wizard.contact_us'),
|
||||
content: this.$t('wizard.email') + 'dataease@fit2cloud.com<br>' + this.$t('wizard.tel') + '400-052-0755<br>' + this.$t('wizard.web') + '<a target="_blank" href="https://www.dataease.io">www.dataease.io</a>',
|
||||
bottom: '',
|
||||
href: 'https://www.dataease.io',
|
||||
component: 'CardDetail'
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
blogLastActive().then(res => {
|
||||
const blogsInfo = res.data[0]
|
||||
this.cardList[2].content = blogsInfo.title
|
||||
this.cardList[2].bottom = blogsInfo.time
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,23 +96,25 @@ export default {
|
||||
.main_container {
|
||||
}
|
||||
.head {
|
||||
background-color: var(--MenuActiveBG, #409EFF);
|
||||
text-align: center;
|
||||
color: white;
|
||||
padding: 10px;
|
||||
margin-top: 25px;
|
||||
margin-top: 35px;
|
||||
background-size: 100% 100% !important;
|
||||
background-image: url('../../assets/banner.png');
|
||||
}
|
||||
.hint_head {
|
||||
line-height: 40px;
|
||||
line-height: 50px;
|
||||
font-weight: bold;
|
||||
font-size: 25px;
|
||||
}
|
||||
.hint_content {
|
||||
line-height: 40px;
|
||||
line-height: 50px;
|
||||
font-size: 15px;
|
||||
}
|
||||
|
||||
.card_container {
|
||||
vertical-align: middle;
|
||||
|
||||
}
|
||||
</style>
|
||||
|
36
frontend/src/views/wizard/infoCard.vue
Normal file
@ -0,0 +1,36 @@
|
||||
<template>
|
||||
<el-col :span="8" class="card_main">
|
||||
<el-row class="card_content">
|
||||
<slot />
|
||||
</el-row>
|
||||
</el-col>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
export default {
|
||||
name: 'InfoCard',
|
||||
props: {
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.card_main{
|
||||
padding: 5% 25px 30px 25px;
|
||||
min-height: 250px;
|
||||
height: 33vh;
|
||||
max-height: 300px;
|
||||
}
|
||||
.card_content{
|
||||
border: lightgray solid 1px;
|
||||
border-radius: 5px;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
</style>
|