构建框架
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<div v-if="pageLoading">
|
||||
<el-main>
|
||||
<el-card shadow="never">
|
||||
<el-skeleton :rows="1"></el-skeleton>
|
||||
</el-card>
|
||||
<el-card shadow="never" style="margin-top: 15px;">
|
||||
<el-skeleton></el-skeleton>
|
||||
</el-card>
|
||||
</el-main>
|
||||
</div>
|
||||
<work v-if="dashboard=='1'" @on-mounted="onMounted"></work>
|
||||
<widgets v-else @on-mounted="onMounted"></widgets>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineAsyncComponent } from 'vue';
|
||||
const work = defineAsyncComponent(() => import('./work'));
|
||||
const widgets = defineAsyncComponent(() => import('./widgets'));
|
||||
|
||||
export default {
|
||||
name: "dashboard",
|
||||
components: {
|
||||
work,
|
||||
widgets
|
||||
},
|
||||
data(){
|
||||
return {
|
||||
pageLoading: true,
|
||||
dashboard: '0'
|
||||
}
|
||||
},
|
||||
created(){
|
||||
this.dashboard = this.$TOOL.data.get("USER_INFO").dashboard || '0';
|
||||
},
|
||||
mounted(){
|
||||
|
||||
},
|
||||
methods: {
|
||||
onMounted(){
|
||||
this.pageLoading = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
@@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<el-card shadow="hover" header="关于项目" class="item-background">
|
||||
<p>高性能 / 精致 / 优雅。基于Vue3 + Element-Plus 的中后台前端解决方案,如果喜欢就点个星星支持一下。</p>
|
||||
<p>
|
||||
<a href='https://gitee.com/lolicode/scui' target="_blank">
|
||||
<img src='https://gitee.com/lolicode/scui/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: "点个星星支持一下",
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.item-background p {color: #999;margin-top:10px;line-height: 1.8;}
|
||||
</style>
|
||||
@@ -0,0 +1,98 @@
|
||||
<template>
|
||||
<el-card shadow="hover" header="实时收入" v-loading="loading">
|
||||
<scEcharts ref="c1" height="300px" :option="option"></scEcharts>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import scEcharts from '@/components/scEcharts';
|
||||
|
||||
export default {
|
||||
title: "实时收入",
|
||||
icon: "el-icon-data-line",
|
||||
description: "Echarts组件演示",
|
||||
components: {
|
||||
scEcharts
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
option: {}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
var _this = this;
|
||||
setTimeout(function() {
|
||||
_this.loading = false
|
||||
}, 500);
|
||||
|
||||
var option = {
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
xAxis: {
|
||||
boundaryGap: false,
|
||||
type: 'category',
|
||||
data: (function (){
|
||||
var now = new Date();
|
||||
var res = [];
|
||||
var len = 30;
|
||||
while (len--) {
|
||||
res.unshift(now.toLocaleTimeString().replace(/^\D*/,''));
|
||||
now = new Date(now - 2000);
|
||||
}
|
||||
return res;
|
||||
})()
|
||||
},
|
||||
yAxis: [{
|
||||
type: 'value',
|
||||
name: '价格',
|
||||
"splitLine": {
|
||||
"show": false
|
||||
}
|
||||
}],
|
||||
series: [
|
||||
{
|
||||
name: '收入',
|
||||
type: 'line',
|
||||
symbol: 'none',
|
||||
lineStyle: {
|
||||
width: 1,
|
||||
color: '#409EFF'
|
||||
},
|
||||
areaStyle: {
|
||||
opacity: 0.1,
|
||||
color: '#79bbff'
|
||||
},
|
||||
data: (function (){
|
||||
var res = [];
|
||||
var len = 30;
|
||||
while (len--) {
|
||||
res.push(Math.round(Math.random() * 0));
|
||||
}
|
||||
return res;
|
||||
})()
|
||||
},
|
||||
],
|
||||
};
|
||||
this.option = option;
|
||||
|
||||
},
|
||||
mounted(){
|
||||
var _this = this;
|
||||
setInterval(function (){
|
||||
var o = _this.option;
|
||||
|
||||
o.series[0].data.shift()
|
||||
o.series[0].data.push(Math.round(Math.random() * 100));
|
||||
|
||||
o.xAxis.data.shift();
|
||||
o.xAxis.data.push((new Date()).toLocaleTimeString().replace(/^\D*/, ''));
|
||||
|
||||
|
||||
//_this.$refs.c1.myChart.setOption(o)
|
||||
},2100)
|
||||
|
||||
},
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,12 @@
|
||||
import {markRaw} from 'vue';
|
||||
const resultComps = {}
|
||||
let requireComponent = require.context(
|
||||
'./', // 在当前目录下查找
|
||||
false, // 不遍历子文件夹
|
||||
/\.vue$/ // 正则匹配 以 .vue结尾的文件
|
||||
)
|
||||
requireComponent.keys().forEach(fileName => {
|
||||
let comp = requireComponent(fileName)
|
||||
resultComps[fileName.replace(/^\.\/(.*)\.\w+$/, '$1')] = comp.default
|
||||
})
|
||||
export default markRaw(resultComps)
|
||||
@@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<el-card shadow="hover" header="进度环">
|
||||
<div class="progress">
|
||||
<el-progress type="dashboard" :percentage="85.5" :width="160">
|
||||
<template #default="{ percentage }">
|
||||
<div class="percentage-value">{{ percentage }}%</div>
|
||||
<div class="percentage-label">当前进度</div>
|
||||
</template>
|
||||
</el-progress>
|
||||
</div>
|
||||
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
title: "进度环",
|
||||
icon: "el-icon-odometer",
|
||||
description: "进度环原子组件演示",
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.progress {text-align: center;}
|
||||
.progress .percentage-value {font-size: 28px;}
|
||||
.progress .percentage-label {font-size: 12px;margin-top: 10px;}
|
||||
</style>
|
||||
@@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<el-card shadow="hover" header="时钟" class="item-background">
|
||||
<div class="time">
|
||||
<h2>{{ time }}</h2>
|
||||
<p>{{ day }}</p>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
title: "时钟",
|
||||
icon: "el-icon-clock",
|
||||
description: "演示部件效果",
|
||||
data() {
|
||||
return {
|
||||
time: '',
|
||||
day: ''
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.showTime()
|
||||
setInterval(()=>{
|
||||
this.showTime()
|
||||
},1000)
|
||||
},
|
||||
methods: {
|
||||
showTime(){
|
||||
this.time = this.$TOOL.dateFormat(new Date(), 'hh:mm:ss')
|
||||
this.day = this.$TOOL.dateFormat(new Date(), '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: 13px;opacity: 0.7;}
|
||||
</style>
|
||||
@@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<el-card shadow="hover" header="版本信息">
|
||||
<div style="height: 210px;text-align: center;">
|
||||
<img src="img/ver.svg" style="height:140px"/>
|
||||
<h2 style="margin-top: 15px;">SCUI {{$CONFIG.CORE_VER}}</h2>
|
||||
<p style="margin-top: 5px;">最新版本 {{ver}}</p>
|
||||
</div>
|
||||
<div style="margin-top: 20px;">
|
||||
<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: "当前项目版本信息",
|
||||
data() {
|
||||
return {
|
||||
ver: 'loading...'
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.getVer()
|
||||
},
|
||||
methods: {
|
||||
async getVer(){
|
||||
const ver = await this.$API.demo.ver.get()
|
||||
this.ver = ver.data
|
||||
},
|
||||
golog(){
|
||||
window.open("https://gitee.com/lolicode/scui/releases")
|
||||
},
|
||||
gogit(){
|
||||
window.open("https://gitee.com/lolicode/scui")
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<el-card shadow="hover" header="欢迎">
|
||||
<div class="welcome">
|
||||
<div class="logo">
|
||||
<img src="img/logo.png">
|
||||
<h2>欢迎体验 SCUI</h2>
|
||||
</div>
|
||||
<div class="tips">
|
||||
<div class="tips-item">
|
||||
<div class="tips-item-icon"><el-icon><el-icon-menu/></el-icon></div>
|
||||
<div class="tips-item-message">这里是项目控制台,你可以点击右上方的“自定义”按钮来添加移除或者移动部件。</div>
|
||||
</div>
|
||||
<div class="tips-item">
|
||||
<div class="tips-item-icon"><el-icon><el-icon-promotion/></el-icon></div>
|
||||
<div class="tips-item-message">在提高前端算力、减少带宽请求和代码执行力上多次优化,并且持续着。</div>
|
||||
</div>
|
||||
<div class="tips-item">
|
||||
<div class="tips-item-icon"><el-icon><el-icon-milk-tea/></el-icon></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>
|
||||
|
||||
<el-card style="max-width: 480px">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>Card name</span>
|
||||
</div>
|
||||
</template>
|
||||
<p v-for="o in 4" :key="o" class="text item">{{ 'List item ' + o }}</p>
|
||||
<template #footer>Footer content</template>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
title: "欢迎",
|
||||
icon: "el-icon-present",
|
||||
description: "项目特色以及文档链接",
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
godoc(){
|
||||
window.open("https://lolicode.gitee.io/scui-doc/")
|
||||
}
|
||||
}
|
||||
}
|
||||
</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>
|
||||
@@ -0,0 +1,256 @@
|
||||
<template>
|
||||
<div :class="['widgets-home', customizing?'customizing':'']" ref="main">
|
||||
<div class="widgets-content">
|
||||
<div class="widgets-top">
|
||||
<div class="widgets-top-title">
|
||||
控制台
|
||||
</div>
|
||||
<div class="widgets-top-actions">
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
<div class="widgets" ref="widgets">
|
||||
<div class="widgets-wrapper">
|
||||
<div v-if="nowCompsList.length<=0" class="no-widgets">
|
||||
<el-empty image="img/no-widgets.svg" description="没有部件啦" :image-size="280"></el-empty>
|
||||
</div>
|
||||
<el-row :gutter="15">
|
||||
<el-col v-for="(item, index) in grid.layout" v-bind:key="index" :md="item" :xs="24">
|
||||
<draggable v-model="grid.copmsList[index]" animation="200" handle=".customize-overlay" group="people" item-key="com" dragClass="aaaaa" force-fallback fallbackOnBody class="draggable-box">
|
||||
<template #item="{ element }">
|
||||
<div class="widgets-item">
|
||||
<component :is="allComps[element]"></component>
|
||||
<div v-if="customizing" class="customize-overlay">
|
||||
<el-button class="close" type="danger" plain icon="el-icon-close" size="small" @click="remove(element)"></el-button>
|
||||
<label><el-icon><component :is="allComps[element].icon" /></el-icon>{{ allComps[element].title }}</label>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</draggable>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="customizing" class="widgets-aside">
|
||||
<el-container>
|
||||
<el-header>
|
||||
<div class="widgets-aside-title"><el-icon><el-icon-circle-plus-filled/></el-icon>添加部件</div>
|
||||
<div class="widgets-aside-close" @click="close()"><el-icon><el-icon-close /></el-icon></div>
|
||||
</el-header>
|
||||
<el-header style="height:auto">
|
||||
<div class="selectLayout">
|
||||
<div class="selectLayout-item item01" :class="{active:grid.layout.join(',')=='12,6,6'}" @click="setLayout([12,6,6])">
|
||||
<el-row :gutter="2">
|
||||
<el-col :span="12"><span></span></el-col>
|
||||
<el-col :span="6"><span></span></el-col>
|
||||
<el-col :span="6"><span></span></el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="selectLayout-item item02" :class="{active:grid.layout.join(',')=='24,16,8'}" @click="setLayout([24,16,8])">
|
||||
<el-row :gutter="2">
|
||||
<el-col :span="24"><span></span></el-col>
|
||||
<el-col :span="16"><span></span></el-col>
|
||||
<el-col :span="8"><span></span></el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
<div class="selectLayout-item item03" :class="{active:grid.layout.join(',')=='24'}" @click="setLayout([24])">
|
||||
<el-row :gutter="2">
|
||||
<el-col :span="24"><span></span></el-col>
|
||||
<el-col :span="24"><span></span></el-col>
|
||||
<el-col :span="24"><span></span></el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</div>
|
||||
</el-header>
|
||||
<el-main class="nopadding">
|
||||
<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">
|
||||
<div class="item-logo"><el-icon><component :is="item.icon" /></el-icon></div>
|
||||
<div class="item-info">
|
||||
<h2>{{ item.title }}</h2>
|
||||
<p>{{ item.description }}</p>
|
||||
</div>
|
||||
<div class="item-actions">
|
||||
<el-button type="primary" icon="el-icon-plus" size="small" @click="push(item)"></el-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</el-main>
|
||||
<el-footer style="height:51px;">
|
||||
<el-button size="small" @click="backDefaul()">恢复默认</el-button>
|
||||
</el-footer>
|
||||
</el-container>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import draggable from 'vuedraggable'
|
||||
import allComps from './components'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
draggable
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
customizing: false,
|
||||
allComps: allComps,
|
||||
selectLayout: [],
|
||||
defaultGrid: this.$CONFIG.DEFAULT_GRID,
|
||||
grid: []
|
||||
}
|
||||
},
|
||||
created(){
|
||||
this.grid = this.$TOOL.data.get("grid") || JSON.parse(JSON.stringify(this.defaultGrid))
|
||||
},
|
||||
mounted() {
|
||||
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,
|
||||
description: allComps[key].description
|
||||
})
|
||||
}
|
||||
var myCopmsList = this.grid.copmsList.reduce(function(a, b){return a.concat(b)})
|
||||
for(let comp of allCompsList){
|
||||
const _item = myCopmsList.find((item)=>{return item === comp.key})
|
||||
if(_item){
|
||||
comp.disabled = true
|
||||
}
|
||||
}
|
||||
return allCompsList
|
||||
},
|
||||
myCompsList(){
|
||||
var myGrid = this.$TOOL.data.get("DASHBOARDGRID")
|
||||
return this.allCompsList.filter(item => !item.disabled && myGrid.includes(item.key))
|
||||
},
|
||||
nowCompsList(){
|
||||
return this.grid.copmsList.reduce(function(a, b){return a.concat(b)})
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
//开启自定义
|
||||
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){
|
||||
this.grid.layout = layout
|
||||
if(layout.join(',')=='24'){
|
||||
this.grid.copmsList[0] = [...this.grid.copmsList[0],...this.grid.copmsList[1],...this.grid.copmsList[2]]
|
||||
this.grid.copmsList[1] = []
|
||||
this.grid.copmsList[2] = []
|
||||
}
|
||||
},
|
||||
//追加
|
||||
push(item){
|
||||
let target = this.grid.copmsList[0]
|
||||
target.push(item.key)
|
||||
},
|
||||
//隐藏组件
|
||||
remove(item){
|
||||
var newCopmsList = this.grid.copmsList
|
||||
newCopmsList.forEach((obj, index) => {
|
||||
var newObj = obj.filter(o=>o!=item)
|
||||
newCopmsList[index] = newObj;
|
||||
})
|
||||
},
|
||||
//保存
|
||||
save(){
|
||||
this.customizing = false
|
||||
this.$refs.widgets.style.removeProperty('transform')
|
||||
this.$TOOL.data.set("grid", this.grid)
|
||||
},
|
||||
//恢复默认
|
||||
backDefaul(){
|
||||
this.customizing = false
|
||||
this.$refs.widgets.style.removeProperty('transform')
|
||||
this.grid = JSON.parse(JSON.stringify(this.defaultGrid))
|
||||
this.$TOOL.data.remove("grid")
|
||||
},
|
||||
//关闭
|
||||
close(){
|
||||
this.customizing = false
|
||||
this.$refs.widgets.style.removeProperty('transform')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.widgets-home {display: flex;flex-direction: row;flex: 1;height: 100%;}
|
||||
.widgets-content {flex: 1;overflow: auto;overflow-x:hidden;padding:15px;}
|
||||
.widgets-aside {width: 360px;background: #fff;box-shadow: 0 0 10px rgba(0,0,0,.1);position: relative;overflow: auto;}
|
||||
.widgets-aside-title {font-size: 14px;display: flex;align-items: center;justify-content: center;}
|
||||
.widgets-aside-title i {margin-right: 10px;font-size: 18px;}
|
||||
.widgets-aside-close {font-size: 18px;width:30px;height: 30px;display: flex;align-items: center;justify-content: center;border-radius: 3px;cursor: pointer;}
|
||||
.widgets-aside-close:hover {background: rgba(180,180,180,0.1);}
|
||||
|
||||
.widgets-top {margin-bottom: 15px;display: flex;justify-content: space-between;align-items: center;}
|
||||
.widgets-top-title {font-size: 18px;font-weight: bold;}
|
||||
|
||||
.widgets {transform-origin: top left;transition: transform .15s;}
|
||||
|
||||
.draggable-box {height: 100%;}
|
||||
|
||||
.customizing .widgets-wrapper {margin-right:-360px}
|
||||
.customizing .widgets-wrapper .el-col {padding-bottom:15px;}
|
||||
.customizing .widgets-wrapper .draggable-box {border: 1px dashed var(--el-color-primary);padding:15px;}
|
||||
.customizing .widgets-wrapper .no-widgets {display: none;}
|
||||
.customizing .widgets-item {position: relative;margin-bottom: 15px;}
|
||||
.customize-overlay {position: absolute;top:0;right:0;bottom:0;left:0;z-index: 1;display: flex;flex-direction: column;align-items: center;justify-content: center;background: rgba(255,255,255,0.9);cursor: move;}
|
||||
.customize-overlay label {background: var(--el-color-primary);color: #fff;height:40px;padding:0 30px;border-radius: 40px;font-size: 18px;display: flex;align-items: center;justify-content: center;cursor: move;}
|
||||
.customize-overlay label i {margin-right: 15px;font-size: 24px;}
|
||||
.customize-overlay .close {position: absolute;top:15px;right:15px;}
|
||||
.customize-overlay .close:focus, .customize-overlay .close:hover {background: var(--el-button-hover-color);}
|
||||
|
||||
.widgets-list {}
|
||||
.widgets-list-item {display: flex;flex-direction: row;padding:15px;align-items: center;}
|
||||
.widgets-list-item .item-logo {width: 40px;height: 40px;border-radius: 50%;background: rgba(180,180,180,0.1);display: flex;align-items: center;justify-content: center;font-size: 18px;margin-right: 15px;color: #6a8bad;}
|
||||
.widgets-list-item .item-info {flex: 1;}
|
||||
.widgets-list-item .item-info h2 {font-size: 16px;font-weight: normal;cursor: default;}
|
||||
.widgets-list-item .item-info p {font-size: 12px;color: #999;cursor: default;}
|
||||
.widgets-list-item:hover {background: rgba(180,180,180,0.1);}
|
||||
|
||||
.widgets-wrapper .sortable-ghost {opacity: 0.5;}
|
||||
|
||||
.selectLayout {width: 100%;display: flex;}
|
||||
.selectLayout-item {width:60px;height:60px;border: 2px solid var(--el-border-color-light);padding:5px;cursor: pointer;margin-right: 15px;}
|
||||
.selectLayout-item span {display: block;background: var(--el-border-color-light);height:46px;}
|
||||
.selectLayout-item.item02 span {height:30px;}
|
||||
.selectLayout-item.item02 .el-col:nth-child(1) span {height:14px;margin-bottom: 2px;}
|
||||
.selectLayout-item.item03 span {height:14px;margin-bottom: 2px;}
|
||||
.selectLayout-item:hover {border-color: var(--el-color-primary);}
|
||||
.selectLayout-item.active {border-color: var(--el-color-primary);}
|
||||
.selectLayout-item.active span {background: var(--el-color-primary);}
|
||||
|
||||
|
||||
.dark {
|
||||
.widgets-aside {background: #2b2b2b;}
|
||||
.customize-overlay {background: rgba(43,43,43,0.9);}
|
||||
}
|
||||
|
||||
@media (max-width: 992px){
|
||||
.customizing .widgets {transform: scale(1) !important;}
|
||||
.customizing .widgets-aside {width: 100%;position: absolute;top:50%;right:0;bottom:0;}
|
||||
.customizing .widgets-wrapper {margin-right:0;}
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,131 @@
|
||||
<template>
|
||||
<div>
|
||||
<ul class="myMods">
|
||||
<li v-for="mod in myMods" :key="mod.path" :style="{background:mod.meta.color||'#909399'}">
|
||||
<a v-if="mod.meta.type=='link'" :href="mod.path" target="_blank">
|
||||
<el-icon><component :is="mod.meta.icon||el-icon-menu" /></el-icon>
|
||||
<p>{{ mod.meta.title }}</p>
|
||||
</a>
|
||||
<router-link v-else :to="{ path: mod.path }">
|
||||
<el-icon><component :is="mod.meta.icon||el-icon-menu" /></el-icon>
|
||||
<p>{{ mod.meta.title }}</p>
|
||||
</router-link>
|
||||
</li>
|
||||
<li class="modItem-add" @click="addMods">
|
||||
<a href="javascript:void(0)">
|
||||
<el-icon><el-icon-plus /></el-icon>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<el-drawer title="添加应用" v-model="modsDrawer" :size="570" destroy-on-close>
|
||||
<div class="setMods">
|
||||
<h4>我的常用 ( {{myMods.length}} )</h4>
|
||||
<draggable tag="ul" v-model="myMods" animation="200" item-key="path" group="people">
|
||||
<template #item="{ element }">
|
||||
<li :style="{background:element.meta.color||'#909399'}">
|
||||
<el-icon><component :is="element.meta.icon||el-icon-menu" /></el-icon>
|
||||
<p>{{element.meta.title}}</p>
|
||||
</li>
|
||||
</template>
|
||||
</draggable>
|
||||
</div>
|
||||
<div class="setMods">
|
||||
<h4>全部应用 ( {{filterMods.length}} )</h4>
|
||||
<draggable tag="ul" v-model="filterMods" animation="200" item-key="path" :sort="false" group="people">
|
||||
<template #item="{ element }">
|
||||
<li :style="{background:element.meta.color||'#909399'}">
|
||||
<el-icon><component :is="element.meta.icon||el-icon-menu" /></el-icon>
|
||||
<p>{{element.meta.title}}</p>
|
||||
</li>
|
||||
</template>
|
||||
</draggable>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button @click="modsDrawer=false">取消</el-button>
|
||||
<el-button type="primary" @click="saveMods">保存</el-button>
|
||||
</template>
|
||||
</el-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import draggable from 'vuedraggable'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
draggable
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
mods: [],
|
||||
myMods: [],
|
||||
myModsName: [],
|
||||
filterMods: [],
|
||||
modsDrawer: false
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
this.getMods()
|
||||
},
|
||||
methods: {
|
||||
addMods(){
|
||||
this.modsDrawer = true
|
||||
},
|
||||
getMods(){
|
||||
//这里可用改为读取远程数据
|
||||
this.myModsName = this.$TOOL.data.get("my-mods") || []
|
||||
var menuTree = this.$TOOL.data.get("MENU")
|
||||
this.filterMenu(menuTree)
|
||||
this.myMods = this.mods.filter(item => {
|
||||
return this.myModsName.includes(item.name)
|
||||
})
|
||||
this.filterMods = this.mods.filter(item => {
|
||||
return !this.myModsName.includes(item.name)
|
||||
})
|
||||
},
|
||||
filterMenu(map){
|
||||
map.forEach(item => {
|
||||
if(item.meta.hidden || item.meta.type=="button"){
|
||||
return false
|
||||
}
|
||||
if(item.meta.type=='iframe'){
|
||||
item.path = `/i/${item.name}`
|
||||
}
|
||||
if(item.children&&item.children.length > 0){
|
||||
this.filterMenu(item.children)
|
||||
}else{
|
||||
this.mods.push(item)
|
||||
}
|
||||
})
|
||||
},
|
||||
saveMods(){
|
||||
const myModsName = this.myMods.map(v => v.name)
|
||||
this.$TOOL.data.set("my-mods", myModsName)
|
||||
this.$message.success("设置常用成功")
|
||||
this.modsDrawer = false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.myMods {list-style:none;margin:-10px;}
|
||||
.myMods li {display: inline-block;width: 100px;height:100px;vertical-align: top;transition:all 0.3s ease;margin:10px;border-radius:5px;}
|
||||
.myMods li:hover {opacity: 0.8;}
|
||||
.myMods li a {width: 100%;height: 100%;padding:10px;display: flex;flex-direction: column;align-items: center;justify-content: center;text-align: center;color: #fff;}
|
||||
.myMods li i {font-size: 26px;color: #fff;}
|
||||
.myMods li p {font-size: 12px;color: #fff;margin-top: 10px;width: 100%;white-space:nowrap;text-overflow:ellipsis;overflow: hidden;}
|
||||
|
||||
.modItem-add {border: 1px dashed #ddd;cursor: pointer;}
|
||||
.modItem-add i {font-size: 30px;color: #999!important;}
|
||||
.modItem-add:hover,.modItem-add:hover i {border-color: #409EFF;color: #409EFF!important;}
|
||||
|
||||
.setMods {padding:0 20px;}
|
||||
.setMods h4 {font-size: 14px;font-weight: normal;}
|
||||
.setMods ul {margin:20px -5px;min-height: 90px;}
|
||||
.setMods li {display: inline-block;width: 80px;height:80px;text-align: center;margin:5px;color: #fff;vertical-align: top;padding:4px;padding-top:15px;cursor: move;border-radius: 3px;}
|
||||
.setMods li i {font-size: 20px;}
|
||||
.setMods li p {font-size: 12px;margin-top: 10px;}
|
||||
.setMods li.sortable-ghost {opacity: 0.3;}
|
||||
</style>
|
||||
@@ -0,0 +1,37 @@
|
||||
<template>
|
||||
<el-main>
|
||||
<el-alert title="根据角色配置,可让不同角色访问不同的控制台视图,参数值在登录成功后返回 dashboard:{type}" type="success" style="margin-bottom:20px;"></el-alert>
|
||||
<el-row :gutter="15">
|
||||
<el-col :lg="24">
|
||||
<el-card shadow="never" header="我的常用">
|
||||
<myapp></myapp>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</el-main>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import myapp from './components/myapp';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
myapp
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
mounted(){
|
||||
this.$emit('on-mounted')
|
||||
},
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user