功能变化: 首页功能优化

pull/92/head
李强 2023-04-05 00:34:35 +08:00
parent 0cc16f29b4
commit 5dfeffc103
14 changed files with 671 additions and 275 deletions

View File

@ -123,6 +123,30 @@ util.randomString = function (e) {
return n
}
util.randomColor = function () {
const color = [
'#50A8F4FF',
'#FD6165FF',
'#E679D8FF',
'#F9AB5BFF'
]
const ran = Math.floor(Math.random() * color.length)
return color[ran]
}
util.randomBackground = function () {
const background = [
'linear-gradient(150deg, #accaff 0%, #3b88ec 100%)',
'linear-gradient(150deg, #c5f8e6 0%, #10a465 100%)',
'linear-gradient(150deg, #e8d6ff 0%, #9f55ff 100%)',
'linear-gradient(150deg, #fdda45 0%, #fe6b62 100%)',
'linear-gradient(150deg, #cefbc8 0%, #00aec5 100%)',
'linear-gradient(150deg, #c5f8e6 0%, #10a465 100%)'
]
const ran = Math.floor(Math.random() * background.length)
return background[ran]
}
util.ArrayToTree = function (rootList, parentValue, parentName, list) {
for (const item of rootList) {
if (item.parent === parentValue) {

View File

@ -34,11 +34,13 @@ import md5 from 'js-md5'
// websocket
import websocket from '@/api/websocket'
import util from '@/libs/util'
// 核心插件
Vue.use(d2Admin)
Vue.use(VXETable)
Vue.prototype.$md5 = md5
Vue.prototype.$util = util
Vue.prototype.$websocket = websocket
new Vue({

View File

@ -1,11 +1,10 @@
<template>
<el-card shadow="hover" header="关于项目" class="card-view" :style="{backgroundColor:randomColor()}">
<p>后端:Django-rest-framework</p>
<p>前端:Vue2 + Element-UI + d2-crud-plus</p>
<p>快速系统开发平台,如果喜欢就点个星星支持一下</p>
<p>
<a href='https://liqianglog.gitee.io/django-vue-admin' target="_blank">
<img src='https://liqianglog.gitee.io/django-vue-admin/badge/star.svg?theme=dark' alt='star' style="vertical-align: middle">
<el-card shadow="hover" header="关于项目" class="card-view" :style="{backgroundColor:randomColor()}">
<p>基于RBAC模型的权限控制的一整套基础开发平台前后端分离后端采用 django+django-rest-framework前端采用
vue+ElementUI+d2-crud-plus如果喜欢就点个星星支持一下
<a href='https://gitee.com/liqianglog/django-vue-admin'>
<img src='https://gitee.com/liqianglog/django-vue-admin/badge/star.svg?theme=dark' alt='star'
style="position: absolute;right: 20px;bottom: 10px;"/>
</a>
</p>
</el-card>
@ -16,36 +15,54 @@ export default {
title: '关于项目',
icon: 'el-icon-setting',
description: '点个星星支持一下',
height: 10,
height: 20,
width: 8,
minH: 10,
minW: 4,
minW: 2,
isResizable: true,
config: {
color: {
label: '背景颜色',
type: 'color',
value: '',
placeholder: '颜色为空则随机变换颜色'
}
},
props: {
config: {
type: Object,
required: false
}
},
data () {
return {}
},
methods:{
//
methods: {
//
randomColor () {
const color = [
'#50A8F4FF',
'#FD6165FF',
'#E679D8FF',
'#F9AB5BFF'
]
const ran = Math.floor(Math.random() * 4)
return color[ran]
if (this.config?.color?.value) {
return this.config.color.value
}
return this.color || this.$util.randomColor()
}
}
}
</script>
<style scoped lang="scss">
.card-view{
color: #FFFFFF;
p {
font-size: 0.7em;
.card-view {
color: #FFFFFF;
p {
font-size: 0.7em;
color: #FFFFFF;
}
}
.el-card{
height: 100%;
}
::v-deep .el-card__body {
height: 110px;
}
</style>

View File

@ -1,23 +0,0 @@
<template>
<el-card shadow="never" header="阿里云" class="item-background">
<img src="/image/card/ali.png" @click="Jump()" alt="阿里云" class="img-style">
</el-card>
</template>
<script>
export default {
title: '阿里云推广',
icon: 'el-icon-present',
description: '阿里云推广',
height: 15,
minH: 10,
width: 14,
minW: 10,
isResizable: true,
methods: {
Jump () {
window.open('https://www.aliyun.com/minisite/goods?userCode=jpef8a71&share_source=copy_link', '_black')
}
}
}
</script>

View File

@ -0,0 +1,70 @@
<template>
<el-card shadow="never" class="item-background">
<img :src="config.src.value || '/image/card/tencent.jpg'" @click="Jump()" class="img-style">
</el-card>
</template>
<script>
export default {
title: '宣传图',
icon: 'el-icon-medal',
height: 10,
width: 8,
minH: 10,
minW: 1,
maxW: 24,
maxH: 100,
isResizable: true,
config: {
src: {
label: '图片地址',
type: 'input',
value: '/image/card/tencent.jpg',
placeholder: '请输入图片地址',
rules: [{ required: true, message: '不能为空' }]
},
url: {
label: '跳转地址',
type: 'input',
placeholder: '请输入跳转地址',
value: 'https://cloud.tencent.com/act/cps/redirect?redirect=1060&cps_key=b302a514a6688aa30823fac954464e5d&from=console',
rules: [{ required: true, message: '不能为空' }]
}
},
props: {
config: {
type: Object,
required: false
}
},
description: '用于展示各种图片宣传页',
data () {
return {
}
},
methods: {
Jump () {
window.open(this.config.url.value, '_black')
}
}
}
</script>
<style scoped lang="scss">
.img-style {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border-radius: 4px;
cursor: pointer;
}
.el-card{
height: 100%;
}
::v-deep .el-card__body {
padding: 0;
border-radius: 4px;
}
</style>

View File

@ -1,23 +0,0 @@
<template>
<el-card shadow="never" header="短信服务" class="item-background">
<img src="/image/card/sms.png" @click="Jump()" alt="短信服务" class="img-style">
</el-card>
</template>
<script>
export default {
title: '短信服务',
icon: 'el-icon-message',
description: '点击跳转到短信服务',
height: 10,
minH: 10,
width: 5,
minW: 5,
isResizable: true,
methods: {
Jump () {
window.open('https://bbs.django-vue-admin.com/plugMarket/128.html', '_black')
}
}
}
</script>

View File

@ -1,31 +0,0 @@
<template>
<el-card shadow="never" header="腾讯云" class="item-background">
<img src="/image/card/tencent.jpg" @click="Jump()" alt="腾讯云" class="img-style">
</el-card>
</template>
<script>
export default {
title: '腾讯云推广',
icon: 'el-icon-medal',
description: '腾讯云推广',
height: 10,
minH: 10,
width: 5,
isResizable: true,
methods: {
Jump () {
window.open('https://cloud.tencent.com/act/cps/redirect?redirect=1060&cps_key=b302a514a6688aa30823fac954464e5d&from=console', '_black')
}
}
}
</script>
<style>
.img-style {
cursor: pointer;
height: 180px;
display: block;
margin: auto;
}
</style>

View File

@ -14,7 +14,7 @@ export default {
title: '时钟',
icon: 'el-icon-alarm-clock',
description: '演示部件效果',
height: 10,
height: 20,
minH: 10,
width: 8,
minW: 4,
@ -33,7 +33,7 @@ export default {
},
methods: {
showTime () {
this.time = dayjs().format('hh:mm:ss')
this.time = dayjs().format('HH:mm:ss')
this.day = dayjs().format('YYYY年MM月DD日')
}
}
@ -55,4 +55,11 @@ export default {
margin-top: 10px;
opacity: 0.7;
}
::v-deep .el-card__body {
height: 110px;
}
.el-card{
height: 100%;
}
</style>

View File

@ -14,7 +14,7 @@ export default {
title: '版本信息',
icon: 'el-icon-monitor',
description: '当前项目版本信息',
height: 10,
height: 20,
minH: 10,
width: 8,
minW: 4,
@ -44,16 +44,9 @@ export default {
gogit () {
window.open('https://gitee.com/liqianglog/django-vue-admin')
},
//
//
randomColor () {
const color = [
'#50A8F4FF',
'#FD6165FF',
'#E679D8FF',
'#F9AB5BFF'
]
const ran = Math.floor(Math.random() * 4)
return color[ran]
return this.color || this.$util.randomColor()
}
}
}
@ -67,4 +60,11 @@ export default {
//text-align: center;
}
}
::v-deep .el-card__body {
height: 110px;
}
.el-card{
height: 100%;
}
</style>

View File

@ -1,5 +1,5 @@
<template>
<el-card shadow="hover" header="欢迎">
<el-card shadow="hover" header="欢迎" style="background: linear-gradient(150deg, #3b88ec 0%, #accaff 100%);color: #fff;">
<div class="welcome">
<div class="logo">
<img src="/image/django-vue-admin.png">
@ -37,10 +37,10 @@ export default {
title: '欢迎',
icon: 'el-icon-present',
description: '项目特色以及文档链接',
height: 50,
minH: 50,
width: 8,
minW: 4,
height: 45,
minH: 45,
minW: 1,
isResizable: true,
data () {
return {}
@ -48,15 +48,19 @@ export default {
methods: {
godoc () {
window.open('https://www.django-vue-admin.com/')
},
//
randomColor () {
if (this.config?.color?.value) {
return this.config.color.value
}
return this.color || this.$util.randomColor()
}
}
}
</script>
<style scoped>
.welcome {
}
.welcome .logo {
text-align: center;
}
@ -108,6 +112,9 @@ export default {
.actions {
text-align: center;
margin: 40px 0 20px 0;
margin: 40rpx 0 20rpx 0;
}
.el-card{
height: 100%;
}
</style>

View File

@ -0,0 +1,70 @@
<template>
<div>
<el-drawer
:visible.sync="deviceUpgradeDrawer"
:size="500">
<div slot="title">
<span>部件配置</span>
<el-tag size="small" style="margin-left: 10px">{{ myComp.title }}</el-tag>
</div>
<!-- 组件内容 -->
<el-form ref="ruleForm" label-width="100px" class="demo-ruleForm">
<el-form-item
v-for="(item,index) in items.config"
:label="item.label"
:key="index"
:rules="item.rules">
<el-input v-if="item.type==='input'" v-model="item.value" :placeholder="item.placeholder || '请输入'"></el-input>
<el-color-picker v-if="item.type==='color'" v-model="item.value" show-alpha :predefine="predefineColors"></el-color-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="deviceUpgradeDrawer = false">保存</el-button>
<el-button @click="deviceUpgradeDrawer = false">关闭</el-button>
</el-form-item>
</el-form>
</el-drawer>
</div>
</template>
<script>
export default {
name: 'dashboardConfig',
data () {
return {
deviceUpgradeDrawer: false,
myComp: {},
items: {},
predefineColors: [
'#ff4500',
'#ff8c00',
'#ffd700',
'#90ee90',
'#00ced1',
'#1e90ff',
'#c71585',
'rgba(255, 69, 0, 0.68)',
'rgb(255, 120, 0)',
'hsv(51, 100, 98)',
'hsva(120, 40, 94, 0.5)',
'hsl(181, 100%, 37%)',
'hsla(209, 100%, 56%, 0.73)',
'#c7158577'
]
}
},
mounted () {
},
methods: {
initData (myComp, items) {
this.myComp = myComp
this.items = items
console.log(1112, this.myComp, this.items)
}
}
}
</script>
<style scoped>
</style>

View File

@ -1,42 +1,45 @@
<template>
<d2-container>
<div class="component-header">
<div class="set-btn-class">
<el-button v-if="customizing" type="primary" icon="el-icon-check" round @click="save"></el-button>
<suspended-library ref="suspendedLibrary">
<div class="set-btn-class" slot="callbackButton">
<el-button v-if="customizing" type="primary" icon="el-icon-check" round @click="save">&nbsp;&nbsp;
</el-button>
<el-button v-else type="primary" icon="el-icon-edit" round @click="custom"></el-button>
<el-button v-if="minimize" type="warning" icon="el-icon-plus" round @click="clickMinimize">&nbsp;&nbsp;
</el-button>
</div>
<div v-if="customizing" class="all-component-class">
<el-card style="margin-bottom: 20px">
<div slot="header">
<i class="el-icon-circle-plus"></i>
<span>添加部件</span>
<el-button-group style="float: right">
<el-button type="primary" size="mini" @click="backDefaul()"></el-button>
<el-button type="danger" size="mini" @click="close()"></el-button>
</el-button-group>
</div>
<div class="widgets-list">
<div v-if="myCompsList.length<=0" class="widgets-list-nodata">
<el-empty description="没有部件啦" :image-size="60"></el-empty>
</div>
<div v-for="item in myCompsList" :key="item.title" class="widgets-list-item" @drag="onDrag($event,item)"
@dragend="onDragend($event,item)" draggable="true"
unselectable="on">
<el-card style="width: 300px">
<div slot="header">
<i :class="item.icon"></i>
<span> {{ item.title }}</span>
<el-button type="primary" style="float: right;" size="mini" @click="push(item)"></el-button>
</div>
<div class="item-info">
<p>{{ item.description }}</p>
</div>
</el-card>
</div>
</div>
</el-card>
<div slot="operateButton">
<el-tooltip class="item" effect="dark" content="最小化" placement="top">
<el-button v-if="customizing" type="success" icon="el-icon-minus" circle size="mini"
@click="clickMinimize"></el-button>
</el-tooltip>
<el-tooltip class="item" effect="dark" content="恢复默认" placement="top">
<el-button v-if="customizing" type="primary" icon="el-icon-refresh-right" circle size="mini"
@click="backDefault()"></el-button>
</el-tooltip>
<el-tooltip class="item" effect="dark" content="关闭" placement="top">
<el-button v-if="customizing" type="danger" icon="el-icon-close" circle size="mini"
@click="close()"></el-button>
</el-tooltip>
</div>
</div>
<div slot="widgetsList">
<div v-if="myCompsList.length<=0" class="widgets-list-nodata">
<el-empty description="没有部件啦" :image-size="60"></el-empty>
</div>
<div class="widgetsListBox">
<span v-for="item in myCompsList" :key="item.title">
<el-tooltip class="item" effect="dark" :content="item.description" placement="top">
<div class="widgetsListItem" :style="{background: $util.randomBackground()}">
<span style="position: relative;right: 8px;float: right;top: -22px;cursor: pointer;" @click="push(item)">
<i class="el-icon-plus"></i>
</span>
<i :class="item.icon"></i> &nbsp;{{ item.title }}
</div>
</el-tooltip>
</span>
</div>
</div>
</suspended-library>
<div class="widgets" ref="widgets">
<div :class="['widgets-wrapper',customizing?'widgets-wrapper-bg':'']">
<div v-if="nowCompsList.length<=0" class="no-widgets">
@ -45,7 +48,7 @@
<grid-layout
ref="gridlayout"
:layout.sync="layout"
:col-num="24"
:col-num="colNum"
:row-height="1"
:is-draggable="customizing"
:vertical-compact="false"
@ -59,22 +62,31 @@
:w="item.w"
:h="item.h"
:i="item.i"
:minW="item.minW"
:minH="item.minH"
:maxW="item.maxW"
:maxH="item.maxH"
:key="index"
:isResizable="customizing"
>
<div v-if="customizing" class="customize-overlay">
<div v-if="customizing" class="customize-overlay">
<el-button v-if="item.config && Object.keys(item.config).length!==0" class="close" style="right: 60px;"
type="primary" plain icon="el-icon-setting" size="small"
@click="clickConfig(item,index)" circle></el-button>
<el-button class="close" type="danger" plain icon="el-icon-close" size="small"
@click="remove(index)"></el-button>
@click="remove(index)" circle></el-button>
<label>
<i :class="allComps[item.element].icon"></i>
{{ allComps[item.element].title }}</label>
</div>
<component :class="customizing?'set-component-bg':''" :is="allComps[item.element]"></component>
<component :class="customizing?'set-component-bg':''" :is="allComps[item.element]"
:config="item.config || {}"></component>
</grid-item>
</grid-layout>
</div>
</div>
<dashboard-config ref="dashboardConfig"></dashboard-config>
</d2-container>
</template>
@ -83,11 +95,14 @@ import draggable from 'vuedraggable'
import allComps from './components'
import util from '@/libs/util'
import VueGridLayout from 'vue-grid-layout'
import XEUtils from 'xe-utils'
const mouseXY = { x: null, y: null }
const DragPos = { x: 0, y: 0, w: 1, h: 1, i: null }
import SuspendedLibrary from '@/views/dashboard/workbench/suspendedLibrary'
import DashboardConfig from '@/views/dashboard/workbench/config'
import initData from './init.js'
export default {
components: {
DashboardConfig,
SuspendedLibrary,
draggable,
GridLayout: VueGridLayout.GridLayout,
GridItem: VueGridLayout.GridItem
@ -97,28 +112,16 @@ export default {
customizing: false,
allComps: allComps,
selectLayout: [],
defaultLayout: [
{ x: 0, y: 0, w: 50, h: 50, i: '0', element: 'welcome' },
{ x: 0, y: 52, w: 8, h: 16, i: '1', element: 'about' },
{ x: 8, y: 52, w: 8, h: 16, i: '2', element: 'time' },
{ x: 16, y: 52, w: 8, h: 20, i: '3', element: 'ver' }
],
layout: [
// { x: 0, y: 0, w: 2, h: 2, i: '0', element: 'welcome' },
// { x: 2, y: 0, w: 2, h: 4, i: '1', element: 'about' },
// { x: 4, y: 0, w: 2, h: 5, i: '2', element: 'time' },
// { x: 6, y: 0, w: 2, h: 3, i: '3', element: 'progress' }
]
defaultLayout: initData,
layout: [],
colNum: 24,
minimize: false
}
},
created () {
this.layout = JSON.parse(util.cookies.get('grid-layout') || JSON.stringify(this.defaultLayout))
},
mounted () {
document.addEventListener('dragover', function (e) {
mouseXY.x = e.clientX
mouseXY.y = e.clientY
}, false)
this.$emit('on-mounted')
},
computed: {
@ -131,8 +134,11 @@ export default {
icon: allComps[key].icon,
height: allComps[key].height,
width: allComps[key].width,
maxH: allComps[key].maxH || Infinity,
maxW: allComps[key].maxW || Infinity,
minH: allComps[key].minH || 1,
minW: allComps[key].minW || 1,
maxH: allComps[key].maxH || 100,
maxW: (allComps[key].maxW > this.colNum ? this.colNum : allComps[key].maxW) || Infinity,
config: allComps[key].config || {},
isResizable: allComps[key].isResizable || null,
description: allComps[key].description
})
@ -150,36 +156,31 @@ export default {
//
custom () {
this.customizing = true
this.$refs.suspendedLibrary.menu = true
const oldWidth = this.$refs.widgets.offsetWidth
this.$nextTick(() => {
const scale = this.$refs.widgets.offsetWidth / oldWidth
this.$refs.widgets.style.setProperty('transform', `scale(${scale})`)
})
},
//
setLayout (layout) {
//
},
getLayoutElementNumber (elementName) {
// var index = 0
// this.layout.map(res => {
// if (elementName === res.element) {
// index += 1
// }
// })
// return index + 1
return elementName + this.layout.length
},
//
push (item) {
console.log(1, item)
this.layout.push({
x: 6,
y: 0,
i: this.getLayoutElementNumber(item.key),
x: (this.layout.length * 2) % (this.colNum || 12),
y: this.layout.length + (this.colNum || 12),
w: item.width,
h: item.height,
minW: item.minW,
minH: item.minH,
maxW: item.maxW,
maxH: item.maxH,
config: item.config || {},
isResizable: item.isResizable || null,
i: this.getLayoutElementNumber(item.key),
element: item.key
})
},
@ -191,12 +192,16 @@ export default {
save () {
console.log(this.layout)
this.customizing = false
this.minimize = false
this.$refs.suspendedLibrary.menu = false
this.$refs.widgets.style.removeProperty('transform')
util.cookies.set('grid-layout', this.layout)
},
//
backDefaul () {
backDefault () {
this.customizing = false
this.minimize = false
this.$refs.suspendedLibrary.menu = false
this.$refs.widgets.style.removeProperty('transform')
this.layout = JSON.parse(JSON.stringify(this.defaultLayout))
util.cookies.remove('grid-layout')
@ -204,87 +209,50 @@ export default {
//
close () {
this.customizing = false
this.minimize = false
this.$refs.suspendedLibrary.menu = false
this.$refs.widgets.style.removeProperty('transform')
},
//
onDrag (e, item) {
const { key, width, height } = item
const parentRect = this.$refs.widgets.getBoundingClientRect()
let mouseInGrid = false
if (((mouseXY.x > parentRect.left) && (mouseXY.x < parentRect.right)) && ((mouseXY.y > parentRect.top) && (mouseXY.y < parentRect.bottom))) {
mouseInGrid = true
}
const cloneLayout = XEUtils.clone(this.layout, true)
if (mouseInGrid === true && (cloneLayout.findIndex(item => item.i === this.getLayoutElementNumber(key)) === -1)) {
// this.layout.push({
// x: (this.layout.length * 2) % (this.colNum || 12),
// y: this.layout.length + (this.colNum || 12), // puts it at the bottom
// w: width,
// h: height,
// i: this.getLayoutElementNumber(key),
// element: key
// })
}
const index = this.layout.findIndex(item => item.i === this.getLayoutElementNumber(key))
if (index !== -1) {
try {
this.$refs.gridlayout.$children[this.layout.length].$refs.item.style.display = 'none'
} catch {
}
const el = this.$refs.gridlayout.$children[index]
el.dragging = { top: mouseXY.y - parentRect.top, left: mouseXY.x - parentRect.left }
const new_pos = el.calcXY(mouseXY.y - parentRect.top, mouseXY.x - parentRect.left)
if (mouseInGrid === true) {
this.$refs.gridlayout.dragEvent('dragstart', this.getLayoutElementNumber(key), new_pos.x, new_pos.y, 1, 1)
DragPos.i = String(index)
DragPos.x = this.layout[index].x
DragPos.y = this.layout[index].y
}
if (mouseInGrid === false) {
this.$refs.gridlayout.dragEvent('dragend', this.getLayoutElementNumber(key), new_pos.x, new_pos.y, 1, 1)
this.layout = this.layout.filter(obj => obj.i !== this.getLayoutElementNumber(key))
}
}
//
clickMinimize () {
this.minimize = !this.minimize
this.$refs.suspendedLibrary.menu = !this.$refs.suspendedLibrary.menu
},
onDragend (e, item) {
const { key, width, height } = item
const parentRect = this.$refs.widgets.getBoundingClientRect()
let mouseInGrid = false
if (((mouseXY.x > parentRect.left) && (mouseXY.x < parentRect.right)) && ((mouseXY.y > parentRect.top) && (mouseXY.y < parentRect.bottom))) {
mouseInGrid = true
}
if (mouseInGrid === true) {
this.layout.push({
x: DragPos.x,
y: DragPos.y,
w: width,
h: height,
i: this.getLayoutElementNumber(key),
element: key
})
this.$refs.gridlayout.dragEvent('dragend', this.getLayoutElementNumber(key), DragPos.x, DragPos.y, 1, 1)
this.layout = this.layout.filter(obj => obj.i !== this.getLayoutElementNumber(key))
// UNCOMMENT below if you want to add a grid-item
/*
this.layout.push({
x: DragPos.x,
y: DragPos.y,
w: 1,
h: 1,
i: DragPos.i,
});
this.$refs.gridLayout.dragEvent('dragend', DragPos.i, DragPos.x,DragPos.y,1,1);
try {
this.$refs.gridLayout.$children[this.layout.length].$refs.item.style.display="block";
} catch {
}
*/
}
//
clickConfig (itme) {
this.$refs.dashboardConfig.deviceUpgradeDrawer = true
this.$refs.dashboardConfig.initData(this.allComps[itme.element], itme)
this.minimize = false
}
}
}
</script>
<style scoped lang="scss">
::v-deep .d2-container-full__body{
padding: 0!important;
}
.widgetsListItem {
width: 168px;
height: 75px;
border-radius: 4px 4px 4px 4px;
font-size: 16px;
font-family: Microsoft YaHei-Bold, Microsoft YaHei;
font-weight: bold;
color: #ffffff;
text-align: center;
margin-left: 7px;
line-height: 75px;
margin-bottom: 10px;
position: initial;
}
.widgetsListBox {
display: flex;
flex-wrap: wrap;
margin-top: 20px;
z-index: 999999;
}
.component-header {
background-color: #FFFFFF;
position: sticky;
@ -294,7 +262,6 @@ export default {
.set-btn-class {
float: right;
z-index: 99;
margin-bottom: 10px;
}
.all-component-class {
@ -326,9 +293,9 @@ export default {
opacity: 0.5;
}
.set-component-bg{
background:rgba(255, 255, 255, 0.5);
border: 1px solid rgba(0,0,0,.5);
.set-component-bg {
background: rgba(255, 255, 255, 0.5);
border: 1px solid rgba(0, 0, 0, .5);
}
.customize-overlay {
@ -370,8 +337,4 @@ export default {
right: 15px;
}
.customize-overlay .close:focus, .customize-overlay .close:hover {
background: #76B1F9;
}
</style>

View File

@ -0,0 +1,188 @@
const log = [
{
i: 'dashboardImg1',
x: 9,
y: 21,
w: 8,
h: 24,
minW: 1,
minH: 10,
maxW: 24,
maxH: 100,
config: {
src: {
label: '图片地址',
type: 'input',
value: '/image/card/tencent.jpg',
rules: [
{
required: true,
message: '不能为空'
}
]
},
url: {
label: '跳转地址',
type: 'input',
value: 'https://cloud.tencent.com/act/cps/redirect?redirect=1060&cps_key=b302a514a6688aa30823fac954464e5d&from=console',
rules: [
{
required: true,
message: '不能为空'
}
]
}
},
isResizable: true,
element: 'dashboardImg',
moved: false
},
{
i: 'dashboardImg2',
x: 9,
y: 0,
w: 15,
h: 21,
minW: 1,
minH: 10,
maxW: 24,
maxH: 100,
config: {
src: {
label: '图片地址',
type: 'input',
value: 'https://kfm-waiter.oss-cn-zhangjiakou.aliyuncs.com/dvadmin/img/aliyun-02.png',
placeholder: '请输入图片地址',
rules: [
{
required: true,
message: '不能为空'
}
]
},
url: {
label: '跳转地址',
type: 'input',
placeholder: '请输入跳转地址',
value: 'https://www.aliyun.com/minisite/goods?userCode=jpef8a71&share_source=copy_link',
rules: [
{
required: true,
message: '不能为空'
}
]
}
},
isResizable: true,
element: 'dashboardImg',
moved: false
},
{
i: 'time3',
x: 9,
y: 45,
w: 8,
h: 19,
minW: 4,
minH: 10,
maxW: null,
maxH: 100,
config: {},
isResizable: true,
element: 'time',
moved: false
},
{
i: 'ver4',
x: 17,
y: 45,
w: 7,
h: 19,
minW: 4,
minH: 10,
maxW: null,
maxH: 100,
config: {},
isResizable: true,
element: 'ver',
moved: false
},
{
i: 'about5',
x: 0,
y: 45,
w: 9,
h: 19,
minW: 2,
minH: 10,
maxW: null,
maxH: 100,
config: {
color: {
label: '背景颜色',
type: 'color',
value: null,
placeholder: '颜色为空则随机变换颜色'
}
},
isResizable: true,
element: 'about',
moved: false
},
{
i: 'welcome5',
x: 0,
y: 0,
w: 9,
h: 45,
minW: 1,
minH: 45,
maxW: null,
maxH: 100,
config: {},
isResizable: true,
element: 'welcome',
moved: false
},
{
i: 'dashboardImg6',
x: 17,
y: 21,
w: 7,
h: 24,
minW: 1,
minH: 10,
maxW: 24,
maxH: 100,
config: {
src: {
label: '图片地址',
type: 'input',
value: 'https://kfm-waiter.oss-cn-zhangjiakou.aliyuncs.com/dvadmin/img/chajianshichang.jpg',
placeholder: '请输入图片地址',
rules: [
{
required: true,
message: '不能为空'
}
]
},
url: {
label: '跳转地址',
type: 'input',
placeholder: '请输入跳转地址',
value: 'https://bbs.django-vue-admin.com/plugMarket.html',
rules: [
{
required: true,
message: '不能为空'
}
]
}
},
isResizable: true,
element: 'dashboardImg',
moved: false
}
]
export default log

View File

@ -0,0 +1,125 @@
<template>
<div>
<div class="sssss">
<div
class="callback float"
@click="onClick"
ref="fu"
>
<slot name="callbackButton"/>
</div>
<div
style="right: 0;position: fixed;bottom: 0;"
v-if="menu"
class="menuclass"
>
<div class="titlea">
添加部件 <i style="color: #409eff" class="el-icon-plus"></i>
<span class="operateCallback">
<slot name="operateButton"/>
</span>
</div>
<slot name="widgetsList"/>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'suspendedLibrary',
data () {
return {
menu: false,
isLoading: false,
background: [
'linear-gradient(150deg, #accaff 0%, #3b88ec 100%)',
'linear-gradient(150deg, #c5f8e6 0%, #10a465 100%)',
'linear-gradient(150deg, #e8d6ff 0%, #9f55ff 100%)',
'linear-gradient(150deg, #fdda45 0%, #fe6b62 100%)',
'linear-gradient(150deg, #cefbc8 0%, #00aec5 100%)',
'linear-gradient(150deg, #c5f8e6 0%, #10a465 100%)'
]
}
},
created () {
},
mounted () {
},
methods: {
onClick () {
this.$emit('click')
}
}
}
</script>
<style scoped>
.callback p {
font-size: 16px;
color: #fff;
background: rgba(56, 57, 58, 0.5);
border-radius: 50%;
text-align: center;
width: 50px;
height: 50px;
line-height: 50px;
font-family: PingFang SC;
font-weight: 600;
box-shadow: 0 0 10px #fff;
}
.callback img {
display: block;
width: 50px;
height: 50px;
box-shadow: 0 0 10px rgb(133, 129, 129);
border-radius: 50%;
background: #fff;
}
.operateCallback {
position: fixed;
height: 40px;
right: 10px;
z-index: 99999;
}
.callback {
position: fixed;
width: 40px;
height: 40px;
background-repeat: no-repeat;
background-size: 100% 100%;
bottom: 55px;
right: 45px;
z-index: 99999;
}
.float {
position: fixed;
touch-action: none;
text-align: center;
border-radius: 24px;
line-height: 48px;
color: white;
}
.menuclass {
text-align: left;
position: absolute;
color: #000;
width: 764px;
background: #ffffff;
box-shadow: 0px 6px 26px 1px rgba(51, 51, 51, 0.16);
padding: 20px;
}
.sssss {
position: relative;
background-color: #000;
right: 0;
z-index: 100;
}
.titlea {
font-size: 18px;
font-family: Microsoft YaHei-Bold, Microsoft YaHei;
font-weight: bold;
color: #333333;
}
</style>