Browse Source

dashboard

old
wangqing 5 years ago
parent
commit
19a4ae4f01
  1. 1
      package.json
  2. 10
      public/index.html
  3. 193
      src/components/CountTo/index.vue
  4. 46
      src/components/CountTo/requestAnimationFrame.js
  5. 102
      src/components/echarts/BarChart.vue
  6. 118
      src/components/echarts/BoxCard.vue
  7. 135
      src/components/echarts/LineChart.vue
  8. 148
      src/components/echarts/MapChart.vue
  9. 181
      src/components/echarts/PanelGroup.vue
  10. 81
      src/components/echarts/PieChart.vue
  11. 116
      src/components/echarts/RaddarChart.vue
  12. 55
      src/components/echarts/TransactionTable.vue
  13. 27
      src/components/echarts/china.js
  14. 55
      src/components/echarts/mixins/resize.js
  15. 2
      src/components/tinymce/index.vue
  16. 27
      src/utils/index.js
  17. 2
      src/views/form/setting.vue
  18. 7
      src/views/form/write.vue
  19. 70
      src/views/home/dashboard.vue
  20. 2
      src/views/project/MyProject.vue
  21. 14
      src/views/test.vue

1
package.json

@ -16,6 +16,7 @@
"core-js": "^3.6.4",
"crypto-js": "^4.0.0",
"dayjs": "^1.9.4",
"echarts": "^5.0.0",
"element-ui": "^2.14.0",
"file-saver": "^2.0.2",
"js-cookie": "^2.2.1",

10
public/index.html

@ -15,6 +15,15 @@
<link href="<%= htmlWebpackPlugin.options.cdn.js[i] %>" rel="external nofollow preload" as="script">
<% } %>
</head>
<script>
var _hmt = _hmt || [];
(function() {
var hm = document.createElement("script");
hm.src = "https://hm.baidu.com/hm.js?8dd57964085e37a5e056c35faa6c5df9";
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hm, s);
})();
</script>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
@ -34,3 +43,4 @@
<% } %>
</body>
</html>

193
src/components/CountTo/index.vue

