整合大屏编辑页面

This commit is contained in:
LeonardYoung
2021-10-29 11:42:58 +08:00
parent b2f457f53c
commit a39ec38406
406 changed files with 34412 additions and 57 deletions

View File

@ -0,0 +1,40 @@
import { url } from '@/config';
// import axios from 'axios';
import request from '@/utils/request'
export const getList = (params) => request({
url: url + '/category/list',
method: 'get',
params: params
});
export const getObj = (id) => request({
url: url + '/category/detail',
method: 'get',
params: {
id
}
});
export const addObj = (data) => request({
url: url + '/category/save',
method: 'post',
data: data
});
export const updateObj = (data) => request({
url: url + '/category/update',
method: 'post',
data: data
});
export const delObj = (id) => request({
url: url + '/category/remove',
method: 'post',
params: {
ids: id
}
});

39
ruoyi-ui/src/api/map.js Normal file
View File

@ -0,0 +1,39 @@
import { url } from '@/config';
// var request = window.axios;
import request from '@/utils/request'
export const getList = (params) => request({
url: url + '/map/list',
method: 'get',
params: params
});
export const getObj = (id) => request({
url: url + '/map/detail',
method: 'get',
params: {
id
}
});
export const addObj = (data) => request({
url: url + '/map/save',
method: 'post',
data: data
});
export const updateObj = (data) => request({
url: url + '/map/update',
method: 'post',
data: data
});
export const delObj = (id) => request({
url: url + '/map/remove',
method: 'post',
params: {
ids: id
}
});

View File

@ -0,0 +1,94 @@
import { url } from '@/config';
// let url = '';
// var request = window.axios;
import request from '@/utils/request'
export const getList = (params) => request({
url: url + '/visual/list',
method: 'get',
params: params
});
export const copyObj = (id) => request({
url: url + '/visual/copy',
method: 'post',
params: {
id: id
}
});
export const getCategory = (params) => request({
url: url + '/category/list',
method: 'get',
params: params
});
export const getObj = (id) => request({
url: url + '/visual/detail',
method: 'get',
params: {
id
}
});
export const uploadImg = (file) => request({
url: url + '/visual/put-file',
method: 'post',
data: 'file=' + file,
headers: { "Content-Type": "multipart/form-data" }
});
export const addObj = (data) => request({
url: url + '/visual/save',
method: 'post',
data: {
visual: {
password: data.password,
category: data.category,
status: data.status,
title: data.title,
},
config: {
detail: JSON.stringify({
name: data.title,
width: data.width,
height: data.height,
scale: 1,
backgroundImage: '/img/bg/bg1.png',
url: '',
mark: {},
gradeShow: false,
gradeLen: 30,
}),
component: '[]'
},
}
});
export const updateComponent = (data) => request({
url: url + '/visual/update',
method: 'post',
data: data
});
export const updateObj = (data) => request({
url: url + '/visual/update',
method: 'post',
data: {
"visual": {
"id": data.id,
"password": data.password,
"category": data.category,
"status": data.status,
"title": data.title,
}
}
});
export const delObj = (id) => request({
url: url + '/visual/remove',
method: 'post',
params: {
ids: id
}
});

View File

@ -0,0 +1,15 @@
/**
* 自定义组件参考文档
* https://cn.vuejs.org/v2/guide/components-registration.html
*/
import Vue from 'vue'
import Test from './test/';
import My from './my/';
const list = [
Test,My
]
//循环注册组件
list.forEach(ele => {
Vue.component(`avue-echart-${ele.name}`, ele)
})

View File

@ -0,0 +1,31 @@
<template>
<div :style="{fontSize:fontSize,color:'#fff',border:'1px solid #fff',borderRadius:'20px'}">
<h2>自定义组件</h2>
<h3>我是参数:{{getContent}}</h3>
</div>
</template>
<script>
import { dicOption } from '@/option/config'
export default {
name: 'my',
props: {
option: Object,
component: Object
},
data () {
return {
dicOption: dicOption
}
},
computed: {
fontSize () {
return (this.option.fontSize || 30) + 'px'
},
getContent () {
return this.option.data;
}
}
}
</script>

View File

@ -0,0 +1,20 @@
<!-- 自定义配置 -->
<template>
<div>
<el-form-item label="字体大小">
<avue-input-number v-model="main.activeOption.fontSize"></avue-input-number>
</el-form-item>
<el-form-item label="文本内容">
<avue-input v-model="main.activeObj.data.value"></avue-input>
</el-form-item>
</div>
</template>
<script>
export default {
inject: ["main"]
}
</script>
<style>
</style>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@ -0,0 +1,8 @@
<svg width="200" xmlns="http://www.w3.org/2000/svg" height="200" viewBox="0 0 16.271 15.656" xmlns:xlink="http://www.w3.org/1999/xlink" enable-background="new 0 0 16.271 15.656" style="width: 1em; height: 1em; vertical-align: middle; fill: currentcolor; overflow: hidden; font-size: 200px;">
<path d="m2.842,13.67c.176,0 .318-.142 .318-.316v-5.455c0-.174-.143-.316-.318-.316h-1.215c-.177,0-.318,.143-.318,.316v5.455c0,.175 .142,.316 .318,.316h1.215z" fill="#ff1222"></path>
<path d="m15.762,14.201h-15.254c-.174,0-.317,.142-.317,.316v.822c0,.176 .144,.317 .317,.317h15.254c.176,0 .316-.142 .316-.317v-.822c0-.175-.14-.316-.316-.316z" fill="#ff1222"></path>
<path d="m6.777,13.67c.174,0 .316-.142 .316-.316v-5.455c0-.174-.143-.316-.316-.316h-1.217c-.174,0-.315,.143-.315,.316v5.455c0,.175 .142,.316 .315,.316h1.217z" fill="#ff1222"></path>
<path d="m14.646,13.67c.174,0 .317-.142 .317-.316v-5.455c0-.174-.144-.316-.317-.316h-1.218c-.175,0-.316,.143-.316,.316v5.455c0,.175 .142,.316 .316,.316h1.218z" fill="#ff1222"></path>
<path d="m15.858,5.798l-6.502-5.381c-.672-.555-1.77-.555-2.441,0l-6.5,5.381c-.674,.558-.509,1.012 .363,1.012h14.717c.87,0 1.034-.454 .363-1.012zm-7.723-.298c-.682,0-1.234-.554-1.234-1.235 0-.681 .553-1.233 1.234-1.233 .684,0 1.234,.552 1.234,1.233 0,.681-.55,1.235-1.234,1.235z" fill="#ff1222"></path>
<path d="m10.71,13.67c.176,0 .317-.142 .317-.316v-5.455c0-.174-.142-.316-.317-.316h-1.216c-.176,0-.317,.143-.317,.316v5.455c0,.175 .142,.316 .317,.316h1.216z" fill="#ff1222"></path>
</svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -0,0 +1,44 @@
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="200" height="200" viewBox="0 0 40 40" style="width: 1em; height: 1em; vertical-align: middle; fill: currentcolor; overflow: hidden; font-size: 200px;" xml:space="preserve">
<g id="_x34_27._Network">
<g>
<path d="M34,26c3.313,0,6-2.687,6-6c0-3.314-2.687-6.001-6-6.001c-2.612,0-4.827,1.672-5.651,4.001H17.463l12.74-7.355
C31.237,11.491,32.559,12,34,12c3.313,0,6-2.687,6-6c0-3.314-2.687-6-6-6c-3.314,0-6,2.686-6,6c0,0.42,0.044,0.829,0.126,1.225
l-16.944,9.783C10.146,15.214,8.22,14,6,14c-3.313,0-6,2.686-6,6c0,3.313,2.687,6,6,6c2.221,0,4.146-1.215,5.182-3.009
l16.944,9.783C28.044,33.17,28,33.58,28,34c0,3.312,2.686,6,6,6c3.313,0,6-2.688,6-6c0-3.314-2.687-6-6-6
c-1.441,0-2.763,0.509-3.797,1.354L17.465,22h10.884C29.173,24.329,31.388,26,34,26z M34,18c1.104,0,2,0.895,2,2
c0,1.104-0.896,2-2,2s-2-0.896-2-2C32,18.895,32.896,18,34,18z M34,4c1.104,0,2,0.895,2,2c0,1.104-0.896,2-2,2s-2-0.896-2-2
C32,4.895,32.896,4,34,4z M6,22c-1.104,0-2-0.896-2-2c0-1.105,0.896-2,2-2s2,0.895,2,2C8,21.104,7.104,22,6,22z M34,32
c1.104,0,2,0.895,2,2c0,1.104-0.896,2-2,2s-2-0.896-2-2C32,32.895,32.896,32,34,32z" fill="#4ec45a"></path>
</g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.4 KiB

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,21 @@
<!-- 自定义配置 -->
<template>
<div>
<el-form-item label="字体大小">
<avue-input-number v-model="main.activeOption.fontSize"></avue-input-number>
</el-form-item>
<el-form-item label="文本内容">
<avue-input v-model="main.activeOption.value"></avue-input>
</el-form-item>
</div>
</template>
<script>
export default {
inject: ["main"]
}
</script>
<style>
</style>

15
ruoyi-ui/src/config.js Normal file
View File

@ -0,0 +1,15 @@
/*
* @Author: your name
* @Date: 2021-10-25 17:14:50
* @LastEditTime: 2021-10-25 19:50:42
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: \avue_echarts_datashow-master\src\config.js
*/
export default {
COMPNAME: "avue-echart-",
NAME: "list",
DEAFNAME: 'item'
}
// export const url = 'https://data.bladex.vip/blade-visual'
export const url = 'http://localhost:8080/avue/api'

View File

@ -1,53 +0,0 @@
import request from '@/utils/request'
// 查询图片管理。管理上传的图片列表
export function listImage(query) {
return request({
url: '/system/image/list',
method: 'get',
params: query
})
}
// 查询图片管理。管理上传的图片详细
export function getImage(id) {
return request({
url: '/system/image/' + id,
method: 'get'
})
}
// 新增图片管理。管理上传的图片
export function addImage(data) {
return request({
url: '/system/image',
method: 'post',
data: data
})
}
// 修改图片管理。管理上传的图片
export function updateImage(data) {
return request({
url: '/system/image',
method: 'put',
data: data
})
}
// 删除图片管理。管理上传的图片
export function delImage(id) {
return request({
url: '/system/image/' + id,
method: 'delete'
})
}
// 导出图片管理。管理上传的图片
export function exportImage(query) {
return request({
url: '/system/image/export',
method: 'get',
params: query
})
}

View File

