parent
3a7d717fae
commit
595e1a06ed
@ -0,0 +1,230 @@
|
||||
<template>
|
||||
<div style="padding: 0 10px 20px 10px">
|
||||
<el-row :gutter="4">
|
||||
<el-col :span="4">
|
||||
<Card style="height: 100%">
|
||||
<template v-slot:title>
|
||||
<p>组件</p>
|
||||
</template>
|
||||
<div
|
||||
class="cpn-name__item"
|
||||
:class="{ 'cpn-name__item--disable': statusFormat(item.i) }"
|
||||
v-for="item in layout"
|
||||
:draggable="!statusFormat(item.i)"
|
||||
@dragend="dragEnd(item, $event)"
|
||||
>
|
||||
<i class="el-icon-folder-remove"></i>
|
||||
<span>{{ item.i }}</span>
|
||||
<Button
|
||||
v-show="statusFormat(item.i)"
|
||||
type="error"
|
||||
size="small"
|
||||
ghost
|
||||
@click="removeLayout(item.i)"
|
||||
>移除</Button
|
||||
>
|
||||
</div>
|
||||
</Card>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="20">
|
||||
<Card>
|
||||
<template v-slot:title>
|
||||
<div style="display: flex;justify-content: space-between;align-items: center;">
|
||||
<p>布局</p>
|
||||
<Button type="primary" style="float: right;" @click="save">保存</Button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<grid-layout
|
||||
id="grid-card"
|
||||
class="gird-card"
|
||||
:layout.sync="layoutList"
|
||||
:col-num="12"
|
||||
:row-height="40"
|
||||
:is-draggable="true"
|
||||
:is-resizable="true"
|
||||
:is-mirrored="false"
|
||||
:vertical-compact="true"
|
||||
:margin="[10, 10]"
|
||||
:autoSize="true"
|
||||
:use-css-transforms="true"
|
||||
>
|
||||
<grid-item
|
||||
v-for="item in layoutList"
|
||||
:x="item.x"
|
||||
:y="item.y"
|
||||
:w="item.w"
|
||||
:h="item.h"
|
||||
:i="item.i"
|
||||
:key="item.i"
|
||||
style="touch-action: none"
|
||||
>
|
||||
<component
|
||||
style="position: absolute; inset: 0 0 0 0"
|
||||
:is="item.component"
|
||||
></component>
|
||||
</grid-item>
|
||||
</grid-layout>
|
||||
</Card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import VueGridLayout from "vue-grid-layout";
|
||||
import path from "path";
|
||||
const files = require.context(
|
||||
"@/views/system/workerComponents",
|
||||
false,
|
||||
/.vue$/
|
||||
);
|
||||
let cpns = files.keys().map((key) => {
|
||||
return files(key).default || files(key);
|
||||
});
|
||||
const componentsRegister = () => {
|
||||
let obj = {};
|
||||
cpns.forEach((cpn) => {
|
||||
Object.defineProperty(obj, cpn.name, {
|
||||
value: cpn,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
configurable: true,
|
||||
});
|
||||
});
|
||||
obj["GridLayout"] = VueGridLayout.GridLayout;
|
||||
obj["GridItem"] = VueGridLayout.GridItem;
|
||||
return obj;
|
||||
};
|
||||
let layout = cpns.map((item) => {
|
||||
return {
|
||||
...item.layout,
|
||||
component: item,
|
||||
};
|
||||
});
|
||||
export default {
|
||||
components: componentsRegister(),
|
||||
data() {
|
||||
return {
|
||||
layout,
|
||||
layoutList: [],
|
||||
isDragEnter: false,
|
||||
|
||||
grid: {
|
||||
x: 0,
|
||||
y: 0,
|
||||
},
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
dragEnd(item, e) {
|
||||
if (e.clientX >= this.grid.x && e.clientY >= this.grid.y) {
|
||||
this.layoutList.push(item);
|
||||
}
|
||||
},
|
||||
|
||||
removeLayout(i) {
|
||||
let temp = -1;
|
||||
this.layoutList.forEach((item, index) => {
|
||||
if (i === item.i) {
|
||||
temp = index;
|
||||
}
|
||||
});
|
||||
this.layoutList.splice(temp, 1);
|
||||
},
|
||||
|
||||
save(){
|
||||
let layout = this.layoutList.map(item => {
|
||||
return {
|
||||
x:item.x,
|
||||
y:item.y,
|
||||
w:item.w,
|
||||
h:item.h,
|
||||
i:item.i
|
||||
}
|
||||
})
|
||||
this.$store.commit('app/SET_LAYOUT',layout)
|
||||
console.log(layout)
|
||||
this.$message({
|
||||
type:'success',
|
||||
message:'保存成功',
|
||||
offset:60
|
||||
})
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
statusFormat() {
|
||||
return function (i) {
|
||||
let iArr = this.layoutList.map((item) => item.i);
|
||||
return iArr.indexOf(i) !== -1;
|
||||
};
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.grid = document.getElementById("grid-card").getBoundingClientRect();
|
||||
},
|
||||
created() {
|
||||
this.layoutList = this.$store.state.app.workerLayout.map(item => {
|
||||
layout.forEach(lay => {
|
||||
lay.i === item.i ? item.component = lay.component : ''
|
||||
})
|
||||
return item
|
||||
})
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.gird-card {
|
||||
min-height: 200px;
|
||||
}
|
||||
.cpn-name__item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
color: rgb(100, 100, 100);
|
||||
border-radius: 4px;
|
||||
background-color: rgba(94, 181, 218, 0.3);
|
||||
cursor: move;
|
||||
|
||||
padding: 6px 6px;
|
||||
& > i {
|
||||
padding-right: 6px;
|
||||
}
|
||||
& > span {
|
||||
flex: 1;
|
||||
}
|
||||
& + div {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
&--disable {
|
||||
cursor: no-drop;
|
||||
background-color: rgba(218, 94, 98, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
.fade-in {
|
||||
animation: fade-in 800ms cubic-bezier(0.39, 0.575, 0.565, 1) both;
|
||||
}
|
||||
@keyframes fade-in {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
.fade-out {
|
||||
animation: fade-out 600ms ease-out both;
|
||||
}
|
||||
@keyframes fade-out {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<el-card class="box-card" shadow="hover">
|
||||
<div slot="header">
|
||||
<span style="border-left: 3px solid #338DE3FF;padding-left: 6px;">进度</span>
|
||||
<i class="el-icon-more" style="float: right;font-size: 20px;"></i>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<el-progress type="circle" :percentage="25"></el-progress>
|
||||
<el-progress type="circle" :percentage="100" status="success"></el-progress>
|
||||
</div>
|
||||
<div>
|
||||
<el-progress type="circle" :percentage="70" status="warning"></el-progress>
|
||||
<el-progress type="circle" :percentage="50" status="exception"></el-progress>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name:"card1",
|
||||
layout:{
|
||||
x:0,
|
||||
y:0,
|
||||
w:4,
|
||||
h:5,
|
||||
i:"card1"
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
methods: {},
|
||||
computed: {},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
@ -0,0 +1,37 @@
|
||||
<template>
|
||||
<el-card class="box-card" shadow="hover">
|
||||
<div slot="header">
|
||||
<span style="border-left: 3px solid #338DE3FF;padding-left: 6px;">卡片名称</span>
|
||||
<i class="el-icon-more" style="float: right;font-size: 20px;"></i>
|
||||
</div>
|
||||
<div>
|
||||
<el-progress :percentage="50"></el-progress>
|
||||
<el-progress :percentage="100" status="success"></el-progress>
|
||||
<el-progress :percentage="100" status="warning"></el-progress>
|
||||
<el-progress :percentage="50" status="exception"></el-progress>
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name:'card2',
|
||||
layout:{
|
||||
x:4,
|
||||
y:0,
|
||||
w:6,
|
||||
h:4,
|
||||
i:"card2"
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
||||
}
|
||||
},
|
||||
methods: {},
|
||||
computed: {},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
@ -0,0 +1,114 @@
|
||||
<template>
|
||||
<el-card class="box-card" shadow="hover">
|
||||
<div slot="header">
|
||||
<span style="border-left: 3px solid #338DE3FF;padding-left: 6px;">图表1</span>
|
||||
<i class="el-icon-more" style="float: right;font-size: 20px;"></i>
|
||||
</div>
|
||||
|
||||
<div id="line-chart" style="width: 100%;height: 200px;">
|
||||
</div>
|
||||
</el-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import echarts from 'echarts'
|
||||
import ElementResize from "element-resize-detector";
|
||||
require('echarts/theme/macarons') // echarts theme
|
||||
|
||||
const animationDuration = 6000
|
||||
export default {
|
||||
name:'card4',
|
||||
layout:{
|
||||
x:6,
|
||||
y:5,
|
||||
w:6,
|
||||
h:4,
|
||||
i:"card4"
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
lineChartOption: {
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
legend: {},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
|
||||
},
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
axisLabel: {
|
||||
formatter: '{value} °C'
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: 'Highest',
|
||||
type: 'line',
|
||||
data: [10, 11, 13, 11, 12, 12, 9],
|
||||
markPoint: {
|
||||
data: [
|
||||
{type: 'max', name: 'Max'},
|
||||
{type: 'min', name: 'Min'}
|
||||
]
|
||||
},
|
||||
markLine: {
|
||||
data: [{type: 'average', name: 'Avg'}]
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Lowest',
|
||||
type: 'line',
|
||||
data: [1, -2, 2, 5, 3, 2, 0],
|
||||
markPoint: {
|
||||
data: [{name: '周最低', value: -2, xAxis: 1, yAxis: -1.5}]
|
||||
},
|
||||
markLine: {
|
||||
data: [
|
||||
{type: 'average', name: 'Avg'},
|
||||
[
|
||||
{
|
||||
symbol: 'none',
|
||||
x: '90%',
|
||||
yAxis: 'max'
|
||||
},
|
||||
{
|
||||
symbol: 'circle',
|
||||
label: {
|
||||
position: 'start',
|
||||
formatter: 'Max'
|
||||
},
|
||||
type: 'max',
|
||||
name: '最高点'
|
||||
}
|
||||
]
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initChart(id,options){
|
||||
let dom = document.getElementById(id)
|
||||
echarts.init(dom,"macarons").setOption(options)
|
||||
const elementResize = ElementResize({
|
||||
strategy:'scroll'
|
||||
})
|
||||
elementResize.listenTo(dom,ele => {
|
||||
echarts.init(dom).resize();
|
||||
})
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
mounted() {
|
||||
this.initChart('line-chart',this.lineChartOption)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
</style>
|
||||
Loading…
Reference in new issue