@ -0,0 +1,193 @@
<template>
<span>
{{ displayValue }}
</span>
</template>
<script>
import {requestAnimationFrame, cancelAnimationFrame} from './requestAnimationFrame.js'
export default {
name: 'CountTo',
props: {
startVal: {
type: Number,
required: false,
default: 0
},
endVal: {
type: Number,
required: false,
default: 2017
},
duration: {
type: Number,
required: false,
default: 3000
},
autoplay: {
type: Boolean,
required: false,
default: true
},
decimals: {
type: Number,
required: false,
default: 0,
validator(value) {
return value >= 0
}
},
decimal: {
type: String,
required: false,
default: '.'
},
separator: {
type: String,
required: false,
default: ','
},
prefix: {
type: String,
required: false,
default: ''
},
suffix: {
type: String,
required: false,
default: ''
},
useEasing: {
type: Boolean,
required: false,
default: true
},
easingFn: {
type: Function,
default(t, b, c, d) {
return c * (-Math.pow(2, -10 * t / d) + 1) * 1024 / 1023 + b
}
}
},
data() {
return {
localStartVal: this.startVal,
displayValue: this.formatNumber(this.startVal),
printVal: null,
paused: false,
localDuration: this.duration,
startTime: null,
timestamp: null,
remaining: null,
rAF: null
}
},
computed: {
countDown() {
return this.startVal > this.endVal
}
},
watch: {
startVal() {
if (this.autoplay) {
this.start()
}
},
endVal() {
if (this.autoplay) {
this.start()
}
}
},
mounted() {
if (this.autoplay) {
this.start()
}
this.$emit('mountedCallback')
},
methods: {
start() {
this.localStartVal = this.startVal
this.startTime = null
this.localDuration = this.duration
this.paused = false
this.rAF = requestAnimationFrame(this.count)
},
pauseResume() {
if (this.paused) {
this.resume()
this.paused = false
} else {
this.pause()
this.paused = true
}
},
pause() {
cancelAnimationFrame(this.rAF)
},
resume() {
this.startTime = null
this.localDuration = +this.remaining
this.localStartVal = +this.printVal
requestAnimationFrame(this.count)
},
reset() {
this.startTime = null
cancelAnimationFrame(this.rAF)
this.displayValue = this.formatNumber(this.startVal)
},
count(timestamp) {
if (!this.startTime) this.startTime = timestamp
this.timestamp = timestamp
const progress = timestamp - this.startTime
this.remaining = this.localDuration - progress
if (this.useEasing) {
if (this.countDown) {
this.printVal = this.localStartVal - this.easingFn(progress, 0, this.localStartVal - this.endVal, this.localDuration)
} else {
this.printVal = this.easingFn(progress, this.localStartVal, this.endVal - this.localStartVal, this.localDuration)
}
} else {
if (this.countDown) {
this.printVal = this.localStartVal - ((this.localStartVal - this.endVal) * (progress / this.localDuration))
} else {
this.printVal = this.localStartVal + (this.endVal - this.localStartVal) * (progress / this.localDuration)
}
}
if (this.countDown) {
this.printVal = this.printVal < this.endVal ? this.endVal : this.printVal
} else {
this.printVal = this.printVal > this.endVal ? this.endVal : this.printVal
}
this.displayValue = this.formatNumber(this.printVal)
if (progress < this.localDuration) {
this.rAF = requestAnimationFrame(this.count)
} else {
this.$emit('callback')
}
},
isNumber(val) {
return !isNaN(parseFloat(val))
},
formatNumber(num) {
num = num.toFixed(this.decimals)
num += ''
const x = num.split('.')
let x1 = x[0]
const x2 = x.length > 1 ? this.decimal + x[1] : ''
const rgx = /(\d+)(\d{3})/
if (this.separator && !this.isNumber(this.separator)) {
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + this.separator + '$2')
}
}
return this.prefix + x1 + x2 + this.suffix
}
},
destroyed() {
cancelAnimationFrame(this.rAF)
}
}
</script>

46
src/components/CountTo/requestAnimationFrame.js

@ -0,0 +1,46 @@
let lastTime = 0
const prefixes = 'webkit moz ms o'.split(' ') // 各浏览器前缀
let requestAnimationFrame
let cancelAnimationFrame
const isServer = typeof window === 'undefined'
if (isServer) {
requestAnimationFrame = function() {
return
}
cancelAnimationFrame = function() {
return
}
} else {
requestAnimationFrame = window.requestAnimationFrame
cancelAnimationFrame = window.cancelAnimationFrame
let prefix
// 通过遍历各浏览器前缀,来得到requestAnimationFrame和cancelAnimationFrame在当前浏览器的实现形式
for (let i = 0; i < prefixes.length; i++) {
if (requestAnimationFrame && cancelAnimationFrame) { break }
prefix = prefixes[i]
requestAnimationFrame = requestAnimationFrame || window[prefix + 'RequestAnimationFrame']
cancelAnimationFrame = cancelAnimationFrame || window[prefix + 'CancelAnimationFrame'] || window[prefix + 'CancelRequestAnimationFrame']
}
// 如果当前浏览器不支持requestAnimationFrame和cancelAnimationFrame,则会退到setTimeout
if (!requestAnimationFrame || !cancelAnimationFrame) {
requestAnimationFrame = function(callback) {
const currTime = new Date().getTime()
// 为了使setTimteout的尽可能的接近每秒60帧的效果
const timeToCall = Math.max(0, 16 - (currTime - lastTime))
const id = window.setTimeout(() => {
callback(currTime + timeToCall)
}, timeToCall)
lastTime = currTime + timeToCall
return id
}
cancelAnimationFrame = function(id) {
window.clearTimeout(id)
}
}
}
export { requestAnimationFrame, cancelAnimationFrame }

102
src/components/echarts/BarChart.vue

