Merge pull request #1657 from dataease/dev

Dev
This commit is contained in:
fit2cloudrd 2022-01-18 18:06:58 +08:00 committed by GitHub
commit cef9af2eb7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 469 additions and 108 deletions

View File

@ -38,6 +38,7 @@ DataEase 是开源的数据可视化分析工具,帮助用户快速分析数
- MongoDB
- Amazon Redshift
- Hive
- DB2
> 更多数据源支持持续增加中...

View File

@ -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();
}
}

View File

@ -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;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 125 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View File

@ -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: {

View File

@ -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: 'TimeoutWill 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:'
}
}

View File

@ -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() {

View File

@ -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: '网址:'
}
}

View File

@ -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: '网址:'
}
}

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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() {

View File

@ -54,7 +54,7 @@ export default {
border: lightgray solid 1px;
border-radius: 0px 5px 5px 5px;
height: 100%;
overflow: hidden;
overflow-y: auto;
}
</style>

View 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>

View File

@ -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>

View 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>

View File

@ -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>

View 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>