@ -3,7 +3,7 @@ import Vue from 'vue'
import Cookies from 'js-cookie'
import Element from 'element-ui'
import './assets/styles/element-variables.scss'
import './assets/styles/element-variables.scss'
import '@/assets/styles/index.scss' // global css
import '@/assets/styles/ruoyi.scss' // ruoyi css
@ -69,9 +69,23 @@ DictData.install()
Vue.use(Element, {
size: Cookies.get('size') || 'medium' // set element-ui default size
})
})
Vue.use(window.AVUE, {
size: 'mini'
});
Vue.config.productionTip = false
//注册自定义组件
import '@/components/'
import { url } from '@/config'
import 'element-ui/lib/theme-chalk/index.css';
Vue.prototype.url = url;
import axios from 'axios';
window.axios = axios;
// import '@/theme/index.js'
// import './styles/common.scss'
// Vue.prototype.$echarts = echarts
new Vue({
el: '#app',

View File

@ -0,0 +1,118 @@
// 查看页面和编辑页面公用的参数和方法
import common from '@/config'
import { config } from '@/option/config'
import container from '@/page/group/container'
import { getList } from '@/api/map'
export default {
components: {
container
},
provide () {
return {
main: this,
contain: this
};
},
data () {
return {
DIC: {
MAP: []
},
contentWidth: '',
config: config,
obj: {},
id: '',
visual: {},
nav: [],
common: common,
active: [],
overactive: '',
}
},
computed: {
list () {
let result = [];
//循环处理数据
const detail = (item) => {
if (item.children) {
item.children.forEach(ele => {
detail(ele);
})
} else {
result.push(item)
}
}
this.nav.forEach(ele => {
detail(ele);
})
const len = result.length - 1;
result.forEach((ele, index) => {
ele.zIndex = len - index;
})
return result
}
},
created () {
this.initDic();
},
methods: {
//初始化字典
initDic () {
getList({
pageNum: 1,
pageSize: 100,
}).then(res => {
const data = res.data;
this.DIC.MAP = data.records.map(ele => {
return {
label: ele.name,
value: this.url + '/map/data?id=' + ele.id
}
});
})
},
findnav (id, type) {
//循环处理数据
let obj = undefined;
let count = 0;
let parent = undefined;
let pcount = 0;
let len = 0;
const detail = (item, list, i, number = 0) => {
if (!item.children || type) {
if (id === item.index) {
obj = item;
len = Array.isArray(list) ? list.length - 1 : list.children.length - 1;
parent = list;
pcount = number;
count = i;
}
}
if (item.children) {
item.children.forEach((ele, index) => {
detail(ele, item, index, number + 1);
})
}
}
this.nav.forEach((ele, index) => {
detail(ele, this.nav, index);
})
return {
obj,
count,
len,
pcount,
parent
}
},
findlist (index) {
return this.list.find(ele => ele.index == index) || {}
},
handleInitActive () {
this.active = []
},
handleMouseDown () {
this.handleInitActive();
},
}
}

479
ruoyi-ui/src/mock/index.js Normal file
View File

@ -0,0 +1,479 @@
import Mock from 'mockjs'
import { getResult } from './utils.js'
//柱状图
Mock.mock(/\/bar/, 'get', (res) => {
const data = {
"categories": [
"苹果",
"三星",
"小米",
"oppo",
"vivo"
],
"series": [{
"name": "手机品牌",
"data": [
1000879,
3400879,
2300879,
5400879,
3400879
]
}]
}
return getResult(data)
})
//折线图
Mock.mock(/\/line/, 'get', () => {
const data = {
"categories": [
"苹果",
"三星",
"小米",
"oppo",
"vivo"
],
"series": [{
"name": "手机品牌",
"data": [
1000879,
3400879,
2300879,
5400879,
3400879
]
}]
}
return getResult(data)
})
//饼图图
Mock.mock(/\/pie/, 'get', () => {
const data = [{
"name": "苹果",
"value": 1000879,
"url": "http://www.baidu.com"
}, {
"name": "三星",
"value": 3400879,
"url": "http://www.baidu.com"
}, {
"name": "小米",
"value": 2300879,
"url": "http://www.baidu.com"
}, {
"name": "oppo",
"value": 5400879,
"url": "http://www.baidu.com"
}, {
"name": "大疆",
"value": 3000,
"url": "http://www.baidu.com"
}, {
"name": "抖音",
"value": 2000,
"url": "http://www.baidu.com"
}]
return getResult(data)
})
//表格1
Mock.mock(/\/table1/, 'get', () => {
const data = [
{
"jg": "开源中国",
"je": "12345/2333",
"sy": "<span>-26%</span>/+5%",
"yx": "12345/2333",
"jnc": "-26%/+5%",
"jl": "smallwei"
},
{
"jg": "开源中国",
"je": "12345/2333",
"sy": "<span>-26%</span>/+5%",
"yx": "12345/2333",
"jnc": "-26%/+5%",
"jl": "smallwei"
},
{
"jg": "开源中国",
"je": "12345/2333",
"sy": "<span>-26%</span>/+5%",
"yx": "12345/2333",
"jnc": "-26%/+5%",
"jl": "smallwei"
},
{
"jg": "开源中国",
"je": "12345/2333",
"sy": "<span>-26%</span>/+5%",
"yx": "12345/2333",
"jnc": "-26%/+5%",
"jl": "smallwei"
},
{
"jg": "开源中国",
"je": "12345/2333",
"sy": "<span>-26%</span>/+5%",
"yx": "12345/2333",
"jnc": "-26%/+5%",
"jl": "smallwei"
},
{
"jg": "开源中国",
"je": "12345/2333",
"sy": "<span>-26%</span>/+5%",
"yx": "12345/2333",
"jnc": "-26%/+5%",
"jl": "smallwei"
},
{
"jg": "开源中国",
"je": "12345/2333",
"sy": "<span>-26%</span>/+5%",
"yx": "12345/2333",
"jnc": "-26%/+5%",
"jl": "smallwei"
},
{
"jg": "开源中国",
"je": "12345/2333",
"sy": "<span>-26%</span>/+5%",
"yx": "12345/2333",
"jnc": "-26%/+5%",
"jl": "smallwei"
},
{
"jg": "开源中国",
"je": "12345/2333",
"sy": "<span>-26%</span>/+5%",
"yx": "12345/2333",
"jnc": "-26%/+5%",
"jl": "smallwei"
},
{
"jg": "开源中国",
"je": "12345/2333",
"sy": "<span>-26%</span>/+5%",
"yx": "12345/2333",
"jnc": "-26%/+5%",
"jl": "smallwei"
},
{
"jg": "开源中国",
"je": "12345/2333",
"sy": "<span>-26%</span>/+5%",
"yx": "12345/2333",
"jnc": "-26%/+5%",
"jl": "smallwei"
},
{
"jg": "开源中国",
"je": "12345/2333",
"sy": "<span>-26%</span>/+5%",
"yx": "12345/2333",
"jnc": "-26%/+5%",
"jl": "smallwei"
},
{
"jg": "开源中国",
"je": "12345/2333",
"sy": "<span>-26%</span>/+5%",
"yx": "12345/2333",
"jnc": "-26%/+5%",
"jl": "smallwei"
},
{
"jg": "开源中国",
"je": "12345/2333",
"sy": "<span>-26%</span>/+5%",
"yx": "12345/2333",
"jnc": "-26%/+5%",
"jl": "smallwei"
},
{
"jg": "开源中国",
"je": "12345/2333",
"sy": "<span>-26%</span>/+5%",
"yx": "12345/2333",
"jnc": "-26%/+5%",
"jl": "smallwei"
},
{
"jg": "开源中国",
"je": "12345/2333",
"sy": "<span>-26%</span>/+5%",
"yx": "12345/2333",
"jnc": "-26%/+5%",
"jl": "smallwei"
}
]
return getResult(data)
})
//表格2
Mock.mock(/\/table2/, 'get', () => {
const data = [{
name: "smallwei",
sj: "60",
type: "抵押",
je: "32400",
jg: "开源中国",
jl: "smallwei"
}, {
name: "smallwei",
sj: "60",
type: "抵押",
je: "32400",
jg: "开源中国",
jl: "smallwei"
}, {
name: "smallwei",
sj: "60",
type: "抵押",
je: "32400",
jg: "开源中国",
jl: "smallwei"
}, {
name: "smallwei",
sj: "60",
type: "抵押",
je: "32400",
jg: "开源中国",
jl: "smallwei"
}, {
name: "smallwei",
sj: "60",
type: "抵押",
je: "32400",
jg: "开源中国",
jl: "smallwei"
}, {
name: "smallwei",
sj: "60",
type: "抵押",
je: "32400",
jg: "开源中国",
jl: "smallwei"
}, {
name: "smallwei",
sj: "60",
type: "抵押",
je: "32400",
jg: "开源中国",
jl: "smallwei"
}, {
name: "smallwei",
sj: "60",
type: "抵押",
je: "32400",
jg: "开源中国",
jl: "smallwei"
}]
return getResult(data)
})
//翻牌器
Mock.mock(/\/table3/, 'get', () => {
const data = [{
"suffixText": "申请户数(时)",
"data": 2333
}, {
"suffixText": "申请户数(时)",
"data": 2333
}, {
"suffixText": "申请户数(时)",
"data": 2333
}, {
"suffixText": "申请户数(时)",
"data": 2333
}, {
"suffixText": "申请户数(时)",
"data": 2333
}, {
"suffixText": "申请户数(时)",
"data": 2333
}]
return getResult(data)
})
//表格4
Mock.mock(/\/table4/, 'get', () => {
const data = [{
"suffixText": "申请户数(时)",
"data": 2333
}, {
"suffixText": "申请户数(时)",
"data": 2333
}, {
"suffixText": "申请户数(时)",
"data": 2333
}, {
"suffixText": "申请户数(时)",
"data": 2333
}, {
"suffixText": "申请户数(时)",
"data": 2333
}, {
"suffixText": "申请户数(时)",
"data": 2333
}]
return getResult(data)
})
//字符云
Mock.mock(/\/wordCloud/, 'get', () => {
const data = [{
name: '三星',
value: '1234'
}, {
name: '小米',
value: '1234'
}, {
name: '华为',
value: '1234'
}, {
name: 'oppo',
value: '1234'
}, {
name: '抖音',
value: '1234'
}, {
name: '快手',
value: '1234'
}, {
name: '淘宝',
value: '1234'
}, {
name: '百度',
value: '1234'
}, {
name: '京东',
value: '1234'
}, {
name: '天猫',
value: '1234'
}, {
name: '字符1',
value: '1234'
}, {
name: '字符1',
value: '1234'
}]
return getResult(data)
})
//象型图
Mock.mock(/\/pictorialBar/, 'get', () => {
const data = {
"categories": [
"苹果",
"三星",
"小米",
"oppo",
"vivo"
],
"series": [{
"name": "手机品牌",
"data": [
1000879,
3400879,
2300879,
5400879,
3400879
]
}]
}
return getResult(data)
})
//雷达图
Mock.mock(/\/radar/, 'get', () => {
const data = {
indicator: [{
name: '销售',
max: 6500
},
{
name: '管理',
max: 16000
},
{
name: '信息技术',
max: 30000
},
{
name: '客服',
max: 38000
},
{
name: '研发',
max: 52000
},
{
name: '市场',
max: 25000
}
],
series: [{
data: [{
value: [4300, 10000, 28000, 35000, 50000, 19000],
name: '预算分配Allocated Budget'
},
{
value: [5000, 14000, 28000, 31000, 42000, 21000],
name: '实际开销Actual Spending'
}
]
}]
}
return getResult(data)
})
//散点图
Mock.mock(/\/scatter/, 'get', () => {
const data = [{
"data": [
[1, 8.04],
[2, 6.95]
]
},
{
"data": [
[1, 4.04],
[2, 3.95]
]
}]
return getResult(data)
})
//仪表盘
Mock.mock(/\/gauge/, 'get', () => {
const data = {
min: 1,
max: 10,
label: '名称',
value: 4,
unit: '%'
}
return getResult(data)
})
//轮播图
Mock.mock(/\/swiper/, 'get', () => {
const data = [
{
value: 'https://img.alicdn.com/tfs/TB1v28TC8v0gK0jSZKbXXbK2FXa-1880-640.jpg',
}, {
value: 'https://img.alicdn.com/tfs/TB1uevcCrj1gK0jSZFuXXcrHpXa-1880-640.jpg',
}]
return getResult(data)
})
//漏斗图
Mock.mock(/\/funnel/, 'get', () => {
const data = [{
value: 335,
name: '直接访问'
},
{
value: 310,
name: '邮件营销'
},
{
value: 234,
name: '联盟广告'
}]
return getResult(data)
})

View File

@ -0,0 +1,3 @@
export const getResult = (data) => {
return data
}

1113
ruoyi-ui/src/option/base.js Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,57 @@
// 底层组件库
import barOption from './components/bar'
import datetimeOption from './components/datetime'
import flopOption from './components/flop'
import funnelOption from './components/funnel'
import gaugeOption from './components/gauge'
import iframeOption from './components/iframe'
import imgOption from './components/img'
import imgborderOption from './components/imgborder'
import lineOption from './components/line'
import mapOption from './components/map'
import pictorialbarOption from './components/pictorialbar'
import pieOption from './components/pie'
import progressOption from './components/progress'
import radarOption from './components/radar'
import scatterOption from './components/scatter'
import swiperOption from './components/swiper'
import tableOption from './components/table'
import tabsOption from './components/tabs'
import textOption from './components/text'
import videoOption from './components/video'
import wordcloudOption from './components/wordcloud'
//通用配置
import commonOption from './components/common'
//自定义组件库
import testOption from '@/components/test/option'
import myOption from '@/components/my/option'
export default {
components: {
commonOption,
barOption,
datetimeOption,
flopOption,
funnelOption,
gaugeOption,
iframeOption,
imgOption,
imgborderOption,
lineOption,
mapOption,
pictorialbarOption,
pieOption,
progressOption,
radarOption,
scatterOption,
swiperOption,
tableOption,
tabsOption,
textOption,
videoOption,
wordcloudOption,
testOption,
myOption
}
}

View File

@ -0,0 +1,34 @@
<!-- 柱状图配置 -->
<template>
<div>
<el-form-item label="竖展示">
<avue-switch type="textarea"
v-model="main.activeOption.category"></avue-switch>
</el-form-item>
<el-collapse accordion>
<el-collapse-item title="柱体设置">
<el-form-item label="最大宽度">
<avue-slider v-model="main.activeOption.barWidth">
</avue-slider>
</el-form-item>
<el-form-item label="圆角">
<avue-slider v-model="main.activeOption.barRadius">
</avue-slider>
</el-form-item>
<el-form-item label="最小高度">
<avue-slider v-model="main.activeOption.barMinHeight">
</avue-slider>
</el-form-item>
</el-collapse-item>
</el-collapse>
</div>
</template>
<script>
export default {
inject: ["main"]
}
</script>
<style>
</style>

View File

@ -0,0 +1,217 @@
<!-- 通用配置-->
<template>
<div>
<!-- 折叠公共配置 -->
<el-collapse accordion>
<!-- 标题设置 -->
<template v-if="main.vaildProp('titleList')">
<el-collapse-item title="标题设置">
<el-form-item label="标题">
<avue-switch v-model="main.activeOption.titleShow"></avue-switch>
</el-form-item>
<el-form-item label="标题">
<avue-input v-model="main.activeOption.title"></avue-input>
</el-form-item>
<el-form-item label="字体颜色">
<avue-color v-model="main.activeOption.titleColor"></avue-color>
</el-form-item>
<el-form-item label="字体大小">
<avue-input-number v-model="main.activeOption.titleFontSize"></avue-input-number>
</el-form-item>
<el-form-item label="字体位置">
<avue-select v-model="main.activeOption.titlePostion"
:dic="dicOption.textAlign">
</avue-select>
</el-form-item>
<el-form-item label="副标题">
<avue-input v-model="main.activeOption.subtext"></avue-input>
</el-form-item>
<el-form-item label="字体颜色">
<avue-color v-model="main.activeOption.subTitleColor"></avue-color>
</el-form-item>
<el-form-item label="字体大小">
<avue-input-number v-model="main.activeOption.subTitleFontSize">
</avue-input-number>
</el-form-item>
</el-collapse-item>
</template>
<!-- 轴设置 -->
<template v-if="main.vaildProp('barList')">
<el-collapse-item title="X轴设置">
<el-form-item label="名称">
<avue-input v-model="main.activeOption.xAxisName">
</avue-input>
</el-form-item>
<el-form-item label="显示">
<avue-switch v-model="main.activeOption.xAxisShow">
</avue-switch>
</el-form-item>
<el-form-item label="显示网格线">
<avue-switch v-model="main.activeOption.xAxisSplitLineShow">
</avue-switch>
</el-form-item>
<el-form-item label="标签间距">
<avue-switch v-model="main.activeOption.xAxisinterval">
</avue-switch>
</el-form-item>
<el-form-item label="文字角度">
<avue-switch v-model="main.activeOption.xAxisRotate">
</avue-switch>
</el-form-item>
<el-form-item label="轴反转">
<avue-switch v-model="main.activeOption.xAxisInverse">
</avue-switch>
</el-form-item>
<el-form-item label="字号">
<avue-input-number v-model="main.activeOption.xNameFontSize">
</avue-input-number>
</el-form-item>
</el-collapse-item>
<el-collapse-item title="Y轴设置">
<el-form-item label="名称">
<avue-input v-model="main.activeOption.yAxisName">
</avue-input>
</el-form-item>
<el-form-item label="显示">
<avue-switch v-model="main.activeOption.yAxisShow">
</avue-switch>
</el-form-item>
<el-form-item label="轴网格线">
<avue-switch v-model="main.activeOption.yAxisSplitLineShow">
</avue-switch>
</el-form-item>
<el-form-item label="反转">
<avue-switch v-model="main.activeOption.yAxisInverse">
</avue-switch>
</el-form-item>
<el-form-item label="字号">
<avue-input-number v-model="main.activeOption.yNameFontSize">
</avue-input-number>
</el-form-item>
</el-collapse-item>
</template>
<!-- 数值设置 -->
<template v-if="main.vaildProp('labelList')">
<el-collapse-item title="数值设置">
<el-form-item label="显示">
<avue-switch v-model="main.activeOption.labelShow">
</avue-switch>
</el-form-item>
<el-form-item label="字体大小">
<avue-input-number v-model="main.activeOption.labelShowFontSize">
</avue-input-number>
</el-form-item>
<el-form-item label="字体颜色">
<avue-color v-model="main.activeOption.labelShowColor">
</avue-color>
</el-form-item>
<el-form-item label="字体粗细">
<avue-select v-model="main.activeOption.labelShowFontWeight"
:dic="dicOption.fontWeight">
</avue-select>
</el-form-item>
</el-collapse-item>
</template>
<!-- 提示语设置 -->
<template v-if="main.vaildProp('tipList')">
<el-collapse-item title="提示语设置">
<el-form-item label="字体大小">
<avue-input-number v-model="main.activeOption.tipFontSize"></avue-input-number>
</el-form-item>
<el-form-item label="字体颜色">
<avue-color v-model="main.activeOption.tipColor"></avue-color>
</el-form-item>
</el-collapse-item>
</template>
<!-- 轴距离设置 -->
<template v-if="main.vaildProp('postionList')">
<el-collapse-item title="坐标轴边距设置">
<el-form-item label="左边距(像素)">
<avue-slider v-model="main.activeOption.gridX"
:max="400"></avue-slider>
</el-form-item>
<el-form-item label="顶边距(像素)">
<avue-slider v-model="main.activeOption.gridY"
:max="400"></avue-slider>
</el-form-item>
<el-form-item label="右边距(像素)">
<avue-slider v-model="main.activeOption.gridX2"
:max="400"></avue-slider>
</el-form-item>
<el-form-item label="底边距(像素)">
<avue-slider v-model="main.activeOption.gridY2"
:max="400"></avue-slider>
</el-form-item>
</el-collapse-item>
</template>
<!-- 图例设置 -->
<template v-if="main.vaildProp('legendList')">
<el-collapse-item title="图例操作">
<el-form-item label="图例">
<avue-switch v-model="main.activeOption.legend"></avue-switch>
</el-form-item>
<el-form-item label="位置">
<avue-select v-model="main.activeOption.legendPostion"
:dic="dicOption.textAlign">
</avue-select>
</el-form-item>
<el-form-item label="布局朝向">
<avue-select v-model="main.activeOption.legendOrient"
:dic="dicOption.orientList">
</avue-select>
</el-form-item>
<el-form-item label="字体大小">
<avue-input-number v-model="main.activeOption.legendFontSize">
</avue-input-number>
</el-form-item>
</el-collapse-item>
</template>
<!-- 颜色设置 -->
<template v-if="main.vaildProp('colorList')">
<el-collapse-item title="自定义配色">
<el-form-item label="文字颜色">
<avue-color v-model="main.activeOption.nameColor">
</avue-color>
</el-form-item>
<el-form-item label="轴线颜色">
<avue-color v-model="main.activeOption.lineColor"></avue-color>
</el-form-item>
<avue-crud :option="colorOption"
:data="main.activeOption.barColor"
@row-save="rowSave"
@row-del="rowDel"
@row-update="rowUpdate"></avue-crud>
</el-collapse-item>
</template>
</el-collapse>
</div>
</template>
<script>
import { dicOption, colorOption } from '@/option/config'
export default {
inject: ["main"],
data () {
return {
dicOption: dicOption,
colorOption: colorOption
}
},
methods: {
rowSave (row, done) {
this.main.activeOption.barColor.push(row);
done()
},
rowDel (row, index) {
this.main.activeOption.barColor.splice(index, 1);
},
rowUpdate (row, index, done) {
this.main.activeOption.barColor.splice(index, 1, row);
done()
},
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,53 @@
<!-- 实时时间配置 -->
<template>
<div>
<el-form-item label="时间格式">
<avue-select v-model="main.activeOption.format"
:dic="dicOption.format">
</avue-select>
</el-form-item>
<el-form-item label="自定义格式">
<avue-input v-model="main.activeOption.format">
</avue-input>
</el-form-item>
<el-form-item label="字体间距">
<avue-input-number v-model="main.activeOption.split"
:max="200"></avue-input-number>
</el-form-item>
<el-form-item label="字体大小">
<avue-input-number v-model="main.activeOption.fontSize"
:max="200"></avue-input-number>
</el-form-item>
<el-form-item label="字体背景">
<avue-color v-model="main.activeOption.backgroundColor"></avue-color>
</el-form-item>
<el-form-item label="对其方式">
<avue-select v-model="main.activeOption.textAlign"
:dic="dicOption.textAlign">
</avue-select>
</el-form-item>
<el-form-item label="文字粗细">
<avue-select v-model="main.activeOption.fontWeight"
:dic="dicOption.fontWeight">
</avue-select>
</el-form-item>
<el-form-item label="字体颜色">
<avue-color v-model="main.activeOption.color"></avue-color>
</el-form-item>
</div>
</template>
<script>
import { dicOption } from '@/option/config'
export default {
data () {
return {
dicOption: dicOption
}
},
inject: ["main"]
}
</script>
<style>
</style>

View File

@ -0,0 +1,169 @@
<!-- 翻牌器配置 -->
<template>
<div>
<el-form-item label="整体">
<avue-switch v-model="main.activeOption.whole">
</avue-switch>
</el-form-item>
<el-form-item label="精度">
<avue-input-number v-model="main.activeOption.decimals">
</avue-input-number>
</el-form-item>
<el-form-item label="行数">
<avue-input-number v-model="main.activeOption.span">
</avue-input-number>
</el-form-item>
<el-collapse accordion>
<el-collapse-item title="边框设置">
<el-form-item label="X间距">
<avue-slider v-model="main.activeOption.splitx"></avue-slider>
</el-form-item>
<el-form-item label="Y间距">
<avue-slider v-model="main.activeOption.splity"></avue-slider>
</el-form-item>
<el-form-item label="边框宽度">
<avue-input-number v-model="main.activeOption.width"
:max="1000"></avue-input-number>
</el-form-item>
<el-form-item label="边框高度">
<avue-input-number v-model="main.activeOption.height"
:max="1000"></avue-input-number>
</el-form-item>
<el-form-item label="边框">
<avue-radio v-model="main.activeOption.type"
:dic="dicOption.border">
</avue-radio>
</el-form-item>
<template v-if="main.activeOption.type==='border'">
<el-form-item label="边框颜色">
<avue-color v-model="main.activeOption.borderColor"></avue-color>
</el-form-item>
<el-form-item label="边框宽度">
<avue-input-number v-model="main.activeOption.borderWidth"
:max="10">
</avue-input-number>
</el-form-item>
</template>
<template v-if="main.activeOption.type==='img'">
<el-form-item label="图片地址">
<img v-if="main.activeOption.backgroundBorder"
:src="main.activeOption.backgroundBorder"
alt=""
width="100%" />
<el-input v-model="main.activeOption.backgroundBorder">
<div @click="main.handleOpenImg('activeOption.backgroundBorder','border')"
slot="append">
<i class="iconfont icon-img"></i>
</div>
</el-input>
</el-form-item>
</template>
<el-form-item label="背景颜色">
<avue-color v-model="main.activeOption.backgroundColor"></avue-color>
</el-form-item>
<el-form-item label="背景图片">
<img v-if="main.activeOption.backgroundImage"
:src="main.activeOption.backgroundImage"
alt=""
width="100%" />
<el-input v-model="main.activeOption.backgroundImage">
<div @click="main.handleOpenImg('activeOption.backgroundImage','')"
slot="append">
<i class="iconfont icon-img"></i>
</div>
</el-input>
</el-form-item>
</el-collapse-item>
<el-collapse-item title="内部设置">
<el-form-item label="字体大小">
<avue-input-number v-model="main.activeOption.fontSize"
:max="200"></avue-input-number>
</el-form-item>
<el-form-item label="字体颜色">
<avue-color v-model="main.activeOption.color"></avue-color>
</el-form-item>
<el-form-item label="文字粗细">
<avue-select v-model="main.activeOption.fontWeight"
:dic="dicOption.fontWeight">
</avue-select>
</el-form-item>
<el-form-item label="对其方式">
<avue-select v-model="main.activeOption.textAlign"
:dic="dicOption.textAlign">
</avue-select>
</el-form-item>
</el-collapse-item>
<el-collapse-item title="前缀设置">
<template v-if="!main.activeOption.whole">
<el-form-item label="前缀内容">
<avue-input v-model="main.activeOption.prefixText"></avue-input>
</el-form-item>
</template>
<template v-if="!main.activeOption.row">
<el-form-item label="对其方式">
<avue-select v-model="main.activeOption.prefixTextAlign"
:dic="dicOption.textAlign">
</avue-select>
</el-form-item>
</template>
<el-form-item label="X间距">
<avue-slider v-model="main.activeOption.prefixSplitx"></avue-slider>
</el-form-item>
<el-form-item label="Y间距">
<avue-slider v-model="main.activeOption.prefixSplity"></avue-slider>
</el-form-item>
<el-form-item label="颜色">
<avue-color v-model="main.activeOption.prefixColor"></avue-color>
</el-form-item>
<el-form-item label="字体大小">
<avue-input-number v-model="main.activeOption.prefixFontSize"
:max="200">
</avue-input-number>
</el-form-item>
</el-collapse-item>
<el-collapse-item title="后缀设置">
<template v-if="!main.activeOption.whole">
<el-form-item label="后缀内容">
<avue-input v-model="main.activeOption.suffixText"></avue-input>
</el-form-item>
</template>
<template v-if="!main.activeOption.row">
<el-form-item label="对其方式">
<avue-select v-model="main.activeOption.suffixTextAlign"
:dic="dicOption.textAlign">
</avue-select>
</el-form-item>
</template>
<el-form-item label="X间距">
<avue-slider v-model="main.activeOption.suffixSplitx"></avue-slider>
</el-form-item>
<el-form-item label="Y间距">
<avue-slider v-model="main.activeOption.suffixSplity"></avue-slider>
</el-form-item>
<el-form-item label="颜色">
<avue-color v-model="main.activeOption.suffixColor"></avue-color>
</el-form-item>
<el-form-item label="字体大小">
<avue-input-number v-model="main.activeOption.suffixFontSize"
:max="200">
</avue-input-number>
</el-form-item>
</el-collapse-item>
</el-collapse>
</div>
</template>
<script>
import { dicOption } from '@/option/config'
export default {
data () {
return {
dicOption: dicOption
}
},
inject: ["main"]
}
</script>
<style>
</style>

View File

@ -0,0 +1,15 @@
<!-- 漏斗图配置 -->
<template>
<div>
</div>
</template>
<script>
export default {
inject: ["main"]
}
</script>
<style>
</style>

View File

@ -0,0 +1,29 @@
<!-- 刻度盘配置 -->
<template>
<div>
<el-form-item label="刻度线粗度(像素)">
<avue-input-number v-model="main.activeOption.lineSize"></avue-input-number>
</el-form-item>
<el-form-item label="显示刻度值">
<avue-switch v-model="main.activeOption.axisLabelShow"></avue-switch>
</el-form-item>
<el-form-item label="刻度字号">
<avue-input-number v-model="main.activeOption.axisLabelFontSize"></avue-input-number>
</el-form-item>
<el-form-item label="指标名称字号">
<avue-input-number v-model="main.activeOption.nameFontSize"></avue-input-number>
</el-form-item>
<el-form-item label="指标字号">
<avue-input-number v-model="main.activeOption.valueFontSize"></avue-input-number>
</el-form-item>
</div>
</template>
<script>
export default {
inject: ["main"]
}
</script>
<style>
</style>

View File

@ -0,0 +1,17 @@
<!-- iframe配置 -->
<template>
<div>
<el-form-item label="地址">
<avue-input v-model="main.activeObj.data.value"></avue-input>
</el-form-item>
</div>
</template>
<script>
export default {
inject: ["main"]
}
</script>
<style>
</style>

View File

@ -0,0 +1,64 @@
<!-- 图片配置 -->
<template>
<div>
<el-form-item label="开启旋转">
<avue-switch v-model="main.activeOption.rotate"></avue-switch>
</el-form-item>
<el-form-item label="透明度">
<el-slider v-model="main.activeOption.opacity"
:max="1"
:step="0.1"></el-slider>
</el-form-item>
<template v-if="main.activeOption.rotate">
<el-form-item label="旋转时间">
<avue-input-number v-model="main.activeOption.duration"></avue-input-number>
</el-form-item>
</template>
<el-form-item label="图片地址">
<img v-if="main.activeObj.data.value"
:src="main.activeObj.data.value"
alt=""
width="100%" />
<el-input v-model="main.activeObj.data.value">
<div @click="main.handleOpenImg('activeObj.data.value')"
slot="append">
<i class="iconfont icon-img"></i>
</div>
</el-input>
</el-form-item>
<el-form-item label="开启旋转">
<avue-switch v-model="main.activeOption.rotate"></avue-switch>
</el-form-item>
<el-form-item label="透明度">
<el-slider v-model="main.activeOption.opacity"
:max="1"
:step="0.1"></el-slider>
</el-form-item>
<template v-if="main.activeOption.rotate">
<el-form-item label="旋转时间">
<avue-input-number v-model="main.activeOption.duration"></avue-input-number>
</el-form-item>
</template>
<el-form-item label="图片地址">
<img v-if="main.activeObj.data.value"
:src="main.activeObj.data.value"
alt=""
width="100%" />
<el-input v-model="main.activeObj.data.value">
<div @click="main.handleOpenImg('activeObj.data.value')"
slot="append">
<i class="iconfont icon-img"></i>
</div>
</el-input>
</el-form-item>
</div>
</template>
<script>
export default {
inject: ["main"]
}
</script>
<style>
</style>

View File

@ -0,0 +1,32 @@
<!-- 图片框配置 -->
<template>
<div>
<el-form-item label="背景色">
<avue-color v-model="main.activeOption.backgroundColor"></avue-color>
</el-form-item>
<el-form-item label="图片透明度">
<avue-slider v-model="main.activeOption.opacity"></avue-slider>
</el-form-item>
<el-form-item label="图片地址">
<img v-if="main.activeObj.data"
:src="main.activeObj.data"
alt=""
width="100%" />
<el-input v-model="main.activeObj.data">
<div @click="main.handleOpenImg('activeObj.data','border')"
slot="append">
<i class="iconfont icon-img"></i>
</div>
</el-input>
</el-form-item>
</div>
</template>
<script>
export default {
inject: ["main"]
}
</script>
<style>
</style>

View File

@ -0,0 +1,33 @@
<!--折线图配置 -->
<template>
<div>
<el-form-item label="竖展示">
<avue-switch type="textarea"
v-model="main.activeOption.category"></avue-switch>
</el-form-item>
<el-collapse accordion>
<el-collapse-item title="折线设置">
<el-form-item label="面积堆积">
<avue-switch v-model="main.activeOption.areaStyle"></avue-switch>
</el-form-item>
<el-form-item label="线条宽度">
<avue-slider v-model="main.activeOption.lineWidth">
</avue-slider>
</el-form-item>
<el-form-item label="点的大小">
<avue-slider v-model="main.activeOption.symbolSize">
</avue-slider>
</el-form-item>
</el-collapse-item>
</el-collapse>
</div>
</template>
<script>
export default {
inject: ["main"]
}
</script>
<style>
</style>

View File

@ -0,0 +1,65 @@
<!-- 地图配置 -->
<template>
<div>
<el-form-item label="开启轮播">
<avue-switch v-model="main.activeOption.banner"></avue-switch>
</el-form-item>
<template v-if="main.activeOption.banner">
<el-form-item label="轮播时间">
<avue-input v-model="main.activeOption.bannerTime"></avue-input>
</el-form-item>
</template>
<template v-if="main.activeOption.type===0">
<el-form-item label="地图选择">
<avue-select :dic="main.DIC.MAP"
v-model="main.activeOption.mapData"
placeholder="请选择地图"></avue-select>
</el-form-item>
<el-form-item label="地图比例">
<avue-slider v-model="main.activeOption.zoom"
:max="5"
:step="0.1"></avue-slider>
</el-form-item>
<el-form-item label="字体大小">
<avue-input-number v-model="main.activeOption.fontSize"></avue-input-number>
</el-form-item>
<el-form-item label="字体高亮颜色">
<avue-color v-model="main.activeOption.empColor"></avue-color>
</el-form-item>
<el-form-item label="字体颜色">
<avue-color v-model="main.activeOption.color"></avue-color>
</el-form-item>
<el-form-item label="区域线">
<avue-input-number v-model="main.activeOption.borderWidth"></avue-input-number>
</el-form-item>
<el-form-item label="区域颜色">
<avue-color v-model="main.activeOption.areaColor"></avue-color>
</el-form-item>
<el-form-item label="区域高亮颜色">
<avue-color v-model="main.activeOption.empAreaColor"></avue-color>
</el-form-item>
<el-form-item label="边框颜色">
<avue-color v-model="main.activeOption.borderColor"></avue-color>
</el-form-item>
</template>
<template v-if="main.activeOption.type===1">
<el-form-item label="图片地址">
<avue-input v-model="main.activeOption.img"></avue-input>
</el-form-item>
<el-form-item label="地图比例">
<avue-slider v-model="main.activeOption.scale"
:max="300"></avue-slider>
</el-form-item>
</template>
</div>
</template>
<script>
export default {
inject: ["main"]
}
</script>
<style>
</style>

View File

@ -0,0 +1,60 @@
<!-- 象形图配置 -->
<template>
<div>
<el-form-item label="图标">
<img v-if="main.activeOption.symbol"
:src="main.activeOption.symbol"
alt=""
width="100%" />
<el-input v-model="main.activeOption.symbol">
<div @click="main.handleOpenImg('activeOption.symbol')"
slot="append">
<i class="iconfont icon-img"></i>
</div>
</el-input>
</el-form-item>
<el-form-item label="图标字号">
<avue-input-number v-model="main.activeOption.symbolSize"></avue-input-number>
</el-form-item>
<el-form-item label="字体颜色">
<avue-color v-model="main.activeOption.color"></avue-color>
</el-form-item>
<el-form-item label="轴字体颜色">
<avue-color v-model="main.activeOption.nameColor"></avue-color>
</el-form-item>
<el-form-item label="间距">
<avue-slider v-model="main.activeOption.split"></avue-slider>
</el-form-item>
<el-collapse accordion>
<el-collapse-item title="X轴设置">
<el-form-item label="显示">
<avue-switch v-model="main.activeOption.xAxisShow">
</avue-switch>
</el-form-item>
<el-form-item label="字号">
<avue-input-number v-model="main.activeOption.xNameFontSize">
</avue-input-number>
</el-form-item>
</el-collapse-item>
<el-collapse-item title="Y轴设置">
<el-form-item label="显示">
<avue-switch v-model="main.activeOption.yAxisShow">
</avue-switch>
</el-form-item>
<el-form-item label="字号">
<avue-input-number v-model="main.activeOption.yNameFontSize">
</avue-input-number>
</el-form-item>
</el-collapse-item>
</el-collapse>
</div>
</template>
<script>
export default {
inject: ["main"]
}
</script>
<style>
</style>

View File

@ -0,0 +1,33 @@
<!-- 饼图的配置 -->
<template>
<div>
<el-form-item label="字体大小">
<avue-input-number v-model="main.activeOption.fontSize"></avue-input-number>
</el-form-item>
<el-collapse accordion>
<el-collapse-item title="饼图设置">
<el-form-item label="设置为环形">
<avue-switch v-model="main.activeOption.radius"></avue-switch>
</el-form-item>
<el-form-item label="南丁格尔玫瑰">
<avue-switch v-model="main.activeOption.roseType"></avue-switch>
</el-form-item>
<el-form-item label="自动排序">
<avue-switch v-model="main.activeOption.sort"></avue-switch>
</el-form-item>
<el-form-item label="不展示零">
<avue-switch v-model="main.activeOption.notCount"></avue-switch>
</el-form-item>
</el-collapse-item>
</el-collapse>
</div>
</template>
<script>
export default {
inject: ["main"]
}
</script>
<style>
</style>

View File

@ -0,0 +1,60 @@
<!-- 进度条配置 -->
<template>
<div>
<el-form-item label="类型">
<avue-radio v-model="main.activeOption.type"
:dic="dicOption.line">
</avue-radio>
</el-form-item>
<el-form-item label="间距">
<avue-input-number v-model="main.activeOption.split"
:max="200"></avue-input-number>
</el-form-item>
<el-form-item label="边框颜色">
<avue-color v-model="main.activeOption.borderColor"></avue-color>
</el-form-item>
<el-form-item label="边框大小">
<avue-input-number v-model="main.activeOption.strokeWidth"
:max="50"></avue-input-number>
</el-form-item>
<el-form-item label="字体大小">
<avue-input-number v-model="main.activeOption.fontSize"
:max="200"></avue-input-number>
</el-form-item>
<el-form-item label="字体颜色">
<avue-color v-model="main.activeOption.color"></avue-color>
</el-form-item>
<el-form-item label="文字粗细">
<avue-select v-model="main.activeOption.FontWeight"
:dic="dicOption.fontWeight">
</avue-select>
</el-form-item>
<el-form-item label="前缀字体大小">
<avue-input-number v-model="main.activeOption.suffixFontSize"
:max="200"></avue-input-number>
</el-form-item>
<el-form-item label="前缀字体颜色">
<avue-color v-model="main.activeOption.suffixColor"></avue-color>
</el-form-item>
<el-form-item label="前缀文字粗细">
<avue-select v-model="main.activeOption.suffixFontWeight"
:dic="dicOption.fontWeight">
</avue-select>
</el-form-item>
</div>
</template>
<script>
import { dicOption } from '@/option/config'
export default {
data () {
return {
dicOption: dicOption
}
},
inject: ["main"]
}
</script>
<style>
</style>

View File

@ -0,0 +1,30 @@
<!-- 雷达图配置 -->
<template>
<div>
<el-form-item label="字体大小">
<avue-input-number v-model="main.activeOption.radarNameSize"
:max="200">
</avue-input-number>
</el-form-item>
<el-form-item label="字体颜色">
<avue-color v-model="main.activeOption.radarNameColor"
:max="200">
</avue-color>
</el-form-item>
<el-form-item label="区域透明度">
<avue-slider v-model="main.activeOption.areaOpacity"
:max="1"
:step="0.1">
</avue-slider>
</el-form-item>
</div>
</template>
<script>
export default {
inject: ["main"]
}
</script>
<style>
</style>

View File

@ -0,0 +1,17 @@
<!-- 散点图配置 -->
<template>
<div>
<el-form-item label="字体大小">
<avue-input-number v-model="main.activeOption.fontSize"></avue-input-number>
</el-form-item>
</div>
</template>
<script>
export default {
inject: ["main"]
}
</script>
<style>
</style>

View File

@ -0,0 +1,35 @@
<!-- 轮播配置 -->
<template>
<div>
<el-form-item label="类型">
<avue-radio v-model="main.activeOption.type"
:dic="dicOption.swiperType"></avue-radio>
</el-form-item>
<el-form-item label="轮播时间">
<avue-input v-model="main.activeOption.interval"></avue-input>
</el-form-item>
<el-form-item label="选择器">
<avue-radio v-model="main.activeOption.indicator"
:dic="dicOption.swiperIndicator">
</avue-radio>
</el-form-item>
<el-form-item label="图片透明度">
<avue-slider v-model="main.activeOption.opacity"></avue-slider>
</el-form-item>
</div>
</template>
<script>
import { dicOption } from '@/option/config'
export default {
data () {
return {
dicOption: dicOption
}
},
inject: ["main"]
}
</script>
<style>
</style>

View File

@ -0,0 +1,110 @@
<!-- 表格配置 -->
<template>
<div>
<el-form-item label="表头颜色">
<avue-color type="textarea"
v-model="main.activeOption.headerColor"></avue-color>
</el-form-item>
<el-form-item label="表头背景">
<avue-color type="textarea"
v-model="main.activeOption.headerBackgroud"></avue-color>
</el-form-item>
<el-form-item label="字体位置">
<avue-select v-model="main.activeOption.headerTextAlign"
:dic="dicOption.textAlign">
</avue-select>
</el-form-item>
<el-form-item label="字体大小">
<avue-input-number v-model="main.activeOption.fontSize">
</avue-input-number>
</el-form-item>
<el-form-item label="显示行数">
<avue-input-number v-model="main.activeOption.count">
</avue-input-number>
</el-form-item>
<el-form-item label="开启滚动">
<avue-switch v-model="main.activeOption.scroll">
</avue-switch>
</el-form-item>
<el-form-item label="开启显隐">
<avue-switch v-model="main.activeOption.columnShow">
</avue-switch>
</el-form-item>
<template v-if="main.activeOption.scroll">
<el-form-item label="滚动时间">
<avue-input-number v-model="main.activeOption.scrollTime">
</avue-input-number>
</el-form-item>
<el-form-item label="滚动行数">
<avue-input-number v-model="main.activeOption.scrollCount">
</avue-input-number>
</el-form-item>
</template>
<el-form-item label="线条">
<avue-switch v-model="main.activeOption.line"></avue-switch>
</el-form-item>
<el-form-item label="开启排名">
<avue-switch v-model="main.activeOption.index"></avue-switch>
</el-form-item>
<el-form-item label="文字颜色">
<avue-color type="textarea"
v-model="main.activeOption.bodyColor"></avue-color>
</el-form-item>
<el-form-item label="表格背景">
<avue-color type="textarea"
v-model="main.activeOption.bodyBackgroud"></avue-color>
</el-form-item>
<el-form-item label="字体位置">
<avue-select v-model="main.activeOption.bodyTextAlign"
:dic="dicOption.textAlign">
</avue-select>
</el-form-item>
<el-form-item label="分割线">
<avue-color type="textarea"
v-model="main.activeOption.borderColor"></avue-color>
</el-form-item>
<el-form-item label="奇行颜色">
<avue-color type="textarea"
v-model="main.activeOption.nthColor"></avue-color>
</el-form-item>
<el-form-item label="偶行颜色">
<avue-color type="textarea"
v-model="main.activeOption.othColor"></avue-color>
</el-form-item>
<avue-crud :option="tableOption"
:data="main.activeOption.column"
@row-save="rowSave"
@row-del="rowDel"
@row-update="rowUpdate"></avue-crud>
</div>
</template>
<script>
import { tableOption, dicOption } from '@/option/config'
export default {
data () {
return {
dicOption: dicOption,
tableOption: tableOption
}
},
inject: ["main"],
methods: {
rowSave (row, done) {
this.main.activeOption.column.push(row);
done()
},
rowDel (row, index) {
this.main.activeOption.column.splice(index, 1);
},
rowUpdate (row, index, done) {
this.main.activeOption.column.splice(index, 1, row);
done()
},
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,94 @@
<!-- 选项卡配置 -->
<template>
<div>
<el-form-item label="字体大小">
<avue-input-number v-model="main.activeOption.fontSize"
:max="200"></avue-input-number>
</el-form-item>
<el-form-item label="字体颜色">
<avue-color v-model="main.activeOption.color"></avue-color>
</el-form-item>
<el-form-item label="类型">
<avue-radio v-model="main.activeOption.type"
:dic="dicOption.tabsTypeList"></avue-radio>
</el-form-item>
<template v-if="main.activeOption.type==='tabs'">
<el-form-item label="字体间距">
<avue-input-number v-model="main.activeOption.split"></avue-input-number>
</el-form-item>
<el-collapse accordion>
<el-collapse-item title="边框设置">
<el-form-item label="背景颜色">
<avue-color v-model="main.activeOption.backgroundColor"></avue-color>
</el-form-item>
<el-form-item label="图标间距">
<avue-input-number v-model="main.activeOption.iconSplit"></avue-input-number>
</el-form-item>
<el-form-item label="图标大小">
<avue-input-number v-model="main.activeOption.iconSize"></avue-input-number>
</el-form-item>
<el-form-item label="图片地址">
<img v-if="main.activeOption.backgroundImage"
:src="main.activeOption.backgroundImage"
alt=""
width="100%" />
<el-input v-model="main.activeOption.backgroundImage">
<div @click="main.handleOpenImg('activeOption.backgroundImage','border')"
slot="append">
<i class="iconfont icon-img"></i>
</div>
</el-input>
</el-form-item>
<el-form-item label="边框颜色">
<avue-color v-model="main.activeOption.borderColor"></avue-color>
</el-form-item>
<el-form-item label="边框宽度">
<avue-input-number v-model="main.activeOption.borderWidth"
:max="10">
</avue-input-number>
</el-form-item>
</el-collapse-item>
<el-collapse-item title="高亮设置">
<el-form-item label="字体高亮颜色">
<avue-color v-model="main.activeOption.empColor"></avue-color>
</el-form-item>
<el-form-item label="背景图片">
<img v-if="main.activeOption.empBackgroundImage"
:src="main.activeOption.empBackgroundImage"
alt=""
width="100%" />
<el-input v-model="main.activeOption.empBackgroundImage">
<div @click="main.handleOpenImg('activeOption.empBackgroundImage','border')"
slot="append">
<i class="iconfont icon-img"></i>
</div>
</el-input>
</el-form-item>
<el-form-item label="边框颜色">
<avue-color v-model="main.activeOption.empBorderColor"></avue-color>
</el-form-item>
<el-form-item label="边框宽度">
<avue-input-number v-model="main.activeOption.empBorderWidth"
:max="10">
</avue-input-number>
</el-form-item>
</el-collapse-item>
</el-collapse>
</template>
</div>
</template>
<script>
import { dicOption } from '@/option/config'
export default {
data () {
return {
dicOption: dicOption
}
},
inject: ["main"]
}
</script>
<style>
</style>

View File

@ -0,0 +1,76 @@
<!-- 文字配置 -->
<template>
<div>
<el-form-item label="文本内容">
<avue-input v-model="main.activeObj.data.value"></avue-input>
</el-form-item>
<el-form-item label="字体大小">
<avue-input-number v-model="main.activeOption.fontSize"
:max="200"></avue-input-number>
</el-form-item>
<el-form-item label="字体颜色">
<avue-color v-model="main.activeOption.color"></avue-color>
</el-form-item>
<el-form-item label="字体间距">
<avue-slider v-model="main.activeOption.split"></avue-slider>
</el-form-item>
<el-form-item label="字体行高">
<avue-slider v-model="main.activeOption.lineHeight"></avue-slider>
</el-form-item>
<el-form-item label="字体背景">
<avue-color v-model="main.activeOption.backgroundColor"></avue-color>
</el-form-item>
<el-form-item label="文字粗细">
<avue-select v-model="main.activeOption.fontWeight"
:dic="dicOption.fontWeight">
</avue-select>
</el-form-item>
<el-form-item label="对齐方式">
<avue-select v-model="main.activeOption.textAlign"
:dic="dicOption.textAlign">
</avue-select>
</el-form-item>
<el-collapse accordion>
<el-collapse-item title="跑马灯设置">
<el-form-item label="开启">
<avue-switch v-model="main.activeOption.scroll"></avue-switch>
</el-form-item>
<template v-if="main.activeOption.scroll">
<el-form-item label="滚动速度">
<avue-input v-model="main.activeOption.speed"></avue-input>
</el-form-item>
</template>
</el-collapse-item>
<el-collapse-item title="超链设置">
<el-form-item label="开启">
<avue-switch v-model="main.activeOption.link"></avue-switch>
</el-form-item>
<template v-if="main.activeOption.link">
<el-form-item label="打开方式">
<avue-radio v-model="main.activeOption.linkTarget"
:dic="dicOption.target">
</avue-radio>
</el-form-item>
<el-form-item label="超链地址">
<avue-input v-model="main.activeOption.linkHref"></avue-input>
</el-form-item>
</template>
</el-collapse-item>
</el-collapse>
</div>
</template>
<script>
import { dicOption } from '@/option/config'
export default {
data () {
return {
dicOption: dicOption
}
},
inject: ["main"]
}
</script>
<style>
</style>

View File

@ -0,0 +1,17 @@
<!-- video配置 -->
<template>
<div>
<el-form-item label="地址">
<avue-input v-model="main.activeObj.data.value"></avue-input>
</el-form-item>
</div>
</template>
<script>
export default {
inject: ["main"]
}
</script>
<style>
</style>

View File

@ -0,0 +1,26 @@
<!-- 字符云配置 -->
<template>
<div>
<el-form-item label="最小字体">
<avue-input-number v-model="main.activeOption.minFontSize"></avue-input-number>
</el-form-item>
<el-form-item label="最大字体">
<avue-input-number v-model="main.activeOption.maxFontSize"></avue-input-number>
</el-form-item>
<el-form-item label="间距">
<avue-input-number v-model="main.activeOption.split"></avue-input-number>
</el-form-item>
<el-form-item label="旋转">
<avue-switch v-model="main.activeOption.rotate"></avue-switch>
</el-form-item>
</div>
</template>
<script>
export default {
inject: ["main"]
}
</script>
<style>
</style>

View File

@ -0,0 +1,119 @@
//基本配置
export const config = {
width: 1920,
height: 1080,
scale: 1,
mark: {
show: false,
text: 'avue数据大屏水印',
fontSize: 20,
textStyle: 'rgba(100,100,100,0.2)',
degree: -20
},
backgroundImage: '/img/bg/bg1.png',
query: {}
};
// 颜色的配置
export const colorOption = {
menuWidth: 150,
refreshBtn: false,
columnBtn: false,
labelWidth: 100,
column: [{
label: '颜色1',
prop: 'color1',
type: 'color',
}, {
label: '渐变色',
prop: 'color2',
type: 'color',
}, {
label: '位置',
prop: 'postion',
type: 'number'
}]
}
// 表格的列配置
export const tableOption = {
menuWidth: 150,
refreshBtn: false,
columnBtn: false,
labelWidth: 100,
column: [{
label: '名称',
prop: 'label',
}, {
label: 'key值',
prop: 'prop',
}, {
label: '宽度',
prop: 'width',
}]
}
//一些字典的配置
export const dicOption = {
line: [{ label: '线条', value: 'line' }, { label: '圆环', value: 'circle' }],
fontWeight: [{ label: 'normal', value: 'normal' }, { label: 'bold', value: 'bold' }, { label: 'bolder', value: 'bolder' }, { label: 'ligter', value: 'ligter' }],
border: [{ label: '无边框', value: '' }, { label: '内置图片', value: 'img' }, { label: '内置边框', value: 'border' }],
textAlign: [{ label: '居中', value: 'center' }, { label: '左对齐', value: 'left' }, { label: '右对齐', value: 'right' }],
dataType: [{ label: '静态数据', value: 0 }, { label: '动态数据', value: 1 }],
orientList: [{ label: '竖排', value: 'vertical' }, { label: '横排', value: 'horizontal' }],
dataMethod: [{ label: 'POST', value: 'post' }, { label: 'GET', value: 'get' }],
eventList: ['tabs'],
dataList: ['text', 'wordcloud', 'img', 'tabs', 'map', 'video', 'pie', 'pictorialbar', 'iframe', 'swiper', 'flop', 'bar', 'line', 'progress', 'table', 'gauge', 'funnel', 'scatter', 'radar', 'test'],
themeList: [{
label: '默认配色',
value: 'avue'
}, {
label: '紫色主题',
value: 'macarons'
}, {
label: '绿色主题',
value: 'wonderland'
}],
barList: ['bar', 'line'],
titleList: ['bar', 'pie', 'line', 'radar', 'funnel'],
labelList: ['bar', 'line', 'pie', 'radar', 'scatter'],
legendList: ['bar', 'pie', 'line', 'radar', 'funnel'],
colorList: ['bar', 'pie', 'line', 'gauge', 'funnel', 'scatter', 'radar'],
tipList: ['bar', 'pie', 'line', 'gauge', 'funnel', 'scatter', 'radar'],
postionList: ['bar', 'line', 'pictorialbar'],
formatterList: ['bar', 'map', 'line', 'pie', 'gauge', 'funnel', 'scatter', 'radar'],
clickFormatterList: ['map'],
labelFormatterList: ['bar'],
tabsTypeList: [{
label: '选项卡',
value: 'tabs',
}, {
label: '选择框',
value: 'select',
}],
mapType: [{
label: '原生',
value: 0
}],
target: [{ label: '本窗口', value: '_self' }, { label: '新窗口', value: '_blank', }],
swiperType: [{ label: '普通', value: '' }, { label: '立体', value: 'card' }],
swiperIndicator: [{ label: '外部', value: 'indicator' }, { label: '不显示', value: 'none' }],
format: [{ label: '日期', value: 'yyyy-MM-dd' }, { label: '日期+时分', value: 'yyyy-MM-dd hh:mm' }, { label: '日期+时分秒', value: 'yyyy-MM-dd hh:mm:ss' }, { label: '日期(无年)', value: 'MM-dd' }, { label: '时分', value: 'hh:mm' }, { label: '时分秒', value: 'hh:mm:ss' }, { label: '星期', value: 'day' }]
}
function concat (prop, count, type, extend = [], defaults) {
let list = [];
for (let i = 1; i <= count; i++) {
list.push({
label: prop + i,
value: `/img/${prop}/${prop}${i}.${extend.includes(i) ? defaults : type}`
})
}
return list;
}
//加载图片素材库
export const imgOption = [
concat('bg', 10, 'jpg', [1, 2, 3], 'png'),
concat('border', 16, 'png'),
concat('source', 260, 'svg', [1, 15, 16, 20, 239.240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260], 'png'),
concat('banner', 10, 'png'),
]

579
ruoyi-ui/src/page/build.vue Normal file
View File

@ -0,0 +1,579 @@
<template>
<div class="build">
<imglist ref="imglist"
@change="handleSetimg"></imglist>
<top ref="top"></top>
<div class="app"
:class="{'app--none':!menuFlag}">
<div class="menu"
v-show="menuFlag"
@click.self="handleMouseDown">
<p class="title">图层</p>
<layer ref="layer"
:nav="nav"></layer>
</div>
<container ref="container"></container>
<div class="menu params"
v-show="menuFlag">
<p class="title">操作</p>
<el-tabs class="tabs"
stretch
v-model="tabsActive">
<el-tab-pane name="0">
<el-tooltip slot="label"
effect="dark"
content="配置"
placement="top">
<div><i class="el-icon-setting"></i></div>
</el-tooltip>
<el-form label-width="120px"
label-position="left"
size="mini">
<!-- 组件配置 -->
<template v-if="!vaildProp('',[undefined])">
<p class="title">{{activeObj.title}}</p>
<el-form-item label="图层名称">
<avue-input v-model="activeObj.name"></avue-input>
</el-form-item>
<el-form-item label="隐藏">
<avue-switch v-model="activeObj.display"></avue-switch>
</el-form-item>
<template v-if="vaildProp('colorList')">
<el-form-item label="系统配色">
<avue-switch v-model="activeOption.switchTheme"></avue-switch>
</el-form-item>
<el-form-item label="配色选择"
v-if="activeOption.switchTheme">
<avue-select v-model="activeOption.theme"
:dic="dicOption.themeList">
</avue-select>
</el-form-item>
</template>
<component :is="activeComponent.prop+'Option'"></component>
<common-option></common-option>
</template>
<!-- 多选配置选项 -->
<template v-else-if="isSelectActive">
<el-form-item label="水平方式">
<el-tooltip content="左对齐"
placement="top">
<i class="el-icon-s-fold icon"
@click="$refs.container.handlePostionSelect('left')"></i>
</el-tooltip>
<el-tooltip content="居中对齐"
placement="top">
<i class="el-icon-s-operation icon"
@click="$refs.container.handlePostionSelect('center')"></i>
</el-tooltip>
<el-tooltip content="右对齐"
placement="top">
<i class="el-icon-s-unfold icon"
@click="$refs.container.handlePostionSelect('right')"></i>
</el-tooltip>
</el-form-item>
<el-form-item label="垂直方式">
<el-tooltip content="顶对齐"
placement="top">
<i class="el-icon-s-fold icon"
@click="$refs.container.handlePostionSelect('top')"></i>
</el-tooltip>
<el-tooltip content="中部对齐"
placement="top">
<i class="el-icon-s-operation icon"
@click="$refs.container.handlePostionSelect('middle')"></i>
</el-tooltip>
<el-tooltip content="底对齐"
placement="top">
<i class="el-icon-s-unfold icon"
@click="$refs.container.handlePostionSelect('bottom')"></i>
</el-tooltip>
</el-form-item>
<el-form-item label-width="0">
<el-button type="primary"
size="mini"
class="block"
@click="handleDeleteSelect">删除</el-button>
</el-form-item>
<el-form-item label-width="0">
<el-button type="danger"
size="mini"
class="block"
@click="handleFloder">成组</el-button>
</el-form-item>
</template>
<!-- 主屏的配置项 -->
<template v-else>
<!-- <el-form-item label="大屏名称">
<avue-input v-model="config.name"></avue-input>
</el-form-item> -->
<el-form-item label="大屏宽度">
<avue-input-number v-model="config.width"></avue-input-number>
</el-form-item>
<el-form-item label="大屏高度">
<avue-input-number v-model="config.height"></avue-input-number>
</el-form-item>
<el-form-item label="大屏简介">
<avue-input v-model="config.info"
type="textarea"
:min-rows="5"></avue-input>
</el-form-item>
<el-form-item label="背景颜色">
<avue-color v-model="config.backgroundColor"></avue-color>
</el-form-item>
<el-form-item label="背景图片">
<img :src="config.backgroundImage"
@click="handleOpenImg('config.backgroundImage','background')"
alt=""
width="100%" />
</el-form-item>
<el-form-item label="缩放">
<el-slider v-model="config.scale"
:max="200"
:format-tooltip="formatTooltip"></el-slider>
</el-form-item>
<el-form-item label="环境地址">
<avue-input type="textarea"
:min-rows="2"
v-model="config.url"></avue-input>
</el-form-item>
<el-form-item label="参数">
<el-button size="mini"
type="primary"
@click="openCode('query')">编辑</el-button>
</el-form-item>
<el-form-item label="水印(预览有效)">
<avue-switch v-model="config.mark.show"></avue-switch>
</el-form-item>
<template v-if="config.mark.show">
<el-form-item label="内容">
<avue-input v-model="config.mark.text"></avue-input>
</el-form-item>
<el-form-item label="大小">
<avue-input-number v-model="config.mark.fontSize"></avue-input-number>
</el-form-item>
<el-form-item label="颜色">
<avue-color v-model="config.mark.textStyle"></avue-color>
</el-form-item>
<el-form-item label="角度">
<avue-input-number v-model="config.mark.degree"></avue-input-number>
</el-form-item>
</template>
</template>
</el-form>
</el-tab-pane>
<!-- 数据配置 -->
<el-tab-pane name="1"
v-if="vaildProp('dataList')">
<el-tooltip slot="label"
effect="dark"
content="数据"
placement="top">
<div><i class="el-icon-document-copy"></i></div>
</el-tooltip>
<el-form label-width="120px"
label-position="left"
size="mini">
<el-form-item label="数据类型">
<avue-radio v-model="activeObj.dataType"
:dic="dicOption.dataType"></avue-radio>
</el-form-item>
<el-form-item label="数据值"
label-position="top"
v-if="activeObj.dataType===0">
<el-button size="mini"
type="primary"
@click="openCode('data')">编辑</el-button>
</el-form-item>
<template v-if="activeObj.dataType===1">
<el-form-item label="接口地址">
<avue-input type="textarea"
:min-rows="6"
v-model="activeObj.url"></avue-input>
</el-form-item>
<el-form-item label="接口方式"
v-if="activeObj.dataType===1">
<avue-radio v-model="activeObj.dataMethod"
:dic="dicOption.dataMethod"></avue-radio>
</el-form-item>
<el-form-item label="接口参数"
v-if="activeObj.dataType===1">
<el-button size="mini"
type="primary"
@click="openCode('dataQuery')">编辑</el-button>
</el-form-item>
<el-form-item label="刷新时间">
<avue-input-number v-model="activeObj.time"></avue-input-number>
</el-form-item>
</template>
<el-form-item label="数据处理">
<el-button size="mini"
type="primary"
@click="openCode('dataFormatter')">编辑</el-button>
</el-form-item>
<el-form-item label-width="0">
<el-button size="mini"
type="primary"
class="block"
@click="handleRefresh">刷新</el-button>
</el-form-item>
</el-form>
</el-tab-pane>
<!-- 交互事件配置 -->
<el-tab-pane name="2"
v-if="vaildProp('eventList')">
<el-tooltip slot="label"
effect="dark"
content="交互"
placement="top">
<div><i class="el-icon-thumb"></i></div>
</el-tooltip>
<el-form label-width="120px"
label-position="left"
size="mini">
<el-form-item label="子类">
<avue-select multiple
v-model="activeObj.child.index"
:dic="childList"
:props="childProps">
</avue-select>
</el-form-item>
<el-form-item label="参数名称">
<avue-input v-model="activeObj.child.paramName"></avue-input>
</el-form-item>
</el-form>
</el-tab-pane>
<!-- 其他事件配置 -->
<el-tab-pane name="3"
v-if="vaildProp('formatterList')">
<el-tooltip slot="label"
effect="dark"
content="事件"
placement="top">
<div><i class="iconfont icon-peizhi"></i></div>
</el-tooltip>
<el-form label-width="120px"
label-position="left"
size="mini">
<el-form-item label="提示事件">
<el-button size="mini"
type="primary"
@click="openCode('formatter')">编辑</el-button>
</el-form-item>
<el-form-item label="点击事件"
v-if="vaildProp('clickFormatterList')">
<el-button size="mini"
type="primary"
@click="openCode('clickFormatter')">编辑</el-button>
</el-form-item>
<el-form-item label="标题事件"
v-if="vaildProp('labelFormatterList')">
<el-button size="mini"
type="primary"
@click="openCode('labelFormatter')">编辑</el-button>
</el-form-item>
<el-form-item label-width="0">
<el-button size="mini"
type="primary"
class="block"
@click="handleRefresh">刷新</el-button>
</el-form-item>
</el-form>
</el-tab-pane>
<!-- 基本参数配置 -->
<el-tab-pane name="4"
v-if="isActive">
<el-tooltip slot="label"
effect="dark"
content="参数"
placement="top">
<div><i class="el-icon-folder"></i></div>
</el-tooltip>
<el-form label-width="120px"
label-position="left"
size="mini">
<el-form-item label="序号">
<avue-input v-model="activeObj.index"
disabled></avue-input>
</el-form-item>
<el-form-item label="X位置">
<avue-input-number v-model="activeObj.left"></avue-input-number>
</el-form-item>
<el-form-item label="Y位置">
<avue-input-number v-model="activeObj.top"></avue-input-number>
</el-form-item>
<el-form-item label="宽度">
<avue-input-number v-model="activeComponent.width"></avue-input-number>
</el-form-item>
<el-form-item label="高度">
<avue-input-number v-model="activeComponent.height"></avue-input-number>
</el-form-item>
</el-form>
</el-tab-pane>
</el-tabs>
</div>
</div>
<el-dialog title="代码编辑"
:visible.sync="code.box"
@close="code.obj={}"
width="60%">
<codeedit ref="codeedit"
v-model="code.obj"></codeedit>
<span slot="footer"
class="dialog-footer">
<el-button size="small"
@click="code.box=false"> </el-button>
<el-button type="primary"
@click="codeClose"
size="small"> </el-button>
</span>
</el-dialog>
<contentmenu ref="contentmenu"></contentmenu>
</div>
</template>
<script>
import layer from './group/layer';
import top from './group/top';
import imglist from './group/imglist'
import contentmenu from './group/contentmenu'
import codeedit from './group/code';
import { dicOption } from '@/option/config'
import init from '@/mixins/'
import { uuid } from '@/utils/utils'
import components from '@/option/components'
export default {
mixins: [init, components],
data () {
return {
keys: {
ctrl: false,
},
loading: '',
childProps: {
label: 'name',
value: 'index'
},
key: '',
menuFlag: true,
code: {
box: false,
type: '',
obj: '',
},
form: {},
dicOption: dicOption,
tabsActive: 0,
}
},
components: {
imglist,
layer,
codeedit,
top,
contentmenu
},
computed: {
isFolder () {
return this.activeObj.children
},
isActive () {
return this.active.length !== 0
},
isSelectActive () {
return this.active.length > 1;
},
childList () {
return this.list.filter(ele => {
if (['tabs'].includes(ele.component.prop)) {
return false;
}
return true;
})
},
activeComponent () {
return this.activeObj.component || {}
},
activeOption () {
return this.activeObj.option || {}
},
activeObj () {
let result
if (this.validatenull(this.active)) {
return {}
}
this.active.forEach(ele => {
const item = this.findnav(ele, true);
if (this.active.length > 1) {
if (!result) result = [];
result.push(item.obj);
} else {
result = item.obj
}
})
return result
}
},
watch: {
menuFlag () {
this.setResize();
},
overactive (n, o) {
[o, n].forEach((ele, index) => {
if (!ele) return
this.setActive(ele, index === 1, 'setOverActive');
})
},
active (n, o) {
[o, n].forEach((ele, index) => {
ele.forEach(item => {
this.setActive(item, index === 1, 'setActive');
})
})
//隐藏右键菜单
this.$refs.contentmenu.hide();
// 初始化选项卡
this.tabsActive = '0';
},
},
created () {
this.listen();
},
mounted () {
this.initFun()
},
methods: {
codeClose () {
let value = this.$refs.codeedit.getValue();
if (this.validatenull(value)) {
value = '{}'
}
try {
if (['query', 'data'].includes(this.code.type)) {
value = JSON.parse(value, null, 4)
}
if (this.code.type === 'query') {
this.config.query = value;
} else {
this.activeObj[this.code.type] = value;
}
this.code.box = false;
} catch (error) {
this.$message.error('数据格式有误')
}
},
openCode (type) {
this.code.type = type;
if (type === 'query') {
this.code.obj = this.config.query;
} else {
this.code.obj = this.activeObj[type];
}
this.code.box = true;
},
initFun () {
['setScale', 'setResize'].forEach(ele => {
this[ele] = this.$refs.container[ele]
});
['handleAdd'].forEach(ele => {
this[ele] = this.$refs.top[ele]
})
},
// 右键菜单
handleContextMenu (e, item = {}) {
if (!item.index) {
return
}
if (!this.isSelectActive) {
this.active = [item.index];
}
setTimeout(() => {
this.$refs.contentmenu.show(e.clientX, e.clientY);
}, 0)
},
//监听键盘的按键
listen () {
document.onkeydown = (e) => {
this.keys.ctrl = e.keyCode === 17;
}
document.onkeyup = () => {
this.keys.ctrl = false;
}
},
setActive (val, result, fun) {
const obj = this.$refs.container.handleGetObj(val);
if (!this.validatenull(obj)) obj[0][fun](result)
},
//批量成组
handleFloder () {
let floder = {
"title": "文件夹",
"name": "文件夹",
"index": uuid(),
"children": []
}
this.active.forEach(index => {
const params = this.findnav(index);
floder.children.push(params.obj);
delete params.parent.splice(params.count, 1);
})
this.nav.push(floder);
this.handleInitActive();
},
//批量删除
handleDeleteSelect () {
this.$confirm(`是否批量删除所选图层?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.active.forEach(index => {
const params = this.findnav(index);
delete params.parent.splice(params.count, 1);
})
this.handleInitActive()
})
},
vaildProp (name, list) {
if (list) {
return list.includes(this.activeComponent.prop)
}
return this.dicOption[name].includes(this.activeComponent.prop)
},
handleRefresh (tip) {
this.$refs.container.handleRefresh(tip);
},
formatTooltip (val) {
return parseInt(val);
},
//打开图库
handleOpenImg (item, type) {
this.$refs.imglist.openImg(item, type);
},
//图库框回调赋值
handleSetimg (val, type) {
if (type === 'activeObj.data') {
this.activeObj.data = val;
} if (type === 'activeObj.data.value') {
this.activeObj.data.value = val;
} else if (type === 'activeOption.backgroundImage') {
this.activeOption.backgroundImage = val;
} else if (type === 'activeOption.backgroundBorder') {
this.activeOption.backgroundBorder = val;
} else if (type === 'activeOption.empBackgroundBorder') {
this.activeOption.empBackgroundBorder = val;
} else if (type === 'config.backgroundImage') {
this.config.backgroundImage = val;
} else if (type === 'activeOption.symbol') {
this.activeOption.symbol = val;
}
}
}
}
</script>
<style lang="scss">
@import "../styles/style.scss";
</style>

View File

@ -0,0 +1,82 @@
<template>
<textarea :ref="id"
v-model="code"
style="height:300px;width:100%;"></textarea>
</template>
<script>
import "codemirror/theme/blackboard.css";
import "codemirror/lib/codemirror.css";
import "codemirror/addon/hint/show-hint.css";
let CodeMirror = require("codemirror/lib/codemirror");
require("codemirror/addon/edit/matchbrackets");
require("codemirror/addon/selection/active-line");
require("codemirror/addon/hint/show-hint");
export default {
name: "codeMirror",
data () {
return {
editor: '',
id: Math.floor(Math.random() * 100),
code: ''
}
},
props: {
value: {
type: [String, Object, Array],
default: ''
}
},
watch: {
value: {
handler (val) {
if (['object', 'array'].includes(typeof val)) {
this.code = JSON.stringify(this.value, null, 4);
} else {
this.code = val;
}
this.setValue(this.code);
},
immediate: true,
deep: true,
},
},
mounted () {
this.init();
},
methods: {
getValue () {
return this.editor.getValue()
},
setValue (val) {
if (this.editor) this.editor.setValue(val);
},
init () {
let mime = 'text/javascript'
let theme = 'blackboard'//设置主题,不设置的会使用默认主题
this.editor = CodeMirror.fromTextArea(this.$refs[this.id], {
mode: mime,//选择对应代码编辑器的语言,我这边选的是数据库,根据个人情况自行设置即可
indentWithTabs: true,
smartIndent: true,
lineNumbers: true,
matchBrackets: true,
theme: theme,
// autofocus: true,
extraKeys: { 'Ctrl': 'autocomplete' },//自定义快捷键
// hintOptions: {//自定义提示选项
// tables: {
// users: ['name', 'score', 'birthDate'],
// countries: ['name', 'population', 'size']
// }
// }
})
//代码自动提示功能记住使用cursorActivity事件不要使用change事件这是一个坑那样页面直接会卡死
this.editor.on('cursorActivity', () => {
this.editor.showHint()
})
}
}
}
</script>

View File

@ -0,0 +1,248 @@
<template>
<div class="middle">
<div class="wrapper__grade"
@mousedown="contain.handleMouseDown"></div>
<div id="wrapper"
class="wrapper"
@mousedown="contain.handleMouseDown">
<div class="content"
id="content"
ref="content">
<div class="container"
:style="styleName"
id="container"
ref="container">
<div class="grade"
v-if="gradeFlag || contain.config.gradeShow"
:style="gradeLenStyle"></div>
<subgroup ref="subgroup"
:nav="contain.list"></subgroup>
</div>
</div>
</div>
</div>
</template>
<script>
import subgroup from './subgroup'
import common from '@/config'
import { getObj } from '@/api/visual'
export default {
name: 'contents',
inject: ["contain"],
provide () {
return {
contain: this.contain,
container: this
};
},
components: {
subgroup
},
data () {
return {
selectCount: {},
scale: 1,
gradeFlag: false,
}
},
computed: {
stepScale () {
let scale = Number(((1 / this.scale) * 100).toFixed(2));
return scale
},
//计算中央可视化大屏比例
styleName () {
const scale = this.contain.config.scale;
return Object.assign({
transform: `scale(${scale / 100}, ${scale / 100})`,
width: this.setPx(this.contain.config.width),
height: this.setPx(this.contain.config.height),
backgroundColor: this.contain.config.backgroundColor
}, (() => {
if (this.contain.config.backgroundImage) {
return {
background: `url(${this.contain.config.backgroundImage}) 0% 0% / 100% 100% rgb(3, 12, 59)`,
}
}
return
})())
},
gradeLenStyle () {
return {
backgroundSize: `${this.setPx(this.contain.config.gradeLen)} ${this.setPx(this.contain.config.gradeLen)},${this.setPx(this.contain.config.gradeLen)} ${this.setPx(this.contain.config.gradeLen)}`
}
}
},
mounted () {
this.initData();
this.initFun();
},
methods: {
initFun () {
['handleRefresh', 'handleGetObj'].forEach(ele => {
console.log('66666');
this[ele] = this.$refs.subgroup[ele]
});
},
//初始化数据
initData () {
const id = this.$route.params.id;
this.contain.id = id;
this.contain.contentWidth = this.$refs.content.offsetWidth;
const isBuild = this.$route.name === 'build';
const width = isBuild ? this.contain.contentWidth : document.body.clientWidth
if (id) {
const loading = this.$loading({
lock: true,
text: '正在加载中,请稍后',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
getObj(id).then(res => {
const callback = () => {
//赋值属性
this.contain.config = JSON.parse(config.detail) || {};
this.contain.nav = JSON.parse(config.component) || [];
this.calcData();
this.setScale(width);
}
const data = res.data;
this.contain.obj = data;
const config = data.config;
this.contain.visual = data.visual;
//添加水印。只有查看页面生效
if (!isBuild) {
if (this.contain.config.mark.show) {
this.watermark(this.contain.config.mark);
}
const password = this.contain.visual.password
if (!this.validatenull(password)) {
this.$prompt('请输入密码', '提示', {
confirmButtonText: '确定',
showCancelButton: false,
showClose: false,
closeOnClickModal: false,
inputPattern: new RegExp(password),
inputErrorMessage: '密码不正确,请重新输入'
}).then(() => {
callback();
})
} else {
callback();
}
} else {
callback();
}
loading.close();
}).catch((err) => {
console.log(err)
loading.close();
})
} else {
this.setScale(width);
}
},
//适配尺寸
setResize () {
this.$nextTick(() => {
this.$refs.content.style.width = this.setPx((this.contain.config.scale * this.contain.config.width) / 100)
this.$refs.content.style.height = this.setPx((this.contain.config.scale * this.contain.config.height) / 100)
})
},
//计算比例
setScale (width) {
this.$nextTick(() => {
this.contain.config.scale = (width / this.contain.config.width) * 100
this.scale = this.contain.config.scale;
this.setResize();
})
},
calcData () {
if (!this.contain.config.mark) this.contain.config.mark = {}
if (!this.contain.config.query) this.contain.config.query = {}
},
handlePostionSelect (postion) {
this.handleCalcPostionSelect();
const x1 = this.selectCount.maxx1;
const x2 = this.selectCount.maxx2;
const y1 = this.selectCount.maxy1;
const y2 = this.selectCount.maxy2;
if (postion === 'left') {
this.handleMoveSelectList(x1, undefined, true, postion);
} else if (postion === 'center') {
this.handleMoveSelectList(x1 + (x2 - x1) / 2, undefined, true, postion);
} else if (postion === 'right') {
this.handleMoveSelectList(x2, undefined, true, postion);
} else if (postion === 'top') {
this.handleMoveSelectList(undefined, y1, true, postion);
} else if (postion === 'middle') {
this.handleMoveSelectList(undefined, y1 + (y2 - y1) / 2, true, postion);
} else if (postion === 'bottom') {
this.handleMoveSelectList(undefined, y2, true, postion);
}
},
handleMoveSelectList (left, top, type, postion) {
this.contain.active.forEach(ele => {
ele = this.contain.findlist(ele)
const ele_component = ele.component;
//水平情况
if (left) {
let baseLeft = Number(type ? left : (ele.left + left).toFixed(2));
if (postion === 'right') {
baseLeft = baseLeft - ele_component.width
}
else if (postion === 'center') {
const obj_center = ele.left + ele_component.width / 2;
baseLeft = ele.left + (left - obj_center)
}
this.$set(ele, 'left', baseLeft);
this.$refs.subgroup.$refs[common.DEAFNAME + ele.index][0].setLeft(baseLeft)
}
//垂直情况
if (top) {
let baseTop = Number(type ? top : (ele.top + top).toFixed(2));
if (postion === 'bottom') {
baseTop = baseTop - ele_component.height
}
else if (postion === 'middle') {
const obj_middle = ele.top + ele_component.height / 2;
baseTop = ele.top + (top - obj_middle)
}
this.$set(ele, 'top', baseTop)
this.$refs.subgroup.$ref[common.DEAFNAME + ele.index][0].setTop(baseTop)
}
})
},
//计算多选状态下的最大边界值
handleCalcPostionSelect () {
this.selectCount.maxx1 = 99999;
this.selectCount.maxy1 = 99999;
this.contain.active.forEach(ele => {
ele = this.contain.findlist(ele)
const left = ele.left;
const top = ele.top;
const width = ele.component.width;
const height = ele.component.height;
if (this.selectCount.maxx1 > left) {
this.selectCount.maxx1 = left;
}
if (this.selectCount.maxx2 < left + width) {
this.selectCount.maxx2 = left + width;
}
if (this.selectCount.maxy1 > top) {
this.selectCount.maxy1 = top;
}
if (this.selectCount.maxy2 < top + height) {
this.selectCount.maxy2 = top + height;
}
})
},
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,232 @@
<template>
<div class="contentmenu"
v-show="contentMenu"
@click="contentMenu=false"
:style="styleName">
<div class="contentmenu__item"
@click="handleLogout()"
v-if="contain.isFolder"> <i class="el-icon-close"></i>解散分组
</div>
<div class="contentmenu__item"
@click="handleCompose()"
v-if="!contain.isFolder"> <i class="el-icon-close"></i>组合分组
</div>
<div class="contentmenu__item"
@click="handleDel()"> <i class="el-icon-close"></i>删除图层
</div>
<div class="contentmenu__item"
@click="handleCopy()"><i class="el-icon-document"></i>复制图层
</div>
<div class="contentmenu__item"
@click="handleTop()"><i class="el-icon-arrow-up"></i>置顶图层
</div>
<div class="contentmenu__item"
@click="handleBottom()"><i class="el-icon-arrow-down"></i>置底图层
</div>
<div class="contentmenu__item"
@click="handleStepTop()"><i class="el-icon-arrow-up"></i>上移一层
</div>
<div class="contentmenu__item"
@click="handleStepBottom()"><i class="el-icon-arrow-down"></i>下移一层
</div>
</div>
</template>
<script>
import { uuid } from '@/utils/utils'
export default {
name: 'contentmenu',
inject: ["contain"],
data () {
return {
contentMenu: false,
contentMenuX: 0,
contentMenuY: 0,
}
},
computed: {
styleName () {
return {
left: this.setPx(this.contentMenuX),
top: this.setPx(this.contentMenuY)
}
}
},
methods: {
show (X = 0, Y = 0) {
this.contentMenuX = X;
this.contentMenuY = Y;
this.contentMenu = true;
},
hide () {
this.contentMenuX = 0;
this.contentMenuY = 0;
this.contentMenu = false;
},
handleStepBottom () {
this.handleCommon(false, true);
},
handleStepTop () {
this.handleCommon(true, true);
},
//文件夹成组逻辑
handleCompose () {
let list = this.contain.active;
this.$confirm(`是否组合所选择的图层?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let floder = {
"title": "文件夹",
"name": "文件夹",
"index": uuid(),
"children": []
}
//查找到每个组件调用核心方法就行组合操作
//寻找父类
const params = this.contain.findnav(list[0], true);
list.forEach(ele => {
const item = this.contain.findnav(ele, true);
item.parent.splice(item.count, 1);
floder.children.push(item.obj);
});
params.parent.push(floder);
}).catch(() => { })
},
//文件夹解散逻辑
handleLogout () {
let ele = this.contain.activeObj
this.$confirm(`是否解散${ele.name}图层?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
//查找到文件夹调用核心方法nav去操作
const params = this.contain.findnav(ele.index, true);
const list = this.deepClone(params.obj.children)
params.parent.splice(params.count, 1);
list.forEach(ele => {
params.parent.push(ele);
});
this.contain.handleInitActive();
}).catch(() => { })
},
//删除组件的方法
handleDel () {
this.$confirm(`是否删除所选图层?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
const params = this.contain.findnav(this.contain.active[0], true);
this.contain.active.forEach(ele => {
const item = this.contain.findnav(ele, true);
if (Array.isArray(params.parent)) {
params.parent.splice(item.count, 1);
} else {
params.parent.children.splice(item.count, 1);
}
});
this.contain.handleInitActive();
}).catch(() => { })
},
//复制组件的方法
handleCopy () {
//寻找父类
const params = this.contain.findnav(this.contain.active[0], true);
this.contain.active.forEach(ele => {
const item = this.contain.findnav(ele, true);
const obj = this.deepClone(item.obj);
obj.index = uuid();
params.parent.push(obj)
});
this.contain.handleInitActive();
},
// 图层的上下移动方法
handleCommon (first = false, step = false) {
// 交换数组元素
var swapItems = function (arr, index1, index2) {
arr[index1] = arr.splice(index2, 1, arr[index1])[0];
return arr;
};
let obj = this.contain.activeObj;
let data = this.deepClone(obj);
let params = this.contain.findnav(obj.index, true);
if (params.pcount !== 0) {
if (params.len < 1) return;
if (step) {
if (first && params.count === 0) return
if (!first && params.count === params.len) return
let count = first ? params.count - 1 : params.count + 1
swapItems(params.parent.children, params.count, count);
} else {
if (first) {
if (params.count === 0) return
params.parent.children.splice(params.count, 1);
params.parent.children.unshift(data);
} else {
if (params.count === params.len) return
params.parent.children.splice(params.count, 1);
params.parent.children.push(data);
}
}
} else {
if (this.contain.nav.length < 1) return;
if (step) {
if (first && params.count === 0) return
if (!first && params.count === params.len) return
let count = first ? params.count - 1 : params.count + 1
swapItems(this.contain.nav, params.count, count);
} else {
if (first) {
if (params.count === 0) return
this.contain.nav.splice(params.count, 1)
this.contain.nav.unshift(data);
} else {
if (params.count === params.len) return
this.contain.nav.splice(params.count, 1)
this.contain.nav.push(data);
}
}
}
},
handleTop () {
this.handleCommon(true);
},
handleBottom () {
this.handleCommon();
}
}
}
</script>
<style>
.contentmenu {
width: 160px;
position: fixed;
z-index: 99999;
list-style: none;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
padding: 0;
background: #27343e;
color: #bcc9d4;
}
.contentmenu__item {
z-index: 10000;
list-style: none;
padding: 8px 12px;
cursor: pointer;
position: relative;
font-size: 12px;
}
.contentmenu__item:hover {
background-color: rgba(0, 192, 222, 0.1);
}
.contentmenu__item i {
margin-right: 5px;
}
.contentmenu__item :first-child {
padding-top: 5px;
}
</style>

View File

@ -0,0 +1,86 @@
<template>
<el-dialog title="图库"
width="80%"
:visible.sync="imgVisible">
<div style="margin:0 auto;">
<el-upload class="upload-demo"
:on-success="onSuccess"
:show-file-list="false"
:action="url+'/visual/put-file'"
multiple
list-type="picture">
<el-button size="small"
icon="el-icon-upload"
type="primary">点击上传</el-button>
</el-upload>
</div>
<el-scrollbar class="imgList">
<img :src="item.value"
:style="styleName"
@click="handleSetimg(item.value)"
v-for="(item,index) in imgOption[imgActive]"
:key="index" />
</el-scrollbar>
</el-dialog>
</template>
<script>
import { imgOption } from '@/option/config'
export default {
data () {
return {
imgVisible: false,
imgObj: '',
type: '',
imgActive: 0,
imgOption: imgOption,
imgTabs: [],
}
},
computed: {
styleName () {
if (this.type === 'background') {
return {
width: '200px'
}
}
return {}
}
},
watch: {
type: {
handler () {
if (this.type === 'background') {
this.imgActive = 0;
} else if (this.type == 'border') {
this.imgActive = 1;
} else {
this.imgActive = 2;
}
},
immediate: true
}
},
methods: {
onSuccess (res) {
const url = res.data.link;
this.imgOption[this.imgActive].unshift({
label: url,
value: url
});
},
openImg (item, type) {
this.type = type;
this.imgObj = item
this.imgVisible = true;
},
handleSetimg (item) {
this.imgVisible = false;
this.$emit('change', item, this.imgObj);
}
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,121 @@
<template>
<draggable :group="{ name: 'form' }"
ghost-class="ghost"
:list="nav"
:animation="300">
<template v-for="item in nav">
<div :key="item.index"
class="menu__folder"
v-if="item.children">
<div @dblclick="hangeChangeName(item)"
@click="handleSetActive(item)"
@contextmenu.prevent="contain.handleContextMenu($event,item)"
:class="['menu__item--folder',{'is-active':handleGetActive(item),'is-over':contain.overactive===item.index}]">
<i class="iconfont icon-fold"
@click="openFolder(item)"
:class="{'is-active':item.menu}"></i>
<i class="iconfont icon-folder"
@click="openFolder(item)"></i>
<input type="text"
@keyup.enter="item.isname=false"
v-if="item.isname"
v-model="item.name">
<span v-else>{{item.name}}</span>
</div>
<div :key="'list'
+item.index"
class="menu__list"
v-show="item.menu">
<draggable :group="{ name: 'form' }"
ghost-class="ghost"
:list="item.children"
:animation="300">
<template v-for="citem in item.children">
<div v-if="!citem.children"
:key="citem.index"
:class="['menu__item',{'is-active':handleGetActive(citem),'is-over':contain.overactive===citem.index}]"
@click="handleSetActive(citem)"
@contextmenu.prevent="contain.handleContextMenu($event,citem)"
@mouseover="contain.overactive=citem.index"
@mouseout="contain.overactive=undefined">
<span class="menu__icon">
<i :class="'iconfont '+citem.icon"></i>
</span>
<span>{{citem.title}}</span>
</div>
<layer v-else
:count="count+1"
:key="citem.index"
:nav="[citem]"></layer>
</template>
</draggable>
</div>
</div>
<div v-else
:key="item.index"
@contextmenu.prevent="contain.handleContextMenu($event,item)"
@click="handleSetActive(item)"
:class="['menu__item',{'is-active':handleGetActive(item),'is-over': contain.overactive===item.index}]"
@mouseover="contain.overactive=item.index"
@mouseout="contain.overactive=undefined">
<span class="menu__icon">
<i :class="'iconfont '+item.icon"></i>
</span>
<span>{{item.title}}</span>
</div>
</template>
</draggable>
</template>
<script>
import vuedraggable from 'vuedraggable';
export default {
name: 'layer',
inject: ["contain"],
provide () {
return {
contain: this.contain
};
},
components: {
draggable: vuedraggable
},
props: {
count: {
type: Number,
default: 1,
},
nav: {
type: Array,
default: () => {
return []
}
}
},
methods: {
handleGetActive (item) {
return this.contain.active.includes(item.index);
},
handleSetActive (item) {
if (this.contain.keys.ctrl) {
if (!Array.isArray(this.contain.active)) {
this.contain.handleInitActive();
}
this.contain.active.push(item.index)
} else {
this.contain.active = [item.index];
}
},
hangeChangeName (item) {
this.$set(item, 'isname', !item.isname)
},
openFolder (item) {
this.$set(item, 'menu', !item.menu)
item.isname = false;
},
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,149 @@
<template>
<div>
<div v-for="item in nav"
:key="item.index"
@contextmenu.prevent="contain.handleContextMenu($event,item)">
<avue-draggable v-if="!item.children"
v-bind="item"
:scale="container.stepScale"
:disabled="!contain.menuFlag"
:step="container.stepScale"
:width="item.component.width"
:height="item.component.height"
:ref="common.DEAFNAME+item.index"
:id="common.DEAFNAME+item.index"
v-show="!item.display"
@over="handleOver"
@focus="handleFocus"
@blur="handleBlur">
<component :ref="common.NAME+item.index"
:id="common.NAME+item.index"
:is="common.COMPNAME+item.component.name"
v-bind="item"
:data-formatter="getFunction(item.dataFormatter)"
:click-formatter="getFunction(item.clickFormatter)"
:label-formatter="getFunction(item.labelFormatter)"
:formatter="getFunction(item.formatter)"
:width="item.component.width"
:data-query="getJson(item.dataQuery)"
:height="item.component.height"
:animation="!contain.menuFlag"
:theme="(item.option || {}).theme"
:disabled="!contain.menuFlag"
:scale="container.stepScale"
:option="item.option"
:home-url="contain.config.url"
:click="handleClick" />
</avue-draggable>
<subgroup :nav="item.children"></subgroup>
</div>
</div>
</template>
<script>
import { addUrlParam } from '@/utils/utils'
import common from '@/config'
export default {
name: 'subgroup',
inject: ["contain", 'container'],
provide () {
return {
contain: this.contain,
container: this.container
};
},
props: {
nav: {
type: Array,
default: () => {
return []
}
}
},
data () {
return {
common: common,
}
},
methods: {
getFunction (fun) {
if (!this.validatenull(fun)) {
try {
return eval(fun);
} catch {
return function () { }
}
}
},
getJson (str) {
if (this.validatenull(str)) return {};
if (typeof str == "string") {
try {
return JSON.parse(str);
} catch {
return {}
}
}
return str;
},
//点击事件交互
handleClick ({ type, child, value }) {
if (type === 'tabs') {
const indexList = child.index;
indexList.forEach((index) => {
const paramName = child.paramName;
const item = this.contain.findlist(index);
if (!item.url) return
let params = {};
if (item.dataQuery) {
params = this.getJson(item.dataQuery)
} else {
params = {}
}
params[paramName] = value;
item.dataQuery = JSON.stringify(params);
this.$refs[this.common.NAME + index].forEach(ele => {
ele.updateData();
})
})
}
},
//刷新数据
handleRefresh (tip = true) {
this.$refs[this.common.NAME + this.contain.activeObj.index][0].updateData();
if (tip) {
this.$message.success('刷新成功')
}
},
//获取对象
handleGetObj (val) {
return this.$refs[`${this.common.DEAFNAME}${val}`];
},
handleOver ({ index }) {
this.contain.overactive = index;
},
handleFocus ({ index }) {
this.container.gradeFlag = true;
if (this.contain.keys.ctrl) {
if (!Array.isArray(this.contain.active)) {
this.contain.handleInitActive();
}
this.contain.active.push(index);
} else if (!this.contain.active.includes(index)) {
this.contain.active = [index];
}
},
handleBlur ({ left, top, width, height }) {
if (Array.isArray(this.contain.activeObj)) return
this.container.gradeFlag = false;
this.$set(this.contain.activeObj.component, 'width', width)
this.$set(this.contain.activeObj.component, 'height', height)
this.$set(this.contain.activeObj, 'left', left)
this.$set(this.contain.activeObj, 'top', top)
},
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,192 @@
<template>
<div>
<el-menu class="nav"
mode="horizontal"
background-color="#212528"
text-color="#fff"
active-text-color="#409EFF"
@mousedown="contain.handleMouseDown">
<el-submenu :index="index+''"
v-for="(item,index) in baseList"
:key="index">
<template slot="title">
<el-tooltip effect="dark"
:content="item.label"
placement="top">
<i :class="'nav__icon iconfont '+item.icon"></i>
</el-tooltip>
</template>
<el-menu-item @click="handleAdd(citem.option,true)"
:key="cindex"
:index="`${index}-${cindex}`"
v-for="(citem,cindex) in item.children">
<i :class="'nav__icon iconfont '+citem.option.icon"></i>
<span>{{citem.label}}</span>
</el-menu-item>
</el-submenu>
<el-menu-item index="6"
@click="handleReset"
v-show="!contain.menuFlag">
<el-tooltip effect="dark"
content="还原"
placement="top">
<i class="nav__icon iconfont icon-reset"></i>
</el-tooltip>
</el-menu-item>
<el-menu-item index="7"
@click="handleView"
v-show="contain.menuFlag">
<el-tooltip effect="dark"
content="预览"
placement="top">
<i class="nav__icon iconfont icon-view"></i>
</el-tooltip>
</el-menu-item>
<el-menu-item index="8"
@click="handleBuild">
<el-tooltip effect="dark"
content="保存"
placement="top">
<i class="nav__icon iconfont icon-build"></i>
</el-tooltip>
</el-menu-item>
</el-menu>
</div>
</template>
<script>
import { uuid } from '@/utils/utils'
import baseList from '@/option/base'
import { updateComponent } from '@/api/visual'
export default {
inject: ["contain"],
data () {
return {
baseList: baseList
}
},
methods: {
vaildData (id) {
const list = [];
for (var i = 0; i < 20; i++) {
list.push(i + '')
}
return list.includes(id)
},
handleView () {
this.contain.menuFlag = false;
this.contain.handleInitActive();
this.contain.setScale(document.body.clientWidth);
},
handleReset () {
this.contain.menuFlag = true;
this.contain.setScale(this.contain.contentWidth);
},
handleBuild () {
this.contain.handleInitActive();
const loading = this.$loading({
lock: true,
text: '正在保存配置,请稍后',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
this.$nextTick(() => {
html2canvas(document.getElementById('content'), {
onrendered: (canvas) => {
function dataURLtoFile (dataurl, filename) {
var arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, { type: mime });
}
var file = dataURLtoFile(canvas.toDataURL('image/jpeg', 0.1), new Date().getTime() + '.jpg');
var formdata = new FormData();
formdata.append('file', file)
axios.post(this.url + '/visual/put-file', formdata, {
headers: {
"Content-Type": "multipart/form-data"
}
}).then(res => {
console.log('666666666666666')
const data = res.data;
console.log(res.data);
console.log('666666666666666888888888888888')
const url = data.link;
console.log('66666666666666688888888888888899999999999999999999')
const formdata = {
visual: {
id: this.contain.visual.id,
backgroundUrl: url
},
config: {
id: this.contain.obj.config.id,
visualId: this.contain.visual.id,
detail: JSON.stringify(this.contain.config),
component: JSON.stringify(this.contain.nav),
},
}
return updateComponent(formdata)
}).then(() => {
loading.close();
this.$confirm('保存成功大屏配置, 是否打开预览?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let routeUrl = this.$router.resolve({
path: '/view/' + this.contain.id
})
window.open(routeUrl.href, '_blank');
}).catch(() => {
});
}).catch(() => {
this.$message.error('模版例子不能修改')
loading.close();
})
},
});
})
},
handleAdd (option, first = false) {
let obj = this.deepClone(option);
obj.left = 0;
obj.top = 0
obj.index = uuid();
if (first) {
this.contain.nav.unshift(obj);
} else {
this.contain.nav.push(obj);
}
},
}
}
</script>
<style>
.nav {
border-bottom: 0 !important;
height: 45px;
line-height: 45px;
overflow: hidden;
}
.nav__icon {
margin-right: 5px;
}
.nav .el-submenu .el-submenu__title,
.nav .el-menu-item {
height: 45px;
line-height: 45px;
font-size: 12px;
}
</style>

View File

@ -0,0 +1,68 @@
<template>
<el-container class="list">
<el-aside width="230px">
<h2 class="title">Avue-data数据大屏</h2>
<el-menu :default-active="activeName"
background-color="#171b22"
text-color="#fff"
@select="handleSelect"
active-text-color="#00baff">
<el-menu-item index="1">
<i class="el-icon-document"></i>
大屏管理
</el-menu-item>
<el-menu-item index="2">
<i class="el-icon-document"></i>
地图管理
</el-menu-item>
<el-menu-item index="3">
<i class="el-icon-document"></i>
分类管理
</el-menu-item>
</el-menu>
</el-aside>
<el-scrollbar class="list"
style="width:100%;height:800px;">
<list v-if="activeName==1"></list>
<maps v-if="activeName==2"></maps>
<category v-if="activeName==3"></category>
</el-scrollbar>
</el-container>
</template>
<script>
import list from './list/index'
import maps from './list/map'
import category from './list/category'
export default {
name: "index",
components: {
list,
maps,
category
},
data () {
return {
activeName: '1',
}
},
created () {
},
methods: {
handleSelect (key) {
this.activeName = key;
},
}
}
</script>
<style lang="scss" scoped>
.title {
font-size: 20px;
color: #fff;
text-align: center;
line-height: 60px;
font-weight: 500;
}
</style>

View File

@ -0,0 +1,126 @@
<template>
<div class="map">
<avue-crud :option="option"
v-model="form"
@row-save="rowSave"
@row-update="rowUpdate"
@row-del="rowDel"
:before-open="beforeOpen"
:data="data"></avue-crud>
</div>
</template>
<script>
import { getList, getObj, addObj, delObj, updateObj } from '@/api/category'
export default {
data () {
return {
form: {},
data: [],
option: {
index: true,
align: 'center',
headerAlign: 'center',
column: [
{
label: '模块名',
prop: 'categoryKey',
rules: [{
required: true,
message: "请输入模块名",
trigger: "blur"
}]
},
{
label: '模块值',
prop: 'categoryValue',
rules: [{
required: true,
message: "请输入模块值",
trigger: "blur"
}]
}
]
}
}
},
created () {
this.getList()
},
methods: {
vaildData (id) {
return [0, 1].includes(id)
},
beforeOpen (done, type) {
if (type == 'edit') {
getObj(this.form.id).then(res => {
const data = res.data.data;
this.form = data
done()
})
} else {
done()
}
},
rowDel (row, index) {
if (this.vaildData(index)) {
this.$message.error('例子模板不允许修改')
return false;
}
this.$confirm('此操作将永久删除, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
delObj(row.id).then(() => {
this.$message.success('删除成功');
this.getList()
})
}).catch(() => {
});
},
rowUpdate (row, index, done) {
if (this.vaildData(index)) {
this.$message.error('例子模板不允许修改')
return false;
}
updateObj(row).then(() => {
this.$message.success('修改成功');
this.getList()
done();
})
},
rowSave (row, done) {
addObj(row).then(() => {
this.$message.success('新增成功');
this.getList()
done();
})
},
getList () {
getList({
pageNum: 1,
pageSize: 100,
}).then(res => {
const data = res.data.data;
this.data = data;
})
}
}
}
</script>
<style lang="scss" scoped>
.map {
padding: 30px;
width: 100%;
.title {
display: block;
margin-bottom: 30px;
padding: 0 50px;
font-size: 20px;
}
}
</style>

View File

@ -0,0 +1,347 @@
<template>
<el-container class="list">
<el-header>
<el-menu :default-active="activeName"
mode="horizontal"
background-color="#171b22"
text-color="#fff"
active-text-color="#00baff"
@select="handleSelect">
<el-menu-item :index="item.categoryValue"
:key="item.categoryValue"
v-for="item in typelist"
@click="getList(item.categoryValue)">
<i class="iconfont icon-daping"></i>
{{item.categoryKey}}
</el-menu-item>
</el-menu>
</el-header>
<el-main>
<div class="page">
<el-pagination layout="total, sizes, prev, pager, next, jumper"
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:page-size="page.size"
:current-page.sync="page.page"
:total="page.total">
</el-pagination>
</div>
<div class="content">
<div class="content__item content__item--add"
@click="handleAdd">
<div>
<i class="el-icon-plus"></i>
<p>新建大屏</p>
</div>
</div>
<div class="content__item"
v-for="(item,index) in list"
:key="index"
@mouseover="item._menu=true"
@mouseout="item._menu=false">
<div class="content__info">
<img v-if="item.backgroundUrl"
:src="item.backgroundUrl"
alt="" />
<div class="content__menu"
v-show="item._menu">
<div class="content__btn"
@click="handleEdit(item)">
编辑
</div>
</div>
</div>
<div class="content__main">
<span class="content__name">{{item.title}}</span>
<div class="content__menulist">
<div class="content__view">
<el-tooltip content="删除">
<i class="el-icon-delete"
@click="handleDel(item,index)"></i>
</el-tooltip>
<el-tooltip content="编辑">
<i class="el-icon-edit"
@click="handleUpdate(item,index)"></i>
</el-tooltip>
<el-tooltip content="预览">
<i class="el-icon-view"
@click="handleViews(item,index)"></i>
</el-tooltip>
<el-tooltip content="复制">
<i class="el-icon-copy-document"
@click="handleCopy(item,index)"></i>
</el-tooltip>
</div>
<span class="content__status"
:class="{'content__status--active':item.status}">
{{item.status?'已发布':'未发布'}}
</span>
</div>
</div>
</div>
</div>
</el-main>
<el-dialog title="新建大屏"
width="35%"
:visible.sync="box">
<avue-form :option="option"
v-model="form"
@submit="handleSave"></avue-form>
</el-dialog>
</el-container>
</template>
<script>
import { getList, addObj, updateObj, delObj, getCategory, copyObj } from '@/api/visual';
export default {
name: "list",
data () {
return {
typelist: [],
index: 0,
type: '',
option: {
column: [{
label: '分组',
prop: 'category',
span: 24,
labelWidth: 100,
type: 'select',
dicUrl: this.url + '/category/list',
props: {
label: 'categoryKey',
value: 'categoryValue',
},
rules: [{
required: true,
message: "请选择分组",
trigger: "blur"
}]
}, {
label: '大屏名称',
span: 24,
labelWidth: 100,
prop: 'title',
rules: [{
required: true,
message: "请输入大屏名称",
trigger: "blur"
}]
}, {
label: '大屏尺寸',
span: 14,
labelWidth: 100,
prop: 'width',
placeholder: '请输入宽度',
rules: [{
required: true,
message: "请输入大屏尺寸",
trigger: "blur"
}]
}, {
label: '',
span: 10,
labelWidth: 1,
prop: 'height',
placeholder: '请输入高度',
rules: [{
required: true,
message: "请输入大屏尺寸",
trigger: "blur"
}]
}, {
label: '密码',
span: 24,
type: 'password',
labelWidth: 100,
prop: 'password',
}, {
label: '发布状态',
prop: 'status',
span: 24,
labelWidth: 100,
type: 'select',
dicData: [{
label: '未发布',
value: 0
}, {
label: '已发布',
value: 1
}]
}]
},
page: {
page: 1,
size: 10,
total: 0,
},
form: {},
box: false,
activeName: '',
list: [],
}
},
created () {
this.getCategory()
},
methods: {
vaildData (id) {
const list = [];
for (var i = 0; i < 20; i++) {
list.push(i)
}
return list.includes(id)
},
getCategory () {
getCategory().then(res => {
const data = res.data;
this.typelist = data;
this.activeName = (data[0] || {}).categoryValue;
this.getList();
})
},
handleCopy (item) {
this.$confirm('确认复制当前大屏', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
copyObj(item.id).then(() => {
this.$message.success('复制成功');
this.getList();
})
}).catch(() => {
});
},
handleDel (item, index) {
this.$confirm('是否确认永久删除?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
if (this.vaildData(index)) {
this.$message.error('例子模板不允许修改')
return false;
}
delObj(item.id).then(() => {
this.list.splice(index, 1)
this.$message.success('删除成功')
})
}).catch(() => {
});
},
handleUpdate (item, index) {
this.form = item
this.form.category = this.form.category + '';
this.type = 'edit';
this.option.column[2].display = false;
this.option.column[3].display = false;
this.box = true;
this.index = index;
},
handleEdit (item) {
let routeUrl = this.$router.resolve({
path: '/build/' + item.id
})
if(self!=top){
   // 页面在iframe中时处理容
window.location.replace(routeUrl.href);
  }else{
window.open(routeUrl.href, '_blank');
}
},
handleViews (item) {
let routeUrl = this.$router.resolve({
path: '/view/' + item.id
})
window.open(routeUrl.href, '_blank');
},
handleAdd () {
this.type = 'add';
this.option.column[5].display = false;
this.form.category = this.activeName;
this.form.width = 1920;
this.form.height = 1080;
this.box = true;
},
handleSave (form, done) {
done();
if (this.type == 'add') {
addObj(Object.assign({
category: this.activeName,
}, this.form)).then(res => {
this.box = false;
this.$message.success('新增成功');
this.getList();
const id = res.data.id;
this.handleEdit({ id })
})
} else {
if (this.vaildData(Number(this.index))) {
this.$message.error('例子模板不允许修改')
return false;
}
updateObj(Object.assign({
category: this.activeName
}, {
id: this.form.id,
password: this.form.password,
status: this.form.status,
title: this.form.title
})).then(() => {
this.box = false;
this.$message.success('修改成功');
this.getList();
})
}
},
handleSelect (key) {
this.activeName = key;
this.page.page = 1;
this.getList();
},
handleCurrentChange (val) {
this.page.page = val;
this.getList();
},
handleSizeChange (val) {
this.page.size = val;
this.getList();
},
getList (category) {
const loading = this.$loading({
lock: true,
text: '正在加载中,请稍后',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
this.list = []
getList({
category: category || this.activeName,
pageNum: this.page.page,
pageSize: this.page.size,
}).then(res => {
loading.close();
const data = res.data;
this.page.total = data.total;
this.list = data.records
this.initData();
})
},
initData () {
this.list.forEach((ele, index) => {
this.$set(this.list[index], '_menu', false)
})
}
}
}
</script>
<style lang="scss">
@import "@/styles/list.scss";
</style>

View File

@ -0,0 +1,142 @@
<template>
<div class="map">
<a class="title"
target="_blank"
href="https://datav.aliyun.com/tools/atlas/#&lat=33.521903996156105&lng=104.29849999999999&zoom=4">点击我添加更多地图</a>
<avue-crud :option="option"
v-model="form"
@row-save="rowSave"
@row-update="rowUpdate"
@row-del="rowDel"
:before-open="beforeOpen"
:data="data">
<template slot="dataForm"
slot-scope="{}">
<codeedit v-model="form.data"
ref="codeedit"></codeedit>
</template>
</avue-crud>
</div>
</template>
<script>
import codeedit from '../group/code';
import { getList, getObj, addObj, delObj, updateObj } from '@/api/map'
export default {
components: {
codeedit
},
data () {
return {
form: {},
data: [],
option: {
labelWidth: 100,
index: true,
align: 'center',
headerAlign: 'center',
column: [
{
label: '地图名称',
prop: 'name',
row: true,
rules: [{
required: true,
message: "请输入地图名称",
trigger: "blur"
}]
},
{
label: '地图数据',
prop: 'data',
span: 24,
hide: true,
formslot: true
}
]
}
}
},
created () {
this.getList()
},
methods: {
vaildData (id) {
return [0, 1, 2].includes(id)
},
beforeOpen (done, type) {
if (type == 'edit') {
getObj(this.form.id).then(res => {
const data = res.data;
this.form = data
this.form.data = JSON.stringify(JSON.parse(this.form.data), null, 4)
done()
})
} else {
done()
}
},
rowDel (row, index) {
if (this.vaildData(index)) {
this.$message.error('例子模板不允许修改')
return false;
}
this.$confirm('此操作将永久删除, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
delObj(row.id).then(() => {
this.$message.success('删除成功');
this.getList()
})
}).catch(() => {
});
},
rowUpdate (row, index, done) {
if (this.vaildData(index)) {
this.$message.error('例子模板不允许修改')
return false;
}
row.data = this.$refs.codeedit.getValue()
updateObj(row).then(() => {
this.$message.success('修改成功');
this.getList()
done();
})
},
rowSave (row, done) {
row.data = this.$refs.codeedit.getValue()
addObj(row).then(() => {
this.$message.success('新增成功');
this.getList()
done();
})
},
getList () {
getList({
pageNum: 1,
pageSize: 100,
}).then(res => {
const data = res.data;
this.data = data.records;
})
}
}
}
</script>
<style lang="scss" scoped>
.map {
padding: 30px;
width: 100%;
.title {
display: block;
margin-bottom: 30px;
padding: 0 50px;
font-size: 20px;
}
}
</style>

View File

@ -0,0 +1,14 @@
<template>
<div class="build views">
<container ref="container"></container>
</div>
</template>
<script>
import init from '@/mixins/'
export default {
mixins: [init],
}
</script>
<style lang="scss">
@import "../styles/style.scss";
</style>

View File

@ -150,6 +150,22 @@ export const constantRoutes = [
meta: { title: '修改生成配置', activeMenu: '/tool/gen'}
}
]
},
{
path: '/',
name: '列表页',
component: () =>
import( /* webpackChunkName: "page" */ '@/views/screen/page/index')
}, {
path: '/build/:id',
name: 'build',
component: () =>
import( /* webpackChunkName: "page" */ '@/views/screen/page/build')
}, {
path: '/view/:id',
name: 'view',
component: () =>
import( /* webpackChunkName: "page" */ '@/views/screen/page/view')
}
]
@ -158,3 +174,4 @@ export default new Router({
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes
})

View File

@ -0,0 +1,243 @@
* {
margin: 0;
padding: 0;
}
a {
text-decoration: none;
}
html,
body,
#app {
height: 100%;
}
body {
background: #171b22;
overflow: hidden;
}
::-webkit-scrollbar-track-piece {
background-color: transparent;
}
::-webkit-scrollbar {
width: 5px;
height: 5px;
background-color: transparent;
}
::-webkit-scrollbar-thumb {
border-radius: 5px;
background-color: hsla(220, 4%, 58%, .3);
}
img {
user-select: none;
}
.img{
margin-right: 5px;
}
.block{
margin: 0 auto;
width:90%;
display: block;
}
a{
text-decoration: none;
font-size: 12px;
color:#409EFF;
}
.el-select-dropdown {
border-radius: 0;
border:none;
color: #bcc9d4;
background-color: #27343e;
color: #bcc9d4;
}
.el-select-dropdown__item{
font-size: 12px;
}
.el-select-dropdown__item.selected,.el-select-dropdown__item.hover{
font-weight: normal;
background-color: rgba(0,192,222,.1);
}
.el-select-dropdown__item.hover{
color: #fff;
}
.el-select-dropdown__item.selected{
color: #fff;
}
.el-input-group__append, .el-input-group__prepend,.el-dialog .el-input-group__append, .el-dialog .el-input-group__prepend{
background-color: #0f1014;
border-color: #282e3a;
}
.el-collapse-item__header.is-active{
color:#fff;
}
.el-collapse-item__wrap{
background-color:#000;
border-bottom: none;
}
.el-radio__input, .params .el-radio__label,.params input{
font-size: 12px;
}
.el-table th, .el-table tr,.el-table, .el-table__expanded-cell {
background-color: transparent !important;
color:#859094 !important;
}
.el-table td, .el-table th.is-leaf {
border-color: #859094 !important;
}
.avue-empty__desc{
color:#fff;
}
.el-form-item__label, .el-dialog .el-form-item__label{
color:#fff !important;
}
.hover-row td,.hover-row th{
background-color: transparent !important;
border-bottom: none;
}
.el-table__fixed-right::before, .el-table__fixed::before,.el-table::before{
display: none;
}
.el-table td, .el-table th.is-leaf {
border-bottom:none;
}
.el-dialog ,.avue-group__item{
background: #1b1e25;
}
.el-message-box{
background: #1b1e25;
border-color: #1b1e25;
}
.el-message-box__title{
color:#fff;
}
.el-dialog__title{
color:#fff;
font-size: 14px;
}
.el-dialog__body{
padding: 10px;
}
.el-collapse-item__arrow.is-active{
color:#fff;
}
.el-collapse{
border-top:none;
border-bottom: none;
}
input{
border-width: 2px;
border-radius: 0;
}
.avue-crud{
width: 90%;
}
.el-radio{
width: 100%;
line-height: 25px;
font-size: 14px;
}
.el-color-picker__trigger,.el-dialog .el-color-picker__trigger{
border:none;
}
.el-collapse-item__arrow{
position: absolute;
left:10px;
line-height: 40px;
color:#bcc9d4;
}
.el-form-item{
margin-top: 10px;
}
.el-pagination__total{
color:#fff;
}
.el-pagination.is-background .btn-next, .el-pagination.is-background .btn-prev, .el-pagination.is-background .el-pager li{
background-color:transparent;
color: #fff;
}
.el-pagination.is-background .el-pager li:not(.disabled).active{
background-color: transparent;
border:1px solid #409EFF;
}
.el-form-item__label,.el-dialog .el-form-item__label{
color:#859094;
padding-left: 20px;
font-size: 12px;
}
.el-form-item__content, .el-dialog .el-form-item__content{
padding-right: 20px;
}
.el-checkbox__inner,input,.el-slider__runway,textarea,
.el-dialog input,.el-switch__core,.el-dialog .el-slider__runway,.el-dialog textarea{
background-color: #0f1014 !important;
color:#859094 !important;
border-color:#282e3a !important;
}
.el-switch.is-checked .el-switch__core {
border-color: #409EFF !important;
background-color: #409EFF !important;
}
.el-button,.el-dialog .el-button{
border-radius: 0;
}
.el-button--primary,.el-dialog .el-button--primary{
background-color: transparent;
color:#409EFF;
border-color:#409EFF;
}
.el-button--danger,.el-dialog .el-button--danger{
background-color: transparent;
color:#f56c6c;
border-color:#f56c6c;
}
.el-button--default,.el-dialog .el-button--default{
background-color: transparent;
color:#859094;
border-color:#859094;
}
.el-collapse-item__content{
padding: 0;
}
.el-select-dropdown.is-multiple .el-select-dropdown__item.selected.hover{
background-color: initial;
color:#fff;
}
.el-select-dropdown.is-multiple .el-select-dropdown__item.selected{
background-color: initial;
color:#fff;
}
.el-dialog__title{
color:#fff !important;
}
.el-collapse-item__header{
padding-left: 20px;
height: 40px;
line-height: 40px;
background: transparent;
color:#bcc9d4;
font-weight: 300;
font-size: 12px;
border-color: #282e3a;
}
.icon-gauge{
font-size: 12px !important;
}

View File

@ -0,0 +1,135 @@
.list{
.el-menu{
border-right: none;
}
.el-menu.el-menu--horizontal {
border-color: rgb(33, 37, 40);
border-width: 2px;
}
.page{
display: flex;
justify-content: center;
}
.el-menu i {
margin-right: 5px;
}
.content{
display: flex;
flex-wrap: wrap;
&__item{
position: relative;
margin: 16px;
display: flex;
flex-direction: column;
width: 258px;
height: 184px;
border: 1px solid #3a4659;
overflow: hidden;
&:hover {
box-shadow: 0 0 20px 0 #000;
border: 1px solid #00baff;
}
&--add {
height: 184px;
width: 258px;
border: 1px solid #00baff;
font-size: 14px;
color: #8eeeff;
background-image: linear-gradient(-90deg, rgba(0, 222, 255, .39) 0, rgba(0, 174, 255, .19) 100%);
box-shadow: 0 0 10px 0 rgba(55, 224, 255, .3);
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
i {
display: block;
padding-bottom: 10px;
text-align: center;
font-size: 19px;
}
p {
letter-spacing: 2px;
}
}
}
&__main {
font-size: 12px;
width: 100%;
height: 36px;
display: flex;
align-items: center;
position: absolute;
bottom: 0;
justify-content: space-between;
background: #1d262e;
box-sizing: border-box;
padding: 0 10px;
color: #bcc9d4;
a{
color:#bcc9d4;
}
i{
margin-right: 1px;
}
}
&__view{
margin-right: 2px;
}
&__menulist{
display: flex;
i{
margin-right: 10px;
}
}
&__status--active {
color: #fff
}
&__name {
width: 100px;
padding: 0 5px;
line-height: 28px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
border: 1px solid transparent;
}
&__info {
position: relative;
height: calc(100% - 36px);
}
&__menu {
position: absolute;
top: 0;
left: 0;
background-color: rgba(29,38,46,0.8);
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
&__btn {
display: inline-block;
vertical-align: middle;
height: 32px;
line-height: 32px;
padding: 0 30px;
box-sizing: border-box;
outline: 0;
text-align: center;
font-size: 14px;
background-image: linear-gradient(-225deg, #00d3f1 0, #12b3ff 100%);
color: #293f52;
border: none;
transition: .3s ease;
cursor: pointer
}
&__info{
img {
width: 100%;
height: 100%;
}
}
}
}

View File

@ -0,0 +1,315 @@
.build{
position: relative;
width: 100%;
height: 100%;
.app {
width:100%;
height: calc(100% - 45px);
display: flex;
box-sizing: border-box;
}
.selectall{
position: absolute;
border: 1px dotted #409EFF;
z-index:10000;
}
.icon{
font-size: 20px;
margin-right: 10px;
}
.selectbg{
width:100%;
height:100%;
position: absolute;
z-index:9999;
}
.selectflag{
width:100%;
height:100%;
position: absolute;
z-index:9999;
cursor: move;
}
.el-menu--horizontal .el-menu .el-menu-item, .el-menu--horizontal .el-menu .el-submenu__title{
font-size: 12px;
}
.menu {
width: 180px;
height: 100%;
overflow: hidden;
overflow-y: auto;
color:#bcc8d4;
background: #1d1f26;
}
.menu__list{
padding-left: 10px;
box-sizing: border-box;
}
.menu__item--folder{
display: flex;
align-items: center;
padding: 6px 6px;
color:#bcc9d4;
font-size: 12px;
input{
border:none;
outline: none;
}
.icon-folder{
font-size: 16px;
margin-right: 5px;
}
.icon-fold{
font-size: 12px;
margin-right: 10px;
transform: rotate(90deg);
display:inline-block;
font-weight: bold;
&.is-active{
transform: rotate(180deg);
}
}
&.is-active{
color: #fff;
background: rgba(143,225,255,.1);
}
&:hover {
color: #fff;
background: rgba(143,225,255,.1);
cursor: pointer;
}
}
.menu__folder{
&.ghost{
opacity: .6;
color:#fff;
background: #409EFF !important;
cursor: move;
}
}
.menu__item {
margin-bottom: 1px;
width: 100%;
box-sizing: border-box;
display: flex;
align-items: center;
height: 48px;
padding: 0 6px;
position: relative;
background: #1b1f25;
cursor: pointer;
flex: none;
font-size: 12px;
&.is-over,&:hover {
color: #fff;
background: rgba(143,225,255,.1);
cursor: pointer;
}
&.ghost{
opacity: .6;
color:#fff;
background: #409EFF !important;
cursor: move;
}
&.is-active {
background: #409EFF !important;
color: #373d41 !important;
}
}
.menu__icon{
color: #409EFF;
margin-right: 10px;
width: 53px;
height: 30px;
line-height: 30px;
text-align: center;
display: block;
border: 1px solid #3a4659;
background: #282a30;
}
.top{
padding: 10px 20px;
position: fixed;
top:0;
left:0;
width:100%;
z-index:9999;
background-color: rgba(255,255,255,.4);
}
.middle{
background-color: #2a2d32;
flex:1;
position: relative;
height: 100%;
overflow: auto;
}
.wrapper {
position: relative;
padding:60px 0 0 0;
box-sizing: border-box;
width: 100%;
position: relative;
box-sizing: border-box;
}
.content{
transform-origin: 0 0;
background-color: #333;
position: relative;
box-sizing: border-box;
}
.footer__menu{
padding-top: 8px;
margin-right:370px;
float: right;
width:300px;
}
.app--none{
padding: 0;
height:100%;
}
.app--none .wrapper{
position: relative;
padding: 0;
width: 100%;
}
.app--none .content{
width: 100%;
height: 100%;
border:none;
}
.container {
user-select: none;
transform-origin: 0 0;
position: relative;
}
.grade {
width: 100%;
height: 100%;
background-size: 30px 30px, 30px 30px;
background-image: linear-gradient(rgba(255, 255, 255, 0.1) 1px, transparent 0px), linear-gradient(90deg, rgba(255, 255, 255, 0.1) 1px, transparent 0px);
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.wrapper__grade{
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
height: 100%;
background: url(https://img.alicdn.com/tfs/TB184VLcPfguuRjSspkXXXchpXa-14-14.png) repeat;
}
.title {
padding:0 20px;
box-sizing: border-box;
margin-bottom: 10px;
line-height: 35px;
height: 35px;
text-align: center;
font-size: 13px;
letter-spacing: 2px;
text-indent: 2px;
background-color:#2d343c;
color:#fff;
&--left{
text-align: left;
}
}
.params {
width: 350px;
}
.tabs{
margin-top: -10px;
box-sizing: border-box;
}
.tabs .el-input-number{
width:100%;
}
.tabs .el-tabs__header{
background: #27343e;
margin: 0 0 2px;
}
.tabs i{
color: #bcc9d4;
font-size: 14px;
}
.tabs .is-active i{
color: #409EFF;
}
.tabs .el-tabs__nav-wrap::after{
background: #27343e;
}
.tabs .el-tabs__item{
padding: 0;
box-sizing: border-box;
}
.tabs .el-tabs__active-bar{
top:0;
}
.el-collapse-item__header{
padding-left: 30px;
}
.el-switch__core{
width: 35px;
height: 16px;
}
.el-switch{
height:10px;
line-height: 10px;
}
.el-switch__core:after{
top:-1px;
width: 16px;
height:16px;
}
.el-slider__button-wrapper{
top:-17px;
}
.el-slider__button{
border-radius: 0;
width: 8px;
height: 8px;
border-width: 1px;
}
.el-slider__bar,.el-slider__runway{
height: 2px;
}
.imgList{
height:350px;
display: flex;
flex-wrap:wrap;
justify-content: space-between;
}
.imgList img{
width: 100px;
height: 100px;
margin: 20px 10px ;
}
.el-input-number__decrease, .el-input-number__increase{
background: transparent;
}
}
.views{
.wrapper{
padding: 0;
}
.middle{
overflow: inherit;
}
}

View File

@ -0,0 +1,169 @@
var theme_avue = {
"version": 1,
"themeName": "avue",
"theme": {
"seriesCnt": "4",
"backgroundColor": "rgba(0,0,0,0)",
"titleColor": "#516b91",
"subtitleColor": "#93b7e3",
"textColorShow": false,
"textColor": "#333",
"markTextColor": "#eee",
"color": [
"#83bff6",
"#23b7e5",
"#188df0",
"#564aa3",
"#a5e7f0",
"#cbb0e3"
],
"borderColor": "#ccc",
"borderWidth": 0,
"visualMapColor": [
"#83bff6",
"#23b7e5",
"#188df0",
"#564aa3"
],
"legendTextColor": "#999999",
"kColor": "#edafda",
"kColor0": "transparent",
"kBorderColor": "#d680bc",
"kBorderColor0": "#8fd3e8",
"kBorderWidth": "2",
"lineWidth": "2",
"symbolSize": "6",
"symbol": "emptyCircle",
"symbolBorderWidth": "2",
"lineSmooth": true,
"graphLineWidth": 1,
"graphLineColor": "#aaa",
"mapLabelColor": "#000000",
"mapLabelColorE": "rgb(81,107,145)",
"mapBorderColor": "#516b91",
"mapBorderColorE": "#516b91",
"mapBorderWidth": 0.5,
"mapBorderWidthE": 1,
"mapAreaColor": "#f3f3f3",
"mapAreaColorE": "rgba(165,231,240,1)",
"axes": [{
"type": "all",
"name": "通用坐标轴",
"axisLineShow": true,
"axisLineColor": "#cccccc",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#999999",
"splitLineShow": true,
"splitLineColor": [
"#eeeeee"
],
"splitAreaShow": false,
"splitAreaColor": [
"rgba(80,36,204,0.05)",
"rgba(223,35,35,0.02)"
]
},
{
"type": "category",
"name": "类目坐标轴",
"axisLineShow": true,
"axisLineColor": "#333",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#333",
"splitLineShow": false,
"splitLineColor": [
"#ccc"
],
"splitAreaShow": false,
"splitAreaColor": [
"rgba(250,250,250,0.3)",
"rgba(200,200,200,0.3)"
]
},
{
"type": "value",
"name": "数值坐标轴",
"axisLineShow": true,
"axisLineColor": "#333",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#333",
"splitLineShow": true,
"splitLineColor": [
"#ccc"
],
"splitAreaShow": false,
"splitAreaColor": [
"rgba(250,250,250,0.3)",
"rgba(200,200,200,0.3)"
]
},
{
"type": "log",
"name": "对数坐标轴",
"axisLineShow": true,
"axisLineColor": "#333",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#333",
"splitLineShow": true,
"splitLineColor": [
"#ccc"
],
"splitAreaShow": false,
"splitAreaColor": [
"rgba(250,250,250,0.3)",
"rgba(200,200,200,0.3)"
]
},
{
"type": "time",
"name": "时间坐标轴",
"axisLineShow": true,
"axisLineColor": "#333",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#333",
"splitLineShow": true,
"splitLineColor": [
"#ccc"
],
"splitAreaShow": false,
"splitAreaColor": [
"rgba(250,250,250,0.3)",
"rgba(200,200,200,0.3)"
]
}
],
"axisSeperateSetting": true,
"toolboxColor": "#999999",
"toolboxEmpasisColor": "#666666",
"tooltipAxisColor": "#f9dbdb",
"tooltipAxisWidth": 1,
"timelineLineColor": "#8fd3e8",
"timelineLineWidth": 1,
"timelineItemColor": "#8fd3e8",
"timelineItemColorE": "#8fd3e8",
"timelineCheckColor": "#8fd3e8",
"timelineCheckBorderColor": "rgba(138,124,168,0.37)",
"timelineItemBorderWidth": 1,
"timelineControlColor": "#213dbc",
"timelineControlBorderColor": "#8fd3e8",
"timelineControlBorderWidth": 0.5,
"timelineLabelColor": "#8fd3e8",
"datazoomBackgroundColor": "rgba(0,0,0,0)",
"datazoomDataColor": "rgba(255,255,255,0.3)",
"datazoomFillColor": "rgba(167,183,204,0.4)",
"datazoomHandleColor": "#2472d9",
"datazoomHandleWidth": "100",
"datazoomLabelColor": "#333333"
}
}
window.echarts.registerTheme(theme_avue.themeName, theme_avue.theme)

View File

@ -0,0 +1,181 @@
var theme_macarons = {
"version": 1,
"themeName": "macarons",
"theme": {
"seriesCnt": "4",
"backgroundColor": "rgba(0,0,0,0)",
"titleColor": "#008acd",
"subtitleColor": "#aaaaaa",
"textColorShow": false,
"textColor": "#333",
"markTextColor": "#eeeeee",
"color": [
"#2ec7c9",
"#b6a2de",
"#5ab1ef",
"#ffb980",
"#d87a80",
"#8d98b3",
"#e5cf0d",
"#97b552",
"#95706d",
"#dc69aa",
"#07a2a4",
"#9a7fd1",
"#588dd5",
"#f5994e",
"#c05050",
"#59678c",
"#c9ab00",
"#7eb00a",
"#6f5553",
"#c14089"
],
"borderColor": "#ccc",
"borderWidth": 0,
"visualMapColor": [
"#5ab1ef",
"#e0ffff"
],
"legendTextColor": "#333333",
"kColor": "#d87a80",
"kColor0": "#2ec7c9",
"kBorderColor": "#d87a80",
"kBorderColor0": "#2ec7c9",
"kBorderWidth": 1,
"lineWidth": 2,
"symbolSize": 3,
"symbol": "emptyCircle",
"symbolBorderWidth": 1,
"lineSmooth": true,
"graphLineWidth": 1,
"graphLineColor": "#aaaaaa",
"mapLabelColor": "#d87a80",
"mapLabelColorE": "rgb(100,0,0)",
"mapBorderColor": "#eeeeee",
"mapBorderColorE": "#444444",
"mapBorderWidth": 0.5,
"mapBorderWidthE": 1,
"mapAreaColor": "#dddddd",
"mapAreaColorE": "rgba(254,153,78,1)",
"axes": [{
"type": "all",
"name": "通用坐标轴",
"axisLineShow": true,
"axisLineColor": "#eeeeee",
"axisTickShow": true,
"axisTickColor": "#eeeeee",
"axisLabelShow": true,
"axisLabelColor": "#eeeeee",
"splitLineShow": true,
"splitLineColor": [
"#aaaaaa"
],
"splitAreaShow": false,
"splitAreaColor": [
"#eeeeee"
]
},
{
"type": "category",
"name": "类目坐标轴",
"axisLineShow": true,
"axisLineColor": "#008acd",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#333",
"splitLineShow": false,
"splitLineColor": [
"#eee"
],
"splitAreaShow": false,
"splitAreaColor": [
"rgba(250,250,250,0.3)",
"rgba(200,200,200,0.3)"
]
},
{
"type": "value",
"name": "数值坐标轴",
"axisLineShow": true,
"axisLineColor": "#008acd",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#333",
"splitLineShow": true,
"splitLineColor": [
"#eee"
],
"splitAreaShow": true,
"splitAreaColor": [
"rgba(250,250,250,0.3)",
"rgba(200,200,200,0.3)"
]
},
{
"type": "log",
"name": "对数坐标轴",
"axisLineShow": true,
"axisLineColor": "#008acd",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#333",
"splitLineShow": true,
"splitLineColor": [
"#eee"
],
"splitAreaShow": true,
"splitAreaColor": [
"rgba(250,250,250,0.3)",
"rgba(200,200,200,0.3)"
]
},
{
"type": "time",
"name": "时间坐标轴",
"axisLineShow": true,
"axisLineColor": "#008acd",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#333",
"splitLineShow": true,
"splitLineColor": [
"#eee"
],
"splitAreaShow": false,
"splitAreaColor": [
"rgba(250,250,250,0.3)",
"rgba(200,200,200,0.3)"
]
}
],
"axisSeperateSetting": true,
"toolboxColor": "#2ec7c9",
"toolboxEmpasisColor": "#18a4a6",
"tooltipAxisColor": "#008acd",
"tooltipAxisWidth": "1",
"timelineLineColor": "#008acd",
"timelineLineWidth": 1,
"timelineItemColor": "#008acd",
"timelineItemColorE": "#a9334c",
"timelineCheckColor": "#2ec7c9",
"timelineCheckBorderColor": "rgba(46,199,201,0.4)",
"timelineItemBorderWidth": 1,
"timelineControlColor": "#008acd",
"timelineControlBorderColor": "#008acd",
"timelineControlBorderWidth": 0.5,
"timelineLabelColor": "#008acd",
"datazoomBackgroundColor": "rgba(47,69,84,0)",
"datazoomDataColor": "rgba(239,239,255,1)",
"datazoomFillColor": "rgba(182,162,222,0.2)",
"datazoomHandleColor": "#008acd",
"datazoomHandleWidth": "100",
"datazoomLabelColor": "#333333"
}
}
window.echarts.registerTheme(theme_macarons.themeName, theme_macarons.theme)

View File

@ -0,0 +1,3 @@
import './avue.project.js'
import './halloween.project.js'
import './wonderland.project'

View File

@ -0,0 +1,168 @@
var theme_wonderland = {
"version": 1,
"themeName": "wonderland",
"theme": {
"seriesCnt": "3",
"backgroundColor": "rgba(255,255,255,0)",
"titleColor": "#666666",
"subtitleColor": "#999999",
"textColorShow": false,
"textColor": "#333",
"markTextColor": "#ffffff",
"color": [
"#4ea397",
"#22c3aa",
"#7bd9a5",
"#d0648a",
"#f58db2",
"#f2b3c9"
],
"borderColor": "#ccc",
"borderWidth": 0,
"visualMapColor": [
"#d0648a",
"#22c3aa",
"#adfff1"
],
"legendTextColor": "#999999",
"kColor": "#d0648a",
"kColor0": "transparent",
"kBorderColor": "#d0648a",
"kBorderColor0": "#22c3aa",
"kBorderWidth": "1",
"lineWidth": "3",
"symbolSize": "8",
"symbol": "emptyCircle",
"symbolBorderWidth": "2",
"lineSmooth": false,
"graphLineWidth": "1",
"graphLineColor": "#cccccc",
"mapLabelColor": "#28544e",
"mapLabelColorE": "rgb(52,158,142)",
"mapBorderColor": "#999999",
"mapBorderColorE": "#22c3aa",
"mapBorderWidth": 0.5,
"mapBorderWidthE": 1,
"mapAreaColor": "#eeeeee",
"mapAreaColorE": "rgba(34,195,170,0.25)",
"axes": [{
"type": "all",
"name": "通用坐标轴",
"axisLineShow": true,
"axisLineColor": "#cccccc",
"axisTickShow": false,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#999999",
"splitLineShow": true,
"splitLineColor": [
"#eeeeee"
],
"splitAreaShow": false,
"splitAreaColor": [
"rgba(250,250,250,0.05)",
"rgba(200,200,200,0.02)"
]
},
{
"type": "category",
"name": "类目坐标轴",
"axisLineShow": true,
"axisLineColor": "#333",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#333",
"splitLineShow": false,
"splitLineColor": [
"#ccc"
],
"splitAreaShow": false,
"splitAreaColor": [
"rgba(250,250,250,0.3)",
"rgba(200,200,200,0.3)"
]
},
{
"type": "value",
"name": "数值坐标轴",
"axisLineShow": true,
"axisLineColor": "#333",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#333",
"splitLineShow": true,
"splitLineColor": [
"#ccc"
],
"splitAreaShow": false,
"splitAreaColor": [
"rgba(250,250,250,0.3)",
"rgba(200,200,200,0.3)"
]
},
{
"type": "log",
"name": "对数坐标轴",
"axisLineShow": true,
"axisLineColor": "#333",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#333",
"splitLineShow": true,
"splitLineColor": [
"#ccc"
],
"splitAreaShow": false,
"splitAreaColor": [
"rgba(250,250,250,0.3)",
"rgba(200,200,200,0.3)"
]
},
{
"type": "time",
"name": "时间坐标轴",
"axisLineShow": true,
"axisLineColor": "#333",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#333",
"splitLineShow": true,
"splitLineColor": [
"#ccc"
],
"splitAreaShow": false,
"splitAreaColor": [
"rgba(250,250,250,0.3)",
"rgba(200,200,200,0.3)"
]
}
],
"axisSeperateSetting": false,
"toolboxColor": "#999999",
"toolboxEmpasisColor": "#666666",
"tooltipAxisColor": "#cccccc",
"tooltipAxisWidth": 1,
"timelineLineColor": "#4ea397",
"timelineLineWidth": 1,
"timelineItemColor": "#4ea397",
"timelineItemColorE": "#4ea397",
"timelineCheckColor": "#4ea397",
"timelineCheckBorderColor": "rgba(60,235,210,0.3)",
"timelineItemBorderWidth": 1,
"timelineControlColor": "#4ea397",
"timelineControlBorderColor": "#4ea397",
"timelineControlBorderWidth": 0.5,
"timelineLabelColor": "#4ea397",
"datazoomBackgroundColor": "rgba(255,255,255,0)",
"datazoomDataColor": "rgba(222,222,222,1)",
"datazoomFillColor": "rgba(114,230,212,0.25)",
"datazoomHandleColor": "#cccccc",
"datazoomHandleWidth": "100",
"datazoomLabelColor": "#999999"
}
}
window.echarts.registerTheme(theme_wonderland.themeName, theme_wonderland.theme)

View File

@ -0,0 +1,87 @@
export const uuid = () => {
var s = [];
var hexDigits = "0123456789abcdef";
for (var i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
}
s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
s[8] = s[13] = s[18] = s[23] = "-";
var uuid = s.join("");
return uuid;
}
export const compare = (propertyName) => {
return function (object1, object2) {
var value1 = object1[propertyName];
var value2 = object2[propertyName];
if (value2 < value1) {
return -1;
} else if (value2 > value1) {
return 1;
} else {
return 0;
}
}
}
export const stringify = (json) => {
let count = 0;
let list = [];
let str = JSON.stringify(json, function (key, val) {
if (typeof val === 'function') {
list.push(val + '');
const result = '$code{' + count + '}$code'
count = count + 1;
return result
}
return val;
}, 2);
let startCode = '$code{';
let endCode = '}$code';
list.forEach((ele, index) => {
str = str.replace(startCode + index + endCode, startCode + ele + endCode)
})
for (let i = 0; i < count; i++) {
str = str.replace('"' + startCode, '').replace(endCode + '"', '')
}
return str
}
export const parse = (str) => {
return JSON.parse(str, function (k, v) {
if (v.indexOf && v.indexOf('function') > -1) {
return eval("(function(){return " + v + " })()")
}
return v;
});
}
export const addUrlParam = (url, param, value) => {
if (!url) return
function GetQueryString (name) {
var num = url.indexOf("?")
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
var r = url.substr(num + 1).match(reg);
if (r != null) {
return unescape(r[2]);
}
return null;
}
function replaceParamVal (paramName, value) {
var re = eval('/(' + paramName + '=)([^&]*)/gi');
return url.replace(re, paramName + '=' + value);
}
if (GetQueryString(param)) {
return replaceParamVal(param, value)
} else {
if (url.includes('?')) {
url = url + '&' + param + '=' + value
} else {
url = url + '?' + param + '=' + value
}
return url;
}
}

View File

@ -0,0 +1,579 @@
<template>
<div class="build">
<imglist ref="imglist"
@change="handleSetimg"></imglist>
<top ref="top"></top>
<div class="app"
:class="{'app--none':!menuFlag}">
<div class="menu"
v-show="menuFlag"
@click.self="handleMouseDown">
<p class="title">图层</p>
<layer ref="layer"
:nav="nav"></layer>
</div>
<container ref="container"></container>
<div class="menu params"
v-show="menuFlag">
<p class="title">操作</p>
<el-tabs class="tabs"
stretch
v-model="tabsActive">
<el-tab-pane name="0">
<el-tooltip slot="label"
effect="dark"
content="配置"
placement="top">
<div><i class="el-icon-setting"></i></div>
</el-tooltip>
<el-form label-width="120px"
label-position="left"
size="mini">
<!-- 组件配置 -->
<template v-if="!vaildProp('',[undefined])">
<p class="title">{{activeObj.title}}</p>
<el-form-item label="图层名称">
<avue-input v-model="activeObj.name"></avue-input>
</el-form-item>
<el-form-item label="隐藏">
<avue-switch v-model="activeObj.display"></avue-switch>
</el-form-item>
<template v-if="vaildProp('colorList')">
<el-form-item label="系统配色">
<avue-switch v-model="activeOption.switchTheme"></avue-switch>
</el-form-item>
<el-form-item label="配色选择"
v-if="activeOption.switchTheme">
<avue-select v-model="activeOption.theme"
:dic="dicOption.themeList">
</avue-select>
</el-form-item>
</template>
<component :is="activeComponent.prop+'Option'"></component>
<common-option></common-option>
</template>
<!-- 多选配置选项 -->
<template v-else-if="isSelectActive">
<el-form-item label="水平方式">
<el-tooltip content="左对齐"
placement="top">
<i class="el-icon-s-fold icon"
@click="$refs.container.handlePostionSelect('left')"></i>
</el-tooltip>
<el-tooltip content="居中对齐"
placement="top">
<i class="el-icon-s-operation icon"
@click="$refs.container.handlePostionSelect('center')"></i>
</el-tooltip>
<el-tooltip content="右对齐"
placement="top">
<i class="el-icon-s-unfold icon"
@click="$refs.container.handlePostionSelect('right')"></i>
</el-tooltip>
</el-form-item>
<el-form-item label="垂直方式">
<el-tooltip content="顶对齐"
placement="top">
<i class="el-icon-s-fold icon"
@click="$refs.container.handlePostionSelect('top')"></i>
</el-tooltip>
<el-tooltip content="中部对齐"
placement="top">
<i class="el-icon-s-operation icon"
@click="$refs.container.handlePostionSelect('middle')"></i>
</el-tooltip>
<el-tooltip content="底对齐"
placement="top">
<i class="el-icon-s-unfold icon"
@click="$refs.container.handlePostionSelect('bottom')"></i>
</el-tooltip>
</el-form-item>
<el-form-item label-width="0">
<el-button type="primary"
size="mini"
class="block"
@click="handleDeleteSelect">删除</el-button>
</el-form-item>
<el-form-item label-width="0">
<el-button type="danger"
size="mini"
class="block"
@click="handleFloder">成组</el-button>
</el-form-item>
</template>
<!-- 主屏的配置项 -->
<template v-else>
<!-- <el-form-item label="大屏名称">
<avue-input v-model="config.name"></avue-input>
</el-form-item> -->
<el-form-item label="大屏宽度">
<avue-input-number v-model="config.width"></avue-input-number>
</el-form-item>
<el-form-item label="大屏高度">
<avue-input-number v-model="config.height"></avue-input-number>
</el-form-item>
<el-form-item label="大屏简介">
<avue-input v-model="config.info"
type="textarea"
:min-rows="5"></avue-input>
</el-form-item>
<el-form-item label="背景颜色">
<avue-color v-model="config.backgroundColor"></avue-color>
</el-form-item>
<el-form-item label="背景图片">
<img :src="config.backgroundImage"
@click="handleOpenImg('config.backgroundImage','background')"
alt=""
width="100%" />
</el-form-item>
<el-form-item label="缩放">
<el-slider v-model="config.scale"
:max="200"
:format-tooltip="formatTooltip"></el-slider>
</el-form-item>
<el-form-item label="环境地址">
<avue-input type="textarea"
:min-rows="2"
v-model="config.url"></avue-input>
</el-form-item>
<el-form-item label="参数">
<el-button size="mini"
type="primary"
@click="openCode('query')">编辑</el-button>
</el-form-item>
<el-form-item label="水印(预览有效)">
<avue-switch v-model="config.mark.show"></avue-switch>
</el-form-item>
<template v-if="config.mark.show">
<el-form-item label="内容">
<avue-input v-model="config.mark.text"></avue-input>
</el-form-item>
<el-form-item label="大小">
<avue-input-number v-model="config.mark.fontSize"></avue-input-number>
</el-form-item>
<el-form-item label="颜色">
<avue-color v-model="config.mark.textStyle"></avue-color>
</el-form-item>
<el-form-item label="角度">
<avue-input-number v-model="config.mark.degree"></avue-input-number>
</el-form-item>
</template>
</template>
</el-form>
</el-tab-pane>
<!-- 数据配置 -->
<el-tab-pane name="1"
v-if="vaildProp('dataList')">
<el-tooltip slot="label"
effect="dark"
content="数据"
placement="top">
<div><i class="el-icon-document-copy"></i></div>
</el-tooltip>
<el-form label-width="120px"
label-position="left"
size="mini">
<el-form-item label="数据类型">
<avue-radio v-model="activeObj.dataType"
:dic="dicOption.dataType"></avue-radio>
</el-form-item>
<el-form-item label="数据值"
label-position="top"
v-if="activeObj.dataType===0">
<el-button size="mini"
type="primary"
@click="openCode('data')">编辑</el-button>
</el-form-item>
<template v-if="activeObj.dataType===1">
<el-form-item label="接口地址">
<avue-input type="textarea"
:min-rows="6"
v-model="activeObj.url"></avue-input>
</el-form-item>
<el-form-item label="接口方式"
v-if="activeObj.dataType===1">
<avue-radio v-model="activeObj.dataMethod"
:dic="dicOption.dataMethod"></avue-radio>
</el-form-item>
<el-form-item label="接口参数"
v-if="activeObj.dataType===1">
<el-button size="mini"
type="primary"
@click="openCode('dataQuery')">编辑</el-button>
</el-form-item>
<el-form-item label="刷新时间">
<avue-input-number v-model="activeObj.time"></avue-input-number>
</el-form-item>
</template>
<el-form-item label="数据处理">
<el-button size="mini"
type="primary"
@click="openCode('dataFormatter')">编辑</el-button>
</el-form-item>
<el-form-item label-width="0">
<el-button size="mini"
type="primary"
class="block"
@click="handleRefresh">刷新</el-button>
</el-form-item>
</el-form>
</el-tab-pane>
<!-- 交互事件配置 -->
<el-tab-pane name="2"
v-if="vaildProp('eventList')">
<el-tooltip slot="label"
effect="dark"
content="交互"
placement="top">
<div><i class="el-icon-thumb"></i></div>
</el-tooltip>
<el-form label-width="120px"
label-position="left"
size="mini">
<el-form-item label="子类">
<avue-select multiple
v-model="activeObj.child.index"
:dic="childList"
:props="childProps">
</avue-select>
</el-form-item>
<el-form-item label="参数名称">
<avue-input v-model="activeObj.child.paramName"></avue-input>
</el-form-item>
</el-form>
</el-tab-pane>
<!-- 其他事件配置 -->
<el-tab-pane name="3"
v-if="vaildProp('formatterList')">
<el-tooltip slot="label"
effect="dark"
content="事件"
placement="top">
<div><i class="iconfont icon-peizhi"></i></div>
</el-tooltip>
<el-form label-width="120px"
label-position="left"
size="mini">
<el-form-item label="提示事件">
<el-button size="mini"
type="primary"
@click="openCode('formatter')">编辑</el-button>
</el-form-item>
<el-form-item label="点击事件"
v-if="vaildProp('clickFormatterList')">
<el-button size="mini"
type="primary"
@click="openCode('clickFormatter')">编辑</el-button>
</el-form-item>
<el-form-item label="标题事件"
v-if="vaildProp('labelFormatterList')">
<el-button size="mini"
type="primary"
@click="openCode('labelFormatter')">编辑</el-button>
</el-form-item>
<el-form-item label-width="0">
<el-button size="mini"
type="primary"
class="block"
@click="handleRefresh">刷新</el-button>
</el-form-item>
</el-form>
</el-tab-pane>
<!-- 基本参数配置 -->
<el-tab-pane name="4"
v-if="isActive">
<el-tooltip slot="label"
effect="dark"
content="参数"
placement="top">
<div><i class="el-icon-folder"></i></div>
</el-tooltip>
<el-form label-width="120px"
label-position="left"
size="mini">
<el-form-item label="序号">
<avue-input v-model="activeObj.index"
disabled></avue-input>
</el-form-item>
<el-form-item label="X位置">
<avue-input-number v-model="activeObj.left"></avue-input-number>
</el-form-item>
<el-form-item label="Y位置">
<avue-input-number v-model="activeObj.top"></avue-input-number>
</el-form-item>
<el-form-item label="宽度">
<avue-input-number v-model="activeComponent.width"></avue-input-number>
</el-form-item>
<el-form-item label="高度">
<avue-input-number v-model="activeComponent.height"></avue-input-number>
</el-form-item>
</el-form>
</el-tab-pane>
</el-tabs>
</div>
</div>
<el-dialog title="代码编辑"
:visible.sync="code.box"
@close="code.obj={}"
width="60%">
<codeedit ref="codeedit"
v-model="code.obj"></codeedit>
<span slot="footer"
class="dialog-footer">
<el-button size="small"
@click="code.box=false"> </el-button>
<el-button type="primary"
@click="codeClose"
size="small"> </el-button>
</span>
</el-dialog>
<contentmenu ref="contentmenu"></contentmenu>
</div>
</template>
<script>
import layer from './group/layer';
import top from './group/top';
import imglist from './group/imglist'
import contentmenu from './group/contentmenu'
import codeedit from './group/code';
import { dicOption } from '@/option/config'
import init from '@/mixins/'
import { uuid } from '@/utils/utils'
import components from '@/option/components'
export default {
mixins: [init, components],
data () {
return {
keys: {
ctrl: false,
},
loading: '',
childProps: {
label: 'name',
value: 'index'
},
key: '',
menuFlag: true,
code: {
box: false,
type: '',
obj: '',
},
form: {},
dicOption: dicOption,
tabsActive: 0,
}
},
components: {
imglist,
layer,
codeedit,
top,
contentmenu
},
computed: {
isFolder () {
return this.activeObj.children
},
isActive () {
return this.active.length !== 0
},
isSelectActive () {
return this.active.length > 1;
},
childList () {
return this.list.filter(ele => {
if (['tabs'].includes(ele.component.prop)) {
return false;
}
return true;
})
},
activeComponent () {
return this.activeObj.component || {}
},
activeOption () {
return this.activeObj.option || {}
},
activeObj () {
let result
if (this.validatenull(this.active)) {
return {}
}
this.active.forEach(ele => {
const item = this.findnav(ele, true);
if (this.active.length > 1) {
if (!result) result = [];
result.push(item.obj);
} else {
result = item.obj
}
})
return result
}
},
watch: {
menuFlag () {
this.setResize();
},
overactive (n, o) {
[o, n].forEach((ele, index) => {
if (!ele) return
this.setActive(ele, index === 1, 'setOverActive');
})
},
active (n, o) {
[o, n].forEach((ele, index) => {
ele.forEach(item => {
this.setActive(item, index === 1, 'setActive');
})
})
//隐藏右键菜单
this.$refs.contentmenu.hide();
// 初始化选项卡
this.tabsActive = '0';
},
},
created () {
this.listen();
},
mounted () {
this.initFun()
},
methods: {
codeClose () {
let value = this.$refs.codeedit.getValue();
if (this.validatenull(value)) {
value = '{}'
}
try {
if (['query', 'data'].includes(this.code.type)) {
value = JSON.parse(value, null, 4)
}
if (this.code.type === 'query') {
this.config.query = value;
} else {
this.activeObj[this.code.type] = value;
}
this.code.box = false;
} catch (error) {
this.$message.error('数据格式有误')
}
},
openCode (type) {
this.code.type = type;
if (type === 'query') {
this.code.obj = this.config.query;
} else {
this.code.obj = this.activeObj[type];
}
this.code.box = true;
},
initFun () {
['setScale', 'setResize'].forEach(ele => {
this[ele] = this.$refs.container[ele]
});
['handleAdd'].forEach(ele => {
this[ele] = this.$refs.top[ele]
})
},
// 右键菜单
handleContextMenu (e, item = {}) {
if (!item.index) {
return
}
if (!this.isSelectActive) {
this.active = [item.index];
}
setTimeout(() => {
this.$refs.contentmenu.show(e.clientX, e.clientY);
}, 0)
},
//监听键盘的按键
listen () {
document.onkeydown = (e) => {
this.keys.ctrl = e.keyCode === 17;
}
document.onkeyup = () => {
this.keys.ctrl = false;
}
},
setActive (val, result, fun) {
const obj = this.$refs.container.handleGetObj(val);
if (!this.validatenull(obj)) obj[0][fun](result)
},
//批量成组
handleFloder () {
let floder = {
"title": "文件夹",
"name": "文件夹",
"index": uuid(),
"children": []
}
this.active.forEach(index => {
const params = this.findnav(index);
floder.children.push(params.obj);
delete params.parent.splice(params.count, 1);
})
this.nav.push(floder);
this.handleInitActive();
},
//批量删除
handleDeleteSelect () {
this.$confirm(`是否批量删除所选图层?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
this.active.forEach(index => {
const params = this.findnav(index);
delete params.parent.splice(params.count, 1);
})
this.handleInitActive()
})
},
vaildProp (name, list) {
if (list) {
return list.includes(this.activeComponent.prop)
}
return this.dicOption[name].includes(this.activeComponent.prop)
},
handleRefresh (tip) {
this.$refs.container.handleRefresh(tip);
},
formatTooltip (val) {
return parseInt(val);
},
//打开图库
handleOpenImg (item, type) {
this.$refs.imglist.openImg(item, type);
},
//图库框回调赋值
handleSetimg (val, type) {
if (type === 'activeObj.data') {
this.activeObj.data = val;
} if (type === 'activeObj.data.value') {
this.activeObj.data.value = val;
} else if (type === 'activeOption.backgroundImage') {
this.activeOption.backgroundImage = val;
} else if (type === 'activeOption.backgroundBorder') {
this.activeOption.backgroundBorder = val;
} else if (type === 'activeOption.empBackgroundBorder') {
this.activeOption.empBackgroundBorder = val;
} else if (type === 'config.backgroundImage') {
this.config.backgroundImage = val;
} else if (type === 'activeOption.symbol') {
this.activeOption.symbol = val;
}
}
}
}
</script>
<style lang="scss">
@import "../styles/style.scss";
</style>

View File

@ -0,0 +1,82 @@
<template>
<textarea :ref="id"
v-model="code"
style="height:300px;width:100%;"></textarea>
</template>
<script>
import "codemirror/theme/blackboard.css";
import "codemirror/lib/codemirror.css";
import "codemirror/addon/hint/show-hint.css";
let CodeMirror = require("codemirror/lib/codemirror");
require("codemirror/addon/edit/matchbrackets");
require("codemirror/addon/selection/active-line");
require("codemirror/addon/hint/show-hint");
export default {
name: "codeMirror",
data () {
return {
editor: '',
id: Math.floor(Math.random() * 100),
code: ''
}
},
props: {
value: {
type: [String, Object, Array],
default: ''
}
},
watch: {
value: {
handler (val) {
if (['object', 'array'].includes(typeof val)) {
this.code = JSON.stringify(this.value, null, 4);
} else {
this.code = val;
}
this.setValue(this.code);
},
immediate: true,
deep: true,
},
},
mounted () {
this.init();
},
methods: {
getValue () {
return this.editor.getValue()
},
setValue (val) {
if (this.editor) this.editor.setValue(val);
},
init () {
let mime = 'text/javascript'
let theme = 'blackboard'//设置主题,不设置的会使用默认主题
this.editor = CodeMirror.fromTextArea(this.$refs[this.id], {
mode: mime,//选择对应代码编辑器的语言,我这边选的是数据库,根据个人情况自行设置即可
indentWithTabs: true,
smartIndent: true,
lineNumbers: true,
matchBrackets: true,
theme: theme,
// autofocus: true,
extraKeys: { 'Ctrl': 'autocomplete' },//自定义快捷键
// hintOptions: {//自定义提示选项
// tables: {
// users: ['name', 'score', 'birthDate'],
// countries: ['name', 'population', 'size']
// }
// }
})
//代码自动提示功能记住使用cursorActivity事件不要使用change事件这是一个坑那样页面直接会卡死
this.editor.on('cursorActivity', () => {
this.editor.showHint()
})
}
}
}
</script>

View File

@ -0,0 +1,248 @@
<template>
<div class="middle">
<div class="wrapper__grade"
@mousedown="contain.handleMouseDown"></div>
<div id="wrapper"
class="wrapper"
@mousedown="contain.handleMouseDown">
<div class="content"
id="content"
ref="content">
<div class="container"
:style="styleName"
id="container"
ref="container">
<div class="grade"
v-if="gradeFlag || contain.config.gradeShow"
:style="gradeLenStyle"></div>
<subgroup ref="subgroup"
:nav="contain.list"></subgroup>
</div>
</div>
</div>
</div>
</template>
<script>
import subgroup from './subgroup'
import common from '@/config'
import { getObj } from '@/api/visual'
export default {
name: 'contents',
inject: ["contain"],
provide () {
return {
// contain: this.contain,
container: this
};
},
components: {
subgroup
},
data () {
return {
selectCount: {},
scale: 1,
gradeFlag: false,
}
},
computed: {
stepScale () {
let scale = Number(((1 / this.scale) * 100).toFixed(2));
return scale
},
//计算中央可视化大屏比例
styleName () {
const scale = this.contain.config.scale;
return Object.assign({
transform: `scale(${scale / 100}, ${scale / 100})`,
width: this.setPx(this.contain.config.width),
height: this.setPx(this.contain.config.height),
backgroundColor: this.contain.config.backgroundColor
}, (() => {
if (this.contain.config.backgroundImage) {
return {
background: `url(${this.contain.config.backgroundImage}) 0% 0% / 100% 100% rgb(3, 12, 59)`,
}
}
return
})())
},
gradeLenStyle () {
return {
backgroundSize: `${this.setPx(this.contain.config.gradeLen)} ${this.setPx(this.contain.config.gradeLen)},${this.setPx(this.contain.config.gradeLen)} ${this.setPx(this.contain.config.gradeLen)}`
}
}
},
mounted () {
this.initData();
this.initFun();
},
methods: {
initFun () {
['handleRefresh', 'handleGetObj'].forEach(ele => {
console.log('66666');
this[ele] = this.$refs.subgroup[ele]
});
},
//初始化数据
initData () {
const id = this.$route.params.id;
this.contain.id = id;
this.contain.contentWidth = this.$refs.content.offsetWidth;
const isBuild = this.$route.name === 'build';
const width = isBuild ? this.contain.contentWidth : document.body.clientWidth
if (id) {
const loading = this.$loading({
lock: true,
text: '正在加载中,请稍后',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
getObj(id).then(res => {
const callback = () => {
//赋值属性
this.contain.config = JSON.parse(config.detail) || {};
this.contain.nav = JSON.parse(config.component) || [];
this.calcData();
this.setScale(width);
}
const data = res.data;
this.contain.obj = data;
const config = data.config;
this.contain.visual = data.visual;
//添加水印。只有查看页面生效
if (!isBuild) {
if (this.contain.config.mark.show) {
this.watermark(this.contain.config.mark);
}
const password = this.contain.visual.password
if (!this.validatenull(password)) {
this.$prompt('请输入密码', '提示', {
confirmButtonText: '确定',
showCancelButton: false,
showClose: false,
closeOnClickModal: false,
inputPattern: new RegExp(password),
inputErrorMessage: '密码不正确,请重新输入'
}).then(() => {
callback();
})
} else {
callback();
}
} else {
callback();
}
loading.close();
}).catch((err) => {
console.log(err)
loading.close();
})
} else {
this.setScale(width);
}
},
//适配尺寸
setResize () {
this.$nextTick(() => {
this.$refs.content.style.width = this.setPx((this.contain.config.scale * this.contain.config.width) / 100)
this.$refs.content.style.height = this.setPx((this.contain.config.scale * this.contain.config.height) / 100)
})
},
//计算比例
setScale (width) {
this.$nextTick(() => {
this.contain.config.scale = (width / this.contain.config.width) * 100
this.scale = this.contain.config.scale;
this.setResize();
})
},
calcData () {
if (!this.contain.config.mark) this.contain.config.mark = {}
if (!this.contain.config.query) this.contain.config.query = {}
},
handlePostionSelect (postion) {
this.handleCalcPostionSelect();
const x1 = this.selectCount.maxx1;
const x2 = this.selectCount.maxx2;
const y1 = this.selectCount.maxy1;
const y2 = this.selectCount.maxy2;
if (postion === 'left') {
this.handleMoveSelectList(x1, undefined, true, postion);
} else if (postion === 'center') {
this.handleMoveSelectList(x1 + (x2 - x1) / 2, undefined, true, postion);
} else if (postion === 'right') {
this.handleMoveSelectList(x2, undefined, true, postion);
} else if (postion === 'top') {
this.handleMoveSelectList(undefined, y1, true, postion);
} else if (postion === 'middle') {
this.handleMoveSelectList(undefined, y1 + (y2 - y1) / 2, true, postion);
} else if (postion === 'bottom') {
this.handleMoveSelectList(undefined, y2, true, postion);
}
},
handleMoveSelectList (left, top, type, postion) {
this.contain.active.forEach(ele => {
ele = this.contain.findlist(ele)
const ele_component = ele.component;
//水平情况
if (left) {
let baseLeft = Number(type ? left : (ele.left + left).toFixed(2));
if (postion === 'right') {
baseLeft = baseLeft - ele_component.width
}
else if (postion === 'center') {
const obj_center = ele.left + ele_component.width / 2;
baseLeft = ele.left + (left - obj_center)
}
this.$set(ele, 'left', baseLeft);
this.$refs.subgroup.$refs[common.DEAFNAME + ele.index][0].setLeft(baseLeft)
}
//垂直情况
if (top) {
let baseTop = Number(type ? top : (ele.top + top).toFixed(2));
if (postion === 'bottom') {
baseTop = baseTop - ele_component.height
}
else if (postion === 'middle') {
const obj_middle = ele.top + ele_component.height / 2;
baseTop = ele.top + (top - obj_middle)
}
this.$set(ele, 'top', baseTop)
this.$refs.subgroup.$ref[common.DEAFNAME + ele.index][0].setTop(baseTop)
}
})
},
//计算多选状态下的最大边界值
handleCalcPostionSelect () {
this.selectCount.maxx1 = 99999;
this.selectCount.maxy1 = 99999;
this.contain.active.forEach(ele => {
ele = this.contain.findlist(ele)
const left = ele.left;
const top = ele.top;
const width = ele.component.width;
const height = ele.component.height;
if (this.selectCount.maxx1 > left) {
this.selectCount.maxx1 = left;
}
if (this.selectCount.maxx2 < left + width) {
this.selectCount.maxx2 = left + width;
}
if (this.selectCount.maxy1 > top) {
this.selectCount.maxy1 = top;
}
if (this.selectCount.maxy2 < top + height) {
this.selectCount.maxy2 = top + height;
}
})
},
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,232 @@
<template>
<div class="contentmenu"
v-show="contentMenu"
@click="contentMenu=false"
:style="styleName">
<div class="contentmenu__item"
@click="handleLogout()"
v-if="contain.isFolder"> <i class="el-icon-close"></i>解散分组
</div>
<div class="contentmenu__item"
@click="handleCompose()"
v-if="!contain.isFolder"> <i class="el-icon-close"></i>组合分组
</div>
<div class="contentmenu__item"
@click="handleDel()"> <i class="el-icon-close"></i>删除图层
</div>
<div class="contentmenu__item"
@click="handleCopy()"><i class="el-icon-document"></i>复制图层
</div>
<div class="contentmenu__item"
@click="handleTop()"><i class="el-icon-arrow-up"></i>置顶图层
</div>
<div class="contentmenu__item"
@click="handleBottom()"><i class="el-icon-arrow-down"></i>置底图层
</div>
<div class="contentmenu__item"
@click="handleStepTop()"><i class="el-icon-arrow-up"></i>上移一层
</div>
<div class="contentmenu__item"
@click="handleStepBottom()"><i class="el-icon-arrow-down"></i>下移一层
</div>
</div>
</template>
<script>
import { uuid } from '@/utils/utils'
export default {
name: 'contentmenu',
inject: ["contain"],
data () {
return {
contentMenu: false,
contentMenuX: 0,
contentMenuY: 0,
}
},
computed: {
styleName () {
return {
left: this.setPx(this.contentMenuX),
top: this.setPx(this.contentMenuY)
}
}
},
methods: {
show (X = 0, Y = 0) {
this.contentMenuX = X;
this.contentMenuY = Y;
this.contentMenu = true;
},
hide () {
this.contentMenuX = 0;
this.contentMenuY = 0;
this.contentMenu = false;
},
handleStepBottom () {
this.handleCommon(false, true);
},
handleStepTop () {
this.handleCommon(true, true);
},
//文件夹成组逻辑
handleCompose () {
let list = this.contain.active;
this.$confirm(`是否组合所选择的图层?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let floder = {
"title": "文件夹",
"name": "文件夹",
"index": uuid(),
"children": []
}
//查找到每个组件调用核心方法就行组合操作
//寻找父类
const params = this.contain.findnav(list[0], true);
list.forEach(ele => {
const item = this.contain.findnav(ele, true);
item.parent.splice(item.count, 1);
floder.children.push(item.obj);
});
params.parent.push(floder);
}).catch(() => { })
},
//文件夹解散逻辑
handleLogout () {
let ele = this.contain.activeObj
this.$confirm(`是否解散${ele.name}图层?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
//查找到文件夹调用核心方法nav去操作
const params = this.contain.findnav(ele.index, true);
const list = this.deepClone(params.obj.children)
params.parent.splice(params.count, 1);
list.forEach(ele => {
params.parent.push(ele);
});
this.contain.handleInitActive();
}).catch(() => { })
},
//删除组件的方法
handleDel () {
this.$confirm(`是否删除所选图层?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
const params = this.contain.findnav(this.contain.active[0], true);
this.contain.active.forEach(ele => {
const item = this.contain.findnav(ele, true);
if (Array.isArray(params.parent)) {
params.parent.splice(item.count, 1);
} else {
params.parent.children.splice(item.count, 1);
}
});
this.contain.handleInitActive();
}).catch(() => { })
},
//复制组件的方法
handleCopy () {
//寻找父类
const params = this.contain.findnav(this.contain.active[0], true);
this.contain.active.forEach(ele => {
const item = this.contain.findnav(ele, true);
const obj = this.deepClone(item.obj);
obj.index = uuid();
params.parent.push(obj)
});
this.contain.handleInitActive();
},
// 图层的上下移动方法
handleCommon (first = false, step = false) {
// 交换数组元素
var swapItems = function (arr, index1, index2) {
arr[index1] = arr.splice(index2, 1, arr[index1])[0];
return arr;
};
let obj = this.contain.activeObj;
let data = this.deepClone(obj);
let params = this.contain.findnav(obj.index, true);
if (params.pcount !== 0) {
if (params.len < 1) return;
if (step) {
if (first && params.count === 0) return
if (!first && params.count === params.len) return
let count = first ? params.count - 1 : params.count + 1
swapItems(params.parent.children, params.count, count);
} else {
if (first) {
if (params.count === 0) return
params.parent.children.splice(params.count, 1);
params.parent.children.unshift(data);
} else {
if (params.count === params.len) return
params.parent.children.splice(params.count, 1);
params.parent.children.push(data);
}
}
} else {
if (this.contain.nav.length < 1) return;
if (step) {
if (first && params.count === 0) return
if (!first && params.count === params.len) return
let count = first ? params.count - 1 : params.count + 1
swapItems(this.contain.nav, params.count, count);
} else {
if (first) {
if (params.count === 0) return
this.contain.nav.splice(params.count, 1)
this.contain.nav.unshift(data);
} else {
if (params.count === params.len) return
this.contain.nav.splice(params.count, 1)
this.contain.nav.push(data);
}
}
}
},
handleTop () {
this.handleCommon(true);
},
handleBottom () {
this.handleCommon();
}
}
}
</script>
<style>
.contentmenu {
width: 160px;
position: fixed;
z-index: 99999;
list-style: none;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
padding: 0;
background: #27343e;
color: #bcc9d4;
}
.contentmenu__item {
z-index: 10000;
list-style: none;
padding: 8px 12px;
cursor: pointer;
position: relative;
font-size: 12px;
}
.contentmenu__item:hover {
background-color: rgba(0, 192, 222, 0.1);
}
.contentmenu__item i {
margin-right: 5px;
}
.contentmenu__item :first-child {
padding-top: 5px;
}
</style>

View File

@ -0,0 +1,86 @@
<template>
<el-dialog title="图库"
width="80%"
:visible.sync="imgVisible">
<div style="margin:0 auto;">
<el-upload class="upload-demo"
:on-success="onSuccess"
:show-file-list="false"
:action="url+'/visual/put-file'"
multiple
list-type="picture">
<el-button size="small"
icon="el-icon-upload"
type="primary">点击上传</el-button>
</el-upload>
</div>
<el-scrollbar class="imgList">
<img :src="item.value"
:style="styleName"
@click="handleSetimg(item.value)"
v-for="(item,index) in imgOption[imgActive]"
:key="index" />
</el-scrollbar>
</el-dialog>
</template>
<script>
import { imgOption } from '@/option/config'
export default {
data () {
return {
imgVisible: false,
imgObj: '',
type: '',
imgActive: 0,
imgOption: imgOption,
imgTabs: [],
}
},
computed: {
styleName () {
if (this.type === 'background') {
return {
width: '200px'
}
}
return {}
}
},
watch: {
type: {
handler () {
if (this.type === 'background') {
this.imgActive = 0;
} else if (this.type == 'border') {
this.imgActive = 1;
} else {
this.imgActive = 2;
}
},
immediate: true
}
},
methods: {
onSuccess (res) {
const url = res.data.link;
this.imgOption[this.imgActive].unshift({
label: url,
value: url
});
},
openImg (item, type) {
this.type = type;
this.imgObj = item
this.imgVisible = true;
},
handleSetimg (item) {
this.imgVisible = false;
this.$emit('change', item, this.imgObj);
}
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,121 @@
<template>
<draggable :group="{ name: 'form' }"
ghost-class="ghost"
:list="nav"
:animation="300">
<template v-for="item in nav">
<div :key="item.index"
class="menu__folder"
v-if="item.children">
<div @dblclick="hangeChangeName(item)"
@click="handleSetActive(item)"
@contextmenu.prevent="contain.handleContextMenu($event,item)"
:class="['menu__item--folder',{'is-active':handleGetActive(item),'is-over':contain.overactive===item.index}]">
<i class="iconfont icon-fold"
@click="openFolder(item)"
:class="{'is-active':item.menu}"></i>
<i class="iconfont icon-folder"
@click="openFolder(item)"></i>
<input type="text"
@keyup.enter="item.isname=false"
v-if="item.isname"
v-model="item.name">
<span v-else>{{item.name}}</span>
</div>
<div :key="'list'
+item.index"
class="menu__list"
v-show="item.menu">
<draggable :group="{ name: 'form' }"
ghost-class="ghost"
:list="item.children"
:animation="300">
<template v-for="citem in item.children">
<div v-if="!citem.children"
:key="citem.index"
:class="['menu__item',{'is-active':handleGetActive(citem),'is-over':contain.overactive===citem.index}]"
@click="handleSetActive(citem)"
@contextmenu.prevent="contain.handleContextMenu($event,citem)"
@mouseover="contain.overactive=citem.index"
@mouseout="contain.overactive=undefined">
<span class="menu__icon">
<i :class="'iconfont '+citem.icon"></i>
</span>
<span>{{citem.title}}</span>
</div>
<layer v-else
:count="count+1"
:key="citem.index"
:nav="[citem]"></layer>
</template>
</draggable>
</div>
</div>
<div v-else
:key="item.index"
@contextmenu.prevent="contain.handleContextMenu($event,item)"
@click="handleSetActive(item)"
:class="['menu__item',{'is-active':handleGetActive(item),'is-over': contain.overactive===item.index}]"
@mouseover="contain.overactive=item.index"
@mouseout="contain.overactive=undefined">
<span class="menu__icon">
<i :class="'iconfont '+item.icon"></i>
</span>
<span>{{item.title}}</span>
</div>
</template>
</draggable>
</template>
<script>
import vuedraggable from 'vuedraggable';
export default {
name: 'layer',
inject: ["contain"],
provide () {
return {
contain: this.contain
};
},
components: {
draggable: vuedraggable
},
props: {
count: {
type: Number,
default: 1,
},
nav: {
type: Array,
default: () => {
return []
}
}
},
methods: {
handleGetActive (item) {
return this.contain.active.includes(item.index);
},
handleSetActive (item) {
if (this.contain.keys.ctrl) {
if (!Array.isArray(this.contain.active)) {
this.contain.handleInitActive();
}
this.contain.active.push(item.index)
} else {
this.contain.active = [item.index];
}
},
hangeChangeName (item) {
this.$set(item, 'isname', !item.isname)
},
openFolder (item) {
this.$set(item, 'menu', !item.menu)
item.isname = false;
},
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,149 @@
<template>
<div>
<div v-for="item in nav"
:key="item.index"
@contextmenu.prevent="contain.handleContextMenu($event,item)">
<avue-draggable v-if="!item.children"
v-bind="item"
:scale="container.stepScale"
:disabled="!contain.menuFlag"
:step="container.stepScale"
:width="item.component.width"
:height="item.component.height"
:ref="common.DEAFNAME+item.index"
:id="common.DEAFNAME+item.index"
v-show="!item.display"
@over="handleOver"
@focus="handleFocus"
@blur="handleBlur">
<component :ref="common.NAME+item.index"
:id="common.NAME+item.index"
:is="common.COMPNAME+item.component.name"
v-bind="item"
:data-formatter="getFunction(item.dataFormatter)"
:click-formatter="getFunction(item.clickFormatter)"
:label-formatter="getFunction(item.labelFormatter)"
:formatter="getFunction(item.formatter)"
:width="item.component.width"
:data-query="getJson(item.dataQuery)"
:height="item.component.height"
:animation="!contain.menuFlag"
:theme="(item.option || {}).theme"
:disabled="!contain.menuFlag"
:scale="container.stepScale"
:option="item.option"
:home-url="contain.config.url"
:click="handleClick" />
</avue-draggable>
<subgroup :nav="item.children"></subgroup>
</div>
</div>
</template>
<script>
import { addUrlParam } from '@/utils/utils'
import common from '@/config'
export default {
name: 'subgroup',
inject: ["contain", 'container'],
// provide () {
// return {
// contain: this.contain,
// container: this.container
// };
// },
props: {
nav: {
type: Array,
default: () => {
return []
}
}
},
data () {
return {
common: common,
}
},
methods: {
getFunction (fun) {
if (!this.validatenull(fun)) {
try {
return eval(fun);
} catch {
return function () { }
}
}
},
getJson (str) {
if (this.validatenull(str)) return {};
if (typeof str == "string") {
try {
return JSON.parse(str);
} catch {
return {}
}
}
return str;
},
//点击事件交互
handleClick ({ type, child, value }) {
if (type === 'tabs') {
const indexList = child.index;
indexList.forEach((index) => {
const paramName = child.paramName;
const item = this.contain.findlist(index);
if (!item.url) return
let params = {};
if (item.dataQuery) {
params = this.getJson(item.dataQuery)
} else {
params = {}
}
params[paramName] = value;
item.dataQuery = JSON.stringify(params);
this.$refs[this.common.NAME + index].forEach(ele => {
ele.updateData();
})
})
}
},
//刷新数据
handleRefresh (tip = true) {
this.$refs[this.common.NAME + this.contain.activeObj.index][0].updateData();
if (tip) {
this.$message.success('刷新成功')
}
},
//获取对象
handleGetObj (val) {
return this.$refs[`${this.common.DEAFNAME}${val}`];
},
handleOver ({ index }) {
this.contain.overactive = index;
},
handleFocus ({ index }) {
this.container.gradeFlag = true;
if (this.contain.keys.ctrl) {
if (!Array.isArray(this.contain.active)) {
this.contain.handleInitActive();
}
this.contain.active.push(index);
} else if (!this.contain.active.includes(index)) {
this.contain.active = [index];
}
},
handleBlur ({ left, top, width, height }) {
if (Array.isArray(this.contain.activeObj)) return
this.container.gradeFlag = false;
this.$set(this.contain.activeObj.component, 'width', width)
this.$set(this.contain.activeObj.component, 'height', height)
this.$set(this.contain.activeObj, 'left', left)
this.$set(this.contain.activeObj, 'top', top)
},
}
}
</script>
<style>
</style>

View File

@ -0,0 +1,192 @@
<template>
<div>
<el-menu class="nav"
mode="horizontal"
background-color="#212528"
text-color="#fff"
active-text-color="#409EFF"
@mousedown="contain.handleMouseDown">
<el-submenu :index="index+''"
v-for="(item,index) in baseList"
:key="index">
<template slot="title">
<el-tooltip effect="dark"
:content="item.label"
placement="top">
<i :class="'nav__icon iconfont '+item.icon"></i>
</el-tooltip>
</template>
<el-menu-item @click="handleAdd(citem.option,true)"
:key="cindex"
:index="`${index}-${cindex}`"
v-for="(citem,cindex) in item.children">
<i :class="'nav__icon iconfont '+citem.option.icon"></i>
<span>{{citem.label}}</span>
</el-menu-item>
</el-submenu>
<el-menu-item index="6"
@click="handleReset"
v-show="!contain.menuFlag">
<el-tooltip effect="dark"
content="还原"
placement="top">
<i class="nav__icon iconfont icon-reset"></i>
</el-tooltip>
</el-menu-item>
<el-menu-item index="7"
@click="handleView"
v-show="contain.menuFlag">
<el-tooltip effect="dark"
content="预览"
placement="top">
<i class="nav__icon iconfont icon-view"></i>
</el-tooltip>
</el-menu-item>
<el-menu-item index="8"
@click="handleBuild">
<el-tooltip effect="dark"
content="保存"
placement="top">
<i class="nav__icon iconfont icon-build"></i>
</el-tooltip>
</el-menu-item>
</el-menu>
</div>
</template>
<script>
import { uuid } from '@/utils/utils'
import baseList from '@/option/base'
import { updateComponent } from '@/api/visual'
export default {
inject: ["contain"],
data () {
return {
baseList: baseList
}
},
methods: {
vaildData (id) {
const list = [];
for (var i = 0; i < 20; i++) {
list.push(i + '')
}
return list.includes(id)
},
handleView () {
this.contain.menuFlag = false;
this.contain.handleInitActive();
this.contain.setScale(document.body.clientWidth);
},
handleReset () {
this.contain.menuFlag = true;
this.contain.setScale(this.contain.contentWidth);
},
handleBuild () {
this.contain.handleInitActive();
const loading = this.$loading({
lock: true,
text: '正在保存配置,请稍后',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
this.$nextTick(() => {
html2canvas(document.getElementById('content'), {
onrendered: (canvas) => {
function dataURLtoFile (dataurl, filename) {
var arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
return new File([u8arr], filename, { type: mime });
}
var file = dataURLtoFile(canvas.toDataURL('image/jpeg', 0.1), new Date().getTime() + '.jpg');
var formdata = new FormData();
formdata.append('file', file)
axios.post(this.url + '/visual/put-file', formdata, {
headers: {
"Content-Type": "multipart/form-data"
}
}).then(res => {
// console.log('666666666666666')
const data = res.data;
console.log(res.data);
// console.log('666666666666666888888888888888')
const url = data.link;
// console.log('66666666666666688888888888888899999999999999999999')
const formdata = {
visual: {
id: this.contain.visual.id,
backgroundUrl: url
},
config: {
id: this.contain.obj.config.id,
visualId: this.contain.visual.id,
detail: JSON.stringify(this.contain.config),
component: JSON.stringify(this.contain.nav),
},
}
return updateComponent(formdata)
}).then(() => {
loading.close();
this.$confirm('保存成功大屏配置, 是否打开预览?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
let routeUrl = this.$router.resolve({
path: '/view/' + this.contain.id
})
window.open(routeUrl.href, '_blank');
}).catch(() => {
});
}).catch(() => {
this.$message.error('模版例子不能修改')
loading.close();
})
},
});
})
},
handleAdd (option, first = false) {
let obj = this.deepClone(option);
obj.left = 0;
obj.top = 0
obj.index = uuid();
if (first) {
this.contain.nav.unshift(obj);
} else {
this.contain.nav.push(obj);
}
},
}
}
</script>
<style>
.nav {
border-bottom: 0 !important;
height: 45px;
line-height: 45px;
overflow: hidden;
}
.nav__icon {
margin-right: 5px;
}
.nav .el-submenu .el-submenu__title,
.nav .el-menu-item {
height: 45px;
line-height: 45px;
font-size: 12px;
}
</style>

View File

@ -0,0 +1,72 @@
<template>
<el-container class="list">
<el-aside width="230px">
<h2 class="title">Avue-data数据大屏</h2>
<el-menu :default-active="activeName"
background-color="#171b22"
text-color="#fff"
@select="handleSelect"
active-text-color="#00baff">
<el-menu-item index="1">
<i class="el-icon-document"></i>
大屏管理
</el-menu-item>
<el-menu-item index="2">
<i class="el-icon-document"></i>
地图管理
</el-menu-item>
<el-menu-item index="3">
<i class="el-icon-document"></i>
分类管理
</el-menu-item>
</el-menu>
</el-aside>
<el-scrollbar class="list"
style="width:100%;height:800px;">
<list v-if="activeName==1"></list>
<maps v-if="activeName==2"></maps>
<category v-if="activeName==3"></category>
</el-scrollbar>
</el-container>
</template>
<script>
import list from './list/index'
import maps from './list/map'
import category from './list/category'
//导入主题文件
import '@/theme/index.js'
// import '@/styles/common.scss'
export default {
name: "index",
components: {
list,
maps,
category
},
data () {
return {
activeName: '1',
}
},
created () {
},
methods: {
handleSelect (key) {
this.activeName = key;
},
}
}
</script>
<style lang="scss" scoped>
.title {
font-size: 20px;
color: #fff;
text-align: center;
line-height: 60px;
font-weight: 500;
}
</style>

View File

@ -0,0 +1,126 @@
<template>
<div class="map">
<avue-crud :option="option"
v-model="form"
@row-save="rowSave"
@row-update="rowUpdate"
@row-del="rowDel"
:before-open="beforeOpen"
:data="data"></avue-crud>
</div>
</template>
<script>
import { getList, getObj, addObj, delObj, updateObj } from '@/api/category'
export default {
data () {
return {
form: {},
data: [],
option: {
index: true,
align: 'center',
headerAlign: 'center',
column: [
{
label: '模块名',
prop: 'categoryKey',
rules: [{
required: true,
message: "请输入模块名",
trigger: "blur"
}]
},
{
label: '模块值',
prop: 'categoryValue',
rules: [{
required: true,
message: "请输入模块值",
trigger: "blur"
}]
}
]
}
}
},
created () {
this.getList()
},
methods: {
vaildData (id) {
return [0, 1].includes(id)
},
beforeOpen (done, type) {
if (type == 'edit') {
getObj(this.form.id).then(res => {
const data = res.data;
this.form = data
done()
})
} else {
done()
}
},
rowDel (row, index) {
if (this.vaildData(index)) {
this.$message.error('例子模板不允许修改')
return false;
}
this.$confirm('此操作将永久删除, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
delObj(row.id).then(() => {
this.$message.success('删除成功');
this.getList()
})
}).catch(() => {
});
},
rowUpdate (row, index, done) {
if (this.vaildData(index)) {
this.$message.error('例子模板不允许修改')
return false;
}
updateObj(row).then(() => {
this.$message.success('修改成功');
this.getList()
done();
})
},
rowSave (row, done) {
addObj(row).then(() => {
this.$message.success('新增成功');
this.getList()
done();
})
},
getList () {
getList({
pageNum: 1,
pageSize: 100,
}).then(res => {
const data = res.data;
this.data = data;
})
}
}
}
</script>
<style lang="scss" scoped>
.map {
padding: 30px;
width: 100%;
.title {
display: block;
margin-bottom: 30px;
padding: 0 50px;
font-size: 20px;
}
}
</style>

View File

@ -0,0 +1,349 @@
<template>
<el-container class="list">
<el-header>
<el-menu :default-active="activeName"
mode="horizontal"
background-color="#171b22"
text-color="#fff"
active-text-color="#00baff"
@select="handleSelect">
<el-menu-item :index="item.categoryValue"
:key="item.categoryValue"
v-for="item in typelist"
@click="getList(item.categoryValue)">
<i class="iconfont icon-daping"></i>
{{item.categoryKey}}
</el-menu-item>
</el-menu>
</el-header>
<el-main>
<div class="page">
<el-pagination layout="total, sizes, prev, pager, next, jumper"
background
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:page-size="page.size"
:current-page.sync="page.page"
:total="page.total">
</el-pagination>
</div>
<div class="content">
<div class="content__item content__item--add"
@click="handleAdd">
<div>
<i class="el-icon-plus"></i>
<p>新建大屏</p>
</div>
</div>
<div class="content__item"
v-for="(item,index) in list"
:key="index"
@mouseover="item._menu=true"
@mouseout="item._menu=false">
<div class="content__info">
<img v-if="item.backgroundUrl"
:src="item.backgroundUrl"
alt="" />
<div class="content__menu"
v-show="item._menu">
<div class="content__btn"
@click="handleEdit(item)">
编辑
</div>
</div>
</div>
<div class="content__main">
<span class="content__name">{{item.title}}</span>
<div class="content__menulist">
<div class="content__view">
<el-tooltip content="删除">
<i class="el-icon-delete"
@click="handleDel(item,index)"></i>
</el-tooltip>
<el-tooltip content="编辑">
<i class="el-icon-edit"
@click="handleUpdate(item,index)"></i>
</el-tooltip>
<el-tooltip content="预览">
<i class="el-icon-view"
@click="handleViews(item,index)"></i>
</el-tooltip>
<el-tooltip content="复制">
<i class="el-icon-copy-document"
@click="handleCopy(item,index)"></i>
</el-tooltip>
</div>
<span class="content__status"
:class="{'content__status--active':item.status}">
{{item.status?'已发布':'未发布'}}
</span>
</div>
</div>
</div>
</div>
</el-main>
<el-dialog title="新建大屏"
width="35%"
:visible.sync="box">
<avue-form :option="option"
v-model="form"
@submit="handleSave"></avue-form>
</el-dialog>
</el-container>
</template>
<script>
import { getList, addObj, updateObj, delObj, getCategory, copyObj } from '@/api/visual';
export default {
name: "list",
data () {
return {
typelist: [],
index: 0,
type: '',
option: {
column: [{
label: '分组',
prop: 'category',
span: 24,
labelWidth: 100,
type: 'select',
dicUrl: this.url + '/category/list',
props: {
label: 'categoryKey',
value: 'categoryValue',
},
rules: [{
required: true,
message: "请选择分组",
trigger: "blur"
}]
}, {
label: '大屏名称',
span: 24,
labelWidth: 100,
prop: 'title',
rules: [{
required: true,
message: "请输入大屏名称",
trigger: "blur"
}]
}, {
label: '大屏尺寸',
span: 14,
labelWidth: 100,
prop: 'width',
placeholder: '请输入宽度',
rules: [{
required: true,
message: "请输入大屏尺寸",
trigger: "blur"
}]
}, {
label: '',
span: 10,
labelWidth: 1,
prop: 'height',
placeholder: '请输入高度',
rules: [{
required: true,
message: "请输入大屏尺寸",
trigger: "blur"
}]
}, {
label: '密码',
span: 24,
type: 'password',
labelWidth: 100,
prop: 'password',
}, {
label: '发布状态',
prop: 'status',
span: 24,
labelWidth: 100,
type: 'select',
dicData: [{
label: '未发布',
value: 0
}, {
label: '已发布',
value: 1
}]
}]
},
page: {
page: 1,
size: 10,
total: 0,
},
form: {},
box: false,
activeName: '',
list: [],
}
},
created () {
this.getCategory()
console.log(this.url);
},
methods: {
vaildData (id) {
const list = [];
for (var i = 0; i < 20; i++) {
list.push(i)
}
return list.includes(id)
},
getCategory () {
getCategory().then(res => {
console.log(res);
const data = res.data;
this.typelist = data;
this.activeName = (data[0] || {}).categoryValue;
this.getList();
})
},
handleCopy (item) {
this.$confirm('确认复制当前大屏', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
copyObj(item.id).then(() => {
this.$message.success('复制成功');
this.getList();
})
}).catch(() => {
});
},
handleDel (item, index) {
this.$confirm('是否确认永久删除?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
if (this.vaildData(index)) {
this.$message.error('例子模板不允许修改')
return false;
}
delObj(item.id).then(() => {
this.list.splice(index, 1)
this.$message.success('删除成功')
})
}).catch(() => {
});
},
handleUpdate (item, index) {
this.form = item
this.form.category = this.form.category + '';
this.type = 'edit';
this.option.column[2].display = false;
this.option.column[3].display = false;
this.box = true;
this.index = index;
},
handleEdit (item) {
let routeUrl = this.$router.resolve({
path: '/build/' + item.id
})
if(self!=top){
   // 页面在iframe中时处理容
window.location.replace(routeUrl.href);
  }else{
window.open(routeUrl.href, '_blank');
}
},
handleViews (item) {
let routeUrl = this.$router.resolve({
path: '/view/' + item.id
})
window.open(routeUrl.href, '_blank');
},
handleAdd () {
this.type = 'add';
this.option.column[5].display = false;
this.form.category = this.activeName;
this.form.width = 1920;
this.form.height = 1080;
this.box = true;
},
handleSave (form, done) {
done();
if (this.type == 'add') {
addObj(Object.assign({
category: this.activeName,
}, this.form)).then(res => {
this.box = false;
this.$message.success('新增成功');
this.getList();
const id = res.data.id;
this.handleEdit({ id })
})
} else {
if (this.vaildData(Number(this.index))) {
this.$message.error('例子模板不允许修改')
return false;
}
updateObj(Object.assign({
category: this.activeName
}, {
id: this.form.id,
password: this.form.password,
status: this.form.status,
title: this.form.title
})).then(() => {
this.box = false;
this.$message.success('修改成功');
this.getList();
})
}
},
handleSelect (key) {
this.activeName = key;
this.page.page = 1;
this.getList();
},
handleCurrentChange (val) {
this.page.page = val;
this.getList();
},
handleSizeChange (val) {
this.page.size = val;
this.getList();
},
getList (category) {
const loading = this.$loading({
lock: true,
text: '正在加载中,请稍后',
spinner: 'el-icon-loading',
background: 'rgba(0, 0, 0, 0.7)'
});
this.list = []
getList({
category: category || this.activeName,
pageNum: this.page.page,
pageSize: this.page.size,
}).then(res => {
loading.close();
const data = res.data;
this.page.total = data.total;
this.list = data.records
this.initData();
})
},
initData () {
this.list.forEach((ele, index) => {
this.$set(this.list[index], '_menu', false)
})
}
}
}
</script>
<style lang="scss">
@import "@/styles/list.scss";
</style>

View File

@ -0,0 +1,142 @@
<template>
<div class="map">
<a class="title"
target="_blank"
href="https://datav.aliyun.com/tools/atlas/#&lat=33.521903996156105&lng=104.29849999999999&zoom=4">点击我添加更多地图</a>
<avue-crud :option="option"
v-model="form"
@row-save="rowSave"
@row-update="rowUpdate"
@row-del="rowDel"
:before-open="beforeOpen"
:data="data">
<template slot="dataForm"
slot-scope="{}">
<codeedit v-model="form.data"
ref="codeedit"></codeedit>
</template>
</avue-crud>
</div>
</template>
<script>
import codeedit from '../group/code';
import { getList, getObj, addObj, delObj, updateObj } from '@/api/map'
export default {
components: {
codeedit
},
data () {
return {
form: {},
data: [],
option: {
labelWidth: 100,
index: true,
align: 'center',
headerAlign: 'center',
column: [
{
label: '地图名称',
prop: 'name',
row: true,
rules: [{
required: true,
message: "请输入地图名称",
trigger: "blur"
}]
},
{
label: '地图数据',
prop: 'data',
span: 24,
hide: true,
formslot: true
}
]
}
}
},
created () {
this.getList()
},
methods: {
vaildData (id) {
return [0, 1, 2].includes(id)
},
beforeOpen (done, type) {
if (type == 'edit') {
getObj(this.form.id).then(res => {
const data = res.data;
this.form = data
this.form.data = JSON.stringify(JSON.parse(this.form.data), null, 4)
done()
})
} else {
done()
}
},
rowDel (row, index) {
if (this.vaildData(index)) {
this.$message.error('例子模板不允许修改')
return false;
}
this.$confirm('此操作将永久删除, 是否继续?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
delObj(row.id).then(() => {
this.$message.success('删除成功');
this.getList()
})
}).catch(() => {
});
},
rowUpdate (row, index, done) {
if (this.vaildData(index)) {
this.$message.error('例子模板不允许修改')
return false;
}
row.data = this.$refs.codeedit.getValue()
updateObj(row).then(() => {
this.$message.success('修改成功');
this.getList()
done();
})
},
rowSave (row, done) {
row.data = this.$refs.codeedit.getValue()
addObj(row).then(() => {
this.$message.success('新增成功');
this.getList()
done();
})
},
getList () {
getList({
pageNum: 1,
pageSize: 100,
}).then(res => {
const data = res.data;
this.data = data.records;
})
}
}
}
</script>
<style lang="scss" scoped>
.map {
padding: 30px;
width: 100%;
.title {
display: block;
margin-bottom: 30px;
padding: 0 50px;
font-size: 20px;
}
}
</style>

View File

@ -0,0 +1,14 @@
<template>
<div class="build views">
<container ref="container"></container>
</div>
</template>
<script>
import init from '@/mixins/'
export default {
mixins: [init],
}
</script>
<style lang="scss">
@import "../styles/style.scss";
</style>

View File

@ -0,0 +1,243 @@
* {
margin: 0;
padding: 0;
}
a {
text-decoration: none;
}
html,
body,
#app {
height: 100%;
}
body {
background: #171b22;
overflow: hidden;
}
::-webkit-scrollbar-track-piece {
background-color: transparent;
}
::-webkit-scrollbar {
width: 5px;
height: 5px;
background-color: transparent;
}
::-webkit-scrollbar-thumb {
border-radius: 5px;
background-color: hsla(220, 4%, 58%, .3);
}
img {
user-select: none;
}
.img{
margin-right: 5px;
}
.block{
margin: 0 auto;
width:90%;
display: block;
}
a{
text-decoration: none;
font-size: 12px;
color:#409EFF;
}
.el-select-dropdown {
border-radius: 0;
border:none;
color: #bcc9d4;
background-color: #27343e;
color: #bcc9d4;
}
.el-select-dropdown__item{
font-size: 12px;
}
.el-select-dropdown__item.selected,.el-select-dropdown__item.hover{
font-weight: normal;
background-color: rgba(0,192,222,.1);
}
.el-select-dropdown__item.hover{
color: #fff;
}
.el-select-dropdown__item.selected{
color: #fff;
}
.el-input-group__append, .el-input-group__prepend,.el-dialog .el-input-group__append, .el-dialog .el-input-group__prepend{
background-color: #0f1014;
border-color: #282e3a;
}
.el-collapse-item__header.is-active{
color:#fff;
}
.el-collapse-item__wrap{
background-color:#000;
border-bottom: none;
}
.el-radio__input, .params .el-radio__label,.params input{
font-size: 12px;
}
.el-table th, .el-table tr,.el-table, .el-table__expanded-cell {
background-color: transparent !important;
color:#859094 !important;
}
.el-table td, .el-table th.is-leaf {
border-color: #859094 !important;
}
.avue-empty__desc{
color:#fff;
}
.el-form-item__label, .el-dialog .el-form-item__label{
color:#fff !important;
}
.hover-row td,.hover-row th{
background-color: transparent !important;
border-bottom: none;
}
.el-table__fixed-right::before, .el-table__fixed::before,.el-table::before{
display: none;
}
.el-table td, .el-table th.is-leaf {
border-bottom:none;
}
.el-dialog ,.avue-group__item{
background: #1b1e25;
}
.el-message-box{
background: #1b1e25;
border-color: #1b1e25;
}
.el-message-box__title{
color:#fff;
}
.el-dialog__title{
color:#fff;
font-size: 14px;
}
.el-dialog__body{
padding: 10px;
}
.el-collapse-item__arrow.is-active{
color:#fff;
}
.el-collapse{
border-top:none;
border-bottom: none;
}
input{
border-width: 2px;
border-radius: 0;
}
.avue-crud{
width: 90%;
}
.el-radio{
width: 100%;
line-height: 25px;
font-size: 14px;
}
.el-color-picker__trigger,.el-dialog .el-color-picker__trigger{
border:none;
}
.el-collapse-item__arrow{
position: absolute;
left:10px;
line-height: 40px;
color:#bcc9d4;
}
.el-form-item{
margin-top: 10px;
}
.el-pagination__total{
color:#fff;
}
.el-pagination.is-background .btn-next, .el-pagination.is-background .btn-prev, .el-pagination.is-background .el-pager li{
background-color:transparent;
color: #fff;
}
.el-pagination.is-background .el-pager li:not(.disabled).active{
background-color: transparent;
border:1px solid #409EFF;
}
.el-form-item__label,.el-dialog .el-form-item__label{
color:#859094;
padding-left: 20px;
font-size: 12px;
}
.el-form-item__content, .el-dialog .el-form-item__content{
padding-right: 20px;
}
.el-checkbox__inner,input,.el-slider__runway,textarea,
.el-dialog input,.el-switch__core,.el-dialog .el-slider__runway,.el-dialog textarea{
background-color: #0f1014 !important;
color:#859094 !important;
border-color:#282e3a !important;
}
.el-switch.is-checked .el-switch__core {
border-color: #409EFF !important;
background-color: #409EFF !important;
}
.el-button,.el-dialog .el-button{
border-radius: 0;
}
.el-button--primary,.el-dialog .el-button--primary{
background-color: transparent;
color:#409EFF;
border-color:#409EFF;
}
.el-button--danger,.el-dialog .el-button--danger{
background-color: transparent;
color:#f56c6c;
border-color:#f56c6c;
}
.el-button--default,.el-dialog .el-button--default{
background-color: transparent;
color:#859094;
border-color:#859094;
}
.el-collapse-item__content{
padding: 0;
}
.el-select-dropdown.is-multiple .el-select-dropdown__item.selected.hover{
background-color: initial;
color:#fff;
}
.el-select-dropdown.is-multiple .el-select-dropdown__item.selected{
background-color: initial;
color:#fff;
}
.el-dialog__title{
color:#fff !important;
}
.el-collapse-item__header{
padding-left: 20px;
height: 40px;
line-height: 40px;
background: transparent;
color:#bcc9d4;
font-weight: 300;
font-size: 12px;
border-color: #282e3a;
}
.icon-gauge{
font-size: 12px !important;
}

View File

@ -0,0 +1,135 @@
.list{
.el-menu{
border-right: none;
}
.el-menu.el-menu--horizontal {
border-color: rgb(33, 37, 40);
border-width: 2px;
}
.page{
display: flex;
justify-content: center;
}
.el-menu i {
margin-right: 5px;
}
.content{
display: flex;
flex-wrap: wrap;
&__item{
position: relative;
margin: 16px;
display: flex;
flex-direction: column;
width: 258px;
height: 184px;
border: 1px solid #3a4659;
overflow: hidden;
&:hover {
box-shadow: 0 0 20px 0 #000;
border: 1px solid #00baff;
}
&--add {
height: 184px;
width: 258px;
border: 1px solid #00baff;
font-size: 14px;
color: #8eeeff;
background-image: linear-gradient(-90deg, rgba(0, 222, 255, .39) 0, rgba(0, 174, 255, .19) 100%);
box-shadow: 0 0 10px 0 rgba(55, 224, 255, .3);
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
i {
display: block;
padding-bottom: 10px;
text-align: center;
font-size: 19px;
}
p {
letter-spacing: 2px;
}
}
}
&__main {
font-size: 12px;
width: 100%;
height: 36px;
display: flex;
align-items: center;
position: absolute;
bottom: 0;
justify-content: space-between;
background: #1d262e;
box-sizing: border-box;
padding: 0 10px;
color: #bcc9d4;
a{
color:#bcc9d4;
}
i{
margin-right: 1px;
}
}
&__view{
margin-right: 2px;
}
&__menulist{
display: flex;
i{
margin-right: 10px;
}
}
&__status--active {
color: #fff
}
&__name {
width: 100px;
padding: 0 5px;
line-height: 28px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
border: 1px solid transparent;
}
&__info {
position: relative;
height: calc(100% - 36px);
}
&__menu {
position: absolute;
top: 0;
left: 0;
background-color: rgba(29,38,46,0.8);
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
}
&__btn {
display: inline-block;
vertical-align: middle;
height: 32px;
line-height: 32px;
padding: 0 30px;
box-sizing: border-box;
outline: 0;
text-align: center;
font-size: 14px;
background-image: linear-gradient(-225deg, #00d3f1 0, #12b3ff 100%);
color: #293f52;
border: none;
transition: .3s ease;
cursor: pointer
}
&__info{
img {
width: 100%;
height: 100%;
}
}
}
}

View File

@ -0,0 +1,315 @@
.build{
position: relative;
width: 100%;
height: 100%;
.app {
width:100%;
height: calc(100% - 45px);
display: flex;
box-sizing: border-box;
}
.selectall{
position: absolute;
border: 1px dotted #409EFF;
z-index:10000;
}
.icon{
font-size: 20px;
margin-right: 10px;
}
.selectbg{
width:100%;
height:100%;
position: absolute;
z-index:9999;
}
.selectflag{
width:100%;
height:100%;
position: absolute;
z-index:9999;
cursor: move;
}
.el-menu--horizontal .el-menu .el-menu-item, .el-menu--horizontal .el-menu .el-submenu__title{
font-size: 12px;
}
.menu {
width: 180px;
height: 100%;
overflow: hidden;
overflow-y: auto;
color:#bcc8d4;
background: #1d1f26;
}
.menu__list{
padding-left: 10px;
box-sizing: border-box;
}
.menu__item--folder{
display: flex;
align-items: center;
padding: 6px 6px;
color:#bcc9d4;
font-size: 12px;
input{
border:none;
outline: none;
}
.icon-folder{
font-size: 16px;
margin-right: 5px;
}
.icon-fold{
font-size: 12px;
margin-right: 10px;
transform: rotate(90deg);
display:inline-block;
font-weight: bold;
&.is-active{
transform: rotate(180deg);
}
}
&.is-active{
color: #fff;
background: rgba(143,225,255,.1);
}
&:hover {
color: #fff;
background: rgba(143,225,255,.1);
cursor: pointer;
}
}
.menu__folder{
&.ghost{
opacity: .6;
color:#fff;
background: #409EFF !important;
cursor: move;
}
}
.menu__item {
margin-bottom: 1px;
width: 100%;
box-sizing: border-box;
display: flex;
align-items: center;
height: 48px;
padding: 0 6px;
position: relative;
background: #1b1f25;
cursor: pointer;
flex: none;
font-size: 12px;
&.is-over,&:hover {
color: #fff;
background: rgba(143,225,255,.1);
cursor: pointer;
}
&.ghost{
opacity: .6;
color:#fff;
background: #409EFF !important;
cursor: move;
}
&.is-active {
background: #409EFF !important;
color: #373d41 !important;
}
}
.menu__icon{
color: #409EFF;
margin-right: 10px;
width: 53px;
height: 30px;
line-height: 30px;
text-align: center;
display: block;
border: 1px solid #3a4659;
background: #282a30;
}
.top{
padding: 10px 20px;
position: fixed;
top:0;
left:0;
width:100%;
z-index:9999;
background-color: rgba(255,255,255,.4);
}
.middle{
background-color: #2a2d32;
flex:1;
position: relative;
height: 100%;
overflow: auto;
}
.wrapper {
position: relative;
padding:60px 0 0 0;
box-sizing: border-box;
width: 100%;
position: relative;
box-sizing: border-box;
}
.content{
transform-origin: 0 0;
background-color: #333;
position: relative;
box-sizing: border-box;
}
.footer__menu{
padding-top: 8px;
margin-right:370px;
float: right;
width:300px;
}
.app--none{
padding: 0;
height:100%;
}
.app--none .wrapper{
position: relative;
padding: 0;
width: 100%;
}
.app--none .content{
width: 100%;
height: 100%;
border:none;
}
.container {
user-select: none;
transform-origin: 0 0;
position: relative;
}
.grade {
width: 100%;
height: 100%;
background-size: 30px 30px, 30px 30px;
background-image: linear-gradient(rgba(255, 255, 255, 0.1) 1px, transparent 0px), linear-gradient(90deg, rgba(255, 255, 255, 0.1) 1px, transparent 0px);
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
.wrapper__grade{
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
height: 100%;
background: url(https://img.alicdn.com/tfs/TB184VLcPfguuRjSspkXXXchpXa-14-14.png) repeat;
}
.title {
padding:0 20px;
box-sizing: border-box;
margin-bottom: 10px;
line-height: 35px;
height: 35px;
text-align: center;
font-size: 13px;
letter-spacing: 2px;
text-indent: 2px;
background-color:#2d343c;
color:#fff;
&--left{
text-align: left;
}
}
.params {
width: 350px;
}
.tabs{
margin-top: -10px;
box-sizing: border-box;
}
.tabs .el-input-number{
width:100%;
}
.tabs .el-tabs__header{
background: #27343e;
margin: 0 0 2px;
}
.tabs i{
color: #bcc9d4;
font-size: 14px;
}
.tabs .is-active i{
color: #409EFF;
}
.tabs .el-tabs__nav-wrap::after{
background: #27343e;
}
.tabs .el-tabs__item{
padding: 0;
box-sizing: border-box;
}
.tabs .el-tabs__active-bar{
top:0;
}
.el-collapse-item__header{
padding-left: 30px;
}
.el-switch__core{
width: 35px;
height: 16px;
}
.el-switch{
height:10px;
line-height: 10px;
}
.el-switch__core:after{
top:-1px;
width: 16px;
height:16px;
}
.el-slider__button-wrapper{
top:-17px;
}
.el-slider__button{
border-radius: 0;
width: 8px;
height: 8px;
border-width: 1px;
}
.el-slider__bar,.el-slider__runway{
height: 2px;
}
.imgList{
height:350px;
display: flex;
flex-wrap:wrap;
justify-content: space-between;
}
.imgList img{
width: 100px;
height: 100px;
margin: 20px 10px ;
}
.el-input-number__decrease, .el-input-number__increase{
background: transparent;
}
}
.views{
.wrapper{
padding: 0;
}
.middle{
overflow: inherit;
}
}

View File

@ -0,0 +1,169 @@
var theme_avue = {
"version": 1,
"themeName": "avue",
"theme": {
"seriesCnt": "4",
"backgroundColor": "rgba(0,0,0,0)",
"titleColor": "#516b91",
"subtitleColor": "#93b7e3",
"textColorShow": false,
"textColor": "#333",
"markTextColor": "#eee",
"color": [
"#83bff6",
"#23b7e5",
"#188df0",
"#564aa3",
"#a5e7f0",
"#cbb0e3"
],
"borderColor": "#ccc",
"borderWidth": 0,
"visualMapColor": [
"#83bff6",
"#23b7e5",
"#188df0",
"#564aa3"
],
"legendTextColor": "#999999",
"kColor": "#edafda",
"kColor0": "transparent",
"kBorderColor": "#d680bc",
"kBorderColor0": "#8fd3e8",
"kBorderWidth": "2",
"lineWidth": "2",
"symbolSize": "6",
"symbol": "emptyCircle",
"symbolBorderWidth": "2",
"lineSmooth": true,
"graphLineWidth": 1,
"graphLineColor": "#aaa",
"mapLabelColor": "#000000",
"mapLabelColorE": "rgb(81,107,145)",
"mapBorderColor": "#516b91",
"mapBorderColorE": "#516b91",
"mapBorderWidth": 0.5,
"mapBorderWidthE": 1,
"mapAreaColor": "#f3f3f3",
"mapAreaColorE": "rgba(165,231,240,1)",
"axes": [{
"type": "all",
"name": "通用坐标轴",
"axisLineShow": true,
"axisLineColor": "#cccccc",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#999999",
"splitLineShow": true,
"splitLineColor": [
"#eeeeee"
],
"splitAreaShow": false,
"splitAreaColor": [
"rgba(80,36,204,0.05)",
"rgba(223,35,35,0.02)"
]
},
{
"type": "category",
"name": "类目坐标轴",
"axisLineShow": true,
"axisLineColor": "#333",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#333",
"splitLineShow": false,
"splitLineColor": [
"#ccc"
],
"splitAreaShow": false,
"splitAreaColor": [
"rgba(250,250,250,0.3)",
"rgba(200,200,200,0.3)"
]
},
{
"type": "value",
"name": "数值坐标轴",
"axisLineShow": true,
"axisLineColor": "#333",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#333",
"splitLineShow": true,
"splitLineColor": [
"#ccc"
],
"splitAreaShow": false,
"splitAreaColor": [
"rgba(250,250,250,0.3)",
"rgba(200,200,200,0.3)"
]
},
{
"type": "log",
"name": "对数坐标轴",
"axisLineShow": true,
"axisLineColor": "#333",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#333",
"splitLineShow": true,
"splitLineColor": [
"#ccc"
],
"splitAreaShow": false,
"splitAreaColor": [
"rgba(250,250,250,0.3)",
"rgba(200,200,200,0.3)"
]
},
{
"type": "time",
"name": "时间坐标轴",
"axisLineShow": true,
"axisLineColor": "#333",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#333",
"splitLineShow": true,
"splitLineColor": [
"#ccc"
],
"splitAreaShow": false,
"splitAreaColor": [
"rgba(250,250,250,0.3)",
"rgba(200,200,200,0.3)"
]
}
],
"axisSeperateSetting": true,
"toolboxColor": "#999999",
"toolboxEmpasisColor": "#666666",
"tooltipAxisColor": "#f9dbdb",
"tooltipAxisWidth": 1,
"timelineLineColor": "#8fd3e8",
"timelineLineWidth": 1,
"timelineItemColor": "#8fd3e8",
"timelineItemColorE": "#8fd3e8",
"timelineCheckColor": "#8fd3e8",
"timelineCheckBorderColor": "rgba(138,124,168,0.37)",
"timelineItemBorderWidth": 1,
"timelineControlColor": "#213dbc",
"timelineControlBorderColor": "#8fd3e8",
"timelineControlBorderWidth": 0.5,
"timelineLabelColor": "#8fd3e8",
"datazoomBackgroundColor": "rgba(0,0,0,0)",
"datazoomDataColor": "rgba(255,255,255,0.3)",
"datazoomFillColor": "rgba(167,183,204,0.4)",
"datazoomHandleColor": "#2472d9",
"datazoomHandleWidth": "100",
"datazoomLabelColor": "#333333"
}
}
window.echarts.registerTheme(theme_avue.themeName, theme_avue.theme)

View File

@ -0,0 +1,181 @@
var theme_macarons = {
"version": 1,
"themeName": "macarons",
"theme": {
"seriesCnt": "4",
"backgroundColor": "rgba(0,0,0,0)",
"titleColor": "#008acd",
"subtitleColor": "#aaaaaa",
"textColorShow": false,
"textColor": "#333",
"markTextColor": "#eeeeee",
"color": [
"#2ec7c9",
"#b6a2de",
"#5ab1ef",
"#ffb980",
"#d87a80",
"#8d98b3",
"#e5cf0d",
"#97b552",
"#95706d",
"#dc69aa",
"#07a2a4",
"#9a7fd1",
"#588dd5",
"#f5994e",
"#c05050",
"#59678c",
"#c9ab00",
"#7eb00a",
"#6f5553",
"#c14089"
],
"borderColor": "#ccc",
"borderWidth": 0,
"visualMapColor": [
"#5ab1ef",
"#e0ffff"
],
"legendTextColor": "#333333",
"kColor": "#d87a80",
"kColor0": "#2ec7c9",
"kBorderColor": "#d87a80",
"kBorderColor0": "#2ec7c9",
"kBorderWidth": 1,
"lineWidth": 2,
"symbolSize": 3,
"symbol": "emptyCircle",
"symbolBorderWidth": 1,
"lineSmooth": true,
"graphLineWidth": 1,
"graphLineColor": "#aaaaaa",
"mapLabelColor": "#d87a80",
"mapLabelColorE": "rgb(100,0,0)",
"mapBorderColor": "#eeeeee",
"mapBorderColorE": "#444444",
"mapBorderWidth": 0.5,
"mapBorderWidthE": 1,
"mapAreaColor": "#dddddd",
"mapAreaColorE": "rgba(254,153,78,1)",
"axes": [{
"type": "all",
"name": "通用坐标轴",
"axisLineShow": true,
"axisLineColor": "#eeeeee",
"axisTickShow": true,
"axisTickColor": "#eeeeee",
"axisLabelShow": true,
"axisLabelColor": "#eeeeee",
"splitLineShow": true,
"splitLineColor": [
"#aaaaaa"
],
"splitAreaShow": false,
"splitAreaColor": [
"#eeeeee"
]
},
{
"type": "category",
"name": "类目坐标轴",
"axisLineShow": true,
"axisLineColor": "#008acd",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#333",
"splitLineShow": false,
"splitLineColor": [
"#eee"
],
"splitAreaShow": false,
"splitAreaColor": [
"rgba(250,250,250,0.3)",
"rgba(200,200,200,0.3)"
]
},
{
"type": "value",
"name": "数值坐标轴",
"axisLineShow": true,
"axisLineColor": "#008acd",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#333",
"splitLineShow": true,
"splitLineColor": [
"#eee"
],
"splitAreaShow": true,
"splitAreaColor": [
"rgba(250,250,250,0.3)",
"rgba(200,200,200,0.3)"
]
},
{
"type": "log",
"name": "对数坐标轴",
"axisLineShow": true,
"axisLineColor": "#008acd",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#333",
"splitLineShow": true,
"splitLineColor": [
"#eee"
],
"splitAreaShow": true,
"splitAreaColor": [
"rgba(250,250,250,0.3)",
"rgba(200,200,200,0.3)"
]
},
{
"type": "time",
"name": "时间坐标轴",
"axisLineShow": true,
"axisLineColor": "#008acd",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#333",
"splitLineShow": true,
"splitLineColor": [
"#eee"
],
"splitAreaShow": false,
"splitAreaColor": [
"rgba(250,250,250,0.3)",
"rgba(200,200,200,0.3)"
]
}
],
"axisSeperateSetting": true,
"toolboxColor": "#2ec7c9",
"toolboxEmpasisColor": "#18a4a6",
"tooltipAxisColor": "#008acd",
"tooltipAxisWidth": "1",
"timelineLineColor": "#008acd",
"timelineLineWidth": 1,
"timelineItemColor": "#008acd",
"timelineItemColorE": "#a9334c",
"timelineCheckColor": "#2ec7c9",
"timelineCheckBorderColor": "rgba(46,199,201,0.4)",
"timelineItemBorderWidth": 1,
"timelineControlColor": "#008acd",
"timelineControlBorderColor": "#008acd",
"timelineControlBorderWidth": 0.5,
"timelineLabelColor": "#008acd",
"datazoomBackgroundColor": "rgba(47,69,84,0)",
"datazoomDataColor": "rgba(239,239,255,1)",
"datazoomFillColor": "rgba(182,162,222,0.2)",
"datazoomHandleColor": "#008acd",
"datazoomHandleWidth": "100",
"datazoomLabelColor": "#333333"
}
}
window.echarts.registerTheme(theme_macarons.themeName, theme_macarons.theme)

View File

@ -0,0 +1,3 @@
import './avue.project.js'
import './halloween.project.js'
import './wonderland.project'

View File

@ -0,0 +1,168 @@
var theme_wonderland = {
"version": 1,
"themeName": "wonderland",
"theme": {
"seriesCnt": "3",
"backgroundColor": "rgba(255,255,255,0)",
"titleColor": "#666666",
"subtitleColor": "#999999",
"textColorShow": false,
"textColor": "#333",
"markTextColor": "#ffffff",
"color": [
"#4ea397",
"#22c3aa",
"#7bd9a5",
"#d0648a",
"#f58db2",
"#f2b3c9"
],
"borderColor": "#ccc",
"borderWidth": 0,
"visualMapColor": [
"#d0648a",
"#22c3aa",
"#adfff1"
],
"legendTextColor": "#999999",
"kColor": "#d0648a",
"kColor0": "transparent",
"kBorderColor": "#d0648a",
"kBorderColor0": "#22c3aa",
"kBorderWidth": "1",
"lineWidth": "3",
"symbolSize": "8",
"symbol": "emptyCircle",
"symbolBorderWidth": "2",
"lineSmooth": false,
"graphLineWidth": "1",
"graphLineColor": "#cccccc",
"mapLabelColor": "#28544e",
"mapLabelColorE": "rgb(52,158,142)",
"mapBorderColor": "#999999",
"mapBorderColorE": "#22c3aa",
"mapBorderWidth": 0.5,
"mapBorderWidthE": 1,
"mapAreaColor": "#eeeeee",
"mapAreaColorE": "rgba(34,195,170,0.25)",
"axes": [{
"type": "all",
"name": "通用坐标轴",
"axisLineShow": true,
"axisLineColor": "#cccccc",
"axisTickShow": false,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#999999",
"splitLineShow": true,
"splitLineColor": [
"#eeeeee"
],
"splitAreaShow": false,
"splitAreaColor": [
"rgba(250,250,250,0.05)",
"rgba(200,200,200,0.02)"
]
},
{
"type": "category",
"name": "类目坐标轴",
"axisLineShow": true,
"axisLineColor": "#333",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#333",
"splitLineShow": false,
"splitLineColor": [
"#ccc"
],
"splitAreaShow": false,
"splitAreaColor": [
"rgba(250,250,250,0.3)",
"rgba(200,200,200,0.3)"
]
},
{
"type": "value",
"name": "数值坐标轴",
"axisLineShow": true,
"axisLineColor": "#333",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#333",
"splitLineShow": true,
"splitLineColor": [
"#ccc"
],
"splitAreaShow": false,
"splitAreaColor": [
"rgba(250,250,250,0.3)",
"rgba(200,200,200,0.3)"
]
},
{
"type": "log",
"name": "对数坐标轴",
"axisLineShow": true,
"axisLineColor": "#333",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#333",
"splitLineShow": true,
"splitLineColor": [
"#ccc"
],
"splitAreaShow": false,
"splitAreaColor": [
"rgba(250,250,250,0.3)",
"rgba(200,200,200,0.3)"
]
},
{
"type": "time",
"name": "时间坐标轴",
"axisLineShow": true,
"axisLineColor": "#333",
"axisTickShow": true,
"axisTickColor": "#333",
"axisLabelShow": true,
"axisLabelColor": "#333",
"splitLineShow": true,
"splitLineColor": [
"#ccc"
],
"splitAreaShow": false,
"splitAreaColor": [
"rgba(250,250,250,0.3)",
"rgba(200,200,200,0.3)"
]
}
],
"axisSeperateSetting": false,
"toolboxColor": "#999999",
"toolboxEmpasisColor": "#666666",
"tooltipAxisColor": "#cccccc",
"tooltipAxisWidth": 1,
"timelineLineColor": "#4ea397",
"timelineLineWidth": 1,
"timelineItemColor": "#4ea397",
"timelineItemColorE": "#4ea397",
"timelineCheckColor": "#4ea397",
"timelineCheckBorderColor": "rgba(60,235,210,0.3)",
"timelineItemBorderWidth": 1,
"timelineControlColor": "#4ea397",
"timelineControlBorderColor": "#4ea397",
"timelineControlBorderWidth": 0.5,
"timelineLabelColor": "#4ea397",
"datazoomBackgroundColor": "rgba(255,255,255,0)",
"datazoomDataColor": "rgba(222,222,222,1)",
"datazoomFillColor": "rgba(114,230,212,0.25)",
"datazoomHandleColor": "#cccccc",
"datazoomHandleWidth": "100",
"datazoomLabelColor": "#999999"
}
}
window.echarts.registerTheme(theme_wonderland.themeName, theme_wonderland.theme)