@ -0,0 +1,102 @@
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
const echarts = require('echarts')
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
const animationDuration = 6000
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
}
},
data() {
return {
chart: null
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.chart.setOption({
tooltip: {
trigger: 'axis',
axisPointer: { //
type: 'shadow' // 线'line' | 'shadow'
}
},
grid: {
top: 10,
left: '2%',
right: '2%',
bottom: '3%',
containLabel: true
},
xAxis: [{
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
axisTick: {
alignWithLabel: true
}
}],
yAxis: [{
type: 'value',
axisTick: {
show: false
}
}],
series: [{
name: 'pageA',
type: 'bar',
stack: 'vistors',
barWidth: '60%',
data: [79, 52, 200, 334, 390, 330, 220],
animationDuration
}, {
name: 'pageB',
type: 'bar',
stack: 'vistors',
barWidth: '60%',
data: [80, 52, 200, 334, 390, 330, 220],
animationDuration
}, {
name: 'pageC',
type: 'bar',
stack: 'vistors',
barWidth: '60%',
data: [30, 52, 200, 334, 390, 330, 220],
animationDuration
}]
})
}
}
}
</script>

118
src/components/echarts/BoxCard.vue

@ -0,0 +1,118 @@
<template>
<el-card class="box-card-component" style="margin-left:8px;">
<div slot="header" class="box-card-header">
<img src="https://wpimg.wallstcn.com/e7d23d71-cf19-4b90-a1cc-f56af8c0903d.png">
</div>
<div style="position:relative;">
<pan-thumb :image="avatar" class="panThumb" />
<mallki class-name="mallki-text" text="vue-element-admin" />
<div style="padding-top:35px;" class="progress-item">
<span>Vue</span>
<el-progress :percentage="70" />
</div>
<div class="progress-item">
<span>JavaScript</span>
<el-progress :percentage="18" />
</div>
<div class="progress-item">
<span>CSS</span>
<el-progress :percentage="12" />
</div>
<div class="progress-item">
<span>ESLint</span>
<el-progress :percentage="100" status="success" />
</div>
</div>
</el-card>
</template>
<script>
import { mapGetters } from 'vuex'
import PanThumb from '@/components/PanThumb'
import Mallki from '@/components/TextHoverEffect/Mallki'
export default {
components: { PanThumb, Mallki },
filters: {
statusFilter(status) {
const statusMap = {
success: 'success',
pending: 'danger'
}
return statusMap[status]
}
},
data() {
return {
statisticsData: {
article_count: 1024,
pageviews_count: 1024
}
}
},
computed: {
...mapGetters([
'name',
'avatar',
'roles'
])
}
}
</script>
<style lang="scss" >
.box-card-component{
.el-card__header {
padding: 0px!important;
}
}
</style>
<style lang="scss" scoped>
.box-card-component {
.box-card-header {
position: relative;
height: 220px;
img {
width: 100%;
height: 100%;
transition: all 0.2s linear;
&:hover {
transform: scale(1.1, 1.1);
filter: contrast(130%);
}
}
}
.mallki-text {
position: absolute;
top: 0px;
right: 0px;
font-size: 20px;
font-weight: bold;
}
.panThumb {
z-index: 100;
height: 70px!important;
width: 70px!important;
position: absolute!important;
top: -45px;
left: 0px;
border: 5px solid #ffffff;
background-color: #fff;
margin: auto;
box-shadow: none!important;
::v-deep .pan-info {
box-shadow: none!important;
}
}
.progress-item {
margin-bottom: 10px;
font-size: 14px;
}
@media only screen and (max-width: 1510px){
.mallki-text{
display: none;
}
}
}
</style>

135
src/components/echarts/LineChart.vue

