功能变化: 1.新增自定义控制台;

2.修复消息中心bug;
3.修复用户导入密码bug
pull/89/head
猿小天 2023-02-26 21:36:09 +08:00
parent ace9c00531
commit ec1962db7f
9 changed files with 613 additions and 281 deletions

View File

@ -121,12 +121,12 @@ class MessageCenterCreateSerializer(CustomModelSerializer):
users = initial_data.get('target_user', []) users = initial_data.get('target_user', [])
if target_type in [1]: # 按角色 if target_type in [1]: # 按角色
target_role = initial_data.get('target_role',[]) target_role = initial_data.get('target_role',[])
users = Users.objects.exclude(is_deleted=True).filter(role__id__in=target_role).values_list('id', flat=True) users = Users.objects.filter(role__id__in=target_role).values_list('id', flat=True)
if target_type in [2]: # 按部门 if target_type in [2]: # 按部门
target_dept = initial_data.get('target_dept',[]) target_dept = initial_data.get('target_dept',[])
users = Users.objects.exclude(is_deleted=True).filter(dept__id__in=target_dept).values_list('id', flat=True) users = Users.objects.filter(dept__id__in=target_dept).values_list('id', flat=True)
if target_type in [3]: # 系统通知 if target_type in [3]: # 系统通知
users = Users.objects.exclude(is_deleted=True).values_list('id', flat=True) users = Users.objects.values_list('id', flat=True)
targetuser_data = [] targetuser_data = []
for user in users: for user in users:
targetuser_data.append({ targetuser_data.append({

View File

@ -219,10 +219,12 @@ class ExportUserProfileSerializer(CustomModelSerializer):
class UserProfileImportSerializer(CustomModelSerializer): class UserProfileImportSerializer(CustomModelSerializer):
password = serializers.CharField(required=True, max_length=50, error_messages={"required": "登录密码不能为空"})
def save(self, **kwargs): def save(self, **kwargs):
data = super().save(**kwargs) data = super().save(**kwargs)
password = hashlib.new( password = hashlib.new(
"md5", str(self.initial_data.get("password", "")).encode(encoding="UTF-8") "md5", str(self.initial_data.get("password", "admin123456")).encode(encoding="UTF-8")
).hexdigest() ).hexdigest()
data.set_password(password) data.set_password(password)
data.save() data.save()

View File

@ -42,6 +42,7 @@
"sortablejs": "^1.10.1", "sortablejs": "^1.10.1",
"ua-parser-js": "^0.7.20", "ua-parser-js": "^0.7.20",
"vue": "2.7.14", "vue": "2.7.14",
"vue-grid-layout": "^2.4.0",
"vue-i18n": "^8.15.1", "vue-i18n": "^8.15.1",
"vue-infinite-scroll": "^2.0.2", "vue-infinite-scroll": "^2.0.2",
"vue-router": "^3.6.5", "vue-router": "^3.6.5",

View File

@ -0,0 +1,32 @@
<template>
<el-card shadow="hover" header="关于项目" class="item-background">
<p>高性能 / 精致 / 优雅基于Vue2 + Element-UI 的中后台前端解决方案如果喜欢就点个星星支持一下</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">
</a>
</p>
</el-card>
</template>
<script>
export default {
title: '关于项目',
icon: 'el-icon-setting',
description: '点个星星支持一下',
height: 20,
width: 8,
minH: 20,
minW: 4,
isResizable: true,
data () {
return {}
}
}
</script>
<style scoped>
.item-background p {
color: #999;
}
</style>

View File

@ -0,0 +1,13 @@
import { markRaw } from 'vue'
const resultComps = {}
const requireComponent = require.context(
'./', // 在当前目录下查找
false, // 不遍历子文件夹
/\.vue$/ // 正则匹配 .vue结尾的文件
)
requireComponent.keys().forEach(fileName => {
const comp = requireComponent(fileName)
resultComps[fileName.replace(/^\.\/(.*)\.\w+$/, '$1')] = comp.default
})
export default markRaw(resultComps)

View File

@ -0,0 +1,58 @@
<template>
<el-card shadow="hover" header="时钟" class="item-background">
<div class="time">
<h2>{{ time }}</h2>
<p>{{ day }}</p>
</div>
</el-card>
</template>
<script>
import dayjs from 'dayjs'
export default {
title: '时钟',
icon: 'el-icon-alarm-clock',
description: '演示部件效果',
height: 17,
minH: 17,
width: 8,
minW: 4,
isResizable: true,
data () {
return {
time: '',
day: ''
}
},
mounted () {
this.showTime()
setInterval(() => {
this.showTime()
}, 1000)
},
methods: {
showTime () {
this.time = dayjs().format('hh:mm:ss')
this.day = dayjs().format('YYYY年MM月DD日')
}
}
}
</script>
<style scoped>
.item-background {
background: linear-gradient(to right, #8E54E9, #4776E6);
color: #fff;
}
.time h2 {
font-size: 40px;
}
.time p {
font-size: 14px;
margin-top: 10px;
opacity: 0.7;
}
</style>

View File

@ -0,0 +1,44 @@
<template>
<el-card shadow="hover" header="版本信息">
<div style="height: 70px;text-align: center;">
<h2 style="margin-top: 5px;">Dvadmin</h2>
<p style="margin-top: 5px;">最新版本 {{ ver }}</p>
</div>
<div style="margin-top: 5px;">
<el-button type="primary" plain round @click="golog"></el-button>
<el-button type="primary" plain round @click="gogit">gitee</el-button>
</div>
</el-card>
</template>
<script>
export default {
title: '版本信息',
icon: 'el-icon-monitor',
description: '当前项目版本信息',
height: 22,
width: 8,
minH: 22,
minW: 4,
isResizable: true,
data () {
return {
ver: 'loading...'
}
},
mounted () {
this.getVer()
},
methods: {
async getVer () {
this.ver = 'v2.0.9'
},
golog () {
window.open('https://gitee.com/liqianglog/django-vue-admin/releases')
},
gogit () {
window.open('https://gitee.com/liqianglog/django-vue-admin')
}
}
}
</script>

View File

@ -0,0 +1,113 @@
<template>
<el-card shadow="hover" header="欢迎">
<div class="welcome">
<div class="logo">
<img src="/image/django-vue-admin.png">
<h2>欢迎体验 Dvadmin</h2>
</div>
<div class="tips">
<div class="tips-item">
<div class="tips-item-icon">
<i class="el-icon-menu"></i>
</div>
<div class="tips-item-message">这里是项目控制台你可以点击右上方的自定义按钮来添加移除或者移动部件</div>
</div>
<div class="tips-item">
<div class="tips-item-icon">
<i class="el-icon-star-on"></i>
</div>
<div class="tips-item-message">热爱Python和Vue,打造一个低代码开源平台并且持续着</div>
</div>
<div class="tips-item">
<div class="tips-item-icon">
<i class="el-icon-milk-tea"></i>
</div>
<div class="tips-item-message">项目目的让前端和后端工作更快乐</div>
</div>
</div>
<div class="actions">
<el-button type="primary" icon="el-icon-check" size="large" @click="godoc"></el-button>
</div>
</div>
</el-card>
</template>
<script>
export default {
title: '欢迎',
icon: 'el-icon-present',
description: '项目特色以及文档链接',
height: 50,
minH: 50,
width: 8,
minW: 4,
isResizable: true,
data () {
return {}
},
methods: {
godoc () {
window.open('https://www.django-vue-admin.com/')
}
}
}
</script>
<style scoped>
.welcome {
}
.welcome .logo {
text-align: center;
}
.welcome .logo img {
vertical-align: bottom;
width: 100px;
height: 100px;
margin-bottom: 20px;
}
.welcome .logo h2 {
font-size: 30px;
font-weight: normal;
display: flex;
align-items: center;
justify-content: center;
}
.tips {
margin-top: 20px;
padding: 0 40px;
}
.tips-item {
display: flex;
align-items: center;
justify-content: center;
padding: 7.5px 0;
}
.tips-item-icon {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
border-radius: 50%;
font-size: 18px;
margin-right: 20px;
color: var(--el-color-primary);
background: rgba(180, 180, 180, 0.1);
}
.tips-item-message {
flex: 1;
font-size: 14px;
}
.actions {
text-align: center;
margin: 40px 0 20px 0;
}
</style>

View File

@ -1,313 +1,382 @@
<template> <template>
<d2-container> <d2-container>
<div class="page-header"> <div class="component-header">
<div class="set-btn-class">
<el-avatar src="https://q1.qlogo.cn/g?b=qq&amp;nk=190848757&amp;s=640" class="user-avatar"> <el-button v-if="customizing" type="primary" icon="el-icon-check" round @click="save"></el-button>
<el-button v-else type="primary" icon="el-icon-edit" round @click="custom"></el-button>
</el-avatar>
<div class="title">
<h1>早安, DVAdmin, 开始您一天的工作吧</h1>
<span> 今日晴20 - 32 </span>
</div> </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>
<div class="widgets-list">
<el-row :gutter="20"> <div v-if="myCompsList.length<=0" class="widgets-list-nodata">
<el-col :span="12"> <el-empty description="没有部件啦" :image-size="60"></el-empty>
<el-card class="box-card">
<div slot="header" class="clearfix">
<span>友情链接</span>
<el-button style="float: right; padding: 3px 0" type="text">
<el-link href="https://bbs.django-vue-admin.com" target="_blank" type="primary">更多</el-link>
</el-button>
</div> </div>
<el-row> <div v-for="item in myCompsList" :key="item.title" class="widgets-list-item" @drag="onDrag($event,item)"
<el-col :span="8" v-for="({name,imageUrl,slogan,link},index) in projects" :key="index"> @dragend="onDragend($event,item)" draggable="true"
<el-card shadow="hover" style="padding: 0"> unselectable="on">
<div class="project-detail"> <el-card style="width: 300px">
<div> <div slot="header">
<a :href="link" target="_blank"> <i :class="item.icon"></i>
<img :src="imageUrl" alt=""> <span> {{ item.title }}</span>
<span v-text="name" class="name"></span> <el-button type="primary" style="float: right;" size="mini" @click="push(item)"></el-button>
</a>
</div> </div>
<div v-text="slogan" class="slogan" :title="slogan"></div> <div class="item-info">
</div> <p>{{ item.description }}</p>
</el-card>
</el-col>
</el-row>
</el-card>
</el-col>
<el-col :span="12">
<div class="grid-content bg-purple">
<el-card class="box-card" >
<div slot="header" class="clearfix">
<span>快捷导航</span>
</div>
<el-row>
<el-col :span="8" v-for="({name,icon,route,color},index) of navigators" :key="index" style="padding: 0">
<el-card shadow="hover">
<div style="display: flex;align-items: center;flex-direction: column;cursor: pointer" @click="()=>{gotoRoute(route)}">
<d2-icon-svg :name="icon" style="width: 25px;height: 25px;" :style="{fill:color}"/>
<div style="text-align: center;font-size: 12px;margin-top: 20px" v-text="name"></div>
</div>
</el-card>
</el-col>
</el-row>
</el-card>
<el-card class="box-card" style="margin-top: 25px">
<div class="work">
<d2-icon-svg name="work" style="margin-left: 50%;transform: translateX(-50%);height: 216px"/>
</div> </div>
</el-card> </el-card>
</div> </div>
</el-col> </div>
</el-row> </el-card>
</div>
</div>
<div class="widgets" ref="widgets">
<div :class="['widgets-wrapper',customizing?'widgets-wrapper-bg':'']">
<div v-if="nowCompsList.length<=0" class="no-widgets">
<el-empty image="img/no-widgets.svg" description="没有部件啦" :image-size="280"></el-empty>
</div>
<grid-layout
ref="gridlayout"
:layout.sync="layout"
:col-num="24"
:row-height="1"
:is-draggable="customizing"
:vertical-compact="false"
:use-css-transforms="true"
:autoSize="true"
>
<grid-item v-for="(item, index) in layout"
:static="item.static"
:x="item.x"
:y="item.y"
:w="item.w"
:h="item.h"
:i="item.i"
:key="index"
:isResizable="customizing"
>
<div v-if="customizing" class="customize-overlay">
<el-button class="close" type="danger" plain icon="el-icon-close" size="small"
@click="remove(index)"></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>
</grid-item>
</grid-layout>
</div>
</div>
</d2-container> </d2-container>
</template> </template>
<script> <script>
import { use } from 'echarts/core' import draggable from 'vuedraggable'
import { CanvasRenderer } from 'echarts/renderers' import allComps from './components'
import { PieChart } from 'echarts/charts' import util from '@/libs/util'
import { import VueGridLayout from 'vue-grid-layout'
TitleComponent, import XEUtils from 'xe-utils'
TooltipComponent, const mouseXY = { x: null, y: null }
LegendComponent const DragPos = { x: 0, y: 0, w: 1, h: 1, i: null }
} from 'echarts/components'
use([
CanvasRenderer,
PieChart,
TitleComponent,
TooltipComponent,
LegendComponent
])
export default { export default {
name: 'workbench', components: {
draggable,
GridLayout: VueGridLayout.GridLayout,
GridItem: VueGridLayout.GridItem
},
data () { data () {
return { return {
projects: [ customizing: false,
{ allComps: allComps,
name: '官方文档', selectLayout: [],
imageUrl: '/image/django-vue-admin.png', defaultGrid: {
slogan: 'Django-Vue-Admin 是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。', // [24] [18,6] [8,8,8] [6,12,6]
link: 'http://django-vue-admin.com' layout: [12, 6, 6],
// com:views/home/components
copmsList: [
['welcome'],
['about', 'ver'],
['time', 'progress']
]
}, },
{ defaultLayout: [],
name: '官方论坛', layout: [
imageUrl: '/image/django-vue-admin.png', // { x: 0, y: 0, w: 2, h: 2, i: '0', element: 'welcome' },
slogan: 'Django-Vue-Admin 官方论坛', // { x: 2, y: 0, w: 2, h: 4, i: '1', element: 'about' },
link: 'http://bbs.django-vue-admin.com' // { x: 4, y: 0, w: 2, h: 5, i: '2', element: 'time' },
}, // { x: 6, y: 0, w: 2, h: 3, i: '3', element: 'progress' }
{
name: 'D2admin',
imageUrl: '/image/d2-pub.png',
slogan: 'D2Admin (opens new window)是一个完全 开源免费 的企业中后台产品前端集成方案,使用最新的前端技术栈,' +
'小于 60kb 的本地首屏 js 加载,已经做好大部分项目前期准备工作,并且带有大量示例代码,助力管理系统快速开发。',
link: 'https://d2.pub/zh'
},
{
name: 'SimpleUi',
imageUrl: '/image/simple-ui.png',
slogan: '一个基于Django Admin的现代化主题。',
link: 'https://simpleui.72wo.com/'
},
{
name: '若依',
imageUrl: '/image/ruoyi.png',
slogan: '基于SpringBoot、Shiro、Mybatis的权限后台管理系统。',
link: 'http://ruoyi.vip/'
},
{
name: 'Gin-Vue-Admin',
imageUrl: '/image/gin-vue-admin.png',
slogan: '使用gin+vue进行极速开发的全栈后台管理系统。',
link: 'https://www.gin-vue-admin.com/'
},
{
name: 'DCM',
imageUrl: '/image/django-comment-migrate.png',
slogan: '这是一个Django model注释迁移的app',
link: 'https://github.com/starryrbs/django-comment-migrate'
},
{
name: 'Jetbrains',
imageUrl: '/image/jetbrains.jpeg',
slogan: '我们构建我们的软件,让您可以享受构建自己的软件的乐趣',
link: 'https://www.jetbrains.com/'
},
{
name: 'Django',
imageUrl: '/image/django.png',
slogan: '有期限的完美主义者的网络框架。',
link: 'https://github.com/django/django'
}
],
navigators: [
{
name: '控制台',
icon: 'home',
route: {
name: 'index'
},
color: 'rgb(31, 218, 202);'
},
{
name: '部门管理',
icon: 'department',
route: {
name: 'dept'
},
color: 'rgb(225, 133, 37);'
},
{
name: '角色管理',
icon: 'role',
route: {
name: 'role'
},
color: 'rgb(191, 12, 44);'
},
{
name: '菜单管理',
icon: 'menu',
route: {
name: 'menu'
},
color: 'rgb(63, 178, 127);'
},
{
name: '用户管理',
icon: 'user',
route: {
name: 'user'
},
color: 'rgb(191, 12, 44);'
},
{
name: '日志管理',
icon: 'log',
route: {
name: 'operationLog'
},
color: 'rgb(0, 216, 255);'
}
],
chartData: {
columns: ['日期', '销售额'],
rows: [
{ 日期: '1月1日', 销售额: 123 },
{ 日期: '1月2日', 销售额: 1223 },
{ 日期: '1月3日', 销售额: 2123 },
{ 日期: '1月4日', 销售额: 4123 },
{ 日期: '1月5日', 销售额: 3123 },
{ 日期: '1月6日', 销售额: 7123 }
] ]
} }
},
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: {
allCompsList () {
var allCompsList = []
for (var key in this.allComps) {
allCompsList.push({
key: key,
title: allComps[key].title,
icon: allComps[key].icon,
height: allComps[key].height,
width: allComps[key].width,
maxH: allComps[key].maxH || Infinity,
maxW: allComps[key].maxW || Infinity,
isResizable: allComps[key].isResizable || null,
description: allComps[key].description
})
}
return allCompsList
},
myCompsList () {
return this.allCompsList
},
nowCompsList () {
return this.allCompsList
} }
}, },
methods: { methods: {
gotoRoute (route) { //
this.$router.push(route) custom () {
this.customizing = 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,
w: item.width,
h: item.height,
isResizable: item.isResizable || null,
i: this.getLayoutElementNumber(item.key),
element: item.key
})
},
//
remove (index) {
this.layout.splice(index, 1)
},
//
save () {
console.log(this.layout)
this.customizing = false
this.$refs.widgets.style.removeProperty('transform')
util.cookies.set('grid-layout', this.layout)
},
//
backDefaul () {
this.customizing = false
this.$refs.widgets.style.removeProperty('transform')
this.layout = JSON.parse(JSON.stringify(this.defaultLayout))
util.cookies.remove('grid-layout')
},
//
close () {
this.customizing = 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))
}
}
},
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 {
}
*/
}
} }
} }
} }
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">
.component-header {
background-color: #FFFFFF;
position: sticky;
top: -20px;
z-index: 99;
$userAvatarLength: 72px; .set-btn-class {
float: right;
.page-header{ z-index: 99;
box-sizing: border-box; margin-bottom: 10px;
padding: 16px;
.user-avatar{
width: $userAvatarLength;
height: $userAvatarLength;
line-height: $userAvatarLength;
display: inline-block;
} }
.title{ .all-component-class {
display: inline-block; clear: right;
padding: 0 0 0 15px;
position: relative;
top: -5px;
h1{ .widgets-list {
font-size: 1.125rem; display: flex;
font-weight: 500; justify-content: space-between;
line-height: 1.75rem; overflow-x: scroll;
} padding-bottom: 10px;
span{
font-size: 14px; .widgets-list-item {
color: rgba(0,0,0,.45); margin-right: 10px;
}
} }
.widgets-list-item:last-child {
margin-right: 0px;
} }
}
}
}
.project-detail{ .widgets-wrapper-bg {
color: rgba(0,0,0,.45); background: rgba(180, 180, 180, .2);
height: 65px; min-height: 500px;
img { }
width: 25px;
height: 25px;
}
.name{
margin-left: 1rem;
font-size: 1rem;
line-height: 2rem;
height: 2rem;
display: inline-block;
color: rgba(0,0,0,.85);
position: relative;
top: -5px;
}
.slogan{
font-size: 12px;
padding: 5px 0;
overflow:hidden;
text-overflow:ellipsis;
white-space:nowrap;
}
.team{
font-size: 14px;
}
}
.activity{ .widgets-wrapper .sortable-ghost {
padding: 0; opacity: 0.5;
.activity-avatar{ }
width: 40px;
.set-component-bg{
background:rgba(255, 255, 255, 0.5);
border: 1px solid rgba(0,0,0,.5);
}
.customize-overlay {
position: absolute;
top: 0;
right: 0;
bottom: 5px;
left: 0;
z-index: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background: rgba(255, 255, 255, 0.5);
cursor: move;
}
.customize-overlay label {
background: #409EFF;
color: #fff;
height: 40px; height: 40px;
line-height: 40px; padding: 0 30px;
} border-radius: 40px;
.activity-detail{ font-size: 18px;
padding: 10px; display: flex;
line-height: 15px; align-items: center;
font-size: 14px; justify-content: center;
color: rgba(0,0,0,.85); cursor: move;
} }
}
.chart {
height: 408px;
}
.el-divider--horizontal{ .customize-overlay label i {
margin: 4px 0; margin-right: 15px;
background: 0 0; font-size: 24px;
border-top: 1px solid #e8eaec; }
.customize-overlay .close {
position: absolute;
top: 15px;
right: 15px;
}
.customize-overlay .close:focus, .customize-overlay .close:hover {
background: #76B1F9;
}
}
.el-card, .el-message {
border-radius: 0;
}
</style> </style>