正在显示
14 个修改的文件
包含
1518 行增加
和
2 行删除
| 1 | +<template> | ||
| 2 | + <div :class="className" :style="{height:height,width:width}"/> | ||
| 3 | +</template> | ||
| 4 | + | ||
| 5 | +<script> | ||
| 6 | +import echarts from 'echarts' | ||
| 7 | +require('echarts/theme/macarons') // echarts theme | ||
| 8 | +import { debounce } from '@/utils' | ||
| 9 | + | ||
| 10 | +const animationDuration = 6000 | ||
| 11 | + | ||
| 12 | +export default { | ||
| 13 | + props: { | ||
| 14 | + className: { | ||
| 15 | + type: String, | ||
| 16 | + default: 'chart' | ||
| 17 | + }, | ||
| 18 | + width: { | ||
| 19 | + type: String, | ||
| 20 | + default: '100%' | ||
| 21 | + }, | ||
| 22 | + height: { | ||
| 23 | + type: String, | ||
| 24 | + default: '300px' | ||
| 25 | + } | ||
| 26 | + }, | ||
| 27 | + data() { | ||
| 28 | + return { | ||
| 29 | + chart: null | ||
| 30 | + } | ||
| 31 | + }, | ||
| 32 | + mounted() { | ||
| 33 | + this.initChart() | ||
| 34 | + this.__resizeHandler = debounce(() => { | ||
| 35 | + if (this.chart) { | ||
| 36 | + this.chart.resize() | ||
| 37 | + } | ||
| 38 | + }, 100) | ||
| 39 | + window.addEventListener('resize', this.__resizeHandler) | ||
| 40 | + }, | ||
| 41 | + beforeDestroy() { | ||
| 42 | + if (!this.chart) { | ||
| 43 | + return | ||
| 44 | + } | ||
| 45 | + window.removeEventListener('resize', this.__resizeHandler) | ||
| 46 | + this.chart.dispose() | ||
| 47 | + this.chart = null | ||
| 48 | + }, | ||
| 49 | + methods: { | ||
| 50 | + initChart() { | ||
| 51 | + this.chart = echarts.init(this.$el, 'macarons') | ||
| 52 | + | ||
| 53 | + this.chart.setOption({ | ||
| 54 | + tooltip: { | ||
| 55 | + trigger: 'axis', | ||
| 56 | + axisPointer: { // 坐标轴指示器,坐标轴触发有效 | ||
| 57 | + type: 'shadow' // 默认为直线,可选为:'line' | 'shadow' | ||
| 58 | + } | ||
| 59 | + }, | ||
| 60 | + grid: { | ||
| 61 | + top: 10, | ||
| 62 | + left: '2%', | ||
| 63 | + right: '2%', | ||
| 64 | + bottom: '3%', | ||
| 65 | + containLabel: true | ||
| 66 | + }, | ||
| 67 | + xAxis: [{ | ||
| 68 | + type: 'category', | ||
| 69 | + data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], | ||
| 70 | + axisTick: { | ||
| 71 | + alignWithLabel: true | ||
| 72 | + } | ||
| 73 | + }], | ||
| 74 | + yAxis: [{ | ||
| 75 | + type: 'value', | ||
| 76 | + axisTick: { | ||
| 77 | + show: false | ||
| 78 | + } | ||
| 79 | + }], | ||
| 80 | + series: [{ | ||
| 81 | + name: 'pageA', | ||
| 82 | + type: 'bar', | ||
| 83 | + stack: 'vistors', | ||
| 84 | + barWidth: '60%', | ||
| 85 | + data: [79, 52, 200, 334, 390, 330, 220], | ||
| 86 | + animationDuration | ||
| 87 | + }, { | ||
| 88 | + name: 'pageB', | ||
| 89 | + type: 'bar', | ||
| 90 | + stack: 'vistors', | ||
| 91 | + barWidth: '60%', | ||
| 92 | + data: [80, 52, 200, 334, 390, 330, 220], | ||
| 93 | + animationDuration | ||
| 94 | + }, { | ||
| 95 | + name: 'pageC', | ||
| 96 | + type: 'bar', | ||
| 97 | + stack: 'vistors', | ||
| 98 | + barWidth: '60%', | ||
| 99 | + data: [30, 52, 200, 334, 390, 330, 220], | ||
| 100 | + animationDuration | ||
| 101 | + }] | ||
| 102 | + }) | ||
| 103 | + } | ||
| 104 | + } | ||
| 105 | +} | ||
| 106 | +</script> |
| 1 | +<template> | ||
| 2 | + <el-card class="box-card-component" style="margin-left:8px;"> | ||
| 3 | + <div slot="header" class="box-card-header"> | ||
| 4 | + <img src="https://wpimg.wallstcn.com/e7d23d71-cf19-4b90-a1cc-f56af8c0903d.png"> | ||
| 5 | + </div> | ||
| 6 | + <div style="position:relative;"> | ||
| 7 | + <pan-thumb :image="avatar" class="panThumb"/> | ||
| 8 | + <mallki class-name="mallki-text" text="vue-element-admin"/> | ||
| 9 | + <div style="padding-top:35px;" class="progress-item"> | ||
| 10 | + <span>Vue</span> | ||
| 11 | + <el-progress :percentage="70"/> | ||
| 12 | + </div> | ||
| 13 | + <div class="progress-item"> | ||
| 14 | + <span>JavaScript</span> | ||
| 15 | + <el-progress :percentage="18"/> | ||
| 16 | + </div> | ||
| 17 | + <div class="progress-item"> | ||
| 18 | + <span>Css</span> | ||
| 19 | + <el-progress :percentage="12"/> | ||
| 20 | + </div> | ||
| 21 | + <div class="progress-item"> | ||
| 22 | + <span>ESLint</span> | ||
| 23 | + <el-progress :percentage="100" status="success"/> | ||
| 24 | + </div> | ||
| 25 | + </div> | ||
| 26 | + </el-card> | ||
| 27 | +</template> | ||
| 28 | + | ||
| 29 | +<script> | ||
| 30 | +import { mapGetters } from 'vuex' | ||
| 31 | +import PanThumb from '@/components/PanThumb' | ||
| 32 | +import Mallki from '@/components/TextHoverEffect/Mallki' | ||
| 33 | + | ||
| 34 | +export default { | ||
| 35 | + components: { PanThumb, Mallki }, | ||
| 36 | + | ||
| 37 | + filters: { | ||
| 38 | + statusFilter(status) { | ||
| 39 | + const statusMap = { | ||
| 40 | + success: 'success', | ||
| 41 | + pending: 'danger' | ||
| 42 | + } | ||
| 43 | + return statusMap[status] | ||
| 44 | + } | ||
| 45 | + }, | ||
| 46 | + data() { | ||
| 47 | + return { | ||
| 48 | + statisticsData: { | ||
| 49 | + article_count: 1024, | ||
| 50 | + pageviews_count: 1024 | ||
| 51 | + } | ||
| 52 | + } | ||
| 53 | + }, | ||
| 54 | + computed: { | ||
| 55 | + ...mapGetters([ | ||
| 56 | + 'name', | ||
| 57 | + 'avatar', | ||
| 58 | + 'roles' | ||
| 59 | + ]) | ||
| 60 | + } | ||
| 61 | +} | ||
| 62 | +</script> | ||
| 63 | + | ||
| 64 | +<style rel="stylesheet/scss" lang="scss" > | ||
| 65 | +.box-card-component{ | ||
| 66 | + .el-card__header { | ||
| 67 | + padding: 0px!important; | ||
| 68 | + } | ||
| 69 | +} | ||
| 70 | +</style> | ||
| 71 | +<style rel="stylesheet/scss" lang="scss" scoped> | ||
| 72 | +.box-card-component { | ||
| 73 | + .box-card-header { | ||
| 74 | + position: relative; | ||
| 75 | + height: 220px; | ||
| 76 | + img { | ||
| 77 | + width: 100%; | ||
| 78 | + height: 100%; | ||
| 79 | + transition: all 0.2s linear; | ||
| 80 | + &:hover { | ||
| 81 | + transform: scale(1.1, 1.1); | ||
| 82 | + filter: contrast(130%); | ||
| 83 | + } | ||
| 84 | + } | ||
| 85 | + } | ||
| 86 | + .mallki-text { | ||
| 87 | + position: absolute; | ||
| 88 | + top: 0px; | ||
| 89 | + right: 0px; | ||
| 90 | + font-size: 20px; | ||
| 91 | + font-weight: bold; | ||
| 92 | + } | ||
| 93 | + .panThumb { | ||
| 94 | + z-index: 100; | ||
| 95 | + height: 70px!important; | ||
| 96 | + width: 70px!important; | ||
| 97 | + position: absolute!important; | ||
| 98 | + top: -45px; | ||
| 99 | + left: 0px; | ||
| 100 | + border: 5px solid #ffffff; | ||
| 101 | + background-color: #fff; | ||
| 102 | + margin: auto; | ||
| 103 | + box-shadow: none!important; | ||
| 104 | + /deep/ .pan-info { | ||
| 105 | + box-shadow: none!important; | ||
| 106 | + } | ||
| 107 | + } | ||
| 108 | + .progress-item { | ||
| 109 | + margin-bottom: 10px; | ||
| 110 | + font-size: 14px; | ||
| 111 | + } | ||
| 112 | + @media only screen and (max-width: 1510px){ | ||
| 113 | + .mallki-text{ | ||
| 114 | + display: none; | ||
| 115 | + } | ||
| 116 | + } | ||
| 117 | +} | ||
| 118 | +</style> |
| 1 | +<template> | ||
| 2 | + <div :class="className" :style="{height:height,width:width}"/> | ||
| 3 | +</template> | ||
| 4 | + | ||
| 5 | +<script> | ||
| 6 | +import echarts from 'echarts' | ||
| 7 | +require('echarts/theme/macarons') // echarts theme | ||
| 8 | +import { debounce } from '@/utils' | ||
| 9 | + | ||
| 10 | +export default { | ||
| 11 | + props: { | ||
| 12 | + className: { | ||
| 13 | + type: String, | ||
| 14 | + default: 'chart' | ||
| 15 | + }, | ||
| 16 | + width: { | ||
| 17 | + type: String, | ||
| 18 | + default: '100%' | ||
| 19 | + }, | ||
| 20 | + height: { | ||
| 21 | + type: String, | ||
| 22 | + default: '350px' | ||
| 23 | + }, | ||
| 24 | + autoResize: { | ||
| 25 | + type: Boolean, | ||
| 26 | + default: true | ||
| 27 | + }, | ||
| 28 | + chartData: { | ||
| 29 | + type: Object, | ||
| 30 | + required: true | ||
| 31 | + } | ||
| 32 | + }, | ||
| 33 | + data() { | ||
| 34 | + return { | ||
| 35 | + chart: null, | ||
| 36 | + sidebarElm: null | ||
| 37 | + } | ||
| 38 | + }, | ||
| 39 | + watch: { | ||
| 40 | + chartData: { | ||
| 41 | + deep: true, | ||
| 42 | + handler(val) { | ||
| 43 | + this.setOptions(val) | ||
| 44 | + } | ||
| 45 | + } | ||
| 46 | + }, | ||
| 47 | + mounted() { | ||
| 48 | + this.initChart() | ||
| 49 | + if (this.autoResize) { | ||
| 50 | + this.__resizeHandler = debounce(() => { | ||
| 51 | + if (this.chart) { | ||
| 52 | + this.chart.resize() | ||
| 53 | + } | ||
| 54 | + }, 100) | ||
| 55 | + window.addEventListener('resize', this.__resizeHandler) | ||
| 56 | + } | ||
| 57 | + | ||
| 58 | + // 监听侧边栏的变化 | ||
| 59 | + this.sidebarElm = document.getElementsByClassName('sidebar-container')[0] | ||
| 60 | + this.sidebarElm && this.sidebarElm.addEventListener('transitionend', this.sidebarResizeHandler) | ||
| 61 | + }, | ||
| 62 | + beforeDestroy() { | ||
| 63 | + if (!this.chart) { | ||
| 64 | + return | ||
| 65 | + } | ||
| 66 | + if (this.autoResize) { | ||
| 67 | + window.removeEventListener('resize', this.__resizeHandler) | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + this.sidebarElm && this.sidebarElm.removeEventListener('transitionend', this.sidebarResizeHandler) | ||
| 71 | + | ||
| 72 | + this.chart.dispose() | ||
| 73 | + this.chart = null | ||
| 74 | + }, | ||
| 75 | + methods: { | ||
| 76 | + sidebarResizeHandler(e) { | ||
| 77 | + if (e.propertyName === 'width') { | ||
| 78 | + this.__resizeHandler() | ||
| 79 | + } | ||
| 80 | + }, | ||
| 81 | + setOptions({ expectedData, actualData } = {}) { | ||
| 82 | + this.chart.setOption({ | ||
| 83 | + xAxis: { | ||
| 84 | + data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], | ||
| 85 | + boundaryGap: false, | ||
| 86 | + axisTick: { | ||
| 87 | + show: false | ||
| 88 | + } | ||
| 89 | + }, | ||
| 90 | + grid: { | ||
| 91 | + left: 10, | ||
| 92 | + right: 10, | ||
| 93 | + bottom: 20, | ||
| 94 | + top: 30, | ||
| 95 | + containLabel: true | ||
| 96 | + }, | ||
| 97 | + tooltip: { | ||
| 98 | + trigger: 'axis', | ||
| 99 | + axisPointer: { | ||
| 100 | + type: 'cross' | ||
| 101 | + }, | ||
| 102 | + padding: [5, 10] | ||
| 103 | + }, | ||
| 104 | + yAxis: { | ||
| 105 | + axisTick: { | ||
| 106 | + show: false | ||
| 107 | + } | ||
| 108 | + }, | ||
| 109 | + legend: { | ||
| 110 | + data: ['expected', 'actual'] | ||
| 111 | + }, | ||
| 112 | + series: [{ | ||
| 113 | + name: 'expected', itemStyle: { | ||
| 114 | + normal: { | ||
| 115 | + color: '#FF005A', | ||
| 116 | + lineStyle: { | ||
| 117 | + color: '#FF005A', | ||
| 118 | + width: 2 | ||
| 119 | + } | ||
| 120 | + } | ||
| 121 | + }, | ||
| 122 | + smooth: true, | ||
| 123 | + type: 'line', | ||
| 124 | + data: expectedData, | ||
| 125 | + animationDuration: 2800, | ||
| 126 | + animationEasing: 'cubicInOut' | ||
| 127 | + }, | ||
| 128 | + { | ||
| 129 | + name: 'actual', | ||
| 130 | + smooth: true, | ||
| 131 | + type: 'line', | ||
| 132 | + itemStyle: { | ||
| 133 | + normal: { | ||
| 134 | + color: '#3888fa', | ||
| 135 | + lineStyle: { | ||
| 136 | + color: '#3888fa', | ||
| 137 | + width: 2 | ||
| 138 | + }, | ||
| 139 | + areaStyle: { | ||
| 140 | + color: '#f3f8ff' | ||
| 141 | + } | ||
| 142 | + } | ||
| 143 | + }, | ||
| 144 | + data: actualData, | ||
| 145 | + animationDuration: 2800, | ||
| 146 | + animationEasing: 'quadraticOut' | ||
| 147 | + }] | ||
| 148 | + }) | ||
| 149 | + }, | ||
| 150 | + initChart() { | ||
| 151 | + this.chart = echarts.init(this.$el, 'macarons') | ||
| 152 | + this.setOptions(this.chartData) | ||
| 153 | + } | ||
| 154 | + } | ||
| 155 | +} | ||
| 156 | +</script> |
| 1 | +<template> | ||
| 2 | + <el-row :gutter="40" class="panel-group"> | ||
| 3 | + <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> | ||
| 4 | + <div class="card-panel" @click="handleSetLineChartData('newVisitis')"> | ||
| 5 | + <div class="card-panel-icon-wrapper icon-people"> | ||
| 6 | + <svg-icon icon-class="peoples" class-name="card-panel-icon" /> | ||
| 7 | + </div> | ||
| 8 | + <div class="card-panel-description"> | ||
| 9 | + <div class="card-panel-text">New Visits</div> | ||
| 10 | + <count-to :start-val="0" :end-val="102400" :duration="2600" class="card-panel-num"/> | ||
| 11 | + </div> | ||
| 12 | + </div> | ||
| 13 | + </el-col> | ||
| 14 | + <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> | ||
| 15 | + <div class="card-panel" @click="handleSetLineChartData('messages')"> | ||
| 16 | + <div class="card-panel-icon-wrapper icon-message"> | ||
| 17 | + <svg-icon icon-class="message" class-name="card-panel-icon" /> | ||
| 18 | + </div> | ||
| 19 | + <div class="card-panel-description"> | ||
| 20 | + <div class="card-panel-text">Messages</div> | ||
| 21 | + <count-to :start-val="0" :end-val="81212" :duration="3000" class="card-panel-num"/> | ||
| 22 | + </div> | ||
| 23 | + </div> | ||
| 24 | + </el-col> | ||
| 25 | + <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> | ||
| 26 | + <div class="card-panel" @click="handleSetLineChartData('purchases')"> | ||
| 27 | + <div class="card-panel-icon-wrapper icon-money"> | ||
| 28 | + <svg-icon icon-class="money" class-name="card-panel-icon" /> | ||
| 29 | + </div> | ||
| 30 | + <div class="card-panel-description"> | ||
| 31 | + <div class="card-panel-text">Purchases</div> | ||
| 32 | + <count-to :start-val="0" :end-val="9280" :duration="3200" class="card-panel-num"/> | ||
| 33 | + </div> | ||
| 34 | + </div> | ||
| 35 | + </el-col> | ||
| 36 | + <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> | ||
| 37 | + <div class="card-panel" @click="handleSetLineChartData('shoppings')"> | ||
| 38 | + <div class="card-panel-icon-wrapper icon-shopping"> | ||
| 39 | + <svg-icon icon-class="shopping" class-name="card-panel-icon" /> | ||
| 40 | + </div> | ||
| 41 | + <div class="card-panel-description"> | ||
| 42 | + <div class="card-panel-text">Shoppings</div> | ||
| 43 | + <count-to :start-val="0" :end-val="13600" :duration="3600" class="card-panel-num"/> | ||
| 44 | + </div> | ||
| 45 | + </div> | ||
| 46 | + </el-col> | ||
| 47 | + </el-row> | ||
| 48 | +</template> | ||
| 49 | + | ||
| 50 | +<script> | ||
| 51 | +import CountTo from 'vue-count-to' | ||
| 52 | + | ||
| 53 | +export default { | ||
| 54 | + components: { | ||
| 55 | + CountTo | ||
| 56 | + }, | ||
| 57 | + methods: { | ||
| 58 | + handleSetLineChartData(type) { | ||
| 59 | + this.$emit('handleSetLineChartData', type) | ||
| 60 | + } | ||
| 61 | + } | ||
| 62 | +} | ||
| 63 | +</script> | ||
| 64 | + | ||
| 65 | +<style rel="stylesheet/scss" lang="scss" scoped> | ||
| 66 | +.panel-group { | ||
| 67 | + margin-top: 18px; | ||
| 68 | + .card-panel-col{ | ||
| 69 | + margin-bottom: 32px; | ||
| 70 | + } | ||
| 71 | + .card-panel { | ||
| 72 | + height: 108px; | ||
| 73 | + cursor: pointer; | ||
| 74 | + font-size: 12px; | ||
| 75 | + position: relative; | ||
| 76 | + overflow: hidden; | ||
| 77 | + color: #666; | ||
| 78 | + background: #fff; | ||
| 79 | + box-shadow: 4px 4px 40px rgba(0, 0, 0, .05); | ||
| 80 | + border-color: rgba(0, 0, 0, .05); | ||
| 81 | + &:hover { | ||
| 82 | + .card-panel-icon-wrapper { | ||
| 83 | + color: #fff; | ||
| 84 | + } | ||
| 85 | + .icon-people { | ||
| 86 | + background: #40c9c6; | ||
| 87 | + } | ||
| 88 | + .icon-message { | ||
| 89 | + background: #36a3f7; | ||
| 90 | + } | ||
| 91 | + .icon-money { | ||
| 92 | + background: #f4516c; | ||
| 93 | + } | ||
| 94 | + .icon-shopping { | ||
| 95 | + background: #34bfa3 | ||
| 96 | + } | ||
| 97 | + } | ||
| 98 | + .icon-people { | ||
| 99 | + color: #40c9c6; | ||
| 100 | + } | ||
| 101 | + .icon-message { | ||
| 102 | + color: #36a3f7; | ||
| 103 | + } | ||
| 104 | + .icon-money { | ||
| 105 | + color: #f4516c; | ||
| 106 | + } | ||
| 107 | + .icon-shopping { | ||
| 108 | + color: #34bfa3 | ||
| 109 | + } | ||
| 110 | + .card-panel-icon-wrapper { | ||
| 111 | + float: left; | ||
| 112 | + margin: 14px 0 0 14px; | ||
| 113 | + padding: 16px; | ||
| 114 | + transition: all 0.38s ease-out; | ||
| 115 | + border-radius: 6px; | ||
| 116 | + } | ||
| 117 | + .card-panel-icon { | ||
| 118 | + float: left; | ||
| 119 | + font-size: 48px; | ||
| 120 | + } | ||
| 121 | + .card-panel-description { | ||
| 122 | + float: right; | ||
| 123 | + font-weight: bold; | ||
| 124 | + margin: 26px; | ||
| 125 | + margin-left: 0px; | ||
| 126 | + .card-panel-text { | ||
| 127 | + line-height: 18px; | ||
| 128 | + color: rgba(0, 0, 0, 0.45); | ||
| 129 | + font-size: 16px; | ||
| 130 | + margin-bottom: 12px; | ||
| 131 | + } | ||
| 132 | + .card-panel-num { | ||
| 133 | + font-size: 20px; | ||
| 134 | + } | ||
| 135 | + } | ||
| 136 | + } | ||
| 137 | +} | ||
| 138 | +</style> |
| 1 | +<template> | ||
| 2 | + <div :class="className" :style="{height:height,width:width}"/> | ||
| 3 | +</template> | ||
| 4 | + | ||
| 5 | +<script> | ||
| 6 | +import echarts from 'echarts' | ||
| 7 | +require('echarts/theme/macarons') // echarts theme | ||
| 8 | +import { debounce } from '@/utils' | ||
| 9 | + | ||
| 10 | +export default { | ||
| 11 | + props: { | ||
| 12 | + className: { | ||
| 13 | + type: String, | ||
| 14 | + default: 'chart' | ||
| 15 | + }, | ||
| 16 | + width: { | ||
| 17 | + type: String, | ||
| 18 | + default: '100%' | ||
| 19 | + }, | ||
| 20 | + height: { | ||
| 21 | + type: String, | ||
| 22 | + default: '300px' | ||
| 23 | + } | ||
| 24 | + }, | ||
| 25 | + data() { | ||
| 26 | + return { | ||
| 27 | + chart: null | ||
| 28 | + } | ||
| 29 | + }, | ||
| 30 | + mounted() { | ||
| 31 | + this.initChart() | ||
| 32 | + this.__resizeHandler = debounce(() => { | ||
| 33 | + if (this.chart) { | ||
| 34 | + this.chart.resize() | ||
| 35 | + } | ||
| 36 | + }, 100) | ||
| 37 | + window.addEventListener('resize', this.__resizeHandler) | ||
| 38 | + }, | ||
| 39 | + beforeDestroy() { | ||
| 40 | + if (!this.chart) { | ||
| 41 | + return | ||
| 42 | + } | ||
| 43 | + window.removeEventListener('resize', this.__resizeHandler) | ||
| 44 | + this.chart.dispose() | ||
| 45 | + this.chart = null | ||
| 46 | + }, | ||
| 47 | + methods: { | ||
| 48 | + initChart() { | ||
| 49 | + this.chart = echarts.init(this.$el, 'macarons') | ||
| 50 | + | ||
| 51 | + this.chart.setOption({ | ||
| 52 | + tooltip: { | ||
| 53 | + trigger: 'item', | ||
| 54 | + formatter: '{a} <br/>{b} : {c} ({d}%)' | ||
| 55 | + }, | ||
| 56 | + legend: { | ||
| 57 | + left: 'center', | ||
| 58 | + bottom: '10', | ||
| 59 | + data: ['Industries', 'Technology', 'Forex', 'Gold', 'Forecasts'] | ||
| 60 | + }, | ||
| 61 | + calculable: true, | ||
| 62 | + series: [ | ||
| 63 | + { | ||
| 64 | + name: 'WEEKLY WRITE ARTICLES', | ||
| 65 | + type: 'pie', | ||
| 66 | + roseType: 'radius', | ||
| 67 | + radius: [15, 95], | ||
| 68 | + center: ['50%', '38%'], | ||
| 69 | + data: [ | ||
| 70 | + { value: 320, name: 'Industries' }, | ||
| 71 | + { value: 240, name: 'Technology' }, | ||
| 72 | + { value: 149, name: 'Forex' }, | ||
| 73 | + { value: 100, name: 'Gold' }, | ||
| 74 | + { value: 59, name: 'Forecasts' } | ||
| 75 | + ], | ||
| 76 | + animationEasing: 'cubicInOut', | ||
| 77 | + animationDuration: 2600 | ||
| 78 | + } | ||
| 79 | + ] | ||
| 80 | + }) | ||
| 81 | + } | ||
| 82 | + } | ||
| 83 | +} | ||
| 84 | +</script> |
| 1 | +<template> | ||
| 2 | + <div :class="className" :style="{height:height,width:width}"/> | ||
| 3 | +</template> | ||
| 4 | + | ||
| 5 | +<script> | ||
| 6 | +import echarts from 'echarts' | ||
| 7 | +require('echarts/theme/macarons') // echarts theme | ||
| 8 | +import { debounce } from '@/utils' | ||
| 9 | + | ||
| 10 | +const animationDuration = 3000 | ||
| 11 | + | ||
| 12 | +export default { | ||
| 13 | + props: { | ||
| 14 | + className: { | ||
| 15 | + type: String, | ||
| 16 | + default: 'chart' | ||
| 17 | + }, | ||
| 18 | + width: { | ||
| 19 | + type: String, | ||
| 20 | + default: '100%' | ||
| 21 | + }, | ||
| 22 | + height: { | ||
| 23 | + type: String, | ||
| 24 | + default: '300px' | ||
| 25 | + } | ||
| 26 | + }, | ||
| 27 | + data() { | ||
| 28 | + return { | ||
| 29 | + chart: null | ||
| 30 | + } | ||
| 31 | + }, | ||
| 32 | + mounted() { | ||
| 33 | + this.initChart() | ||
| 34 | + this.__resizeHandler = debounce(() => { | ||
| 35 | + if (this.chart) { | ||
| 36 | + this.chart.resize() | ||
| 37 | + } | ||
| 38 | + }, 100) | ||
| 39 | + window.addEventListener('resize', this.__resizeHandler) | ||
| 40 | + }, | ||
| 41 | + beforeDestroy() { | ||
| 42 | + if (!this.chart) { | ||
| 43 | + return | ||
| 44 | + } | ||
| 45 | + window.removeEventListener('resize', this.__resizeHandler) | ||
| 46 | + this.chart.dispose() | ||
| 47 | + this.chart = null | ||
| 48 | + }, | ||
| 49 | + methods: { | ||
| 50 | + initChart() { | ||
| 51 | + this.chart = echarts.init(this.$el, 'macarons') | ||
| 52 | + | ||
| 53 | + this.chart.setOption({ | ||
| 54 | + tooltip: { | ||
| 55 | + trigger: 'axis', | ||
| 56 | + axisPointer: { // 坐标轴指示器,坐标轴触发有效 | ||
| 57 | + type: 'shadow' // 默认为直线,可选为:'line' | 'shadow' | ||
| 58 | + } | ||
| 59 | + }, | ||
| 60 | + radar: { | ||
| 61 | + radius: '66%', | ||
| 62 | + center: ['50%', '42%'], | ||
| 63 | + splitNumber: 8, | ||
| 64 | + splitArea: { | ||
| 65 | + areaStyle: { | ||
| 66 | + color: 'rgba(127,95,132,.3)', | ||
| 67 | + opacity: 1, | ||
| 68 | + shadowBlur: 45, | ||
| 69 | + shadowColor: 'rgba(0,0,0,.5)', | ||
| 70 | + shadowOffsetX: 0, | ||
| 71 | + shadowOffsetY: 15 | ||
| 72 | + } | ||
| 73 | + }, | ||
| 74 | + indicator: [ | ||
| 75 | + { name: 'Sales', max: 10000 }, | ||
| 76 | + { name: 'Administration', max: 20000 }, | ||
| 77 | + { name: 'Information Techology', max: 20000 }, | ||
| 78 | + { name: 'Customer Support', max: 20000 }, | ||
| 79 | + { name: 'Development', max: 20000 }, | ||
| 80 | + { name: 'Marketing', max: 20000 } | ||
| 81 | + ] | ||
| 82 | + }, | ||
| 83 | + legend: { | ||
| 84 | + left: 'center', | ||
| 85 | + bottom: '10', | ||
| 86 | + data: ['Allocated Budget', 'Expected Spending', 'Actual Spending'] | ||
| 87 | + }, | ||
| 88 | + series: [{ | ||
| 89 | + type: 'radar', | ||
| 90 | + symbolSize: 0, | ||
| 91 | + areaStyle: { | ||
| 92 | + normal: { | ||
| 93 | + shadowBlur: 13, | ||
| 94 | + shadowColor: 'rgba(0,0,0,.2)', | ||
| 95 | + shadowOffsetX: 0, | ||
| 96 | + shadowOffsetY: 10, | ||
| 97 | + opacity: 1 | ||
| 98 | + } | ||
| 99 | + }, | ||
| 100 | + data: [ | ||
| 101 | + { | ||
| 102 | + value: [5000, 7000, 12000, 11000, 15000, 14000], | ||
| 103 | + name: 'Allocated Budget' | ||
| 104 | + }, | ||
| 105 | + { | ||
| 106 | + value: [4000, 9000, 15000, 15000, 13000, 11000], | ||
| 107 | + name: 'Expected Spending' | ||
| 108 | + }, | ||
| 109 | + { | ||
| 110 | + value: [5500, 11000, 12000, 15000, 12000, 12000], | ||
| 111 | + name: 'Actual Spending' | ||
| 112 | + } | ||
| 113 | + ], | ||
| 114 | + animationDuration: animationDuration | ||
| 115 | + }] | ||
| 116 | + }) | ||
| 117 | + } | ||
| 118 | + } | ||
| 119 | +} | ||
| 120 | +</script> |
| 1 | +<template> | ||
| 2 | + <li :class="{ completed: todo.done, editing: editing }" class="todo"> | ||
| 3 | + <div class="view"> | ||
| 4 | + <input | ||
| 5 | + :checked="todo.done" | ||
| 6 | + class="toggle" | ||
| 7 | + type="checkbox" | ||
| 8 | + @change="toggleTodo( todo)"> | ||
| 9 | + <label @dblclick="editing = true" v-text="todo.text"/> | ||
| 10 | + <button class="destroy" @click="deleteTodo( todo )"/> | ||
| 11 | + </div> | ||
| 12 | + <input | ||
| 13 | + v-focus="editing" | ||
| 14 | + v-show="editing" | ||
| 15 | + :value="todo.text" | ||
| 16 | + class="edit" | ||
| 17 | + @keyup.enter="doneEdit" | ||
| 18 | + @keyup.esc="cancelEdit" | ||
| 19 | + @blur="doneEdit"> | ||
| 20 | + </li> | ||
| 21 | +</template> | ||
| 22 | + | ||
| 23 | +<script> | ||
| 24 | +export default { | ||
| 25 | + name: 'Todo', | ||
| 26 | + directives: { | ||
| 27 | + focus(el, { value }, { context }) { | ||
| 28 | + if (value) { | ||
| 29 | + context.$nextTick(() => { | ||
| 30 | + el.focus() | ||
| 31 | + }) | ||
| 32 | + } | ||
| 33 | + } | ||
| 34 | + }, | ||
| 35 | + props: { | ||
| 36 | + todo: { | ||
| 37 | + type: Object, | ||
| 38 | + default: function() { | ||
| 39 | + return {} | ||
| 40 | + } | ||
| 41 | + } | ||
| 42 | + }, | ||
| 43 | + data() { | ||
| 44 | + return { | ||
| 45 | + editing: false | ||
| 46 | + } | ||
| 47 | + }, | ||
| 48 | + methods: { | ||
| 49 | + deleteTodo(todo) { | ||
| 50 | + this.$emit('deleteTodo', todo) | ||
| 51 | + }, | ||
| 52 | + editTodo({ todo, value }) { | ||
| 53 | + this.$emit('editTodo', { todo, value }) | ||
| 54 | + }, | ||
| 55 | + toggleTodo(todo) { | ||
| 56 | + this.$emit('toggleTodo', todo) | ||
| 57 | + }, | ||
| 58 | + doneEdit(e) { | ||
| 59 | + const value = e.target.value.trim() | ||
| 60 | + const { todo } = this | ||
| 61 | + if (!value) { | ||
| 62 | + this.deleteTodo({ | ||
| 63 | + todo | ||
| 64 | + }) | ||
| 65 | + } else if (this.editing) { | ||
| 66 | + this.editTodo({ | ||
| 67 | + todo, | ||
| 68 | + value | ||
| 69 | + }) | ||
| 70 | + this.editing = false | ||
| 71 | + } | ||
| 72 | + }, | ||
| 73 | + cancelEdit(e) { | ||
| 74 | + e.target.value = this.todo.text | ||
| 75 | + this.editing = false | ||
| 76 | + } | ||
| 77 | + } | ||
| 78 | +} | ||
| 79 | +</script> |
| 1 | +.todoapp { | ||
| 2 | + font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif; | ||
| 3 | + line-height: 1.4em; | ||
| 4 | + color: #4d4d4d; | ||
| 5 | + min-width: 230px; | ||
| 6 | + max-width: 550px; | ||
| 7 | + margin: 0 auto ; | ||
| 8 | + -webkit-font-smoothing: antialiased; | ||
| 9 | + -moz-osx-font-smoothing: grayscale; | ||
| 10 | + font-weight: 300; | ||
| 11 | + background: #fff; | ||
| 12 | + z-index: 1; | ||
| 13 | + position: relative; | ||
| 14 | + button { | ||
| 15 | + margin: 0; | ||
| 16 | + padding: 0; | ||
| 17 | + border: 0; | ||
| 18 | + background: none; | ||
| 19 | + font-size: 100%; | ||
| 20 | + vertical-align: baseline; | ||
| 21 | + font-family: inherit; | ||
| 22 | + font-weight: inherit; | ||
| 23 | + color: inherit; | ||
| 24 | + -webkit-appearance: none; | ||
| 25 | + appearance: none; | ||
| 26 | + -webkit-font-smoothing: antialiased; | ||
| 27 | + -moz-osx-font-smoothing: grayscale; | ||
| 28 | + } | ||
| 29 | + :focus { | ||
| 30 | + outline: 0; | ||
| 31 | + } | ||
| 32 | + .hidden { | ||
| 33 | + display: none; | ||
| 34 | + } | ||
| 35 | + .todoapp { | ||
| 36 | + background: #fff; | ||
| 37 | + margin: 130px 0 40px 0; | ||
| 38 | + position: relative; | ||
| 39 | + box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1); | ||
| 40 | + } | ||
| 41 | + .todoapp input::-webkit-input-placeholder { | ||
| 42 | + font-style: italic; | ||
| 43 | + font-weight: 300; | ||
| 44 | + color: #e6e6e6; | ||
| 45 | + } | ||
| 46 | + .todoapp input::-moz-placeholder { | ||
| 47 | + font-style: italic; | ||
| 48 | + font-weight: 300; | ||
| 49 | + color: #e6e6e6; | ||
| 50 | + } | ||
| 51 | + .todoapp input::input-placeholder { | ||
| 52 | + font-style: italic; | ||
| 53 | + font-weight: 300; | ||
| 54 | + color: #e6e6e6; | ||
| 55 | + } | ||
| 56 | + .todoapp h1 { | ||
| 57 | + position: absolute; | ||
| 58 | + top: -155px; | ||
| 59 | + width: 100%; | ||
| 60 | + font-size: 100px; | ||
| 61 | + font-weight: 100; | ||
| 62 | + text-align: center; | ||
| 63 | + color: rgba(175, 47, 47, 0.15); | ||
| 64 | + -webkit-text-rendering: optimizeLegibility; | ||
| 65 | + -moz-text-rendering: optimizeLegibility; | ||
| 66 | + text-rendering: optimizeLegibility; | ||
| 67 | + } | ||
| 68 | + .new-todo, | ||
| 69 | + .edit { | ||
| 70 | + position: relative; | ||
| 71 | + margin: 0; | ||
| 72 | + width: 100%; | ||
| 73 | + font-size: 18px; | ||
| 74 | + font-family: inherit; | ||
| 75 | + font-weight: inherit; | ||
| 76 | + line-height: 1.4em; | ||
| 77 | + border: 0; | ||
| 78 | + color: inherit; | ||
| 79 | + padding: 6px; | ||
| 80 | + border: 1px solid #999; | ||
| 81 | + box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2); | ||
| 82 | + box-sizing: border-box; | ||
| 83 | + -webkit-font-smoothing: antialiased; | ||
| 84 | + -moz-osx-font-smoothing: grayscale; | ||
| 85 | + } | ||
| 86 | + .new-todo { | ||
| 87 | + padding: 10px 16px 16px 60px; | ||
| 88 | + border: none; | ||
| 89 | + background: rgba(0, 0, 0, 0.003); | ||
| 90 | + box-shadow: inset 0 -2px 1px rgba(0, 0, 0, 0.03); | ||
| 91 | + } | ||
| 92 | + .main { | ||
| 93 | + position: relative; | ||
| 94 | + z-index: 2; | ||
| 95 | + border-top: 1px solid #e6e6e6; | ||
| 96 | + } | ||
| 97 | + .toggle-all { | ||
| 98 | + text-align: center; | ||
| 99 | + border: none; | ||
| 100 | + /* Mobile Safari */ | ||
| 101 | + opacity: 0; | ||
| 102 | + position: absolute; | ||
| 103 | + } | ||
| 104 | + .toggle-all+label { | ||
| 105 | + width: 60px; | ||
| 106 | + height: 34px; | ||
| 107 | + font-size: 0; | ||
| 108 | + position: absolute; | ||
| 109 | + top: -52px; | ||
| 110 | + left: -13px; | ||
| 111 | + -webkit-transform: rotate(90deg); | ||
| 112 | + transform: rotate(90deg); | ||
| 113 | + } | ||
| 114 | + .toggle-all+label:before { | ||
| 115 | + content: '❯'; | ||
| 116 | + font-size: 22px; | ||
| 117 | + color: #e6e6e6; | ||
| 118 | + padding: 10px 27px 10px 27px; | ||
| 119 | + } | ||
| 120 | + .toggle-all:checked+label:before { | ||
| 121 | + color: #737373; | ||
| 122 | + } | ||
| 123 | + .todo-list { | ||
| 124 | + margin: 0; | ||
| 125 | + padding: 0; | ||
| 126 | + list-style: none; | ||
| 127 | + } | ||
| 128 | + .todo-list li { | ||
| 129 | + position: relative; | ||
| 130 | + font-size: 24px; | ||
| 131 | + border-bottom: 1px solid #ededed; | ||
| 132 | + } | ||
| 133 | + .todo-list li:last-child { | ||
| 134 | + border-bottom: none; | ||
| 135 | + } | ||
| 136 | + .todo-list li.editing { | ||
| 137 | + border-bottom: none; | ||
| 138 | + padding: 0; | ||
| 139 | + } | ||
| 140 | + .todo-list li.editing .edit { | ||
| 141 | + display: block; | ||
| 142 | + width: 506px; | ||
| 143 | + padding: 12px 16px; | ||
| 144 | + margin: 0 0 0 43px; | ||
| 145 | + } | ||
| 146 | + .todo-list li.editing .view { | ||
| 147 | + display: none; | ||
| 148 | + } | ||
| 149 | + .todo-list li .toggle { | ||
| 150 | + text-align: center; | ||
| 151 | + width: 40px; | ||
| 152 | + /* auto, since non-WebKit browsers doesn't support input styling */ | ||
| 153 | + height: auto; | ||
| 154 | + position: absolute; | ||
| 155 | + top: 0; | ||
| 156 | + bottom: 0; | ||
| 157 | + margin: auto 0; | ||
| 158 | + border: none; | ||
| 159 | + /* Mobile Safari */ | ||
| 160 | + -webkit-appearance: none; | ||
| 161 | + appearance: none; | ||
| 162 | + } | ||
| 163 | + .todo-list li .toggle { | ||
| 164 | + opacity: 0; | ||
| 165 | + } | ||
| 166 | + .todo-list li .toggle+label { | ||
| 167 | + /* | ||
| 168 | + Firefox requires `#` to be escaped - https://bugzilla.mozilla.org/show_bug.cgi?id=922433 | ||
| 169 | + IE and Edge requires *everything* to be escaped to render, so we do that instead of just the `#` - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7157459/ | ||
| 170 | + */ | ||
| 171 | + background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23ededed%22%20stroke-width%3D%223%22/%3E%3C/svg%3E'); | ||
| 172 | + background-repeat: no-repeat; | ||
| 173 | + background-position: center left; | ||
| 174 | + background-size: 36px; | ||
| 175 | + } | ||
| 176 | + .todo-list li .toggle:checked+label { | ||
| 177 | + background-size: 36px; | ||
| 178 | + background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23bddad5%22%20stroke-width%3D%223%22/%3E%3Cpath%20fill%3D%22%235dc2af%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22/%3E%3C/svg%3E'); | ||
| 179 | + } | ||
| 180 | + .todo-list li label { | ||
| 181 | + word-break: break-all; | ||
| 182 | + padding: 15px 15px 15px 50px; | ||
| 183 | + display: block; | ||
| 184 | + line-height: 1.0; | ||
| 185 | + font-size: 14px; | ||
| 186 | + transition: color 0.4s; | ||
| 187 | + } | ||
| 188 | + .todo-list li.completed label { | ||
| 189 | + color: #d9d9d9; | ||
| 190 | + text-decoration: line-through; | ||
| 191 | + } | ||
| 192 | + .todo-list li .destroy { | ||
| 193 | + display: none; | ||
| 194 | + position: absolute; | ||
| 195 | + top: 0; | ||
| 196 | + right: 10px; | ||
| 197 | + bottom: 0; | ||
| 198 | + width: 40px; | ||
| 199 | + height: 40px; | ||
| 200 | + margin: auto 0; | ||
| 201 | + font-size: 30px; | ||
| 202 | + color: #cc9a9a; | ||
| 203 | + transition: color 0.2s ease-out; | ||
| 204 | + cursor: pointer; | ||
| 205 | + } | ||
| 206 | + .todo-list li .destroy:hover { | ||
| 207 | + color: #af5b5e; | ||
| 208 | + } | ||
| 209 | + .todo-list li .destroy:after { | ||
| 210 | + content: '×'; | ||
| 211 | + } | ||
| 212 | + .todo-list li:hover .destroy { | ||
| 213 | + display: block; | ||
| 214 | + } | ||
| 215 | + .todo-list li .edit { | ||
| 216 | + display: none; | ||
| 217 | + } | ||
| 218 | + .todo-list li.editing:last-child { | ||
| 219 | + margin-bottom: -1px; | ||
| 220 | + } | ||
| 221 | + .footer { | ||
| 222 | + color: #777; | ||
| 223 | + position: relative; | ||
| 224 | + padding: 10px 15px; | ||
| 225 | + height: 40px; | ||
| 226 | + text-align: center; | ||
| 227 | + border-top: 1px solid #e6e6e6; | ||
| 228 | + } | ||
| 229 | + .footer:before { | ||
| 230 | + content: ''; | ||
| 231 | + position: absolute; | ||
| 232 | + right: 0; | ||
| 233 | + bottom: 0; | ||
| 234 | + left: 0; | ||
| 235 | + height: 40px; | ||
| 236 | + overflow: hidden; | ||
| 237 | + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 8px 0 -3px #f6f6f6, 0 9px 1px -3px rgba(0, 0, 0, 0.2), 0 16px 0 -6px #f6f6f6, 0 17px 2px -6px rgba(0, 0, 0, 0.2); | ||
| 238 | + } | ||
| 239 | + .todo-count { | ||
| 240 | + float: left; | ||
| 241 | + text-align: left; | ||
| 242 | + } | ||
| 243 | + .todo-count strong { | ||
| 244 | + font-weight: 300; | ||
| 245 | + } | ||
| 246 | + .filters { | ||
| 247 | + margin: 0; | ||
| 248 | + padding: 0; | ||
| 249 | + position: relative; | ||
| 250 | + z-index: 1; | ||
| 251 | + list-style: none; | ||
| 252 | + } | ||
| 253 | + .filters li { | ||
| 254 | + display: inline; | ||
| 255 | + } | ||
| 256 | + .filters li a { | ||
| 257 | + color: inherit; | ||
| 258 | + font-size: 12px; | ||
| 259 | + padding: 3px 7px; | ||
| 260 | + text-decoration: none; | ||
| 261 | + border: 1px solid transparent; | ||
| 262 | + border-radius: 3px; | ||
| 263 | + } | ||
| 264 | + .filters li a:hover { | ||
| 265 | + border-color: rgba(175, 47, 47, 0.1); | ||
| 266 | + } | ||
| 267 | + .filters li a.selected { | ||
| 268 | + border-color: rgba(175, 47, 47, 0.2); | ||
| 269 | + } | ||
| 270 | + .clear-completed, | ||
| 271 | + html .clear-completed:active { | ||
| 272 | + float: right; | ||
| 273 | + position: relative; | ||
| 274 | + line-height: 20px; | ||
| 275 | + text-decoration: none; | ||
| 276 | + cursor: pointer; | ||
| 277 | + } | ||
| 278 | + .clear-completed:hover { | ||
| 279 | + text-decoration: underline; | ||
| 280 | + } | ||
| 281 | + .info { | ||
| 282 | + margin: 65px auto 0; | ||
| 283 | + color: #bfbfbf; | ||
| 284 | + font-size: 10px; | ||
| 285 | + text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); | ||
| 286 | + text-align: center; | ||
| 287 | + } | ||
| 288 | + .info p { | ||
| 289 | + line-height: 1; | ||
| 290 | + } | ||
| 291 | + .info a { | ||
| 292 | + color: inherit; | ||
| 293 | + text-decoration: none; | ||
| 294 | + font-weight: 400; | ||
| 295 | + } | ||
| 296 | + .info a:hover { | ||
| 297 | + text-decoration: underline; | ||
| 298 | + } | ||
| 299 | + /* | ||
| 300 | + Hack to remove background from Mobile Safari. | ||
| 301 | + Can't use it globally since it destroys checkboxes in Firefox | ||
| 302 | +*/ | ||
| 303 | + @media screen and (-webkit-min-device-pixel-ratio:0) { | ||
| 304 | + .toggle-all, | ||
| 305 | + .todo-list li .toggle { | ||
| 306 | + background: none; | ||
| 307 | + } | ||
| 308 | + .todo-list li .toggle { | ||
| 309 | + height: 40px; | ||
| 310 | + } | ||
| 311 | + } | ||
| 312 | + @media (max-width: 430px) { | ||
| 313 | + .footer { | ||
| 314 | + height: 50px; | ||
| 315 | + } | ||
| 316 | + .filters { | ||
| 317 | + bottom: 10px; | ||
| 318 | + } | ||
| 319 | + } | ||
| 320 | +} |
| 1 | +<template> | ||
| 2 | + <section class="todoapp"> | ||
| 3 | + <!-- header --> | ||
| 4 | + <header class="header"> | ||
| 5 | + <input class="new-todo" autocomplete="off" placeholder="Todo List" @keyup.enter="addTodo"> | ||
| 6 | + </header> | ||
| 7 | + <!-- main section --> | ||
| 8 | + <section v-show="todos.length" class="main"> | ||
| 9 | + <input id="toggle-all" :checked="allChecked" class="toggle-all" type="checkbox" @change="toggleAll({ done: !allChecked })"> | ||
| 10 | + <label for="toggle-all"/> | ||
| 11 | + <ul class="todo-list"> | ||
| 12 | + <todo | ||
| 13 | + v-for="(todo, index) in filteredTodos" | ||
| 14 | + :key="index" | ||
| 15 | + :todo="todo" | ||
| 16 | + @toggleTodo="toggleTodo" | ||
| 17 | + @editTodo="editTodo" | ||
| 18 | + @deleteTodo="deleteTodo"/> | ||
| 19 | + </ul> | ||
| 20 | + </section> | ||
| 21 | + <!-- footer --> | ||
| 22 | + <footer v-show="todos.length" class="footer"> | ||
| 23 | + <span class="todo-count"> | ||
| 24 | + <strong>{{ remaining }}</strong> | ||
| 25 | + {{ remaining | pluralize('item') }} left | ||
| 26 | + </span> | ||
| 27 | + <ul class="filters"> | ||
| 28 | + <li v-for="(val, key) in filters" :key="key"> | ||
| 29 | + <a :class="{ selected: visibility === key }" @click.prevent="visibility = key">{{ key | capitalize }}</a> | ||
| 30 | + </li> | ||
| 31 | + </ul> | ||
| 32 | + <!-- <button class="clear-completed" v-show="todos.length > remaining" @click="clearCompleted"> | ||
| 33 | + Clear completed | ||
| 34 | + </button> --> | ||
| 35 | + </footer> | ||
| 36 | + </section> | ||
| 37 | +</template> | ||
| 38 | + | ||
| 39 | +<script> | ||
| 40 | +import Todo from './Todo.vue' | ||
| 41 | + | ||
| 42 | +const STORAGE_KEY = 'todos' | ||
| 43 | +const filters = { | ||
| 44 | + all: todos => todos, | ||
| 45 | + active: todos => todos.filter(todo => !todo.done), | ||
| 46 | + completed: todos => todos.filter(todo => todo.done) | ||
| 47 | +} | ||
| 48 | +const defalutList = [ | ||
| 49 | + { text: 'star this repository', done: false }, | ||
| 50 | + { text: 'fork this repository', done: false }, | ||
| 51 | + { text: 'follow author', done: false }, | ||
| 52 | + { text: 'vue-element-admin', done: true }, | ||
| 53 | + { text: 'vue', done: true }, | ||
| 54 | + { text: 'element-ui', done: true }, | ||
| 55 | + { text: 'axios', done: true }, | ||
| 56 | + { text: 'webpack', done: true } | ||
| 57 | +] | ||
| 58 | +export default { | ||
| 59 | + components: { Todo }, | ||
| 60 | + filters: { | ||
| 61 | + pluralize: (n, w) => n === 1 ? w : w + 's', | ||
| 62 | + capitalize: s => s.charAt(0).toUpperCase() + s.slice(1) | ||
| 63 | + }, | ||
| 64 | + data() { | ||
| 65 | + return { | ||
| 66 | + visibility: 'all', | ||
| 67 | + filters, | ||
| 68 | + // todos: JSON.parse(window.localStorage.getItem(STORAGE_KEY)) || defalutList | ||
| 69 | + todos: defalutList | ||
| 70 | + } | ||
| 71 | + }, | ||
| 72 | + computed: { | ||
| 73 | + allChecked() { | ||
| 74 | + return this.todos.every(todo => todo.done) | ||
| 75 | + }, | ||
| 76 | + filteredTodos() { | ||
| 77 | + return filters[this.visibility](this.todos) | ||
| 78 | + }, | ||
| 79 | + remaining() { | ||
| 80 | + return this.todos.filter(todo => !todo.done).length | ||
| 81 | + } | ||
| 82 | + }, | ||
| 83 | + methods: { | ||
| 84 | + setLocalStorage() { | ||
| 85 | + window.localStorage.setItem(STORAGE_KEY, JSON.stringify(this.todos)) | ||
| 86 | + }, | ||
| 87 | + addTodo(e) { | ||
| 88 | + const text = e.target.value | ||
| 89 | + if (text.trim()) { | ||
| 90 | + this.todos.push({ | ||
| 91 | + text, | ||
| 92 | + done: false | ||
| 93 | + }) | ||
| 94 | + this.setLocalStorage() | ||
| 95 | + } | ||
| 96 | + e.target.value = '' | ||
| 97 | + }, | ||
| 98 | + toggleTodo(val) { | ||
| 99 | + val.done = !val.done | ||
| 100 | + this.setLocalStorage() | ||
| 101 | + }, | ||
| 102 | + deleteTodo(todo) { | ||
| 103 | + this.todos.splice(this.todos.indexOf(todo), 1) | ||
| 104 | + this.setLocalStorage() | ||
| 105 | + }, | ||
| 106 | + editTodo({ todo, value }) { | ||
| 107 | + todo.text = value | ||
| 108 | + this.setLocalStorage() | ||
| 109 | + }, | ||
| 110 | + clearCompleted() { | ||
| 111 | + this.todos = this.todos.filter(todo => !todo.done) | ||
| 112 | + this.setLocalStorage() | ||
| 113 | + }, | ||
| 114 | + toggleAll({ done }) { | ||
| 115 | + this.todos.forEach(todo => { | ||
| 116 | + todo.done = done | ||
| 117 | + this.setLocalStorage() | ||
| 118 | + }) | ||
| 119 | + } | ||
| 120 | + } | ||
| 121 | +} | ||
| 122 | +</script> | ||
| 123 | + | ||
| 124 | +<style lang="scss"> | ||
| 125 | + @import './index.scss'; | ||
| 126 | +</style> |
| 1 | +<template> | ||
| 2 | + <el-table :data="list" style="width: 100%;padding-top: 15px;"> | ||
| 3 | + <el-table-column label="Order_No" min-width="200"> | ||
| 4 | + <template slot-scope="scope"> | ||
| 5 | + {{ scope.row.order_no | orderNoFilter }} | ||
| 6 | + </template> | ||
| 7 | + </el-table-column> | ||
| 8 | + <el-table-column label="Price" width="195" align="center"> | ||
| 9 | + <template slot-scope="scope"> | ||
| 10 | + ¥{{ scope.row.price | toThousandFilter }} | ||
| 11 | + </template> | ||
| 12 | + </el-table-column> | ||
| 13 | + <el-table-column label="Status" width="100" align="center"> | ||
| 14 | + <template slot-scope="scope"> | ||
| 15 | + <el-tag :type="scope.row.status | statusFilter"> {{ scope.row.status }}</el-tag> | ||
| 16 | + </template> | ||
| 17 | + </el-table-column> | ||
| 18 | + </el-table> | ||
| 19 | +</template> | ||
| 20 | + | ||
| 21 | +<script> | ||
| 22 | +import { fetchList } from '@/api/transaction' | ||
| 23 | + | ||
| 24 | +export default { | ||
| 25 | + filters: { | ||
| 26 | + statusFilter(status) { | ||
| 27 | + const statusMap = { | ||
| 28 | + success: 'success', | ||
| 29 | + pending: 'danger' | ||
| 30 | + } | ||
| 31 | + return statusMap[status] | ||
| 32 | + }, | ||
| 33 | + orderNoFilter(str) { | ||
| 34 | + return str.substring(0, 30) | ||
| 35 | + } | ||
| 36 | + }, | ||
| 37 | + data() { | ||
| 38 | + return { | ||
| 39 | + list: null | ||
| 40 | + } | ||
| 41 | + }, | ||
| 42 | + created() { | ||
| 43 | + this.fetchData() | ||
| 44 | + }, | ||
| 45 | + methods: { | ||
| 46 | + fetchData() { | ||
| 47 | + fetchList().then(response => { | ||
| 48 | + this.list = response.data.items.slice(0, 8) | ||
| 49 | + }) | ||
| 50 | + } | ||
| 51 | + } | ||
| 52 | +} | ||
| 53 | +</script> |
src/views/dashboard/admin/index.vue
0 → 100755
| 1 | +<template> | ||
| 2 | + <div class="dashboard-editor-container"> | ||
| 3 | + | ||
| 4 | + <panel-group @handleSetLineChartData="handleSetLineChartData"/> | ||
| 5 | + | ||
| 6 | + <el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;"> | ||
| 7 | + <line-chart :chart-data="lineChartData"/> | ||
| 8 | + </el-row> | ||
| 9 | + | ||
| 10 | + <el-row :gutter="32"> | ||
| 11 | + <el-col :xs="24" :sm="24" :lg="8"> | ||
| 12 | + <div class="chart-wrapper"> | ||
| 13 | + <raddar-chart/> | ||
| 14 | + </div> | ||
| 15 | + </el-col> | ||
| 16 | + <el-col :xs="24" :sm="24" :lg="8"> | ||
| 17 | + <div class="chart-wrapper"> | ||
| 18 | + <pie-chart/> | ||
| 19 | + </div> | ||
| 20 | + </el-col> | ||
| 21 | + <el-col :xs="24" :sm="24" :lg="8"> | ||
| 22 | + <div class="chart-wrapper"> | ||
| 23 | + <bar-chart/> | ||
| 24 | + </div> | ||
| 25 | + </el-col> | ||
| 26 | + </el-row> | ||
| 27 | + | ||
| 28 | + <el-row :gutter="8"> | ||
| 29 | + <el-col :xs="{span: 24}" :sm="{span: 24}" :md="{span: 24}" :lg="{span: 12}" :xl="{span: 12}" style="padding-right:8px;margin-bottom:30px;"> | ||
| 30 | + <transaction-table/> | ||
| 31 | + </el-col> | ||
| 32 | + <el-col :xs="{span: 24}" :sm="{span: 12}" :md="{span: 12}" :lg="{span: 6}" :xl="{span: 6}" style="margin-bottom:30px;"> | ||
| 33 | + <todo-list/> | ||
| 34 | + </el-col> | ||
| 35 | + <el-col :xs="{span: 24}" :sm="{span: 12}" :md="{span: 12}" :lg="{span: 6}" :xl="{span: 6}" style="margin-bottom:30px;"> | ||
| 36 | + <box-card/> | ||
| 37 | + </el-col> | ||
| 38 | + </el-row> | ||
| 39 | + | ||
| 40 | + </div> | ||
| 41 | +</template> | ||
| 42 | + | ||
| 43 | +<script> | ||
| 44 | +import PanelGroup from './components/PanelGroup' | ||
| 45 | +import LineChart from './components/LineChart' | ||
| 46 | +import RaddarChart from './components/RaddarChart' | ||
| 47 | +import PieChart from './components/PieChart' | ||
| 48 | +import BarChart from './components/BarChart' | ||
| 49 | +import TransactionTable from './components/TransactionTable' | ||
| 50 | +import TodoList from './components/TodoList' | ||
| 51 | +import BoxCard from './components/BoxCard' | ||
| 52 | + | ||
| 53 | +const lineChartData = { | ||
| 54 | + newVisitis: { | ||
| 55 | + expectedData: [100, 120, 161, 134, 105, 160, 165], | ||
| 56 | + actualData: [120, 82, 91, 154, 162, 140, 145] | ||
| 57 | + }, | ||
| 58 | + messages: { | ||
| 59 | + expectedData: [200, 192, 120, 144, 160, 130, 140], | ||
| 60 | + actualData: [180, 160, 151, 106, 145, 150, 130] | ||
| 61 | + }, | ||
| 62 | + purchases: { | ||
| 63 | + expectedData: [80, 100, 121, 104, 105, 90, 100], | ||
| 64 | + actualData: [120, 90, 100, 138, 142, 130, 130] | ||
| 65 | + }, | ||
| 66 | + shoppings: { | ||
| 67 | + expectedData: [130, 140, 141, 142, 145, 150, 160], | ||
| 68 | + actualData: [120, 82, 91, 154, 162, 140, 130] | ||
| 69 | + } | ||
| 70 | +} | ||
| 71 | + | ||
| 72 | +export default { | ||
| 73 | + name: 'DashboardAdmin', | ||
| 74 | + components: { | ||
| 75 | + GithubCorner, | ||
| 76 | + PanelGroup, | ||
| 77 | + LineChart, | ||
| 78 | + RaddarChart, | ||
| 79 | + PieChart, | ||
| 80 | + BarChart, | ||
| 81 | + TransactionTable, | ||
| 82 | + TodoList, | ||
| 83 | + BoxCard | ||
| 84 | + }, | ||
| 85 | + data() { | ||
| 86 | + return { | ||
| 87 | + lineChartData: lineChartData.newVisitis | ||
| 88 | + } | ||
| 89 | + }, | ||
| 90 | + methods: { | ||
| 91 | + handleSetLineChartData(type) { | ||
| 92 | + this.lineChartData = lineChartData[type] | ||
| 93 | + } | ||
| 94 | + } | ||
| 95 | +} | ||
| 96 | +</script> | ||
| 97 | + | ||
| 98 | +<style rel="stylesheet/scss" lang="scss" scoped> | ||
| 99 | +.dashboard-editor-container { | ||
| 100 | + padding: 32px; | ||
| 101 | + background-color: rgb(240, 242, 245); | ||
| 102 | + .chart-wrapper { | ||
| 103 | + background: #fff; | ||
| 104 | + padding: 16px 16px 0; | ||
| 105 | + margin-bottom: 32px; | ||
| 106 | + } | ||
| 107 | +} | ||
| 108 | +</style> |
src/views/dashboard/editor/index.vue
0 → 100755
| 1 | +<template> | ||
| 2 | + <div class="dashboard-editor-container"> | ||
| 3 | + <div class=" clearfix"> | ||
| 4 | + <pan-thumb :image="avatar" style="float: left"> Your roles: | ||
| 5 | + <span v-for="item in roles" :key="item" class="pan-info-roles">{{ item }}</span> | ||
| 6 | + </pan-thumb> | ||
| 7 | + <github-corner style="position: absolute; top: 0px; border: 0; right: 0;"/> | ||
| 8 | + <div class="info-container"> | ||
| 9 | + <span class="display_name">{{ name }}</span> | ||
| 10 | + <span style="font-size:20px;padding-top:20px;display:inline-block;">Editor's Dashboard</span> | ||
| 11 | + </div> | ||
| 12 | + </div> | ||
| 13 | + <div> | ||
| 14 | + <img :src="emptyGif" class="emptyGif"> | ||
| 15 | + </div> | ||
| 16 | + </div> | ||
| 17 | +</template> | ||
| 18 | + | ||
| 19 | +<script> | ||
| 20 | +import { mapGetters } from 'vuex' | ||
| 21 | +import PanThumb from '@/components/PanThumb' | ||
| 22 | +import GithubCorner from '@/components/GithubCorner' | ||
| 23 | + | ||
| 24 | +export default { | ||
| 25 | + name: 'DashboardEditor', | ||
| 26 | + components: { PanThumb, GithubCorner }, | ||
| 27 | + data() { | ||
| 28 | + return { | ||
| 29 | + emptyGif: 'https://wpimg.wallstcn.com/0e03b7da-db9e-4819-ba10-9016ddfdaed3' | ||
| 30 | + } | ||
| 31 | + }, | ||
| 32 | + computed: { | ||
| 33 | + ...mapGetters([ | ||
| 34 | + 'name', | ||
| 35 | + 'avatar', | ||
| 36 | + 'roles' | ||
| 37 | + ]) | ||
| 38 | + } | ||
| 39 | +} | ||
| 40 | +</script> | ||
| 41 | + | ||
| 42 | +<style rel="stylesheet/scss" lang="scss" scoped> | ||
| 43 | + .emptyGif { | ||
| 44 | + display: block; | ||
| 45 | + width: 45%; | ||
| 46 | + margin: 0 auto; | ||
| 47 | + } | ||
| 48 | + | ||
| 49 | + .dashboard-editor-container { | ||
| 50 | + background-color: #e3e3e3; | ||
| 51 | + min-height: 100vh; | ||
| 52 | + padding: 50px 60px 0px; | ||
| 53 | + .pan-info-roles { | ||
| 54 | + font-size: 12px; | ||
| 55 | + font-weight: 700; | ||
| 56 | + color: #333; | ||
| 57 | + display: block; | ||
| 58 | + } | ||
| 59 | + .info-container { | ||
| 60 | + position: relative; | ||
| 61 | + margin-left: 190px; | ||
| 62 | + height: 150px; | ||
| 63 | + line-height: 200px; | ||
| 64 | + .display_name { | ||
| 65 | + font-size: 48px; | ||
| 66 | + line-height: 48px; | ||
| 67 | + color: #212121; | ||
| 68 | + position: absolute; | ||
| 69 | + top: 25px; | ||
| 70 | + } | ||
| 71 | + } | ||
| 72 | + } | ||
| 73 | +</style> |
src/views/dashboard/index.vue
0 → 100755
| 1 | +<template> | ||
| 2 | + <div class="dashboard-container"> | ||
| 3 | + <component :is="currentRole"/> | ||
| 4 | + </div> | ||
| 5 | +</template> | ||
| 6 | + | ||
| 7 | +<script> | ||
| 8 | +import { mapGetters } from 'vuex' | ||
| 9 | +import adminDashboard from './admin' | ||
| 10 | +import editorDashboard from './editor' | ||
| 11 | + | ||
| 12 | +export default { | ||
| 13 | + name: 'Dashboard', | ||
| 14 | + components: { adminDashboard, editorDashboard }, | ||
| 15 | + data() { | ||
| 16 | + return { | ||
| 17 | + currentRole: 'adminDashboard' | ||
| 18 | + } | ||
| 19 | + }, | ||
| 20 | + computed: { | ||
| 21 | + ...mapGetters([ | ||
| 22 | + 'roles' | ||
| 23 | + ]) | ||
| 24 | + }, | ||
| 25 | + created() { | ||
| 26 | + if (!this.roles.includes('admin')) { | ||
| 27 | + this.currentRole = 'editorDashboard' | ||
| 28 | + } | ||
| 29 | + } | ||
| 30 | +} | ||
| 31 | +</script> |
| @@ -15,6 +15,9 @@ | @@ -15,6 +15,9 @@ | ||
| 15 | ></el-date-picker> | 15 | ></el-date-picker> |
| 16 | </el-form-item> | 16 | </el-form-item> |
| 17 | <el-form-item> | 17 | <el-form-item> |
| 18 | + <el-input v-model="searchText.flightno" placeholder="航班号" ></el-input> | ||
| 19 | + </el-form-item> | ||
| 20 | + <el-form-item> | ||
| 18 | <el-button :loading="listLoading" style="margin:0 0 20px 20px;" type="primary" icon="document" @click="fetchData">查询</el-button> | 21 | <el-button :loading="listLoading" style="margin:0 0 20px 20px;" type="primary" icon="document" @click="fetchData">查询</el-button> |
| 19 | </el-form-item> | 22 | </el-form-item> |
| 20 | <el-tag | 23 | <el-tag |
| @@ -85,7 +88,8 @@ export default { | @@ -85,7 +88,8 @@ export default { | ||
| 85 | bookType: 'xlsx', | 88 | bookType: 'xlsx', |
| 86 | searchText: { | 89 | searchText: { |
| 87 | startdate: undefined, | 90 | startdate: undefined, |
| 88 | - enddate: undefined | 91 | + enddate: undefined, |
| 92 | + flightno: undefined | ||
| 89 | }, | 93 | }, |
| 90 | note: { | 94 | note: { |
| 91 | type: 'info', | 95 | type: 'info', |
| @@ -181,7 +185,7 @@ export default { | @@ -181,7 +185,7 @@ export default { | ||
| 181 | }, | 185 | }, |
| 182 | formatJson(filterVal, jsonData) { | 186 | formatJson(filterVal, jsonData) { |
| 183 | return jsonData.map(v => filterVal.map(j => { | 187 | return jsonData.map(v => filterVal.map(j => { |
| 184 | - if (j === 'timestamp') { | 188 | + if (j === 'timeamp') { |
| 185 | return parseTime(v[j]) | 189 | return parseTime(v[j]) |
| 186 | } else { | 190 | } else { |
| 187 | return v[j] | 191 | return v[j] |
-
请 注册 或 登录 后发表评论