@ -0,0 +1,135 @@
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
const echarts = require('echarts')
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '350px'
},
autoResize: {
type: Boolean,
default: true
},
chartData: {
type: Object,
required: true
}
},
data() {
return {
chart: null
}
},
watch: {
chartData: {
deep: true,
handler(val) {
this.setOptions(val)
}
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.setOptions(this.chartData)
},
setOptions({ expectedData, actualData } = {}) {
this.chart.setOption({
xAxis: {
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],
boundaryGap: false,
axisTick: {
show: false
}
},
grid: {
left: 10,
right: 10,
bottom: 20,
top: 30,
containLabel: true
},
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross'
},
padding: [5, 10]
},
yAxis: {
axisTick: {
show: false
}
},
legend: {
data: ['expected', 'actual']
},
series: [{
name: 'expected', itemStyle: {
normal: {
color: '#FF005A',
lineStyle: {
color: '#FF005A',
width: 2
}
}
},
smooth: true,
type: 'line',
data: expectedData,
animationDuration: 2800,
animationEasing: 'cubicInOut'
},
{
name: 'actual',
smooth: true,
type: 'line',
itemStyle: {
normal: {
color: '#3888fa',
lineStyle: {
color: '#3888fa',
width: 2
},
areaStyle: {
color: '#f3f8ff'
}
}
},
data: actualData,
animationDuration: 2800,
animationEasing: 'quadraticOut'
}]
})
}
}
}
</script>

148
src/components/echarts/MapChart.vue

@ -0,0 +1,148 @@
<template>
<div :class="className" :style="{height:height,width:width}"/>
</template>
<script>
const echarts = require('echarts')
require('./china.js')
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
}
},
data() {
return {
chart: null
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.chart.setOption({
title: {
text: '订单量',
subtext: '纯属虚构',
left: 'center'
},
tooltip: {
trigger: 'item'
},
legend: {
orient: 'vertical',
left: 'left',
data: ['订单量']
},
visualMap: {
type: 'piecewise',
pieces: [
{min: 1500},
{min: 900, max: 1500},
{min: 310, max: 1000},
{min: 200, max: 300},
{min: 10, max: 200, label: '10 到 200(自定义label)'},
{value: 123, label: '123(自定义特殊颜色)', color: 'grey'},
{min: 5, max: 5, label: '5(自定义特殊颜色)', color: 'black'},
{max: 5}
],
color: ['#E0022B', '#E09107', '#A3E00B']
},
toolbox: {
show: true,
orient: 'vertical',
left: 'right',
top: 'center',
feature: {
mark: {show: true},
dataView: {show: true, readOnly: false},
restore: {show: true},
saveAsImage: {show: true}
}
},
roamController: {
show: true,
left: 'right',
mapTypeControl: {
'china': true
}
},
series: [
{
name: '订单量',
type: 'map',
mapType: 'china',
roam: false,
label: {
show: true,
color: 'rgb(249, 249, 249)'
},
data: [
{name: '北京', value: 5},
{name: '天津', value: Math.round(Math.random() * 2000)},
{name: '上海', value: Math.round(Math.random() * 2000)},
{name: '重庆', value: Math.round(Math.random() * 2000)},
{name: '河北', value: 0},
{name: '河南', value: Math.round(Math.random() * 2000)},
{name: '云南', value: 123},
{name: '辽宁', value: 305},
{name: '黑龙江', value: Math.round(Math.random() * 2000)},
{name: '湖南', value: 200},
{name: '安徽', value: Math.round(Math.random() * 2000)},
{name: '山东', value: Math.round(Math.random() * 2000)},
{name: '新疆', value: Math.round(Math.random() * 2000)},
{name: '江苏', value: Math.round(Math.random() * 2000)},
{name: '浙江', value: Math.round(Math.random() * 2000)},
{name: '江西', value: Math.round(Math.random() * 2000)},
{name: '湖北', value: Math.round(Math.random() * 2000)},
{name: '广西', value: Math.round(Math.random() * 2000)},
{name: '甘肃', value: Math.round(Math.random() * 2000)},
{name: '山西', value: Math.round(Math.random() * 2000)},
{name: '内蒙古', value: Math.round(Math.random() * 2000)},
{name: '陕西', value: Math.round(Math.random() * 2000)},
{name: '吉林', value: Math.round(Math.random() * 2000)},
{name: '福建', value: Math.round(Math.random() * 2000)},
{name: '贵州', value: Math.round(Math.random() * 2000)},
{name: '广东', value: Math.round(Math.random() * 2000)},
{name: '青海', value: Math.round(Math.random() * 2000)},
{name: '西藏', value: Math.round(Math.random() * 2000)},
{name: '四川', value: Math.round(Math.random() * 2000)},
{name: '宁夏', value: Math.round(Math.random() * 2000)},
{name: '海南', value: Math.round(Math.random() * 2000)},
{name: '台湾', value: Math.round(Math.random() * 2000)},
{name: '香港', value: Math.round(Math.random() * 2000)},
{name: '澳门', value: Math.round(Math.random() * 2000)}
]
}
]
})
}
}
}
</script>

181
src/components/echarts/PanelGroup.vue

@ -0,0 +1,181 @@
<template>
<el-row :gutter="40" class="panel-group">
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('newVisitis')">
<div class="card-panel-icon-wrapper icon-people">
<svg-icon icon-class="peoples" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
New Visits
</div>
<count-to :start-val="0" :end-val="102400" :duration="2600" class="card-panel-num" />
</div>
</div>
</el-col>
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('messages')">
<div class="card-panel-icon-wrapper icon-message">
<svg-icon icon-class="message" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
Messages
</div>
<count-to :start-val="0" :end-val="81212" :duration="3000" class="card-panel-num" />
</div>
</div>
</el-col>
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('purchases')">
<div class="card-panel-icon-wrapper icon-money">
<svg-icon icon-class="money" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
Purchases
</div>
<count-to :start-val="0" :end-val="9280" :duration="3200" class="card-panel-num" />
</div>
</div>
</el-col>
<el-col :xs="12" :sm="12" :lg="6" class="card-panel-col">
<div class="card-panel" @click="handleSetLineChartData('shoppings')">
<div class="card-panel-icon-wrapper icon-shopping">
<svg-icon icon-class="shopping" class-name="card-panel-icon" />
</div>
<div class="card-panel-description">
<div class="card-panel-text">
Shoppings
</div>
<count-to :start-val="0" :end-val="13600" :duration="3600" class="card-panel-num" />
</div>
</div>
</el-col>
</el-row>
</template>
<script>
import CountTo from 'CountTo'
export default {
components: {
CountTo
},
methods: {
handleSetLineChartData(type) {
this.$emit('handleSetLineChartData', type)
}
}
}
</script>
<style lang="scss" scoped>
.panel-group {
margin-top: 18px;
.card-panel-col {
margin-bottom: 32px;
}
.card-panel {
height: 108px;
cursor: pointer;
font-size: 12px;
position: relative;
overflow: hidden;
color: #666;
background: #fff;
box-shadow: 4px 4px 40px rgba(0, 0, 0, .05);
border-color: rgba(0, 0, 0, .05);
&:hover {
.card-panel-icon-wrapper {
color: #fff;
}
.icon-people {
background: #40c9c6;
}
.icon-message {
background: #36a3f7;
}
.icon-money {
background: #f4516c;
}
.icon-shopping {
background: #34bfa3
}
}
.icon-people {
color: #40c9c6;
}
.icon-message {
color: #36a3f7;
}
.icon-money {
color: #f4516c;
}
.icon-shopping {
color: #34bfa3
}
.card-panel-icon-wrapper {
float: left;
margin: 14px 0 0 14px;
padding: 16px;
transition: all 0.38s ease-out;
border-radius: 6px;
}
.card-panel-icon {
float: left;
font-size: 48px;
}
.card-panel-description {
float: right;
font-weight: bold;
margin: 26px;
margin-left: 0px;
.card-panel-text {
line-height: 18px;
color: rgba(0, 0, 0, 0.45);
font-size: 16px;
margin-bottom: 12px;
}
.card-panel-num {
font-size: 20px;
}
}
}
}
@media (max-width:550px) {
.card-panel-description {
display: none;
}
.card-panel-icon-wrapper {
float: none !important;
width: 100%;
height: 100%;
margin: 0 !important;
.svg-icon {
display: block;
margin: 14px auto !important;
float: none !important;
}
}
}
</style>

81
src/components/echarts/PieChart.vue

@ -0,0 +1,81 @@
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
const echarts = require('echarts')
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
}
},
data() {
return {
chart: null
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.chart.setOption({
tooltip: {
trigger: 'item',
formatter: '{a} <br/>{b} : {c} ({d}%)'
},
legend: {
left: 'center',
bottom: '10',
data: ['Industries', 'Technology', 'Forex', 'Gold', 'Forecasts']
},
series: [
{
name: 'WEEKLY WRITE ARTICLES',
type: 'pie',
roseType: 'radius',
radius: [15, 95],
center: ['50%', '38%'],
data: [
{ value: 320, name: 'Industries' },
{ value: 240, name: 'Technology' },
{ value: 149, name: 'Forex' },
{ value: 100, name: 'Gold' },
{ value: 59, name: 'Forecasts' }
],
animationEasing: 'cubicInOut',
animationDuration: 2600
}
]
})
}
}
}
</script>

116
src/components/echarts/RaddarChart.vue

@ -0,0 +1,116 @@
<template>
<div :class="className" :style="{height:height,width:width}" />
</template>
<script>
import echarts from 'echarts'
require('echarts/theme/macarons') // echarts theme
import resize from './mixins/resize'
const animationDuration = 3000
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '100%'
},
height: {
type: String,
default: '300px'
}
},
data() {
return {
chart: null
}
},
mounted() {
this.$nextTick(() => {
this.initChart()
})
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(this.$el, 'macarons')
this.chart.setOption({
tooltip: {
trigger: 'axis',
axisPointer: { //
type: 'shadow' // 线'line' | 'shadow'
}
},
radar: {
radius: '66%',
center: ['50%', '42%'],
splitNumber: 8,
splitArea: {
areaStyle: {
color: 'rgba(127,95,132,.3)',
opacity: 1,
shadowBlur: 45,
shadowColor: 'rgba(0,0,0,.5)',
shadowOffsetX: 0,
shadowOffsetY: 15
}
},
indicator: [
{ name: 'Sales', max: 10000 },
{ name: 'Administration', max: 20000 },
{ name: 'Information Technology', max: 20000 },
{ name: 'Customer Support', max: 20000 },
{ name: 'Development', max: 20000 },
{ name: 'Marketing', max: 20000 }
]
},
legend: {
left: 'center',
bottom: '10',
data: ['Allocated Budget', 'Expected Spending', 'Actual Spending']
},
series: [{
type: 'radar',
symbolSize: 0,
areaStyle: {
normal: {
shadowBlur: 13,
shadowColor: 'rgba(0,0,0,.2)',
shadowOffsetX: 0,
shadowOffsetY: 10,
opacity: 1
}
},
data: [
{
value: [5000, 7000, 12000, 11000, 15000, 14000],
name: 'Allocated Budget'
},
{
value: [4000, 9000, 15000, 15000, 13000, 11000],
name: 'Expected Spending'
},
{
value: [5500, 11000, 12000, 15000, 12000, 12000],
name: 'Actual Spending'
}
],
animationDuration: animationDuration
}]
})
}
}
}
</script>

55
src/components/echarts/TransactionTable.vue

@ -0,0 +1,55 @@
<template>
<el-table :data="list" style="width: 100%;padding-top: 15px;">
<el-table-column label="Order_No" min-width="200">
<template slot-scope="scope">
{{ scope.row.order_no | orderNoFilter }}
</template>
</el-table-column>
<el-table-column label="Price" width="195" align="center">
<template slot-scope="scope">
¥{{ scope.row.price | toThousandFilter }}
</template>
</el-table-column>
<el-table-column label="Status" width="100" align="center">
<template slot-scope="{row}">
<el-tag :type="row.status | statusFilter">
{{ row.status }}
</el-tag>
</template>
</el-table-column>
</el-table>
</template>
<script>
import { transactionList } from '@/api/remote-search'
export default {
filters: {
statusFilter(status) {
const statusMap = {
success: 'success',
pending: 'danger'
}
return statusMap[status]
},
orderNoFilter(str) {
return str.substring(0, 30)
}
},
data() {
return {
list: null
}
},
created() {
this.fetchData()
},
methods: {
fetchData() {
transactionList().then(response => {
this.list = response.data.items.slice(0, 8)
})
}
}
}
</script>

27
src/components/echarts/china.js

File diff suppressed because one or more lines are too long

55
src/components/echarts/mixins/resize.js

@ -0,0 +1,55 @@
import {debounce} from '@/utils'
export default {
data() {
return {
$_sidebarElm: null,
$_resizeHandler: null
}
},
mounted() {
this.$_resizeHandler = debounce(() => {
if (this.chart) {
this.chart.resize()
}
}, 100)
this.$_initResizeEvent()
this.$_initSidebarResizeEvent()
},
beforeDestroy() {
this.$_destroyResizeEvent()
this.$_destroySidebarResizeEvent()
},
// to fixed bug when cached by keep-alive
// https://github.com/PanJiaChen/vue-element-admin/issues/2116
activated() {
this.$_initResizeEvent()
this.$_initSidebarResizeEvent()
},
deactivated() {
this.$_destroyResizeEvent()
this.$_destroySidebarResizeEvent()
},
methods: {
// use $_ for mixins properties
// https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
$_initResizeEvent() {
window.addEventListener('resize', this.$_resizeHandler)
},
$_destroyResizeEvent() {
window.removeEventListener('resize', this.$_resizeHandler)
},
$_sidebarResizeHandler(e) {
if (e.propertyName === 'width') {
this.$_resizeHandler()
}
},
$_initSidebarResizeEvent() {
this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
},
$_destroySidebarResizeEvent() {
this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
}
}
}

2
src/components/tinymce/index.vue

@ -42,7 +42,7 @@ export default {
menubar: 'false',
skin_url: '/tinymce/skins/ui/tduck',
content_css : '/tinymce/skins/content/tduck' ,
cache_suffix: '?v='+new Date(),
cache_suffix: '?v=0.0.1',
plugins,
toolbar,
toolbar_drawer:'sliding',

27
src/utils/index.js

@ -180,3 +180,30 @@ export function getQueryString(name) {
export function getCurrentDomain() {
return window.location.protocol + '//' + window.location.host
}
/**
* @param {Function} func
* @param {number} wait
* @param {boolean} immediate
* @return {*}
*/
export function debounce(func, wait, immediate) {
let timeout, args, context, timestamp, result
const later = function() {
// 据上一次触发时间间隔
const last = +new Date() - timestamp
// 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
if (last < wait && last > 0) {
timeout = setTimeout(later, wait - last)
} else {
timeout = null
// 如果设定为immediate===true,因为开始边界已经调用过了此处无需调用
if (!immediate) {
result = func.apply(context, args)
if (!timeout) context = args = null
}
}
}
}

2
src/views/form/setting.vue

@ -487,7 +487,7 @@
</p>
</div>
<div>
<img :src="userProjectSettingData.shareImg" style="width: 49px;height: 46px;"/>
<img :src="userProjectSettingData.shareImg" v-if="userProjectSettingData.shareImg" style="width: 49px;height: 46px;"/>
</div>
</div>
<div>

7
src/views/form/write.vue

@ -88,10 +88,17 @@ export default {
})
},
mounted() {
this.viewProjectHandle()
},
components: {
ProjectForm
}, methods: {
viewProjectHandle(){
//
this.$api.post(`/user/project/result/view/${this.projectConfig.projectKey}`, {params: {projectKey: this.projectConfig.projectKey}}).then(res => {
})
},
queryProjectSettingStatus() {
//
this.$api.get(`/user/project/setting/status`, {params: {projectKey: this.projectConfig.projectKey}}).then(res => {

70
src/views/home/dashboard.vue

@ -18,7 +18,7 @@
</el-col>
</el-row>
<el-row
style="width: 719px; height: 416px; border-radius: 10px; border: 1px solid rgba(187, 187, 187, 100);"
style="width: 719px; height: 450px; border-radius: 10px; border: 1px solid rgba(187, 187, 187, 100);"
>
<el-row style="height: 50px;" />
<el-row>
@ -38,27 +38,28 @@
</el-row>
<el-row type="flex" justify="space-around">
<el-col :offset="2" :span="5">
<h4>
<count-to style="font-size: 20px;">
1231
</h4>
</count-to>
</el-col>
<el-col :span="5">
<h4>
<count-to style="font-size: 20px;">
3921
</h4>
</count-to>
</el-col>
<el-col :span="5">
<h4>28%</h4>
<count-to style="font-size: 20px;">
28
</count-to>
%
</el-col>
<el-col :span="5">
<h4>12分16秒</h4>
<span style="font-size: 20px;"> 12分16秒</span>
</el-col>
</el-row>
</el-row>
<el-row>
<img style="width: 719px; height: 252px;"
src="https://freebrio.oss-cn-shanghai.aliyuncs.com/t/v2_q2cdrp.png"
>
<line-chart :chart-data="lineChartData" />
</el-row>
</el-row>
</el-col>
@ -70,9 +71,7 @@
</el-row>
<el-row>
<el-col :span="18">
<img style="height: 215px;"
src="https://freebrio.oss-cn-shanghai.aliyuncs.com/t/v2_q2cdw0.png"
>
<map-chart />
</el-col>
</el-row>
<el-row type="flex" justify="space-around">
@ -83,9 +82,7 @@
</el-col>
</el-row>
<el-row>
<img style="height: 160px;"
src="https://freebrio.oss-cn-shanghai.aliyuncs.com/t/v2_q2cdta.png"
>
<bar-chart />
</el-row>
</el-col>
<el-col :span="12">
@ -95,9 +92,7 @@
</el-col>
</el-row>
<el-row>
<img style="height: 160px;"
src="https://freebrio.oss-cn-shanghai.aliyuncs.com/t/v2_q2cdo2.png"
>
<pie-chart />
</el-row>
</el-col>
</el-row>
@ -107,8 +102,43 @@
</el-row>
</template>
<script>
import PieChart from '@/components/echarts/PieChart'
import LineChart from '@/components/echarts/LineChart'
import MapChart from '@/components/echarts/MapChart'
import CountTo from '@/components/CountTo'
import BarChart from '@/components/echarts/BarChart'
const lineChartData = {
newVisitis: {
expectedData: [100, 120, 161, 134, 105, 160, 165],
actualData: [120, 82, 91, 154, 162, 140, 145]
},
messages: {
expectedData: [200, 192, 120, 144, 160, 130, 140],
actualData: [180, 160, 151, 106, 145, 150, 130]
},
purchases: {
expectedData: [80, 100, 121, 104, 105, 90, 100],
actualData: [120, 90, 100, 138, 142, 130, 130]
},
shoppings: {
expectedData: [130, 140, 141, 142, 145, 150, 160],
actualData: [120, 82, 91, 154, 162, 140, 130]
}
}
export default {
name: 'HomeDashboard'
name: 'HomeDashboard',
components: {
CountTo,
PieChart,
MapChart,
BarChart,
LineChart
},
data() {
return {
lineChartData: lineChartData.newVisitis
}
}
}
</script>

2
src/views/project/MyProject.vue

@ -107,7 +107,7 @@
</div>
</div>
</div>
<div v-else>
<div v-else v-loading="projectListLoading">
<data-empty />
</div>
</div>

14
src/views/test.vue

@ -1,28 +1,26 @@
<template>
<div>
<el-radio-group v-model="radio">
<el-radio :label="3">备选项</el-radio>
<el-radio :label="6">备选项</el-radio>
<el-radio :label="9">备选项</el-radio>
<el-radio :label="0">其他<input/>
</el-radio>
</el-radio-group>
<map-chart />
</div>
</template>
<script>
//
// import Verify from '@/components/verifition/Verify'
import MapChart from '@/components/echarts/MapChart'
export default {
name: 'App',
components: {
MapChart
},
data() {
return {
radio: 3
}
},
created() {
mounted() {
},
methods: {
success(params) {

Loading…
Cancel
Save