Commit 398cda401f1a6df9900737efbdd62ea1b3450755
1 parent
a86b16bba6
Exists in
master
auto commit the code by alias command
Showing
30 changed files
with
1837 additions
and
1392 deletions
Show diff stats
src/components/BarChart/index.vue
| File was created | 1 | <template> | |
| 2 | <div | ||
| 3 | :class="className" | ||
| 4 | :style="{height:height,width:width}" | ||
| 5 | /> | ||
| 6 | </template> | ||
| 7 | |||
| 8 | <script> | ||
| 9 | import echarts from 'echarts' | ||
| 10 | require('echarts/theme/macarons') // echarts theme | ||
| 11 | import resize from '@/components/mixins/resize' | ||
| 12 | |||
| 13 | const animationDuration = 6000 | ||
| 14 | |||
| 15 | export default { | ||
| 16 | mixins: [resize], | ||
| 17 | props: { | ||
| 18 | className: { | ||
| 19 | type: String, | ||
| 20 | default: 'chart' | ||
| 21 | }, | ||
| 22 | width: { | ||
| 23 | type: String, | ||
| 24 | default: '100%' | ||
| 25 | }, | ||
| 26 | height: { | ||
| 27 | type: String, | ||
| 28 | default: '300px' | ||
| 29 | } | ||
| 30 | }, | ||
| 31 | data() { | ||
| 32 | return { | ||
| 33 | chart: null | ||
| 34 | } | ||
| 35 | }, | ||
| 36 | mounted() { | ||
| 37 | this.$nextTick(() => { | ||
| 38 | this.initChart() | ||
| 39 | }) | ||
| 40 | }, | ||
| 41 | beforeDestroy() { | ||
| 42 | if (!this.chart) { | ||
| 43 | return | ||
| 44 | } | ||
| 45 | this.chart.dispose() | ||
| 46 | this.chart = null | ||
| 47 | }, | ||
| 48 | methods: { | ||
| 49 | initChart() { | ||
| 50 | this.chart = echarts.init(this.$el, 'macarons') | ||
| 51 | |||
| 52 | this.chart.setOption({ | ||
| 53 | tooltip: { | ||
| 54 | trigger: 'axis', | ||
| 55 | axisPointer: { | ||
| 56 | // 坐标轴指示器,坐标轴触发有效 | ||
| 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 | { | ||
| 69 | type: 'category', | ||
| 70 | data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], | ||
| 71 | axisTick: { | ||
| 72 | alignWithLabel: true | ||
| 73 | } | ||
| 74 | } | ||
| 75 | ], | ||
| 76 | yAxis: [ | ||
| 77 | { | ||
| 78 | type: 'value', | ||
| 79 | axisTick: { | ||
| 80 | show: false | ||
| 81 | } | ||
| 82 | } | ||
| 83 | ], | ||
| 84 | series: [ | ||
| 85 | { | ||
| 86 | name: 'pageA', | ||
| 87 | type: 'bar', | ||
| 88 | stack: 'vistors', | ||
| 89 | barWidth: '60%', | ||
| 90 | data: [79, 52, 200, 334, 390, 330, 220], | ||
| 91 | animationDuration | ||
| 92 | }, | ||
| 93 | { | ||
| 94 | name: 'pageB', | ||
| 95 | type: 'bar', | ||
| 96 | stack: 'vistors', | ||
| 97 | barWidth: '60%', | ||
| 98 | data: [80, 52, 200, 334, 390, 330, 220], | ||
| 99 | animationDuration | ||
| 100 | }, | ||
| 101 | { | ||
| 102 | name: 'pageC', | ||
| 103 | type: 'bar', | ||
| 104 | stack: 'vistors', | ||
| 105 | barWidth: '60%', | ||
| 106 | data: [30, 52, 200, 334, 390, 330, 220], | ||
| 107 | animationDuration | ||
| 108 | } | ||
| 109 | ] | ||
| 110 | }) | ||
| 111 | } | ||
| 112 | } | ||
| 113 | } | ||
| 114 | </script> | ||
| 115 |
src/components/BoxCard/index.vue
| File was created | 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 | // import logoPath from "~@/assets/img/yp_logo.jpeg" | ||
| 34 | |||
| 35 | export default { | ||
| 36 | components: { PanThumb, Mallki }, | ||
| 37 | |||
| 38 | filters: { | ||
| 39 | statusFilter(status) { | ||
| 40 | const statusMap = { | ||
| 41 | success: 'success', | ||
| 42 | pending: 'danger' | ||
| 43 | } | ||
| 44 | return statusMap[status] | ||
| 45 | } | ||
| 46 | }, | ||
| 47 | data() { | ||
| 48 | return { | ||
| 49 | statisticsData: { | ||
| 50 | article_count: 1024, | ||
| 51 | pageviews_count: 1024 | ||
| 52 | } | ||
| 53 | } | ||
| 54 | }, | ||
| 55 | computed: { | ||
| 56 | ...mapGetters([ | ||
| 57 | 'name', | ||
| 58 | 'avatar', | ||
| 59 | 'roles' | ||
| 60 | ]) | ||
| 61 | } | ||
| 62 | } | ||
| 63 | </script> | ||
| 64 | |||
| 65 | <style lang="scss" > | ||
| 66 | .box-card-component{ | ||
| 67 | .el-card__header { | ||
| 68 | padding: 0px!important; | ||
| 69 | } | ||
| 70 | } | ||
| 71 | </style> | ||
| 72 | <style lang="scss" scoped> | ||
| 73 | .box-card-component { | ||
| 74 | .box-card-header { | ||
| 75 | position: relative; | ||
| 76 | height: 220px; | ||
| 77 | img { | ||
| 78 | width: 100%; | ||
| 79 | height: 100%; | ||
| 80 | transition: all 0.2s linear; | ||
| 81 | &:hover { | ||
| 82 | transform: scale(1.1, 1.1); | ||
| 83 | filter: contrast(130%); | ||
| 84 | } | ||
| 85 | } | ||
| 86 | } | ||
| 87 | .mallki-text { | ||
| 88 | position: absolute; | ||
| 89 | top: 0px; | ||
| 90 | right: 0px; | ||
| 91 | font-size: 20px; | ||
| 92 | font-weight: bold; | ||
| 93 | } | ||
| 94 | .panThumb { | ||
| 95 | z-index: 100; | ||
| 96 | height: 70px!important; | ||
| 97 | width: 70px!important; | ||
| 98 | position: absolute!important; | ||
| 99 | top: -45px; | ||
| 100 | left: 0px; | ||
| 101 | border: 5px solid #ffffff; | ||
| 102 | background-color: #fff; | ||
| 103 | margin: auto; | ||
| 104 | box-shadow: none!important; | ||
| 105 | /deep/ .pan-info { | ||
| 106 | box-shadow: none!important; | ||
| 107 | } | ||
| 108 | } | ||
| 109 | .progress-item { | ||
| 110 | margin-bottom: 10px; | ||
| 111 | font-size: 14px; | ||
| 112 | } | ||
| 113 | @media only screen and (max-width: 1510px){ | ||
| 114 | .mallki-text{ | ||
| 115 | display: none; | ||
| 116 | } | ||
| 117 | } | ||
| 118 | } | ||
| 119 | </style> | ||
| 120 |
src/components/LineChart/index.vue
| File was created | 1 | <template> | |
| 2 | <div | ||
| 3 | :class="className" | ||
| 4 | :style="{height:height,width:width}" | ||
| 5 | /> | ||
| 6 | </template> | ||
| 7 | |||
| 8 | <script> | ||
| 9 | import echarts from 'echarts' | ||
| 10 | require('echarts/theme/macarons') // echarts theme | ||
| 11 | import resize from '@/components/mixins/resize' | ||
| 12 | |||
| 13 | export default { | ||
| 14 | mixins: [resize], | ||
| 15 | props: { | ||
| 16 | className: { | ||
| 17 | type: String, | ||
| 18 | default: 'chart' | ||
| 19 | }, | ||
| 20 | width: { | ||
| 21 | type: String, | ||
| 22 | default: '100%' | ||
| 23 | }, | ||
| 24 | height: { | ||
| 25 | type: String, | ||
| 26 | default: '350px' | ||
| 27 | }, | ||
| 28 | autoResize: { | ||
| 29 | type: Boolean, | ||
| 30 | default: true | ||
| 31 | }, | ||
| 32 | chartData: { | ||
| 33 | type: Object, | ||
| 34 | required: true | ||
| 35 | } | ||
| 36 | }, | ||
| 37 | data() { | ||
| 38 | return { | ||
| 39 | chart: null | ||
| 40 | } | ||
| 41 | }, | ||
| 42 | watch: { | ||
| 43 | chartData: { | ||
| 44 | deep: true, | ||
| 45 | handler(val) { | ||
| 46 | this.setOptions(val) | ||
| 47 | } | ||
| 48 | } | ||
| 49 | }, | ||
| 50 | mounted() { | ||
| 51 | this.$nextTick(() => { | ||
| 52 | this.initChart() | ||
| 53 | }) | ||
| 54 | }, | ||
| 55 | beforeDestroy() { | ||
| 56 | if (!this.chart) { | ||
| 57 | return | ||
| 58 | } | ||
| 59 | this.chart.dispose() | ||
| 60 | this.chart = null | ||
| 61 | }, | ||
| 62 | methods: { | ||
| 63 | initChart() { | ||
| 64 | this.chart = echarts.init(this.$el, 'macarons') | ||
| 65 | this.setOptions(this.chartData) | ||
| 66 | }, | ||
| 67 | setOptions({ expectedData, actualData } = {}) { | ||
| 68 | this.chart.setOption({ | ||
| 69 | xAxis: { | ||
| 70 | data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], | ||
| 71 | boundaryGap: false, | ||
| 72 | axisTick: { | ||
| 73 | show: false | ||
| 74 | } | ||
| 75 | }, | ||
| 76 | grid: { | ||
| 77 | left: 10, | ||
| 78 | right: 10, | ||
| 79 | bottom: 20, | ||
| 80 | top: 30, | ||
| 81 | containLabel: true | ||
| 82 | }, | ||
| 83 | tooltip: { | ||
| 84 | trigger: 'axis', | ||
| 85 | axisPointer: { | ||
| 86 | type: 'cross' | ||
| 87 | }, | ||
| 88 | padding: [5, 10] | ||
| 89 | }, | ||
| 90 | yAxis: { | ||
| 91 | axisTick: { | ||
| 92 | show: false | ||
| 93 | } | ||
| 94 | }, | ||
| 95 | legend: { | ||
| 96 | data: ['expected', 'actual'] | ||
| 97 | }, | ||
| 98 | series: [ | ||
| 99 | { | ||
| 100 | name: 'expected', | ||
| 101 | itemStyle: { | ||
| 102 | normal: { | ||
| 103 | color: '#FF005A', | ||
| 104 | lineStyle: { | ||
| 105 | color: '#FF005A', | ||
| 106 | width: 2 | ||
| 107 | } | ||
| 108 | } | ||
| 109 | }, | ||
| 110 | smooth: true, | ||
| 111 | type: 'line', | ||
| 112 | data: expectedData, | ||
| 113 | animationDuration: 2800, | ||
| 114 | animationEasing: 'cubicInOut' | ||
| 115 | }, | ||
| 116 | { | ||
| 117 | name: 'actual', | ||
| 118 | smooth: true, | ||
| 119 | type: 'line', | ||
| 120 | itemStyle: { | ||
| 121 | normal: { | ||
| 122 | color: '#3888fa', | ||
| 123 | lineStyle: { | ||
| 124 | color: '#3888fa', | ||
| 125 | width: 2 | ||
| 126 | }, | ||
| 127 | areaStyle: { | ||
| 128 | color: '#f3f8ff' | ||
| 129 | } | ||
| 130 | } | ||
| 131 | }, | ||
| 132 | data: actualData, | ||
| 133 | animationDuration: 2800, | ||
| 134 | animationEasing: 'quadraticOut' | ||
| 135 | } | ||
| 136 | ] | ||
| 137 | }) | ||
| 138 | } | ||
| 139 | } | ||
| 140 | } | ||
| 141 | </script> | ||
| 142 |
src/components/PanelGroup/index.vue
| File was created | 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"> | ||
| 10 | New Visits | ||
| 11 | </div> | ||
| 12 | <count-to :start-val="0" :end-val="102400" :duration="2600" class="card-panel-num" /> | ||
| 13 | </div> | ||
| 14 | </div> | ||
| 15 | </el-col> | ||
| 16 | <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> | ||
| 17 | <div class="card-panel" @click="handleSetLineChartData('messages')"> | ||
| 18 | <div class="card-panel-icon-wrapper icon-message"> | ||
| 19 | <svg-icon icon-class="message" class-name="card-panel-icon" /> | ||
| 20 | </div> | ||
| 21 | <div class="card-panel-description"> | ||
| 22 | <div class="card-panel-text"> | ||
| 23 | Messages | ||
| 24 | </div> | ||
| 25 | <count-to :start-val="0" :end-val="81212" :duration="3000" class="card-panel-num" /> | ||
| 26 | </div> | ||
| 27 | </div> | ||
| 28 | </el-col> | ||
| 29 | <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> | ||
| 30 | <div class="card-panel" @click="handleSetLineChartData('purchases')"> | ||
| 31 | <div class="card-panel-icon-wrapper icon-money"> | ||
| 32 | <svg-icon icon-class="money" class-name="card-panel-icon" /> | ||
| 33 | </div> | ||
| 34 | <div class="card-panel-description"> | ||
| 35 | <div class="card-panel-text"> | ||
| 36 | Purchases | ||
| 37 | </div> | ||
| 38 | <count-to :start-val="0" :end-val="9280" :duration="3200" class="card-panel-num" /> | ||
| 39 | </div> | ||
| 40 | </div> | ||
| 41 | </el-col> | ||
| 42 | <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> | ||
| 43 | <div class="card-panel" @click="handleSetLineChartData('shoppings')"> | ||
| 44 | <div class="card-panel-icon-wrapper icon-shopping"> | ||
| 45 | <svg-icon icon-class="shopping" class-name="card-panel-icon" /> | ||
| 46 | </div> | ||
| 47 | <div class="card-panel-description"> | ||
| 48 | <div class="card-panel-text"> | ||
| 49 | Shoppings | ||
| 50 | </div> | ||
| 51 | <count-to :start-val="0" :end-val="13600" :duration="3600" class="card-panel-num" /> | ||
| 52 | </div> | ||
| 53 | </div> | ||
| 54 | </el-col> | ||
| 55 | </el-row> | ||
| 56 | </template> | ||
| 57 | |||
| 58 | <script> | ||
| 59 | import CountTo from 'vue-count-to' | ||
| 60 | |||
| 61 | export default { | ||
| 62 | components: { | ||
| 63 | CountTo | ||
| 64 | }, | ||
| 65 | methods: { | ||
| 66 | handleSetLineChartData(type) { | ||
| 67 | this.$emit('handleSetLineChartData', type) | ||
| 68 | } | ||
| 69 | } | ||
| 70 | } | ||
| 71 | </script> | ||
| 72 | |||
| 73 | <style lang="scss" scoped> | ||
| 74 | .panel-group { | ||
| 75 | margin-top: 18px; | ||
| 76 | |||
| 77 | .card-panel-col { | ||
| 78 | margin-bottom: 32px; | ||
| 79 | } | ||
| 80 | |||
| 81 | .card-panel { | ||
| 82 | height: 108px; | ||
| 83 | cursor: pointer; | ||
| 84 | font-size: 12px; | ||
| 85 | position: relative; | ||
| 86 | overflow: hidden; | ||
| 87 | color: #666; | ||
| 88 | background: #fff; | ||
| 89 | box-shadow: 4px 4px 40px rgba(0, 0, 0, .05); | ||
| 90 | border-color: rgba(0, 0, 0, .05); | ||
| 91 | |||
| 92 | &:hover { | ||
| 93 | .card-panel-icon-wrapper { | ||
| 94 | color: #fff; | ||
| 95 | } | ||
| 96 | |||
| 97 | .icon-people { | ||
| 98 | background: #40c9c6; | ||
| 99 | } | ||
| 100 | |||
| 101 | .icon-message { | ||
| 102 | background: #36a3f7; | ||
| 103 | } | ||
| 104 | |||
| 105 | .icon-money { | ||
| 106 | background: #f4516c; | ||
| 107 | } | ||
| 108 | |||
| 109 | .icon-shopping { | ||
| 110 | background: #34bfa3 | ||
| 111 | } | ||
| 112 | } | ||
| 113 | |||
| 114 | .icon-people { | ||
| 115 | color: #40c9c6; | ||
| 116 | } | ||
| 117 | |||
| 118 | .icon-message { | ||
| 119 | color: #36a3f7; | ||
| 120 | } | ||
| 121 | |||
| 122 | .icon-money { | ||
| 123 | color: #f4516c; | ||
| 124 | } | ||
| 125 | |||
| 126 | .icon-shopping { | ||
| 127 | color: #34bfa3 | ||
| 128 | } | ||
| 129 | |||
| 130 | .card-panel-icon-wrapper { | ||
| 131 | float: left; | ||
| 132 | margin: 14px 0 0 14px; | ||
| 133 | padding: 16px; | ||
| 134 | transition: all 0.38s ease-out; | ||
| 135 | border-radius: 6px; | ||
| 136 | } | ||
| 137 | |||
| 138 | .card-panel-icon { | ||
| 139 | float: left; | ||
| 140 | font-size: 48px; | ||
| 141 | } | ||
| 142 | |||
| 143 | .card-panel-description { | ||
| 144 | float: right; | ||
| 145 | font-weight: bold; | ||
| 146 | margin: 26px; | ||
| 147 | margin-left: 0px; | ||
| 148 | |||
| 149 | .card-panel-text { | ||
| 150 | line-height: 18px; | ||
| 151 | color: rgba(0, 0, 0, 0.45); | ||
| 152 | font-size: 16px; | ||
| 153 | margin-bottom: 12px; | ||
| 154 | } | ||
| 155 | |||
| 156 | .card-panel-num { | ||
| 157 | font-size: 20px; | ||
| 158 | } | ||
| 159 | } | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 163 | @media (max-width:550px) { | ||
| 164 | .card-panel-description { | ||
| 165 | display: none; | ||
| 166 | } | ||
| 167 | |||
| 168 | .card-panel-icon-wrapper { | ||
| 169 | float: none !important; | ||
| 170 | width: 100%; | ||
| 171 | height: 100%; | ||
| 172 | margin: 0 !important; | ||
| 173 | |||
| 174 | .svg-icon { | ||
| 175 | display: block; | ||
| 176 | margin: 14px auto !important; | ||
| 177 | float: none !important; | ||
| 178 | } | ||
| 179 | } | ||
| 180 | } | ||
| 181 | </style> | ||
| 182 |
src/components/PieChart/index.vue
| File was created | 1 | <template> | |
| 2 | <div | ||
| 3 | :class="className" | ||
| 4 | :style="{height:height,width:width}" | ||
| 5 | /> | ||
| 6 | </template> | ||
| 7 | |||
| 8 | <script> | ||
| 9 | import echarts from 'echarts' | ||
| 10 | require('echarts/theme/macarons') // echarts theme | ||
| 11 | import resize from '@/components/mixins/resize' | ||
| 12 | // import resize from './mixins/resize' | ||
| 13 | |||
| 14 | export default { | ||
| 15 | mixins: [resize], | ||
| 16 | props: { | ||
| 17 | className: { | ||
| 18 | type: String, | ||
| 19 | default: 'chart' | ||
| 20 | }, | ||
| 21 | width: { | ||
| 22 | type: String, | ||
| 23 | default: '100%' | ||
| 24 | }, | ||
| 25 | height: { | ||
| 26 | type: String, | ||
| 27 | default: '300px' | ||
| 28 | } | ||
| 29 | }, | ||
| 30 | data() { | ||
| 31 | return { | ||
| 32 | chart: null | ||
| 33 | } | ||
| 34 | }, | ||
| 35 | mounted() { | ||
| 36 | this.$nextTick(() => { | ||
| 37 | this.initChart() | ||
| 38 | }) | ||
| 39 | }, | ||
| 40 | beforeDestroy() { | ||
| 41 | if (!this.chart) { | ||
| 42 | return | ||
| 43 | } | ||
| 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 | series: [ | ||
| 62 | { | ||
| 63 | name: 'WEEKLY WRITE ARTICLES', | ||
| 64 | type: 'pie', | ||
| 65 | roseType: 'radius', | ||
| 66 | radius: [15, 95], | ||
| 67 | center: ['50%', '38%'], | ||
| 68 | data: [ | ||
| 69 | { value: 320, name: 'Industries' }, | ||
| 70 | { value: 240, name: 'Technology' }, | ||
| 71 | { value: 149, name: 'Forex' }, | ||
| 72 | { value: 100, name: 'Gold' }, | ||
| 73 | { value: 59, name: 'Forecasts' } | ||
| 74 | ], | ||
| 75 | animationEasing: 'cubicInOut', | ||
| 76 | animationDuration: 2600 | ||
| 77 | } | ||
| 78 | ] | ||
| 79 | }) | ||
| 80 | } | ||
| 81 | } | ||
| 82 | } | ||
| 83 | </script> | ||
| 84 |
src/components/RaddarChart/index.vue
| File was created | 1 | <template> | |
| 2 | <div | ||
| 3 | :class="className" | ||
| 4 | :style="{height:height,width:width}" | ||
| 5 | /> | ||
| 6 | </template> | ||
| 7 | |||
| 8 | <script> | ||
| 9 | import echarts from 'echarts' | ||
| 10 | require('echarts/theme/macarons') // echarts theme | ||
| 11 | import resize from '@/components/mixins/resize' | ||
| 12 | // import resize from './mixins/resize' | ||
| 13 | |||
| 14 | const animationDuration = 3000 | ||
| 15 | |||
| 16 | export default { | ||
| 17 | mixins: [resize], | ||
| 18 | props: { | ||
| 19 | className: { | ||
| 20 | type: String, | ||
| 21 | default: 'chart' | ||
| 22 | }, | ||
| 23 | width: { | ||
| 24 | type: String, | ||
| 25 | default: '100%' | ||
| 26 | }, | ||
| 27 | height: { | ||
| 28 | type: String, | ||
| 29 | default: '300px' | ||
| 30 | } | ||
| 31 | }, | ||
| 32 | data() { | ||
| 33 | return { | ||
| 34 | chart: null | ||
| 35 | } | ||
| 36 | }, | ||
| 37 | mounted() { | ||
| 38 | this.$nextTick(() => { | ||
| 39 | this.initChart() | ||
| 40 | }) | ||
| 41 | }, | ||
| 42 | beforeDestroy() { | ||
| 43 | if (!this.chart) { | ||
| 44 | return | ||
| 45 | } | ||
| 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 | // 坐标轴指示器,坐标轴触发有效 | ||
| 58 | type: 'shadow' // 默认为直线,可选为:'line' | 'shadow' | ||
| 59 | } | ||
| 60 | }, | ||
| 61 | radar: { | ||
| 62 | radius: '66%', | ||
| 63 | center: ['50%', '42%'], | ||
| 64 | splitNumber: 8, | ||
| 65 | splitArea: { | ||
| 66 | areaStyle: { | ||
| 67 | color: 'rgba(127,95,132,.3)', | ||
| 68 | opacity: 1, | ||
| 69 | shadowBlur: 45, | ||
| 70 | shadowColor: 'rgba(0,0,0,.5)', | ||
| 71 | shadowOffsetX: 0, | ||
| 72 | shadowOffsetY: 15 | ||
| 73 | } | ||
| 74 | }, | ||
| 75 | indicator: [ | ||
| 76 | { name: 'Sales', max: 10000 }, | ||
| 77 | { name: 'Administration', max: 20000 }, | ||
| 78 | { name: 'Information Techology', max: 20000 }, | ||
| 79 | { name: 'Customer Support', max: 20000 }, | ||
| 80 | { name: 'Development', max: 20000 }, | ||
| 81 | { name: 'Marketing', max: 20000 } | ||
| 82 | ] | ||
| 83 | }, | ||
| 84 | legend: { | ||
| 85 | left: 'center', | ||
| 86 | bottom: '10', | ||
| 87 | data: ['Allocated Budget', 'Expected Spending', 'Actual Spending'] | ||
| 88 | }, | ||
| 89 | series: [ | ||
| 90 | { | ||
| 91 | type: 'radar', | ||
| 92 | symbolSize: 0, | ||
| 93 | areaStyle: { | ||
| 94 | normal: { | ||
| 95 | shadowBlur: 13, | ||
| 96 | shadowColor: 'rgba(0,0,0,.2)', | ||
| 97 | shadowOffsetX: 0, | ||
| 98 | shadowOffsetY: 10, | ||
| 99 | opacity: 1 | ||
| 100 | } | ||
| 101 | }, | ||
| 102 | data: [ | ||
| 103 | { | ||
| 104 | value: [5000, 7000, 12000, 11000, 15000, 14000], | ||
| 105 | name: 'Allocated Budget' | ||
| 106 | }, | ||
| 107 | { | ||
| 108 | value: [4000, 9000, 15000, 15000, 13000, 11000], | ||
| 109 | name: 'Expected Spending' | ||
| 110 | }, | ||
| 111 | { | ||
| 112 | value: [5500, 11000, 12000, 15000, 12000, 12000], | ||
| 113 | name: 'Actual Spending' | ||
| 114 | } | ||
| 115 | ], | ||
| 116 | animationDuration: animationDuration | ||
| 117 | } | ||
| 118 | ] | ||
| 119 | }) | ||
| 120 | } | ||
| 121 | } | ||
| 122 | } | ||
| 123 | </script> | ||
| 124 |
src/components/TodoList/Todo.vue
| File was created | 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 | > | ||
| 10 | <label @dblclick="editing = true" v-text="todo.text" /> | ||
| 11 | <button class="destroy" @click="deleteTodo( todo )" /> | ||
| 12 | </div> | ||
| 13 | <input | ||
| 14 | v-show="editing" | ||
| 15 | v-focus="editing" | ||
| 16 | :value="todo.text" | ||
| 17 | class="edit" | ||
| 18 | @keyup.enter="doneEdit" | ||
| 19 | @keyup.esc="cancelEdit" | ||
| 20 | @blur="doneEdit" | ||
| 21 | > | ||
| 22 | </li> | ||
| 23 | </template> | ||
| 24 | |||
| 25 | <script> | ||
| 26 | export default { | ||
| 27 | name: 'Todo', | ||
| 28 | directives: { | ||
| 29 | focus(el, { value }, { context }) { | ||
| 30 | if (value) { | ||
| 31 | context.$nextTick(() => { | ||
| 32 | el.focus() | ||
| 33 | }) | ||
| 34 | } | ||
| 35 | } | ||
| 36 | }, | ||
| 37 | props: { | ||
| 38 | todo: { | ||
| 39 | type: Object, | ||
| 40 | default: function() { | ||
| 41 | return {} | ||
| 42 | } | ||
| 43 | } | ||
| 44 | }, | ||
| 45 | data() { | ||
| 46 | return { | ||
| 47 | editing: false | ||
| 48 | } | ||
| 49 | }, | ||
| 50 | methods: { | ||
| 51 | deleteTodo(todo) { | ||
| 52 | this.$emit('deleteTodo', todo) | ||
| 53 | }, | ||
| 54 | editTodo({ todo, value }) { | ||
| 55 | this.$emit('editTodo', { todo, value }) | ||
| 56 | }, | ||
| 57 | toggleTodo(todo) { | ||
| 58 | this.$emit('toggleTodo', todo) | ||
| 59 | }, | ||
| 60 | doneEdit(e) { | ||
| 61 | const value = e.target.value.trim() | ||
| 62 | const { todo } = this | ||
| 63 | if (!value) { | ||
| 64 | this.deleteTodo({ | ||
| 65 | todo | ||
| 66 | }) | ||
| 67 | } else if (this.editing) { | ||
| 68 | this.editTodo({ | ||
| 69 | todo, | ||
| 70 | value | ||
| 71 | }) | ||
| 72 | this.editing = false | ||
| 73 | } | ||
| 74 | }, | ||
| 75 | cancelEdit(e) { | ||
| 76 | e.target.value = this.todo.text | ||
| 77 | this.editing = false | ||
| 78 | } | ||
| 79 | } | ||
| 80 | } | ||
| 81 | </script> | ||
| 82 |
src/components/TodoList/index.scss
| File was created | 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 | } | ||
| 321 |
src/components/TodoList/index.vue
| File was created | 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 | /> | ||
| 20 | </ul> | ||
| 21 | </section> | ||
| 22 | <!-- footer --> | ||
| 23 | <footer v-show="todos.length" class="footer"> | ||
| 24 | <span class="todo-count"> | ||
| 25 | <strong>{{ remaining }}</strong> | ||
| 26 | {{ remaining | pluralize('item') }} left | ||
| 27 | </span> | ||
| 28 | <ul class="filters"> | ||
| 29 | <li v-for="(val, key) in filters" :key="key"> | ||
| 30 | <a :class="{ selected: visibility === key }" @click.prevent="visibility = key">{{ key | capitalize }}</a> | ||
| 31 | </li> | ||
| 32 | </ul> | ||
| 33 | <!-- <button class="clear-completed" v-show="todos.length > remaining" @click="clearCompleted"> | ||
| 34 | Clear completed | ||
| 35 | </button> --> | ||
| 36 | </footer> | ||
| 37 | </section> | ||
| 38 | </template> | ||
| 39 | |||
| 40 | <script> | ||
| 41 | import Todo from './Todo.vue' | ||
| 42 | |||
| 43 | const STORAGE_KEY = 'todos' | ||
| 44 | const filters = { | ||
| 45 | all: todos => todos, | ||
| 46 | active: todos => todos.filter(todo => !todo.done), | ||
| 47 | completed: todos => todos.filter(todo => todo.done) | ||
| 48 | } | ||
| 49 | const defalutList = [ | ||
| 50 | { text: 'star this repository', done: false }, | ||
| 51 | { text: 'fork this repository', done: false }, | ||
| 52 | { text: 'follow author', done: false }, | ||
| 53 | { text: 'vue-element-admin', done: true }, | ||
| 54 | { text: 'vue', done: true }, | ||
| 55 | { text: 'element-ui', done: true }, | ||
| 56 | { text: 'axios', done: true }, | ||
| 57 | { text: 'webpack', done: true } | ||
| 58 | ] | ||
| 59 | export default { | ||
| 60 | components: { Todo }, | ||
| 61 | filters: { | ||
| 62 | pluralize: (n, w) => n === 1 ? w : w + 's', | ||
| 63 | capitalize: s => s.charAt(0).toUpperCase() + s.slice(1) | ||
| 64 | }, | ||
| 65 | data() { | ||
| 66 | return { | ||
| 67 | visibility: 'all', | ||
| 68 | filters, | ||
| 69 | // todos: JSON.parse(window.localStorage.getItem(STORAGE_KEY)) || defalutList | ||
| 70 | todos: defalutList | ||
| 71 | } | ||
| 72 | }, | ||
| 73 | computed: { | ||
| 74 | allChecked() { | ||
| 75 | return this.todos.every(todo => todo.done) | ||
| 76 | }, | ||
| 77 | filteredTodos() { | ||
| 78 | return filters[this.visibility](this.todos) | ||
| 79 | }, | ||
| 80 | remaining() { | ||
| 81 | return this.todos.filter(todo => !todo.done).length | ||
| 82 | } | ||
| 83 | }, | ||
| 84 | methods: { | ||
| 85 | setLocalStorage() { | ||
| 86 | window.localStorage.setItem(STORAGE_KEY, JSON.stringify(this.todos)) | ||
| 87 | }, | ||
| 88 | addTodo(e) { | ||
| 89 | const text = e.target.value | ||
| 90 | if (text.trim()) { | ||
| 91 | this.todos.push({ | ||
| 92 | text, | ||
| 93 | done: false | ||
| 94 | }) | ||
| 95 | this.setLocalStorage() | ||
| 96 | } | ||
| 97 | e.target.value = '' | ||
| 98 | }, | ||
| 99 | toggleTodo(val) { | ||
| 100 | val.done = !val.done | ||
| 101 | this.setLocalStorage() | ||
| 102 | }, | ||
| 103 | deleteTodo(todo) { | ||
| 104 | this.todos.splice(this.todos.indexOf(todo), 1) | ||
| 105 | this.setLocalStorage() | ||
| 106 | }, | ||
| 107 | editTodo({ todo, value }) { | ||
| 108 | todo.text = value | ||
| 109 | this.setLocalStorage() | ||
| 110 | }, | ||
| 111 | clearCompleted() { | ||
| 112 | this.todos = this.todos.filter(todo => !todo.done) | ||
| 113 | this.setLocalStorage() | ||
| 114 | }, | ||
| 115 | toggleAll({ done }) { | ||
| 116 | this.todos.forEach(todo => { | ||
| 117 | todo.done = done | ||
| 118 | this.setLocalStorage() | ||
| 119 | }) | ||
| 120 | } | ||
| 121 | } | ||
| 122 | } | ||
| 123 | </script> | ||
| 124 | |||
| 125 | <style lang="scss"> | ||
| 126 | @import './index.scss'; | ||
| 127 | </style> | ||
| 128 |
src/components/TransactionTable/index.vue
| File was created | 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="{row}"> | ||
| 15 | <el-tag :type="row.status | statusFilter"> | ||
| 16 | {{ row.status }} | ||
| 17 | </el-tag> | ||
| 18 | </template> | ||
| 19 | </el-table-column> | ||
| 20 | </el-table> | ||
| 21 | </template> | ||
| 22 | |||
| 23 | <script> | ||
| 24 | import { transactionList } from '@/api/remote-search' | ||
| 25 | |||
| 26 | export default { | ||
| 27 | filters: { | ||
| 28 | statusFilter(status) { | ||
| 29 | const statusMap = { | ||
| 30 | success: 'success', | ||
| 31 | pending: 'danger' | ||
| 32 | } | ||
| 33 | return statusMap[status] | ||
| 34 | }, | ||
| 35 | orderNoFilter(str) { | ||
| 36 | return str.substring(0, 30) | ||
| 37 | } | ||
| 38 | }, | ||
| 39 | data() { | ||
| 40 | return { | ||
| 41 | list: null | ||
| 42 | } | ||
| 43 | }, | ||
| 44 | created() { | ||
| 45 | this.fetchData() | ||
| 46 | }, | ||
| 47 | methods: { | ||
| 48 | fetchData() { | ||
| 49 | transactionList().then(response => { | ||
| 50 | this.list = response.data.items.slice(0, 8) | ||
| 51 | }) | ||
| 52 | } | ||
| 53 | } | ||
| 54 | } | ||
| 55 | </script> | ||
| 56 |
src/components/mixins/resize.js
| File was created | 1 | import { debounce } from '@/utils' | |
| 2 | |||
| 3 | export default { | ||
| 4 | data() { | ||
| 5 | return { | ||
| 6 | $_sidebarElm: null, | ||
| 7 | $_resizeHandler: null | ||
| 8 | } | ||
| 9 | }, | ||
| 10 | mounted() { | ||
| 11 | this.$_resizeHandler = debounce(() => { | ||
| 12 | if (this.chart) { | ||
| 13 | this.chart.resize() | ||
| 14 | } | ||
| 15 | }, 100) | ||
| 16 | this.$_initResizeEvent() | ||
| 17 | this.$_initSidebarResizeEvent() | ||
| 18 | }, | ||
| 19 | beforeDestroy() { | ||
| 20 | this.$_destroyResizeEvent() | ||
| 21 | this.$_destroySidebarResizeEvent() | ||
| 22 | }, | ||
| 23 | // to fixed bug when cached by keep-alive | ||
| 24 | // https://github.com/PanJiaChen/vue-element-admin/issues/2116 | ||
| 25 | activated() { | ||
| 26 | this.$_initResizeEvent() | ||
| 27 | this.$_initSidebarResizeEvent() | ||
| 28 | }, | ||
| 29 | deactivated() { | ||
| 30 | this.$_destroyResizeEvent() | ||
| 31 | this.$_destroySidebarResizeEvent() | ||
| 32 | }, | ||
| 33 | methods: { | ||
| 34 | // use $_ for mixins properties | ||
| 35 | // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential | ||
| 36 | $_initResizeEvent() { | ||
| 37 | window.addEventListener('resize', this.$_resizeHandler) | ||
| 38 | }, | ||
| 39 | $_destroyResizeEvent() { | ||
| 40 | window.removeEventListener('resize', this.$_resizeHandler) | ||
| 41 | }, | ||
| 42 | $_sidebarResizeHandler(e) { | ||
| 43 | if (e.propertyName === 'width') { | ||
| 44 | this.$_resizeHandler() | ||
| 45 | } | ||
| 46 | }, | ||
| 47 | $_initSidebarResizeEvent() { | ||
| 48 | this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0] | ||
| 49 | this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler) | ||
| 50 | }, | ||
| 51 | $_destroySidebarResizeEvent() { | ||
| 52 | this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler) | ||
| 53 | } | ||
| 54 | } | ||
| 55 | } | ||
| 56 |
src/lang/zh.js
| 1 | export default { | 1 | export default { |
| 2 | // 添加的新词条------start | 2 | // 添加的新词条------start |
| 3 | prod: { | 3 | prod: { |
| 4 | menu_title: 'products', | 4 | menu_title: 'products', |
| 5 | sku_modle_pic: '模型图', | 5 | sku_modle_pic: '模型图', |
| 6 | sku_buy_pic: '购买效果图', | 6 | sku_buy_pic: '购买效果图', |
| 7 | window_pic: '橱窗图', | 7 | window_pic: '橱窗图', |
| 8 | detail_pic: '详情图' | 8 | detail_pic: '详情图' |
| 9 | }, | 9 | }, |
| 10 | order: { | 10 | order: { |
| 11 | refunding: '退款中', | 11 | refunding: '退款中', |
| 12 | refunded: '退款完成', | 12 | refunded: '退款完成', |
| 13 | 13 | ||
| 14 | pay_pending: '待支付', | 14 | pay_pending: '待支付', |
| 15 | pay_finished: '支付完成', | 15 | pay_finished: '支付完成', |
| 16 | 16 | ||
| 17 | deliver_pre: '准备配送', | 17 | deliver_pre: '准备配送', |
| 18 | deliver_ing: '配送中', | 18 | deliver_ing: '配送中', |
| 19 | deliver_finished: '物流完成' | 19 | deliver_finished: '物流完成' |
| 20 | }, | 20 | }, |
| 21 | users: { | 21 | users: { |
| 22 | table: { | 22 | table: { |
| 23 | uid: '用户id', | 23 | uid: '用户id', |
| 24 | username: '用户名', | 24 | username: '用户名', |
| 25 | password: '密码', | 25 | password: '密码', |
| 26 | create_at: '注册时间', | 26 | create_at: '注册时间', |
| 27 | nickname: '昵称', | 27 | nickname: '昵称', |
| 28 | roles: '角色', | 28 | roles: '角色', |
| 29 | openid: 'openid', | 29 | openid: 'openid', |
| 30 | son_of_adv: '下线', | 30 | son_of_adv: '下线', |
| 31 | status: '当前状态', | 31 | status: '当前状态', |
| 32 | level: '等级', | 32 | level: '等级', |
| 33 | oper: '操作', | 33 | oper: '操作', |
| 34 | souceof: '上线', | 34 | souceof: '上线', |
| 35 | revernew: '收益', | 35 | revernew: '收益', |
| 36 | buyvalue: '消费价值', | 36 | buyvalue: '消费价值', |
| 37 | buywill: '消费潜力', | 37 | buywill: '消费潜力', |
| 38 | score: '积分', | 38 | score: '积分', |
| 39 | weixin: '微信', | 39 | weixin: '微信', |
| 40 | facebook: 'facebook', | 40 | facebook: 'facebook', |
| 41 | comefromperson: '来自人', | 41 | comefromperson: '来自人', |
| 42 | comefromplatform: '来自平台', | 42 | comefromplatform: '来自平台', |
| 43 | benifit: '提成', | 43 | benifit: '提成', |
| 44 | coupon: '优惠券', | 44 | coupon: '优惠券', |
| 45 | remark: '备注', | 45 | remark: '备注', |
| 46 | importance: '重要度', | 46 | importance: '重要度', |
| 47 | num: '数量' | 47 | num: '数量' |
| 48 | }, | 48 | }, |
| 49 | add: '添加', | 49 | add: '添加', |
| 50 | search: '搜索', | 50 | search: '搜索', |
| 51 | del: '删除', | 51 | del: '删除', |
| 52 | update: '修改', | 52 | update: '修改', |
| 53 | edit: '修改', | 53 | edit: '修改', |
| 54 | selectall: '全选' | 54 | selectall: '全选' |
| 55 | }, | 55 | }, |
| 56 | site: { | 56 | site: { |
| 57 | // seo:'seo', | 57 | // seo:'seo', |
| 58 | 58 | ||
| 59 | }, | 59 | }, |
| 60 | meta: { | 60 | meta: { |
| 61 | metadefine: '元定义' | 61 | metadefine: '元定义' |
| 62 | }, | 62 | }, |
| 63 | system: { | 63 | system: { |
| 64 | memu: '系统' | 64 | memu: '系统' |
| 65 | }, | 65 | }, |
| 66 | route: { | 66 | route: { |
| 67 | users: { | 67 | users: { |
| 68 | people: '用户', | 68 | people: '用户', |
| 69 | user: '普通用户', | 69 | user: '普通用户', |
| 70 | list: '列表', | 70 | list: '列表', |
| 71 | shoper: '厂商', | 71 | shoper: '厂商', |
| 72 | runner: '运营官', | 72 | runner: '运营官', |
| 73 | assistant: '操作员', | 73 | assistant: '操作员', |
| 74 | admin: '超级管理员' | 74 | admin: '超级管理员' |
| 75 | }, | 75 | }, |
| 76 | shopers: '厂商', | 76 | shopers: '厂商', |
| 77 | prods: { | 77 | prods: { |
| 78 | prod_menu: '产品', | 78 | prod_menu: '产品', |
| 79 | prodlist: '产品列表' | 79 | prodlist: '产品列表' |
| 80 | }, | 80 | }, |
| 81 | orders: '订单', | 81 | orders: '订单', |
| 82 | sites: { | 82 | sites: { |
| 83 | sites: '站点', | 83 | sites: '站点', |
| 84 | siteList: '站点列表' | 84 | siteList: '站点列表' |
| 85 | }, | 85 | }, |
| 86 | metas: { | 86 | metas: { |
| 87 | metas: '元', | 87 | metas: '元', |
| 88 | list: '树' | 88 | list: '树' |
| 89 | }, | 89 | }, |
| 90 | systems: { | 90 | systems: { |
| 91 | systems: '系统设置', | 91 | systems: '系统设置', |
| 92 | sites: '站点设置', | 92 | sites: '站点设置', |
| 93 | money: '货币设置', | 93 | money: '货币设置', |
| 94 | industry: '行业设置', | 94 | industry: '行业设置', |
| 95 | template: '模版设置' | 95 | template: '模版设置' |
| 96 | }, | 96 | }, |
| 97 | // 添加的新词条------end | 97 | // 添加的新词条------end |
| 98 | dashboard: '首页', | 98 | dashboard: '首页', |
| 99 | documentation: '文档', | 99 | documentation: '文档', |
| 100 | guide: '引导页', | 100 | guide: '引导页', |
| 101 | permission: '权限测试页', | 101 | permission: '权限测试页', |
| 102 | rolePermission: '角色权限', | 102 | rolePermission: '角色权限', |
| 103 | pagePermission: '页面权限', | 103 | pagePermission: '页面权限', |
| 104 | directivePermission: '指令权限', | 104 | directivePermission: '指令权限', |
| 105 | icons: '图标', | 105 | icons: '图标', |
| 106 | components: '组件', | 106 | components: '组件', |
| 107 | tinymce: '富文本编辑器', | 107 | tinymce: '富文本编辑器', |
| 108 | markdown: 'Markdown', | 108 | markdown: 'Markdown', |
| 109 | jsonEditor: 'JSON 编辑器', | 109 | jsonEditor: 'JSON 编辑器', |
| 110 | dndList: '列表拖拽', | 110 | dndList: '列表拖拽', |
| 111 | splitPane: 'Splitpane', | 111 | splitPane: 'Splitpane', |
| 112 | avatarUpload: '头像上传', | 112 | avatarUpload: '头像上传', |
| 113 | dropzone: 'Dropzone', | 113 | dropzone: 'Dropzone', |
| 114 | sticky: 'Sticky', | 114 | sticky: 'Sticky', |
| 115 | countTo: 'Count To', | 115 | countTo: 'Count To', |
| 116 | componentMixin: '小组件', | 116 | componentMixin: '小组件', |
| 117 | backToTop: '返回顶部', | 117 | backToTop: '返回顶部', |
| 118 | dragDialog: '拖拽 Dialog', | 118 | dragDialog: '拖拽 Dialog', |
| 119 | dragSelect: '拖拽 Select', | 119 | dragSelect: '拖拽 Select', |
| 120 | dragKanban: '可拖拽看板', | 120 | dragKanban: '可拖拽看板', |
| 121 | charts: '图表', | 121 | charts: '图表', |
| 122 | keyboardChart: '键盘图表', | 122 | keyboardChart: '键盘图表', |
| 123 | lineChart: '折线图', | 123 | lineChart: '折线图', |
| 124 | mixChart: '混合图表', | 124 | mixChart: '混合图表', |
| 125 | example: '综合实例', | 125 | example: '综合实例', |
| 126 | nested: '路由嵌套', | 126 | nested: '路由嵌套', |
| 127 | menu1: '菜单1', | 127 | menu1: '菜单1', |
| 128 | 'menu1-1': '菜单 1-1', | 128 | 'menu1-1': '菜单 1-1', |
| 129 | 'menu1-2': '菜单 1-2', | 129 | 'menu1-2': '菜单 1-2', |
| 130 | 'menu1-2-1': '菜单 1-2-1', | 130 | 'menu1-2-1': '菜单 1-2-1', |
| 131 | 'menu1-2-2': '菜单 1-2-2', | 131 | 'menu1-2-2': '菜单 1-2-2', |
| 132 | 'menu1-3': '菜单 1-3', | 132 | 'menu1-3': '菜单 1-3', |
| 133 | menu2: '菜单 2', | 133 | menu2: '菜单 2', |
| 134 | Table: 'Table', | 134 | Table: 'Table', |
| 135 | dynamicTable: '动态 Table', | 135 | dynamicTable: '动态 Table', |
| 136 | dragTable: '拖拽 Table', | 136 | dragTable: '拖拽 Table', |
| 137 | inlineEditTable: 'Table 内编辑', | 137 | inlineEditTable: 'Table 内编辑', |
| 138 | complexTable: '综合 Table', | 138 | complexTable: '综合 Table', |
| 139 | tab: 'Tab', | 139 | tab: 'Tab', |
| 140 | form: '表单', | 140 | form: '表单', |
| 141 | createArticle: '创建文章', | 141 | createArticle: '创建文章', |
| 142 | editArticle: '编辑文章', | 142 | editArticle: '编辑文章', |
| 143 | articleList: '文章列表', | 143 | articleList: '文章列表', |
| 144 | errorPages: '错误页面', | 144 | errorPages: '错误页面', |
| 145 | page401: '401', | 145 | page401: '401', |
| 146 | page404: '404', | 146 | page404: '404', |
| 147 | errorLog: '错误日志', | 147 | errorLog: '错误日志', |
| 148 | excel: 'Excel', | 148 | excel: 'Excel', |
| 149 | exportExcel: '导出 Excel', | 149 | exportExcel: '导出 Excel', |
| 150 | selectExcel: '导出 已选择项', | 150 | selectExcel: '导出 已选择项', |
| 151 | mergeHeader: '导出 多级表头', | 151 | mergeHeader: '导出 多级表头', |
| 152 | uploadExcel: '上传 Excel', | 152 | uploadExcel: '上传 Excel', |
| 153 | zip: 'Zip', | 153 | zip: 'Zip', |
| 154 | pdf: 'PDF', | 154 | pdf: 'PDF', |
| 155 | exportZip: 'Export Zip', | 155 | exportZip: 'Export Zip', |
| 156 | theme: '换肤', | 156 | theme: '换肤', |
| 157 | clipboardDemo: 'Clipboard', | 157 | clipboardDemo: 'Clipboard', |
| 158 | i18n: '国际化', | 158 | i18n: '国际化', |
| 159 | externalLink: '外链', | 159 | externalLink: '外链', |
| 160 | profile: '个人中心' | 160 | profile: '个人中心' |
| 161 | }, | 161 | }, |
| 162 | navbar: { | 162 | navbar: { |
| 163 | dashboard: '首页', | 163 | dashboard: '首页', |
| 164 | github: '项目地址', | 164 | github: '项目地址', |
| 165 | logOut: '退出登录', | 165 | logOut: '退出登录', |
| 166 | profile: '个人中心', | 166 | profile: '个人中心', |
| 167 | theme: '换肤', | 167 | theme: '换肤', |
| 168 | size: '布局大小' | 168 | size: '布局大小' |
| 169 | }, | 169 | }, |
| 170 | login: { | 170 | login: { |
| 171 | runner: '运营官', | 171 | runner: '运营官', |
| 172 | shoper: '商家', | 172 | shoper: '商家', |
| 173 | assistant: '操作员', | 173 | assistant: '操作员', |
| 174 | signup: '注册', | 174 | signup: '注册', |
| 175 | forgetpassword: '忘记密码', | 175 | forgetpassword: '忘记密码', |
| 176 | rememberpassword: 'remember password', | 176 | rememberpassword: 'remember password', |
| 177 | 177 | ||
| 178 | title: '鱼皮出海--让我们荡起双浆', | 178 | title: '【富贵】出海--让我们荡起双浆', |
| 179 | logIn: '登录', | 179 | logIn: '登录', |
| 180 | username: '账号', | 180 | username: '账号', |
| 181 | password: '密码', | 181 | password: '密码', |
| 182 | any: '随便填', | 182 | any: '随便填', |
| 183 | thirdparty: '第三方登录', | 183 | thirdparty: '第三方登录', |
| 184 | thirdpartyTips: '本地不能模拟,请结合自己业务进行模拟!!!' | 184 | thirdpartyTips: '本地不能模拟,请结合自己业务进行模拟!!!' |
| 185 | }, | 185 | }, |
| 186 | documentation: { | 186 | documentation: { |
| 187 | documentation: '文档', | 187 | documentation: '文档', |
| 188 | github: 'Github 地址' | 188 | github: 'Github 地址' |
| 189 | }, | 189 | }, |
| 190 | permission: { | 190 | permission: { |
| 191 | addRole: '新增角色', | 191 | addRole: '新增角色', |
| 192 | editPermission: '编辑权限', | 192 | editPermission: '编辑权限', |
| 193 | roles: '你的权限', | 193 | roles: '你的权限', |
| 194 | switchRoles: '切换权限', | 194 | switchRoles: '切换权限', |
| 195 | tips: '在某些情况下,不适合使用 v-permission。例如:Element-UI 的 el-tab 或 el-table-column 以及其它动态渲染 dom 的场景。你只能通过手动设置 v-if 来实现。', | 195 | tips: '在某些情况下,不适合使用 v-permission。例如:Element-UI 的 el-tab 或 el-table-column 以及其它动态渲染 dom 的场景。你只能通过手动设置 v-if 来实现。', |
| 196 | delete: '删除', | 196 | delete: '删除', |
| 197 | confirm: '确定', | 197 | confirm: '确定', |
| 198 | cancel: '取消' | 198 | cancel: '取消' |
| 199 | }, | 199 | }, |
| 200 | guide: { | 200 | guide: { |
| 201 | description: '引导页对于一些第一次进入项目的人很有用,你可以简单介绍下项目的功能。本 Demo 是基于', | 201 | description: '引导页对于一些第一次进入项目的人很有用,你可以简单介绍下项目的功能。本 Demo 是基于', |
| 202 | button: '打开引导' | 202 | button: '打开引导' |
| 203 | }, | 203 | }, |
| 204 | components: { | 204 | components: { |
| 205 | documentation: '文档', | 205 | documentation: '文档', |
| 206 | tinymceTips: '富文本是管理后台一个核心的功能,但同时又是一个有很多坑的地方。在选择富文本的过程中我也走了不少的弯路,市面上常见的富文本都基本用过了,最终权衡了一下选择了Tinymce。更详细的富文本比较和介绍见', | 206 | tinymceTips: '富文本是管理后台一个核心的功能,但同时又是一个有很多坑的地方。在选择富文本的过程中我也走了不少的弯路,市面上常见的富文本都基本用过了,最终权衡了一下选择了Tinymce。更详细的富文本比较和介绍见', |
| 207 | dropzoneTips: '由于我司业务有特殊需求,而且要传七牛 所以没用第三方,选择了自己封装。代码非常的简单,具体代码你可以在这里看到 @/components/Dropzone', | 207 | dropzoneTips: '由于我司业务有特殊需求,而且要传七牛 所以没用第三方,选择了自己封装。代码非常的简单,具体代码你可以在这里看到 @/components/Dropzone', |
| 208 | stickyTips: '当页面滚动到预设的位置会吸附在顶部', | 208 | stickyTips: '当页面滚动到预设的位置会吸附在顶部', |
| 209 | backToTopTips1: '页面滚动到指定位置会在右下角出现返回顶部按钮', | 209 | backToTopTips1: '页面滚动到指定位置会在右下角出现返回顶部按钮', |
| 210 | backToTopTips2: '可自定义按钮的样式、show/hide、出现的高度、返回的位置 如需文字提示,可在外部使用Element的el-tooltip元素', | 210 | backToTopTips2: '可自定义按钮的样式、show/hide、出现的高度、返回的位置 如需文字提示,可在外部使用Element的el-tooltip元素', |
| 211 | imageUploadTips: '由于我在使用时它只有vue@1版本,而且和mockjs不兼容,所以自己改造了一下,如果大家要使用的话,优先还是使用官方版本。' | 211 | imageUploadTips: '由于我在使用时它只有vue@1版本,而且和mockjs不兼容,所以自己改造了一下,如果大家要使用的话,优先还是使用官方版本。' |
| 212 | }, | 212 | }, |
| 213 | table: { | 213 | table: { |
| 214 | dynamicTips1: '固定表头, 按照表头顺序排序', | 214 | dynamicTips1: '固定表头, 按照表头顺序排序', |
| 215 | dynamicTips2: '不固定表头, 按照点击顺序排序', | 215 | dynamicTips2: '不固定表头, 按照点击顺序排序', |
| 216 | dragTips1: '默认顺序', | 216 | dragTips1: '默认顺序', |
| 217 | dragTips2: '拖拽后顺序', | 217 | dragTips2: '拖拽后顺序', |
| 218 | title: '标题', | 218 | title: '标题', |
| 219 | importance: '重要性', | 219 | importance: '重要性', |
| 220 | type: '类型', | 220 | type: '类型', |
| 221 | remark: '点评', | 221 | remark: '点评', |
| 222 | search: '搜索', | 222 | search: '搜索', |
| 223 | add: '添加', | 223 | add: '添加', |
| 224 | export: '导出', | 224 | export: '导出', |
| 225 | reviewer: '审核人', | 225 | reviewer: '审核人', |
| 226 | id: '序号', | 226 | id: '序号', |
| 227 | date: '时间', | 227 | date: '时间', |
| 228 | author: '作者', | 228 | author: '作者', |
| 229 | readings: '阅读数', | 229 | readings: '阅读数', |
| 230 | status: '状态', | 230 | status: '状态', |
| 231 | actions: '操作', | 231 | actions: '操作', |
| 232 | edit: '编辑', | 232 | edit: '编辑', |
| 233 | publish: '发布', | 233 | publish: '发布', |
| 234 | draft: '草稿', | 234 | draft: '草稿', |
| 235 | delete: '删除', | 235 | delete: '删除', |
| 236 | cancel: '取 消', | 236 | cancel: '取 消', |
| 237 | confirm: '确 定' | 237 | confirm: '确 定' |
| 238 | }, | 238 | }, |
| 239 | example: { | 239 | example: { |
| 240 | warning: '创建和编辑页面是不能被 keep-alive 缓存的,因为keep-alive 的 include 目前不支持根据路由来缓存,所以目前都是基于 component name 来进行缓存的。如果你想类似的实现缓存效果,可以使用 localStorage 等浏览器缓存方案。或者不要使用 keep-alive 的 include,直接缓存所有页面。详情见' | 240 | warning: '创建和编辑页面是不能被 keep-alive 缓存的,因为keep-alive 的 include 目前不支持根据路由来缓存,所以目前都是基于 component name 来进行缓存的。如果你想类似的实现缓存效果,可以使用 localStorage 等浏览器缓存方案。或者不要使用 keep-alive 的 include,直接缓存所有页面。详情见' |
| 241 | }, | 241 | }, |
| 242 | errorLog: { | 242 | errorLog: { |
| 243 | tips: '请点击右上角bug小图标', | 243 | tips: '请点击右上角bug小图标', |
| 244 | description: '现在的管理后台基本都是spa的形式了,它增强了用户体验,但同时也会增加页面出问题的可能性,可能一个小小的疏忽就导致整个页面的死锁。好在 Vue 官网提供了一个方法来捕获处理异常,你可以在其中进行错误处理或者异常上报。', | 244 | description: '现在的管理后台基本都是spa的形式了,它增强了用户体验,但同时也会增加页面出问题的可能性,可能一个小小的疏忽就导致整个页面的死锁。好在 Vue 官网提供了一个方法来捕获处理异常,你可以在其中进行错误处理或者异常上报。', |
| 245 | documentation: '文档介绍' | 245 | documentation: '文档介绍' |
| 246 | }, | 246 | }, |
| 247 | excel: { | 247 | excel: { |
| 248 | export: '导出', | 248 | export: '导出', |
| 249 | selectedExport: '导出已选择项', | 249 | selectedExport: '导出已选择项', |
| 250 | placeholder: '请输入文件名(默认excel-list)' | 250 | placeholder: '请输入文件名(默认excel-list)' |
| 251 | }, | 251 | }, |
| 252 | zip: { | 252 | zip: { |
| 253 | export: '导出', | 253 | export: '导出', |
| 254 | placeholder: '请输入文件名(默认file)' | 254 | placeholder: '请输入文件名(默认file)' |
| 255 | }, | 255 | }, |
| 256 | pdf: { | 256 | pdf: { |
| 257 | tips: '这里使用 window.print() 来实现下载pdf的功能' | 257 | tips: '这里使用 window.print() 来实现下载pdf的功能' |
| 258 | }, | 258 | }, |
| 259 | theme: { | 259 | theme: { |
| 260 | change: '换肤', | 260 | change: '换肤', |
| 261 | documentation: '换肤文档', | 261 | documentation: '换肤文档', |
| 262 | tips: 'Tips: 它区别于 navbar 上的 theme-pick, 是两种不同的换肤方法,各自有不同的应用场景,具体请参考文档。' | 262 | tips: 'Tips: 它区别于 navbar 上的 theme-pick, 是两种不同的换肤方法,各自有不同的应用场景,具体请参考文档。' |
| 263 | }, | 263 | }, |
| 264 | tagsView: { | 264 | tagsView: { |
| 265 | refresh: '刷新', | 265 | refresh: '刷新', |
| 266 | close: '关闭', | 266 | close: '关闭', |
| 267 | closeOthers: '关闭其它', | 267 | closeOthers: '关闭其它', |
| 268 | closeAll: '关闭所有' | 268 | closeAll: '关闭所有' |
| 269 | }, | 269 | }, |
| 270 | settings: { | 270 | settings: { |
| 271 | title: '系统布局配置', | 271 | title: '系统布局配置', |
| 272 | theme: '主题色', | 272 | theme: '主题色', |
| 273 | tagsView: '开启 Tags-View', | 273 | tagsView: '开启 Tags-View', |
| 274 | fixedHeader: '固定 Header', | 274 | fixedHeader: '固定 Header', |
| 275 | sidebarLogo: '侧边栏 Logo' | 275 | sidebarLogo: '侧边栏 Logo' |
| 276 | } | 276 | } |
| 277 | } | 277 | } |
| 278 | 278 |
src/router/modules/prod.js
| 1 | /** When your routing table is too long, you can split it into small modules**/ | 1 | /** When your routing table is too long, you can split it into small modules**/ |
| 2 | 2 | ||
| 3 | import Layout from '@/layout' | 3 | import Layout from '@/layout' |
| 4 | 4 | ||
| 5 | const prodRouter = { | 5 | const prodRouter = { |
| 6 | path: '/prod', | 6 | path: '/prod', |
| 7 | component: Layout, | 7 | component: Layout, |
| 8 | redirect: '/prod/page', | 8 | redirect: '/prod/page', |
| 9 | alwaysShow: true, // will always show the root menu | 9 | alwaysShow: true, // will always show the root menu |
| 10 | name: 'Prod', | 10 | name: 'Prod', |
| 11 | meta: { | 11 | meta: { |
| 12 | title: 'prods.prod_menu', // 会自动被i18n替换 | 12 | title: 'prods.prod_menu', // 会自动被i18n替换 |
| 13 | icon: 'star', | 13 | icon: 'star', |
| 14 | roles: ['admin', 'assistant', 'runner', 'shoper'] // you can set roles in root nav | 14 | roles: ['admin', 'assistant', 'runner', 'shoper'] // you can set roles in root nav |
| 15 | }, | 15 | }, |
| 16 | children: [{ | 16 | children: [{ |
| 17 | path: 'list', | 17 | path: 'list', |
| 18 | component: () => import('@/views/prod/list'), | 18 | component: () => import('@/views/prod/list'), |
| 19 | name: 'ProdList', | 19 | name: 'ProdList', |
| 20 | meta: { | 20 | meta: { |
| 21 | title: 'prods.prodlist', | 21 | title: 'prods.prodlist', |
| 22 | roles: ['admin', 'assistant', 'shoper', 'runner'] | 22 | roles: ['admin', 'assistant', 'shoper', 'runner'] |
| 23 | } | 23 | } |
| 24 | }, { | 24 | }, { |
| 25 | path: 'fav', | ||
| 26 | component: () => import('@/views/prod/fav'), | ||
| 27 | name: 'ProdFav', | ||
| 28 | meta: { | ||
| 29 | title: 'prods.prodfav', | ||
| 30 | roles: ['runner'] | ||
| 31 | } | ||
| 32 | }, { | ||
| 25 | path: 'edit/:pid(\\d+)', | 33 | path: 'edit/:pid(\\d+)', |
| 26 | component: () => import('@/views/prod/edit'), | 34 | component: () => import('@/views/prod/edit'), |
| 27 | name: 'ProdEdit', | 35 | name: 'ProdEdit', |
| 28 | meta: { | 36 | meta: { |
| 29 | title: 'prods.prodedit', | 37 | title: 'prods.prodedit', |
| 30 | noCache: true, | 38 | noCache: true, |
| 31 | activeMenu: '/prod/list' | 39 | activeMenu: '/prod/list' |
| 32 | }, | 40 | }, |
| 33 | hidden: true | 41 | hidden: true |
| 34 | }, { | 42 | }, { |
| 35 | path: 'create/:fid(\\d+)', | 43 | path: 'create/:fid(\\d+)', |
| 36 | component: () => import('@/views/prod/create'), | 44 | component: () => import('@/views/prod/create'), |
| 37 | name: 'ProdCreate', | 45 | name: 'ProdCreate', |
| 38 | meta: { | 46 | meta: { |
| 39 | title: 'prods.prodcreate', | 47 | title: 'prods.prodcreate', |
| 40 | noCache: true, | 48 | noCache: true, |
| 41 | activeMenu: '/prod/list' | 49 | activeMenu: '/prod/list' |
| 42 | }, | 50 | }, |
| 43 | hidden: true | 51 | hidden: true |
| 44 | }] | 52 | }] |
| 45 | } | 53 | } |
| 46 | 54 | ||
| 47 | export default prodRouter | 55 | export default prodRouter |
| 48 | 56 |
src/views/dashboard/admin/components/BarChart.vue
| 1 | <template> | File was deleted | |
| 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 resize from './mixins/resize' | ||
| 9 | |||
| 10 | const animationDuration = 6000 | ||
| 11 | |||
| 12 | export default { | ||
| 13 | mixins: [resize], | ||
| 14 | props: { | ||
| 15 | className: { | ||
| 16 | type: String, | ||
| 17 | default: 'chart' | ||
| 18 | }, | ||
| 19 | width: { | ||
| 20 | type: String, | ||
| 21 | default: '100%' | ||
| 22 | }, | ||
| 23 | height: { | ||
| 24 | type: String, | ||
| 25 | default: '300px' | ||
| 26 | } | ||
| 27 | }, | ||
| 28 | data() { | ||
| 29 | return { | ||
| 30 | chart: null | ||
| 31 | } | ||
| 32 | }, | ||
| 33 | mounted() { | ||
| 34 | this.$nextTick(() => { | ||
| 35 | this.initChart() | ||
| 36 | }) | ||
| 37 | }, | ||
| 38 | beforeDestroy() { | ||
| 39 | if (!this.chart) { | ||
| 40 | return | ||
| 41 | } | ||
| 42 | this.chart.dispose() | ||
| 43 | this.chart = null | ||
| 44 | }, | ||
| 45 | methods: { | ||
| 46 | initChart() { | ||
| 47 | this.chart = echarts.init(this.$el, 'macarons') | ||
| 48 | |||
| 49 | this.chart.setOption({ | ||
| 50 | tooltip: { | ||
| 51 | trigger: 'axis', | ||
| 52 | axisPointer: { // 坐标轴指示器,坐标轴触发有效 | ||
| 53 | type: 'shadow' // 默认为直线,可选为:'line' | 'shadow' | ||
| 54 | } | ||
| 55 | }, | ||
| 56 | grid: { | ||
| 57 | top: 10, | ||
| 58 | left: '2%', | ||
| 59 | right: '2%', | ||
| 60 | bottom: '3%', | ||
| 61 | containLabel: true | ||
| 62 | }, | ||
| 63 | xAxis: [{ | ||
| 64 | type: 'category', | ||
| 65 | data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], | ||
| 66 | axisTick: { | ||
| 67 | alignWithLabel: true | ||
| 68 | } | ||
| 69 | }], | ||
| 70 | yAxis: [{ | ||
| 71 | type: 'value', | ||
| 72 | axisTick: { | ||
| 73 | show: false | ||
| 74 | } | ||
| 75 | }], | ||
| 76 | series: [{ | ||
| 77 | name: 'pageA', | ||
| 78 | type: 'bar', | ||
| 79 | stack: 'vistors', | ||
| 80 | barWidth: '60%', | ||
| 81 | data: [79, 52, 200, 334, 390, 330, 220], | ||
| 82 | animationDuration | ||
| 83 | }, { | ||
| 84 | name: 'pageB', | ||
| 85 | type: 'bar', | ||
| 86 | stack: 'vistors', | ||
| 87 | barWidth: '60%', | ||
| 88 | data: [80, 52, 200, 334, 390, 330, 220], | ||
| 89 | animationDuration | ||
| 90 | }, { | ||
| 91 | name: 'pageC', | ||
| 92 | type: 'bar', | ||
| 93 | stack: 'vistors', | ||
| 94 | barWidth: '60%', | ||
| 95 | data: [30, 52, 200, 334, 390, 330, 220], | ||
| 96 | animationDuration | ||
| 97 | }] | ||
| 98 | }) | ||
| 99 | } | ||
| 100 | } | ||
| 101 | } | ||
| 102 | </script> | ||
| 103 | 1 | <template> |
src/views/dashboard/admin/components/BoxCard.vue
| 1 | <template> | File was deleted | |
| 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 | // import logoPath from "~@/assets/img/yp_logo.jpeg" | ||
| 34 | |||
| 35 | export default { | ||
| 36 | components: { PanThumb, Mallki }, | ||
| 37 | |||
| 38 | filters: { | ||
| 39 | statusFilter(status) { | ||
| 40 | const statusMap = { | ||
| 41 | success: 'success', | ||
| 42 | pending: 'danger' | ||
| 43 | } | ||
| 44 | return statusMap[status] | ||
| 45 | } | ||
| 46 | }, | ||
| 47 | data() { | ||
| 48 | return { | ||
| 49 | statisticsData: { | ||
| 50 | article_count: 1024, | ||
| 51 | pageviews_count: 1024 | ||
| 52 | } | ||
| 53 | } | ||
| 54 | }, | ||
| 55 | computed: { | ||
| 56 | ...mapGetters([ | ||
| 57 | 'name', | ||
| 58 | 'avatar', | ||
| 59 | 'roles' | ||
| 60 | ]) | ||
| 61 | } | ||
| 62 | } | ||
| 63 | </script> | ||
| 64 | |||
| 65 | <style lang="scss" > | ||
| 66 | .box-card-component{ | ||
| 67 | .el-card__header { | ||
| 68 | padding: 0px!important; | ||
| 69 | } | ||
| 70 | } | ||
| 71 | </style> | ||
| 72 | <style lang="scss" scoped> | ||
| 73 | .box-card-component { | ||
| 74 | .box-card-header { | ||
| 75 | position: relative; | ||
| 76 | height: 220px; | ||
| 77 | img { | ||
| 78 | width: 100%; | ||
| 79 | height: 100%; | ||
| 80 | transition: all 0.2s linear; | ||
| 81 | &:hover { | ||
| 82 | transform: scale(1.1, 1.1); | ||
| 83 | filter: contrast(130%); | ||
| 84 | } | ||
| 85 | } | ||
| 86 | } | ||
| 87 | .mallki-text { | ||
| 88 | position: absolute; | ||
| 89 | top: 0px; | ||
| 90 | right: 0px; | ||
| 91 | font-size: 20px; | ||
| 92 | font-weight: bold; | ||
| 93 | } | ||
| 94 | .panThumb { | ||
| 95 | z-index: 100; | ||
| 96 | height: 70px!important; | ||
| 97 | width: 70px!important; | ||
| 98 | position: absolute!important; | ||
| 99 | top: -45px; | ||
| 100 | left: 0px; | ||
| 101 | border: 5px solid #ffffff; | ||
| 102 | background-color: #fff; | ||
| 103 | margin: auto; | ||
| 104 | box-shadow: none!important; | ||
| 105 | /deep/ .pan-info { | ||
| 106 | box-shadow: none!important; | ||
| 107 | } | ||
| 108 | } | ||
| 109 | .progress-item { | ||
| 110 | margin-bottom: 10px; | ||
| 111 | font-size: 14px; | ||
| 112 | } | ||
| 113 | @media only screen and (max-width: 1510px){ | ||
| 114 | .mallki-text{ | ||
| 115 | display: none; | ||
| 116 | } | ||
| 117 | } | ||
| 118 | } | ||
| 119 | </style> | ||
| 120 | 1 | <template> |
src/views/dashboard/admin/components/LineChart.vue
| 1 | <template> | File was deleted | |
| 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 resize from './mixins/resize' | ||
| 9 | |||
| 10 | export default { | ||
| 11 | mixins: [resize], | ||
| 12 | props: { | ||
| 13 | className: { | ||
| 14 | type: String, | ||
| 15 | default: 'chart' | ||
| 16 | }, | ||
| 17 | width: { | ||
| 18 | type: String, | ||
| 19 | default: '100%' | ||
| 20 | }, | ||
| 21 | height: { | ||
| 22 | type: String, | ||
| 23 | default: '350px' | ||
| 24 | }, | ||
| 25 | autoResize: { | ||
| 26 | type: Boolean, | ||
| 27 | default: true | ||
| 28 | }, | ||
| 29 | chartData: { | ||
| 30 | type: Object, | ||
| 31 | required: true | ||
| 32 | } | ||
| 33 | }, | ||
| 34 | data() { | ||
| 35 | return { | ||
| 36 | chart: null | ||
| 37 | } | ||
| 38 | }, | ||
| 39 | watch: { | ||
| 40 | chartData: { | ||
| 41 | deep: true, | ||
| 42 | handler(val) { | ||
| 43 | this.setOptions(val) | ||
| 44 | } | ||
| 45 | } | ||
| 46 | }, | ||
| 47 | mounted() { | ||
| 48 | this.$nextTick(() => { | ||
| 49 | this.initChart() | ||
| 50 | }) | ||
| 51 | }, | ||
| 52 | beforeDestroy() { | ||
| 53 | if (!this.chart) { | ||
| 54 | return | ||
| 55 | } | ||
| 56 | this.chart.dispose() | ||
| 57 | this.chart = null | ||
| 58 | }, | ||
| 59 | methods: { | ||
| 60 | initChart() { | ||
| 61 | this.chart = echarts.init(this.$el, 'macarons') | ||
| 62 | this.setOptions(this.chartData) | ||
| 63 | }, | ||
| 64 | setOptions({ expectedData, actualData } = {}) { | ||
| 65 | this.chart.setOption({ | ||
| 66 | xAxis: { | ||
| 67 | data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'], | ||
| 68 | boundaryGap: false, | ||
| 69 | axisTick: { | ||
| 70 | show: false | ||
| 71 | } | ||
| 72 | }, | ||
| 73 | grid: { | ||
| 74 | left: 10, | ||
| 75 | right: 10, | ||
| 76 | bottom: 20, | ||
| 77 | top: 30, | ||
| 78 | containLabel: true | ||
| 79 | }, | ||
| 80 | tooltip: { | ||
| 81 | trigger: 'axis', | ||
| 82 | axisPointer: { | ||
| 83 | type: 'cross' | ||
| 84 | }, | ||
| 85 | padding: [5, 10] | ||
| 86 | }, | ||
| 87 | yAxis: { | ||
| 88 | axisTick: { | ||
| 89 | show: false | ||
| 90 | } | ||
| 91 | }, | ||
| 92 | legend: { | ||
| 93 | data: ['expected', 'actual'] | ||
| 94 | }, | ||
| 95 | series: [{ | ||
| 96 | name: 'expected', itemStyle: { | ||
| 97 | normal: { | ||
| 98 | color: '#FF005A', | ||
| 99 | lineStyle: { | ||
| 100 | color: '#FF005A', | ||
| 101 | width: 2 | ||
| 102 | } | ||
| 103 | } | ||
| 104 | }, | ||
| 105 | smooth: true, | ||
| 106 | type: 'line', | ||
| 107 | data: expectedData, | ||
| 108 | animationDuration: 2800, | ||
| 109 | animationEasing: 'cubicInOut' | ||
| 110 | }, | ||
| 111 | { | ||
| 112 | name: 'actual', | ||
| 113 | smooth: true, | ||
| 114 | type: 'line', | ||
| 115 | itemStyle: { | ||
| 116 | normal: { | ||
| 117 | color: '#3888fa', | ||
| 118 | lineStyle: { | ||
| 119 | color: '#3888fa', | ||
| 120 | width: 2 | ||
| 121 | }, | ||
| 122 | areaStyle: { | ||
| 123 | color: '#f3f8ff' | ||
| 124 | } | ||
| 125 | } | ||
| 126 | }, | ||
| 127 | data: actualData, | ||
| 128 | animationDuration: 2800, | ||
| 129 | animationEasing: 'quadraticOut' | ||
| 130 | }] | ||
| 131 | }) | ||
| 132 | } | ||
| 133 | } | ||
| 134 | } | ||
| 135 | </script> | ||
| 136 | 1 | <template> |
src/views/dashboard/admin/components/PanelGroup.vue
| 1 | <template> | File was deleted | |
| 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"> | ||
| 10 | New Visits | ||
| 11 | </div> | ||
| 12 | <count-to :start-val="0" :end-val="102400" :duration="2600" class="card-panel-num" /> | ||
| 13 | </div> | ||
| 14 | </div> | ||
| 15 | </el-col> | ||
| 16 | <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> | ||
| 17 | <div class="card-panel" @click="handleSetLineChartData('messages')"> | ||
| 18 | <div class="card-panel-icon-wrapper icon-message"> | ||
| 19 | <svg-icon icon-class="message" class-name="card-panel-icon" /> | ||
| 20 | </div> | ||
| 21 | <div class="card-panel-description"> | ||
| 22 | <div class="card-panel-text"> | ||
| 23 | Messages | ||
| 24 | </div> | ||
| 25 | <count-to :start-val="0" :end-val="81212" :duration="3000" class="card-panel-num" /> | ||
| 26 | </div> | ||
| 27 | </div> | ||
| 28 | </el-col> | ||
| 29 | <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> | ||
| 30 | <div class="card-panel" @click="handleSetLineChartData('purchases')"> | ||
| 31 | <div class="card-panel-icon-wrapper icon-money"> | ||
| 32 | <svg-icon icon-class="money" class-name="card-panel-icon" /> | ||
| 33 | </div> | ||
| 34 | <div class="card-panel-description"> | ||
| 35 | <div class="card-panel-text"> | ||
| 36 | Purchases | ||
| 37 | </div> | ||
| 38 | <count-to :start-val="0" :end-val="9280" :duration="3200" class="card-panel-num" /> | ||
| 39 | </div> | ||
| 40 | </div> | ||
| 41 | </el-col> | ||
| 42 | <el-col :xs="12" :sm="12" :lg="6" class="card-panel-col"> | ||
| 43 | <div class="card-panel" @click="handleSetLineChartData('shoppings')"> | ||
| 44 | <div class="card-panel-icon-wrapper icon-shopping"> | ||
| 45 | <svg-icon icon-class="shopping" class-name="card-panel-icon" /> | ||
| 46 | </div> | ||
| 47 | <div class="card-panel-description"> | ||
| 48 | <div class="card-panel-text"> | ||
| 49 | Shoppings | ||
| 50 | </div> | ||
| 51 | <count-to :start-val="0" :end-val="13600" :duration="3600" class="card-panel-num" /> | ||
| 52 | </div> | ||
| 53 | </div> | ||
| 54 | </el-col> | ||
| 55 | </el-row> | ||
| 56 | </template> | ||
| 57 | |||
| 58 | <script> | ||
| 59 | import CountTo from 'vue-count-to' | ||
| 60 | |||
| 61 | export default { | ||
| 62 | components: { | ||
| 63 | CountTo | ||
| 64 | }, | ||
| 65 | methods: { | ||
| 66 | handleSetLineChartData(type) { | ||
| 67 | this.$emit('handleSetLineChartData', type) | ||
| 68 | } | ||
| 69 | } | ||
| 70 | } | ||
| 71 | </script> | ||
| 72 | |||
| 73 | <style lang="scss" scoped> | ||
| 74 | .panel-group { | ||
| 75 | margin-top: 18px; | ||
| 76 | |||
| 77 | .card-panel-col { | ||
| 78 | margin-bottom: 32px; | ||
| 79 | } | ||
| 80 | |||
| 81 | .card-panel { | ||
| 82 | height: 108px; | ||
| 83 | cursor: pointer; | ||
| 84 | font-size: 12px; | ||
| 85 | position: relative; | ||
| 86 | overflow: hidden; | ||
| 87 | color: #666; | ||
| 88 | background: #fff; | ||
| 89 | box-shadow: 4px 4px 40px rgba(0, 0, 0, .05); | ||
| 90 | border-color: rgba(0, 0, 0, .05); | ||
| 91 | |||
| 92 | &:hover { | ||
| 93 | .card-panel-icon-wrapper { | ||
| 94 | color: #fff; | ||
| 95 | } | ||
| 96 | |||
| 97 | .icon-people { | ||
| 98 | background: #40c9c6; | ||
| 99 | } | ||
| 100 | |||
| 101 | .icon-message { | ||
| 102 | background: #36a3f7; | ||
| 103 | } | ||
| 104 | |||
| 105 | .icon-money { | ||
| 106 | background: #f4516c; | ||
| 107 | } | ||
| 108 | |||
| 109 | .icon-shopping { | ||
| 110 | background: #34bfa3 | ||
| 111 | } | ||
| 112 | } | ||
| 113 | |||
| 114 | .icon-people { | ||
| 115 | color: #40c9c6; | ||
| 116 | } | ||
| 117 | |||
| 118 | .icon-message { | ||
| 119 | color: #36a3f7; | ||
| 120 | } | ||
| 121 | |||
| 122 | .icon-money { | ||
| 123 | color: #f4516c; | ||
| 124 | } | ||
| 125 | |||
| 126 | .icon-shopping { | ||
| 127 | color: #34bfa3 | ||
| 128 | } | ||
| 129 | |||
| 130 | .card-panel-icon-wrapper { | ||
| 131 | float: left; | ||
| 132 | margin: 14px 0 0 14px; | ||
| 133 | padding: 16px; | ||
| 134 | transition: all 0.38s ease-out; | ||
| 135 | border-radius: 6px; | ||
| 136 | } | ||
| 137 | |||
| 138 | .card-panel-icon { | ||
| 139 | float: left; | ||
| 140 | font-size: 48px; | ||
| 141 | } | ||
| 142 | |||
| 143 | .card-panel-description { | ||
| 144 | float: right; | ||
| 145 | font-weight: bold; | ||
| 146 | margin: 26px; | ||
| 147 | margin-left: 0px; | ||
| 148 | |||
| 149 | .card-panel-text { | ||
| 150 | line-height: 18px; | ||
| 151 | color: rgba(0, 0, 0, 0.45); | ||
| 152 | font-size: 16px; | ||
| 153 | margin-bottom: 12px; | ||
| 154 | } | ||
| 155 | |||
| 156 | .card-panel-num { | ||
| 157 | font-size: 20px; | ||
| 158 | } | ||
| 159 | } | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 163 | @media (max-width:550px) { | ||
| 164 | .card-panel-description { | ||
| 165 | display: none; | ||
| 166 | } | ||
| 167 | |||
| 168 | .card-panel-icon-wrapper { | ||
| 169 | float: none !important; | ||
| 170 | width: 100%; | ||
| 171 | height: 100%; | ||
| 172 | margin: 0 !important; | ||
| 173 | |||
| 174 | .svg-icon { | ||
| 175 | display: block; | ||
| 176 | margin: 14px auto !important; | ||
| 177 | float: none !important; | ||
| 178 | } | ||
| 179 | } | ||
| 180 | } | ||
| 181 | </style> | ||
| 182 | 1 | <template> |
src/views/dashboard/admin/components/PieChart.vue
| 1 | <template> | File was deleted | |
| 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 resize from './mixins/resize' | ||
| 9 | |||
| 10 | export default { | ||
| 11 | mixins: [resize], | ||
| 12 | props: { | ||
| 13 | className: { | ||
| 14 | type: String, | ||
| 15 | default: 'chart' | ||
| 16 | }, | ||
| 17 | width: { | ||
| 18 | type: String, | ||
| 19 | default: '100%' | ||
| 20 | }, | ||
| 21 | height: { | ||
| 22 | type: String, | ||
| 23 | default: '300px' | ||
| 24 | } | ||
| 25 | }, | ||
| 26 | data() { | ||
| 27 | return { | ||
| 28 | chart: null | ||
| 29 | } | ||
| 30 | }, | ||
| 31 | mounted() { | ||
| 32 | this.$nextTick(() => { | ||
| 33 | this.initChart() | ||
| 34 | }) | ||
| 35 | }, | ||
| 36 | beforeDestroy() { | ||
| 37 | if (!this.chart) { | ||
| 38 | return | ||
| 39 | } | ||
| 40 | this.chart.dispose() | ||
| 41 | this.chart = null | ||
| 42 | }, | ||
| 43 | methods: { | ||
| 44 | initChart() { | ||
| 45 | this.chart = echarts.init(this.$el, 'macarons') | ||
| 46 | |||
| 47 | this.chart.setOption({ | ||
| 48 | tooltip: { | ||
| 49 | trigger: 'item', | ||
| 50 | formatter: '{a} <br/>{b} : {c} ({d}%)' | ||
| 51 | }, | ||
| 52 | legend: { | ||
| 53 | left: 'center', | ||
| 54 | bottom: '10', | ||
| 55 | data: ['Industries', 'Technology', 'Forex', 'Gold', 'Forecasts'] | ||
| 56 | }, | ||
| 57 | series: [ | ||
| 58 | { | ||
| 59 | name: 'WEEKLY WRITE ARTICLES', | ||
| 60 | type: 'pie', | ||
| 61 | roseType: 'radius', | ||
| 62 | radius: [15, 95], | ||
| 63 | center: ['50%', '38%'], | ||
| 64 | data: [ | ||
| 65 | { value: 320, name: 'Industries' }, | ||
| 66 | { value: 240, name: 'Technology' }, | ||
| 67 | { value: 149, name: 'Forex' }, | ||
| 68 | { value: 100, name: 'Gold' }, | ||
| 69 | { value: 59, name: 'Forecasts' } | ||
| 70 | ], | ||
| 71 | animationEasing: 'cubicInOut', | ||
| 72 | animationDuration: 2600 | ||
| 73 | } | ||
| 74 | ] | ||
| 75 | }) | ||
| 76 | } | ||
| 77 | } | ||
| 78 | } | ||
| 79 | </script> | ||
| 80 | 1 | <template> |
src/views/dashboard/admin/components/RaddarChart.vue
| 1 | <template> | File was deleted | |
| 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 resize from './mixins/resize' | ||
| 9 | |||
| 10 | const animationDuration = 3000 | ||
| 11 | |||
| 12 | export default { | ||
| 13 | mixins: [resize], | ||
| 14 | props: { | ||
| 15 | className: { | ||
| 16 | type: String, | ||
| 17 | default: 'chart' | ||
| 18 | }, | ||
| 19 | width: { | ||
| 20 | type: String, | ||
| 21 | default: '100%' | ||
| 22 | }, | ||
| 23 | height: { | ||
| 24 | type: String, | ||
| 25 | default: '300px' | ||
| 26 | } | ||
| 27 | }, | ||
| 28 | data() { | ||
| 29 | return { | ||
| 30 | chart: null | ||
| 31 | } | ||
| 32 | }, | ||
| 33 | mounted() { | ||
| 34 | this.$nextTick(() => { | ||
| 35 | this.initChart() | ||
| 36 | }) | ||
| 37 | }, | ||
| 38 | beforeDestroy() { | ||
| 39 | if (!this.chart) { | ||
| 40 | return | ||
| 41 | } | ||
| 42 | this.chart.dispose() | ||
| 43 | this.chart = null | ||
| 44 | }, | ||
| 45 | methods: { | ||
| 46 | initChart() { | ||
| 47 | this.chart = echarts.init(this.$el, 'macarons') | ||
| 48 | |||
| 49 | this.chart.setOption({ | ||
| 50 | tooltip: { | ||
| 51 | trigger: 'axis', | ||
| 52 | axisPointer: { // 坐标轴指示器,坐标轴触发有效 | ||
| 53 | type: 'shadow' // 默认为直线,可选为:'line' | 'shadow' | ||
| 54 | } | ||
| 55 | }, | ||
| 56 | radar: { | ||
| 57 | radius: '66%', | ||
| 58 | center: ['50%', '42%'], | ||
| 59 | splitNumber: 8, | ||
| 60 | splitArea: { | ||
| 61 | areaStyle: { | ||
| 62 | color: 'rgba(127,95,132,.3)', | ||
| 63 | opacity: 1, | ||
| 64 | shadowBlur: 45, | ||
| 65 | shadowColor: 'rgba(0,0,0,.5)', | ||
| 66 | shadowOffsetX: 0, | ||
| 67 | shadowOffsetY: 15 | ||
| 68 | } | ||
| 69 | }, | ||
| 70 | indicator: [ | ||
| 71 | { name: 'Sales', max: 10000 }, | ||
| 72 | { name: 'Administration', max: 20000 }, | ||
| 73 | { name: 'Information Techology', max: 20000 }, | ||
| 74 | { name: 'Customer Support', max: 20000 }, | ||
| 75 | { name: 'Development', max: 20000 }, | ||
| 76 | { name: 'Marketing', max: 20000 } | ||
| 77 | ] | ||
| 78 | }, | ||
| 79 | legend: { | ||
| 80 | left: 'center', | ||
| 81 | bottom: '10', | ||
| 82 | data: ['Allocated Budget', 'Expected Spending', 'Actual Spending'] | ||
| 83 | }, | ||
| 84 | series: [{ | ||
| 85 | type: 'radar', | ||
| 86 | symbolSize: 0, | ||
| 87 | areaStyle: { | ||
| 88 | normal: { | ||
| 89 | shadowBlur: 13, | ||
| 90 | shadowColor: 'rgba(0,0,0,.2)', | ||
| 91 | shadowOffsetX: 0, | ||
| 92 | shadowOffsetY: 10, | ||
| 93 | opacity: 1 | ||
| 94 | } | ||
| 95 | }, | ||
| 96 | data: [ | ||
| 97 | { | ||
| 98 | value: [5000, 7000, 12000, 11000, 15000, 14000], | ||
| 99 | name: 'Allocated Budget' | ||
| 100 | }, | ||
| 101 | { | ||
| 102 | value: [4000, 9000, 15000, 15000, 13000, 11000], | ||
| 103 | name: 'Expected Spending' | ||
| 104 | }, | ||
| 105 | { | ||
| 106 | value: [5500, 11000, 12000, 15000, 12000, 12000], | ||
| 107 | name: 'Actual Spending' | ||
| 108 | } | ||
| 109 | ], | ||
| 110 | animationDuration: animationDuration | ||
| 111 | }] | ||
| 112 | }) | ||
| 113 | } | ||
| 114 | } | ||
| 115 | } | ||
| 116 | </script> | ||
| 117 | 1 | <template> |
src/views/dashboard/admin/components/TodoList/Todo.vue
| 1 | <template> | File was deleted | |
| 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 | > | ||
| 10 | <label @dblclick="editing = true" v-text="todo.text" /> | ||
| 11 | <button class="destroy" @click="deleteTodo( todo )" /> | ||
| 12 | </div> | ||
| 13 | <input | ||
| 14 | v-show="editing" | ||
| 15 | v-focus="editing" | ||
| 16 | :value="todo.text" | ||
| 17 | class="edit" | ||
| 18 | @keyup.enter="doneEdit" | ||
| 19 | @keyup.esc="cancelEdit" | ||
| 20 | @blur="doneEdit" | ||
| 21 | > | ||
| 22 | </li> | ||
| 23 | </template> | ||
| 24 | |||
| 25 | <script> | ||
| 26 | export default { | ||
| 27 | name: 'Todo', | ||
| 28 | directives: { | ||
| 29 | focus(el, { value }, { context }) { | ||
| 30 | if (value) { | ||
| 31 | context.$nextTick(() => { | ||
| 32 | el.focus() | ||
| 33 | }) | ||
| 34 | } | ||
| 35 | } | ||
| 36 | }, | ||
| 37 | props: { | ||
| 38 | todo: { | ||
| 39 | type: Object, | ||
| 40 | default: function() { | ||
| 41 | return {} | ||
| 42 | } | ||
| 43 | } | ||
| 44 | }, | ||
| 45 | data() { | ||
| 46 | return { | ||
| 47 | editing: false | ||
| 48 | } | ||
| 49 | }, | ||
| 50 | methods: { | ||
| 51 | deleteTodo(todo) { | ||
| 52 | this.$emit('deleteTodo', todo) | ||
| 53 | }, | ||
| 54 | editTodo({ todo, value }) { | ||
| 55 | this.$emit('editTodo', { todo, value }) | ||
| 56 | }, | ||
| 57 | toggleTodo(todo) { | ||
| 58 | this.$emit('toggleTodo', todo) | ||
| 59 | }, | ||
| 60 | doneEdit(e) { | ||
| 61 | const value = e.target.value.trim() | ||
| 62 | const { todo } = this | ||
| 63 | if (!value) { | ||
| 64 | this.deleteTodo({ | ||
| 65 | todo | ||
| 66 | }) | ||
| 67 | } else if (this.editing) { | ||
| 68 | this.editTodo({ | ||
| 69 | todo, | ||
| 70 | value | ||
| 71 | }) | ||
| 72 | this.editing = false | ||
| 73 | } | ||
| 74 | }, | ||
| 75 | cancelEdit(e) { | ||
| 76 | e.target.value = this.todo.text | ||
| 77 | this.editing = false | ||
| 78 | } | ||
| 79 | } | ||
| 80 | } | ||
| 81 | </script> | ||
| 82 | 1 | <template> |
src/views/dashboard/admin/components/TodoList/index.scss
| 1 | .todoapp { | File was deleted | |
| 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 | } | ||
| 321 | 1 | .todoapp { |
src/views/dashboard/admin/components/TodoList/index.vue
| 1 | <template> | File was deleted | |
| 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 | /> | ||
| 20 | </ul> | ||
| 21 | </section> | ||
| 22 | <!-- footer --> | ||
| 23 | <footer v-show="todos.length" class="footer"> | ||
| 24 | <span class="todo-count"> | ||
| 25 | <strong>{{ remaining }}</strong> | ||
| 26 | {{ remaining | pluralize('item') }} left | ||
| 27 | </span> | ||
| 28 | <ul class="filters"> | ||
| 29 | <li v-for="(val, key) in filters" :key="key"> | ||
| 30 | <a :class="{ selected: visibility === key }" @click.prevent="visibility = key">{{ key | capitalize }}</a> | ||
| 31 | </li> | ||
| 32 | </ul> | ||
| 33 | <!-- <button class="clear-completed" v-show="todos.length > remaining" @click="clearCompleted"> | ||
| 34 | Clear completed | ||
| 35 | </button> --> | ||
| 36 | </footer> | ||
| 37 | </section> | ||
| 38 | </template> | ||
| 39 | |||
| 40 | <script> | ||
| 41 | import Todo from './Todo.vue' | ||
| 42 | |||
| 43 | const STORAGE_KEY = 'todos' | ||
| 44 | const filters = { | ||
| 45 | all: todos => todos, | ||
| 46 | active: todos => todos.filter(todo => !todo.done), | ||
| 47 | completed: todos => todos.filter(todo => todo.done) | ||
| 48 | } | ||
| 49 | const defalutList = [ | ||
| 50 | { text: 'star this repository', done: false }, | ||
| 51 | { text: 'fork this repository', done: false }, | ||
| 52 | { text: 'follow author', done: false }, | ||
| 53 | { text: 'vue-element-admin', done: true }, | ||
| 54 | { text: 'vue', done: true }, | ||
| 55 | { text: 'element-ui', done: true }, | ||
| 56 | { text: 'axios', done: true }, | ||
| 57 | { text: 'webpack', done: true } | ||
| 58 | ] | ||
| 59 | export default { | ||
| 60 | components: { Todo }, | ||
| 61 | filters: { | ||
| 62 | pluralize: (n, w) => n === 1 ? w : w + 's', | ||
| 63 | capitalize: s => s.charAt(0).toUpperCase() + s.slice(1) | ||
| 64 | }, | ||
| 65 | data() { | ||
| 66 | return { | ||
| 67 | visibility: 'all', | ||
| 68 | filters, | ||
| 69 | // todos: JSON.parse(window.localStorage.getItem(STORAGE_KEY)) || defalutList | ||
| 70 | todos: defalutList | ||
| 71 | } | ||
| 72 | }, | ||
| 73 | computed: { | ||
| 74 | allChecked() { | ||
| 75 | return this.todos.every(todo => todo.done) | ||
| 76 | }, | ||
| 77 | filteredTodos() { | ||
| 78 | return filters[this.visibility](this.todos) | ||
| 79 | }, | ||
| 80 | remaining() { | ||
| 81 | return this.todos.filter(todo => !todo.done).length | ||
| 82 | } | ||
| 83 | }, | ||
| 84 | methods: { | ||
| 85 | setLocalStorage() { | ||
| 86 | window.localStorage.setItem(STORAGE_KEY, JSON.stringify(this.todos)) | ||
| 87 | }, | ||
| 88 | addTodo(e) { | ||
| 89 | const text = e.target.value | ||
| 90 | if (text.trim()) { | ||
| 91 | this.todos.push({ | ||
| 92 | text, | ||
| 93 | done: false | ||
| 94 | }) | ||
| 95 | this.setLocalStorage() | ||
| 96 | } | ||
| 97 | e.target.value = '' | ||
| 98 | }, | ||
| 99 | toggleTodo(val) { | ||
| 100 | val.done = !val.done | ||
| 101 | this.setLocalStorage() | ||
| 102 | }, | ||
| 103 | deleteTodo(todo) { | ||
| 104 | this.todos.splice(this.todos.indexOf(todo), 1) | ||
| 105 | this.setLocalStorage() | ||
| 106 | }, | ||
| 107 | editTodo({ todo, value }) { | ||
| 108 | todo.text = value | ||
| 109 | this.setLocalStorage() | ||
| 110 | }, | ||
| 111 | clearCompleted() { | ||
| 112 | this.todos = this.todos.filter(todo => !todo.done) | ||
| 113 | this.setLocalStorage() | ||
| 114 | }, | ||
| 115 | toggleAll({ done }) { | ||
| 116 | this.todos.forEach(todo => { | ||
| 117 | todo.done = done | ||
| 118 | this.setLocalStorage() | ||
| 119 | }) | ||
| 120 | } | ||
| 121 | } | ||
| 122 | } | ||
| 123 | </script> | ||
| 124 | |||
| 125 | <style lang="scss"> | ||
| 126 | @import './index.scss'; | ||
| 127 | </style> | ||
| 128 | 1 | <template> |
src/views/dashboard/admin/components/TransactionTable.vue
| 1 | <template> | File was deleted | |
| 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="{row}"> | ||
| 15 | <el-tag :type="row.status | statusFilter"> | ||
| 16 | {{ row.status }} | ||
| 17 | </el-tag> | ||
| 18 | </template> | ||
| 19 | </el-table-column> | ||
| 20 | </el-table> | ||
| 21 | </template> | ||
| 22 | |||
| 23 | <script> | ||
| 24 | import { transactionList } from '@/api/remote-search' | ||
| 25 | |||
| 26 | export default { | ||
| 27 | filters: { | ||
| 28 | statusFilter(status) { | ||
| 29 | const statusMap = { | ||
| 30 | success: 'success', | ||
| 31 | pending: 'danger' | ||
| 32 | } | ||
| 33 | return statusMap[status] | ||
| 34 | }, | ||
| 35 | orderNoFilter(str) { | ||
| 36 | return str.substring(0, 30) | ||
| 37 | } | ||
| 38 | }, | ||
| 39 | data() { | ||
| 40 | return { | ||
| 41 | list: null | ||
| 42 | } | ||
| 43 | }, | ||
| 44 | created() { | ||
| 45 | this.fetchData() | ||
| 46 | }, | ||
| 47 | methods: { | ||
| 48 | fetchData() { | ||
| 49 | transactionList().then(response => { | ||
| 50 | this.list = response.data.items.slice(0, 8) | ||
| 51 | }) | ||
| 52 | } | ||
| 53 | } | ||
| 54 | } | ||
| 55 | </script> | ||
| 56 | 1 | <template> |
src/views/dashboard/admin/components/mixins/resize.js
| 1 | import { debounce } from '@/utils' | File was deleted | |
| 2 | |||
| 3 | export default { | ||
| 4 | data() { | ||
| 5 | return { | ||
| 6 | $_sidebarElm: null, | ||
| 7 | $_resizeHandler: null | ||
| 8 | } | ||
| 9 | }, | ||
| 10 | mounted() { | ||
| 11 | this.$_resizeHandler = debounce(() => { | ||
| 12 | if (this.chart) { | ||
| 13 | this.chart.resize() | ||
| 14 | } | ||
| 15 | }, 100) | ||
| 16 | this.$_initResizeEvent() | ||
| 17 | this.$_initSidebarResizeEvent() | ||
| 18 | }, | ||
| 19 | beforeDestroy() { | ||
| 20 | this.$_destroyResizeEvent() | ||
| 21 | this.$_destroySidebarResizeEvent() | ||
| 22 | }, | ||
| 23 | // to fixed bug when cached by keep-alive | ||
| 24 | // https://github.com/PanJiaChen/vue-element-admin/issues/2116 | ||
| 25 | activated() { | ||
| 26 | this.$_initResizeEvent() | ||
| 27 | this.$_initSidebarResizeEvent() | ||
| 28 | }, | ||
| 29 | deactivated() { | ||
| 30 | this.$_destroyResizeEvent() | ||
| 31 | this.$_destroySidebarResizeEvent() | ||
| 32 | }, | ||
| 33 | methods: { | ||
| 34 | // use $_ for mixins properties | ||
| 35 | // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential | ||
| 36 | $_initResizeEvent() { | ||
| 37 | window.addEventListener('resize', this.$_resizeHandler) | ||
| 38 | }, | ||
| 39 | $_destroyResizeEvent() { | ||
| 40 | window.removeEventListener('resize', this.$_resizeHandler) | ||
| 41 | }, | ||
| 42 | $_sidebarResizeHandler(e) { | ||
| 43 | if (e.propertyName === 'width') { | ||
| 44 | this.$_resizeHandler() | ||
| 45 | } | ||
| 46 | }, | ||
| 47 | $_initSidebarResizeEvent() { | ||
| 48 | this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0] | ||
| 49 | this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler) | ||
| 50 | }, | ||
| 51 | $_destroySidebarResizeEvent() { | ||
| 52 | this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler) | ||
| 53 | } | ||
| 54 | } | ||
| 55 | } | ||
| 56 | 1 | import { debounce } from '@/utils' |
src/views/dashboard/admin/index.vue
| 1 | <template> | 1 | <template> |
| 2 | <div class="dashboard-editor-container"> | 2 | <div class="dashboard-editor-container"> |
| 3 | <!-- <github-corner class="github-corner" /> --> | 3 | <!-- <github-corner class="github-corner" /> --> |
| 4 | 4 | ||
| 5 | <panel-group @handleSetLineChartData="handleSetLineChartData" /> | 5 | <panel-group @handleSetLineChartData="handleSetLineChartData" /> |
| 6 | 6 | ||
| 7 | <el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;"> | 7 | <el-row style="background:#fff;padding:16px 16px 0;margin-bottom:32px;"> |
| 8 | <line-chart :chart-data="lineChartData" /> | 8 | <line-chart :chart-data="lineChartData" /> |
| 9 | </el-row> | 9 | </el-row> |
| 10 | 10 | ||
| 11 | <el-row :gutter="32"> | 11 | <el-row :gutter="32"> |
| 12 | <el-col :xs="24" :sm="24" :lg="8"> | 12 | <el-col |
| 13 | :xs="24" | ||
| 14 | :sm="24" | ||
| 15 | :lg="8" | ||
| 16 | > | ||
| 13 | <div class="chart-wrapper"> | 17 | <div class="chart-wrapper"> |
| 14 | <raddar-chart /> | 18 | <raddar-chart /> |
| 15 | </div> | 19 | </div> |
| 16 | </el-col> | 20 | </el-col> |
| 17 | <el-col :xs="24" :sm="24" :lg="8"> | 21 | <el-col |
| 22 | :xs="24" | ||
| 23 | :sm="24" | ||
| 24 | :lg="8" | ||
| 25 | > | ||
| 18 | <div class="chart-wrapper"> | 26 | <div class="chart-wrapper"> |
| 19 | <pie-chart /> | 27 | <pie-chart /> |
| 20 | </div> | 28 | </div> |
| 21 | </el-col> | 29 | </el-col> |
| 22 | <el-col :xs="24" :sm="24" :lg="8"> | 30 | <el-col |
| 31 | :xs="24" | ||
| 32 | :sm="24" | ||
| 33 | :lg="8" | ||
| 34 | > | ||
| 23 | <div class="chart-wrapper"> | 35 | <div class="chart-wrapper"> |
| 24 | <bar-chart /> | 36 | <bar-chart /> |
| 25 | </div> | 37 | </div> |
| 26 | </el-col> | 38 | </el-col> |
| 27 | </el-row> | 39 | </el-row> |
| 28 | 40 | ||
| 29 | <el-row :gutter="8"> | 41 | <el-row :gutter="8"> |
| 30 | <el-col :xs="{span: 24}" :sm="{span: 24}" :md="{span: 24}" :lg="{span: 12}" :xl="{span: 12}" style="padding-right:8px;margin-bottom:30px;"> | 42 | <el-col |
| 43 | :xs="{span: 24}" | ||
| 44 | :sm="{span: 24}" | ||
| 45 | :md="{span: 24}" | ||
| 46 | :lg="{span: 12}" | ||
| 47 | :xl="{span: 12}" | ||
| 48 | style="padding-right:8px;margin-bottom:30px;" | ||
| 49 | > | ||
| 31 | <transaction-table /> | 50 | <transaction-table /> |
| 32 | </el-col> | 51 | </el-col> |
| 33 | <el-col :xs="{span: 24}" :sm="{span: 12}" :md="{span: 12}" :lg="{span: 6}" :xl="{span: 6}" style="margin-bottom:30px;"> | 52 | <el-col |
| 53 | :xs="{span: 24}" | ||
| 54 | :sm="{span: 12}" | ||
| 55 | :md="{span: 12}" | ||
| 56 | :lg="{span: 6}" | ||
| 57 | :xl="{span: 6}" | ||
| 58 | style="margin-bottom:30px;" | ||
| 59 | > | ||
| 34 | <todo-list /> | 60 | <todo-list /> |
| 35 | </el-col> | 61 | </el-col> |
| 36 | <el-col :xs="{span: 24}" :sm="{span: 12}" :md="{span: 12}" :lg="{span: 6}" :xl="{span: 6}" style="margin-bottom:30px;"> | 62 | <el-col |
| 63 | :xs="{span: 24}" | ||
| 64 | :sm="{span: 12}" | ||
| 65 | :md="{span: 12}" | ||
| 66 | :lg="{span: 6}" | ||
| 67 | :xl="{span: 6}" | ||
| 68 | style="margin-bottom:30px;" | ||
| 69 | > | ||
| 37 | <box-card /> | 70 | <box-card /> |
| 38 | </el-col> | 71 | </el-col> |
| 39 | </el-row> | 72 | </el-row> |
| 40 | </div> | 73 | </div> |
| 41 | </template> | 74 | </template> |
| 42 | 75 | ||
| 43 | <script> | 76 | <script> |
| 44 | // import GithubCorner from '@/components/GithubCorner' | 77 | // import GithubCorner from '@/components/GithubCorner' |
| 45 | import PanelGroup from './components/PanelGroup' | 78 | import PanelGroup from '@/components/PanelGroup' |
| 46 | import LineChart from './components/LineChart' | 79 | import RaddarChart from '@/components/RaddarChart' |
| 47 | import RaddarChart from './components/RaddarChart' | 80 | import PieChart from '@/components/PieChart' |
| 48 | import PieChart from './components/PieChart' | 81 | import BarChart from '@/components/BarChart' |
| 49 | import BarChart from './components/BarChart' | 82 | import LineChart from '@/components/LineChart' |
| 50 | import TransactionTable from './components/TransactionTable' | 83 | import TransactionTable from '@/components/TransactionTable' |
| 51 | import TodoList from './components/TodoList' | 84 | import TodoList from '@/components/TodoList' |
| 52 | import BoxCard from './components/BoxCard' | 85 | import BoxCard from '@/components/BoxCard' |
| 53 | 86 | ||
| 54 | const lineChartData = { | 87 | const lineChartData = { |
| 55 | newVisitis: { | 88 | newVisitis: { |
| 56 | expectedData: [100, 120, 161, 134, 105, 160, 165], | 89 | expectedData: [100, 120, 161, 134, 105, 160, 165], |
| 57 | actualData: [120, 82, 91, 154, 162, 140, 145] | 90 | actualData: [120, 82, 91, 154, 162, 140, 145] |
| 58 | }, | 91 | }, |
| 59 | messages: { | 92 | messages: { |
| 60 | expectedData: [200, 192, 120, 144, 160, 130, 140], | 93 | expectedData: [200, 192, 120, 144, 160, 130, 140], |
| 61 | actualData: [180, 160, 151, 106, 145, 150, 130] | 94 | actualData: [180, 160, 151, 106, 145, 150, 130] |
| 62 | }, | 95 | }, |
| 63 | purchases: { | 96 | purchases: { |
| 64 | expectedData: [80, 100, 121, 104, 105, 90, 100], | 97 | expectedData: [80, 100, 121, 104, 105, 90, 100], |
| 65 | actualData: [120, 90, 100, 138, 142, 130, 130] | 98 | actualData: [120, 90, 100, 138, 142, 130, 130] |
| 66 | }, | 99 | }, |
| 67 | shoppings: { | 100 | shoppings: { |
| 68 | expectedData: [130, 140, 141, 142, 145, 150, 160], | 101 | expectedData: [130, 140, 141, 142, 145, 150, 160], |
| 69 | actualData: [120, 82, 91, 154, 162, 140, 130] | 102 | actualData: [120, 82, 91, 154, 162, 140, 130] |
| 70 | } | 103 | } |
| 71 | } | 104 | } |
| 72 | 105 | ||
| 73 | export default { | 106 | export default { |
| 74 | name: 'DashboardAdmin', | 107 | name: 'DashboardAdmin', |
| 75 | components: { | 108 | components: { |
| 76 | // GithubCorner, | 109 | // GithubCorner, |
| 77 | PanelGroup, | 110 | PanelGroup, |
| 78 | LineChart, | 111 | LineChart, |
| 79 | RaddarChart, | 112 | RaddarChart, |
| 80 | PieChart, | 113 | PieChart, |
| 81 | BarChart, | 114 | BarChart, |
| 82 | TransactionTable, | 115 | TransactionTable, |
| 83 | TodoList, | 116 | TodoList, |
| 84 | BoxCard | 117 | BoxCard |
| 85 | }, | 118 | }, |
| 86 | data() { | 119 | data() { |
| 87 | return { | 120 | return { |
| 88 | lineChartData: lineChartData.newVisitis | 121 | lineChartData: lineChartData.newVisitis |
| 89 | } | 122 | } |
| 90 | }, | 123 | }, |
| 91 | methods: { | 124 | methods: { |
| 92 | handleSetLineChartData(type) { | 125 | handleSetLineChartData(type) { |
| 93 | this.lineChartData = lineChartData[type] | 126 | this.lineChartData = lineChartData[type] |
| 94 | } | 127 | } |
| 95 | } | 128 | } |
| 96 | } | 129 | } |
| 97 | </script> | 130 | </script> |
| 98 | 131 | ||
| 99 | <style lang="scss" scoped> | 132 | <style lang="scss" scoped> |
| 100 | .dashboard-editor-container { | 133 | .dashboard-editor-container { |
| 101 | padding: 32px; | 134 | padding: 32px; |
| 102 | background-color: rgb(240, 242, 245); | 135 | background-color: rgb(240, 242, 245); |
| 103 | position: relative; | 136 | position: relative; |
| 104 | 137 | ||
| 105 | .github-corner { | 138 | .github-corner { |
| 106 | position: absolute; | 139 | position: absolute; |
| 107 | top: 0px; | 140 | top: 0px; |
| 108 | border: 0; | 141 | border: 0; |
| 109 | right: 0; | 142 | right: 0; |
| 110 | } | 143 | } |
| 111 | 144 | ||
| 112 | .chart-wrapper { | 145 | .chart-wrapper { |
| 113 | background: #fff; | 146 | background: #fff; |
| 114 | padding: 16px 16px 0; | 147 | padding: 16px 16px 0; |
| 115 | margin-bottom: 32px; | 148 | margin-bottom: 32px; |
| 116 | } | 149 | } |
| 117 | } | 150 | } |
| 118 | 151 | ||
| 119 | @media (max-width:1024px) { | 152 | @media (max-width: 1024px) { |
| 120 | .chart-wrapper { | 153 | .chart-wrapper { |
| 121 | padding: 8px; | 154 | padding: 8px; |
| 122 | } | 155 | } |
| 123 | } | 156 | } |
| 124 | </style> | 157 | </style> |
| 125 | 158 |
src/views/dashboard/runner/index.vue
| 1 | <template> | 1 | <template> |
| 2 | <div class="dashboard-editor-container"> | 2 | <div class="dashboard-editor-container"> |
| 3 | <div class="clearfix"> | 3 | <div class="clearfix"> |
| 4 | <pan-thumb :image="avatar" style="float: left"> | 4 | <pan-thumb |
| 5 | :image="avatar" | ||
| 6 | style="float: left" | ||
| 7 | > | ||
| 5 | Your roles: | 8 | Your roles: |
| 6 | <span v-for="item in roles" :key="item" class="pan-info-roles">{{ item }}</span> | 9 | <span |
| 10 | v-for="item in roles" | ||
| 11 | :key="item" | ||
| 12 | class="pan-info-roles" | ||
| 13 | >{{ item }}</span> | ||
| 7 | </pan-thumb> | 14 | </pan-thumb> |
| 8 | <github-corner style="position: absolute; top: 0px; border: 0; right: 0;" /> | 15 | <!-- <github-corner style="position: absolute; top: 0px; border: 0; right: 0;" /> --> |
| 9 | <div class="info-container"> | 16 | <div class="info-container"> |
| 10 | <span class="display_name">{{ name }}</span> | 17 | <span class="display_name">{{ name }}</span> |
| 11 | <span style="font-size:20px;padding-top:20px;display:inline-block;">{{ roles }}'s Dashboard</span> | 18 | <span style="font-size:20px;padding-top:20px;display:inline-block;">{{ roles }}'s Dashboard</span> |
| 12 | </div> | 19 | </div> |
| 13 | </div> | 20 | </div> |
| 14 | <div> | 21 | <div> |
| 15 | <img :src="emptyGif" class="emptyGif"> | 22 | <!-- <img :src="emptyGif" class="emptyGif"> --> |
| 23 | </div> | ||
| 24 | <div> | ||
| 25 | <el-row :gutter="8"> | ||
| 26 | <el-col | ||
| 27 | :xs="{span: 24}" | ||
| 28 | :sm="{span: 24}" | ||
| 29 | :md="{span: 24}" | ||
| 30 | :lg="{span: 12}" | ||
| 31 | :xl="{span: 12}" | ||
| 32 | style="padding-right:8px;margin-bottom:30px;" | ||
| 33 | > | ||
| 34 | <transaction-table /> | ||
| 35 | </el-col> | ||
| 36 | <el-col | ||
| 37 | :xs="{span: 24}" | ||
| 38 | :sm="{span: 24}" | ||
| 39 | :md="{span: 24}" | ||
| 40 | :lg="{span: 12}" | ||
| 41 | :xl="{span: 12}" | ||
| 42 | style="margin-bottom:30px;" | ||
| 43 | > | ||
| 44 | <todo-list /> | ||
| 45 | </el-col> | ||
| 46 | </el-row> | ||
| 16 | </div> | 47 | </div> |
| 17 | </div> | 48 | </div> |
| 18 | </template> | 49 | </template> |
| 19 | 50 | ||
| 20 | <script> | 51 | <script> |
| 21 | import { mapGetters } from 'vuex' | 52 | import { mapGetters } from 'vuex' |
| 22 | import PanThumb from '@/components/PanThumb' | 53 | import PanThumb from '@/components/PanThumb' |
| 54 | import TransactionTable from '@/components/TransactionTable' | ||
| 55 | import TodoList from '@/components/TodoList' | ||
| 56 | // import BoxCard from "./components/BoxCard"; | ||
| 23 | // import GithubCorner from '@/components/GithubCorner' | 57 | // import GithubCorner from '@/components/GithubCorner' |
| 24 | 58 | ||
| 25 | export default { | 59 | export default { |
| 26 | name: 'DashboardEditor', | 60 | name: 'DashboardEditor', |
| 27 | // components: { PanThumb, GithubCorner }, | 61 | // components: { PanThumb, GithubCorner }, |
| 28 | components: { PanThumb }, | 62 | components: { PanThumb, TransactionTable, TodoList }, |
| 29 | data() { | 63 | data() { |
| 30 | return { | 64 | return { |
| 31 | emptyGif: | 65 | emptyGif: |
| 32 | 'https://wpimg.wallstcn.com/0e03b7da-db9e-4819-ba10-9016ddfdaed3' | 66 | 'https://wpimg.wallstcn.com/0e03b7da-db9e-4819-ba10-9016ddfdaed3' |
| 33 | } | 67 | } |
| 34 | }, | 68 | }, |
| 35 | computed: { | 69 | computed: { |
| 36 | ...mapGetters(['name', 'avatar', 'roles']) | 70 | ...mapGetters(['name', 'avatar', 'roles']) |
| 37 | } | 71 | } |
| 38 | } | 72 | } |
| 39 | </script> | 73 | </script> |
| 40 | 74 | ||
| 41 | <style lang="scss" scoped> | 75 | <style lang="scss" scoped> |
| 42 | .emptyGif { | 76 | .emptyGif { |
| 43 | display: block; | 77 | display: block; |
| 44 | width: 45%; | 78 | width: 45%; |
| 45 | margin: 0 auto; | 79 | margin: 0 auto; |
| 46 | } | 80 | } |
| 47 | 81 | ||
| 48 | .dashboard-editor-container { | 82 | .dashboard-editor-container { |
| 49 | background-color: #e3e3e3; | 83 | background-color: #e3e3e3; |
| 50 | min-height: 100vh; | 84 | min-height: 100vh; |
| 51 | padding: 50px 60px 0px; | 85 | padding: 50px 60px 0px; |
| 52 | .pan-info-roles { | 86 | .pan-info-roles { |
| 53 | font-size: 12px; | 87 | font-size: 12px; |
| 54 | font-weight: 700; | 88 | font-weight: 700; |
| 55 | color: #333; | 89 | color: #333; |
| 56 | display: block; | 90 | display: block; |
| 57 | } | 91 | } |
| 58 | .info-container { | 92 | .info-container { |
| 59 | position: relative; | 93 | position: relative; |
| 60 | margin-left: 190px; | 94 | margin-left: 190px; |
| 61 | height: 150px; | 95 | height: 150px; |
| 62 | line-height: 200px; | 96 | line-height: 200px; |
| 63 | .display_name { | 97 | .display_name { |
| 64 | font-size: 48px; | 98 | font-size: 48px; |
| 65 | line-height: 48px; | 99 | line-height: 48px; |
| 66 | color: #212121; | 100 | color: #212121; |
| 67 | position: absolute; | 101 | position: absolute; |
| 68 | top: 25px; | 102 | top: 25px; |
| 69 | } | 103 | } |
| 70 | } | 104 | } |
| 71 | } | 105 | } |
| 72 | </style> | 106 | </style> |
| 73 | 107 |
src/views/dashboard/shoper/index.vue
| File was created | 1 | <template> | |
| 2 | <div class="dashboard-editor-container"> | ||
| 3 | <div class="clearfix"> | ||
| 4 | <pan-thumb | ||
| 5 | :image="avatar" | ||
| 6 | style="float: left" | ||
| 7 | > | ||
| 8 | Your roles: | ||
| 9 | <span | ||
| 10 | v-for="item in roles" | ||
| 11 | :key="item" | ||
| 12 | class="pan-info-roles" | ||
| 13 | >{{ item }}</span> | ||
| 14 | </pan-thumb> | ||
| 15 | <github-corner style="position: absolute; top: 0px; border: 0; right: 0;" /> | ||
| 16 | <div class="info-container"> | ||
| 17 | <span class="display_name">{{ name }}</span> | ||
| 18 | <span style="font-size:20px;padding-top:20px;display:inline-block;">{{ roles }}'s Dashboard</span> | ||
| 19 | </div> | ||
| 20 | </div> | ||
| 21 | <div> | ||
| 22 | <img | ||
| 23 | :src="emptyGif" | ||
| 24 | class="emptyGif" | ||
| 25 | > | ||
| 26 | </div> | ||
| 27 | </div> | ||
| 28 | </template> | ||
| 29 | |||
| 30 | <script> | ||
| 31 | import { mapGetters } from 'vuex' | ||
| 32 | import PanThumb from '@/components/PanThumb' | ||
| 33 | // import GithubCorner from '@/components/GithubCorner' | ||
| 34 | |||
| 35 | export default { | ||
| 36 | name: 'DashboardEditor', | ||
| 37 | // components: { PanThumb, GithubCorner }, | ||
| 38 | components: { PanThumb }, | ||
| 39 | data() { | ||
| 40 | return { | ||
| 41 | emptyGif: | ||
| 42 | 'https://wpimg.wallstcn.com/0e03b7da-db9e-4819-ba10-9016ddfdaed3' | ||
| 43 | } | ||
| 44 | }, | ||
| 45 | computed: { | ||
| 46 | ...mapGetters(['name', 'avatar', 'roles']) | ||
| 47 | } | ||
| 48 | } | ||
| 49 | </script> | ||
| 50 | |||
| 51 | <style lang="scss" scoped> | ||
| 52 | .emptyGif { | ||
| 53 | display: block; | ||
| 54 | width: 45%; | ||
| 55 | margin: 0 auto; | ||
| 56 | } | ||
| 57 | |||
| 58 | .dashboard-editor-container { | ||
| 59 | background-color: #e3e3e3; | ||
| 60 | min-height: 100vh; | ||
| 61 | padding: 50px 60px 0px; | ||
| 62 | .pan-info-roles { | ||
| 63 | font-size: 12px; | ||
| 64 | font-weight: 700; | ||
| 65 | color: #333; | ||
| 66 | display: block; | ||
| 67 | } | ||
| 68 | .info-container { | ||
| 69 | position: relative; | ||
| 70 | margin-left: 190px; | ||
| 71 | height: 150px; | ||
| 72 | line-height: 200px; | ||
| 73 | .display_name { | ||
| 74 | font-size: 48px; | ||
| 75 | line-height: 48px; | ||
| 76 | color: #212121; | ||
| 77 | position: absolute; | ||
| 78 | top: 25px; | ||
| 79 | } | ||
| 80 | } | ||
| 81 | } | ||
| 82 | </style> | ||
| 83 |
src/views/prod/fav.vue
| File was created | 1 | <template> | |
| 2 | <div class="app-container"> | ||
| 3 | <!-- <el-header> | ||
| 4 | |||
| 5 | </el-header> --> | ||
| 6 | <template> | ||
| 7 | <router-link :to="'/prod/create/1111'"> | ||
| 8 | <el-button | ||
| 9 | type="primary" | ||
| 10 | size="small" | ||
| 11 | icon="el-icon-edit" | ||
| 12 | > | ||
| 13 | create | ||
| 14 | </el-button> | ||
| 15 | </router-link> | ||
| 16 | </template> | ||
| 17 | <el-table | ||
| 18 | v-loading="listLoading" | ||
| 19 | :data="list" | ||
| 20 | border | ||
| 21 | fit | ||
| 22 | highlight-current-row | ||
| 23 | style="width: 100%" | ||
| 24 | > | ||
| 25 | <el-table-column | ||
| 26 | align="center" | ||
| 27 | label="pid" | ||
| 28 | > | ||
| 29 | <template slot-scope="scope"> | ||
| 30 | <span>{{ scope.row.pid }}</span> | ||
| 31 | </template> | ||
| 32 | </el-table-column> | ||
| 33 | <el-table-column | ||
| 34 | align="center" | ||
| 35 | label="pname" | ||
| 36 | > | ||
| 37 | <template slot-scope="scope"> | ||
| 38 | <span>{{ scope.row.pname }}</span> | ||
| 39 | </template> | ||
| 40 | </el-table-column> | ||
| 41 | <el-table-column | ||
| 42 | align="center" | ||
| 43 | label="参数信息" | ||
| 44 | > | ||
| 45 | <template slot-scope="scope"> | ||
| 46 | <span>框宽{{ scope.row.prod_info_frame_width }}mm</span><br> | ||
| 47 | <span>腿长{{ scope.row.prod_info_leg_long }}mm</span><br> | ||
| 48 | <span>镜宽{{ scope.row.prod_info_glass_width }}mm</span><br> | ||
| 49 | <span>镜高{{ scope.row.prod_info_glass_height }}mm</span><br> | ||
| 50 | <span>鼻宽{{ scope.row.prod_info_norse_width }}mm</span><br> | ||
| 51 | <span>重量{{ scope.row.prod_info_weight }}g</span> | ||
| 52 | </template> | ||
| 53 | </el-table-column> | ||
| 54 | |||
| 55 | <el-table-column | ||
| 56 | align="center" | ||
| 57 | label="Date" | ||
| 58 | > | ||
| 59 | <template slot-scope="scope"> | ||
| 60 | <span>{{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span> | ||
| 61 | </template> | ||
| 62 | </el-table-column> | ||
| 63 | |||
| 64 | <el-table-column label="Importance"> | ||
| 65 | <template slot-scope="scope"> | ||
| 66 | <svg-icon | ||
| 67 | v-for="n in +scope.row.importance" | ||
| 68 | :key="n" | ||
| 69 | icon-class="star" | ||
| 70 | class="meta-item__icon" | ||
| 71 | /> | ||
| 72 | </template> | ||
| 73 | </el-table-column> | ||
| 74 | |||
| 75 | <el-table-column | ||
| 76 | class-name="status-col" | ||
| 77 | label="prod_status" | ||
| 78 | > | ||
| 79 | <template slot-scope="{row}"> | ||
| 80 | <el-tag :type="row.prod_status | statusFilter"> | ||
| 81 | {{ row.prod_status }} | ||
| 82 | </el-tag> | ||
| 83 | </template> | ||
| 84 | </el-table-column> | ||
| 85 | |||
| 86 | <el-table-column | ||
| 87 | align="center" | ||
| 88 | label="Actions" | ||
| 89 | > | ||
| 90 | <template slot-scope="{row}"> | ||
| 91 | <router-link :to="'/prod/edit/'+row.pid"> | ||
| 92 | <el-button | ||
| 93 | type="primary" | ||
| 94 | size="small" | ||
| 95 | icon="el-icon-edit" | ||
| 96 | > | ||
| 97 | Edit1 | ||
| 98 | </el-button> | ||
| 99 | </router-link> | ||
| 100 | <router-link :to="'/prod/del/'+row.pid"> | ||
| 101 | <el-button | ||
| 102 | type="primary" | ||
| 103 | size="small" | ||
| 104 | icon="el-icon-edit" | ||
| 105 | > | ||
| 106 | Edit2 | ||
| 107 | </el-button> | ||
| 108 | </router-link> | ||
| 109 | </template> | ||
| 110 | </el-table-column> | ||
| 111 | </el-table> | ||
| 112 | |||
| 113 | <pagination | ||
| 114 | v-show="total>0" | ||
| 115 | :total="total" | ||
| 116 | :page.sync="listQuery.page" | ||
| 117 | :limit.sync="listQuery.limit" | ||
| 118 | @pagination="getList" | ||
| 119 | /> | ||
| 120 | </div> | ||
| 121 | </template> | ||
| 122 | |||
| 123 | <script> | ||
| 124 | import { fetchList } from '@/api/prod' | ||
| 125 | // import { Pagination } from "@/components/Pagination"; // Secondary package based on el-pagination | ||
| 126 | import Pagination from '@/components/Pagination' // Secondary package based on el-pagination | ||
| 127 | export default { | ||
| 128 | name: 'ProdList', | ||
| 129 | components: { Pagination }, | ||
| 130 | filters: { | ||
| 131 | statusFilter(prod_status) { | ||
| 132 | const statusMap = { | ||
| 133 | published: 'success', | ||
| 134 | draft: 'info', | ||
| 135 | deleted: 'danger' | ||
| 136 | } | ||
| 137 | return statusMap[prod_status] | ||
| 138 | } | ||
| 139 | }, | ||
| 140 | data() { | ||
| 141 | return { | ||
| 142 | list: null, | ||
| 143 | total: 0, | ||
| 144 | listLoading: true, | ||
| 145 | listQuery: { | ||
| 146 | page: 1, | ||
| 147 | limit: 20 | ||
| 148 | } | ||
| 149 | } | ||
| 150 | }, | ||
| 151 | created() { | ||
| 152 | this.getList() | ||
| 153 | }, | ||
| 154 | methods: { | ||
| 155 | getList() { | ||
| 156 | this.listLoading = true | ||
| 157 | console.log('getList', 'dddddd') | ||
| 158 | fetchList(this.listQuery).then(response => { | ||
| 159 | this.list = response.data.items | ||
| 160 | this.total = response.data.total | ||
| 161 | this.listLoading = false | ||
| 162 | }) | ||
| 163 | } | ||
| 164 | } | ||
| 165 | } | ||
| 166 | </script> | ||
| 167 | |||
| 168 | <style scoped> | ||
| 169 | .edit-input { | ||
| 170 | padding-right: 100px; | ||
| 171 | } | ||
| 172 | .cancel-btn { | ||
| 173 | position: absolute; | ||
| 174 | right: 15px; | ||
| 175 | top: 10px; | ||
| 176 | } | ||
| 177 | </style> | ||
| 178 |
src/views/prod/list.vue
| 1 | <template> | 1 | <template> |
| 2 | <div class="app-container"> | 2 | <div class="app-container"> |
| 3 | <!-- <el-header> | 3 | <!-- <el-header> |
| 4 | 4 | ||
| 5 | </el-header> --> | 5 | </el-header> --> |
| 6 | <template> | 6 | <template> |
| 7 | <router-link :to="'/prod/create/1111'"> | 7 | <router-link :to="'/prod/create/1111'"> |
| 8 | <el-button | 8 | <el-button |
| 9 | type="primary" | 9 | type="primary" |
| 10 | size="small" | 10 | size="small" |
| 11 | icon="el-icon-edit" | 11 | icon="el-icon-edit" |
| 12 | > | 12 | > |
| 13 | create | 13 | create |
| 14 | </el-button> | 14 | </el-button> |
| 15 | </router-link> | 15 | </router-link> |
| 16 | </template> | 16 | </template> |
| 17 | <el-dialog | ||
| 18 | title="提示" | ||
| 19 | :visible.sync="dialogVisible" | ||
| 20 | width="30%" | ||
| 21 | :before-close="handleClose" | ||
| 22 | > | ||
| 23 | <span>这是一段信息</span> | ||
| 24 | <span>这是一段信息</span> | ||
| 25 | <span>这是一段信息</span> | ||
| 26 | <span>这是一段信息</span> | ||
| 27 | <span>这是一段信息</span> | ||
| 28 | <span>这是一段信息</span> | ||
| 29 | <span>这是一段信息</span> | ||
| 30 | <span>这是一段信息</span> | ||
| 31 | <span>这是一段信息</span> | ||
| 32 | <span>这是一段信息</span> | ||
| 33 | <span>这是一段信息</span> | ||
| 34 | <span>这是一段信息</span> | ||
| 35 | <span>这是一段信息</span> | ||
| 36 | <span>这是一段信息</span> | ||
| 37 | <span>这是一段信息</span> | ||
| 38 | <span>这是一段信息</span> | ||
| 39 | <span>这是一段信息</span> | ||
| 40 | <span>这是一段信息</span> | ||
| 41 | <span>这是一段信息</span> | ||
| 42 | <span>这是一段信息</span> | ||
| 43 | <span>这是一段信息</span> | ||
| 44 | <span>这是一段信息</span> | ||
| 45 | <span>这是一段信息</span> | ||
| 46 | <span>这是一段信息</span> | ||
| 47 | <span>这是一段信息</span> | ||
| 48 | <span>这是一段信息</span> | ||
| 49 | <span>这是一段信息</span> | ||
| 50 | <span>这是一段信息</span> | ||
| 51 | <span>这是一段信息</span> | ||
| 52 | <span>这是一段信息</span> | ||
| 53 | <span>这是一段信息</span> | ||
| 54 | <span>这是一段信息</span> | ||
| 55 | <span>这是一段信息</span> | ||
| 56 | <span>这是一段信息</span> | ||
| 57 | <span | ||
| 58 | slot="footer" | ||
| 59 | class="dialog-footer" | ||
| 60 | > | ||
| 61 | <el-button @click="dialogVisible = false">取 消</el-button> | ||
| 62 | <el-button | ||
| 63 | type="primary" | ||
| 64 | @click="dialogVisible = false" | ||
| 65 | >确 定</el-button> | ||
| 66 | </span> | ||
| 67 | </el-dialog> | ||
| 17 | <el-table | 68 | <el-table |
| 18 | v-loading="listLoading" | 69 | v-loading="listLoading" |
| 19 | :data="list" | 70 | :data="list" |
| 20 | border | 71 | border |
| 21 | fit | 72 | fit |
| 22 | highlight-current-row | 73 | highlight-current-row |
| 23 | style="width: 100%" | 74 | style="width: 100%" |
| 24 | > | 75 | > |
| 25 | <el-table-column | 76 | <el-table-column |
| 26 | align="center" | 77 | align="center" |
| 27 | label="pid" | 78 | label="pid" |
| 28 | > | 79 | > |
| 29 | <template slot-scope="scope"> | 80 | <template slot-scope="scope"> |
| 81 | <el-button | ||
| 82 | type="primary" | ||
| 83 | size="small" | ||
| 84 | icon="el-icon-more" | ||
| 85 | @click="dialogVisible = true" | ||
| 86 | >SKU管理</el-button> | ||
| 87 | <el-button | ||
| 88 | type="primary" | ||
| 89 | size="small" | ||
| 90 | icon="el-icon-chat-round" | ||
| 91 | @click="dialogVisible = true" | ||
| 92 | >评论管理</el-button> | ||
| 93 | <el-button | ||
| 94 | type="primary" | ||
| 95 | size="small" | ||
| 96 | icon="el-icon-setting" | ||
| 97 | @click="dialogVisible = true" | ||
| 98 | >产品定义</el-button> | ||
| 99 | <br> | ||
| 30 | <span>{{ scope.row.pid }}</span> | 100 | <span>{{ scope.row.pid }}</span> |
| 31 | </template> | 101 | </template> |
| 32 | </el-table-column> | 102 | </el-table-column> |
| 33 | <el-table-column | 103 | <el-table-column |
| 34 | align="center" | 104 | align="center" |
| 35 | label="pname" | 105 | label="pname" |
| 36 | > | 106 | > |
| 37 | <template slot-scope="scope"> | 107 | <template slot-scope="scope"> |
| 38 | <span>{{ scope.row.pname }}</span> | 108 | <span>{{ scope.row.pname }}</span> |
| 39 | </template> | 109 | </template> |
| 40 | </el-table-column> | 110 | </el-table-column> |
| 41 | <el-table-column | 111 | <el-table-column |
| 42 | align="center" | 112 | align="center" |
| 43 | label="参数信息" | 113 | label="参数信息" |
| 44 | > | 114 | > |
| 45 | <template slot-scope="scope"> | 115 | <template slot-scope="scope"> |
| 46 | <span>框宽{{ scope.row.prod_info_frame_width }}mm</span><br> | 116 | <span>框宽{{ scope.row.prod_info_frame_width }}mm</span><br> |
| 47 | <span>腿长{{ scope.row.prod_info_leg_long }}mm</span><br> | 117 | <span>腿长{{ scope.row.prod_info_leg_long }}mm</span><br> |
| 48 | <span>镜宽{{ scope.row.prod_info_glass_width }}mm</span><br> | 118 | <span>镜宽{{ scope.row.prod_info_glass_width }}mm</span><br> |
| 49 | <span>镜高{{ scope.row.prod_info_glass_height }}mm</span><br> | 119 | <span>镜高{{ scope.row.prod_info_glass_height }}mm</span><br> |
| 50 | <span>鼻宽{{ scope.row.prod_info_norse_width }}mm</span><br> | 120 | <span>鼻宽{{ scope.row.prod_info_norse_width }}mm</span><br> |
| 51 | <span>重量{{ scope.row.prod_info_weight }}g</span> | 121 | <span>重量{{ scope.row.prod_info_weight }}g</span> |
| 52 | </template> | 122 | </template> |
| 53 | </el-table-column> | 123 | </el-table-column> |
| 54 | 124 | ||
| 55 | <el-table-column | 125 | <el-table-column |
| 56 | align="center" | 126 | align="center" |
| 57 | label="Date" | 127 | label="Date" |
| 58 | > | 128 | > |
| 59 | <template slot-scope="scope"> | 129 | <template slot-scope="scope"> |
| 60 | <span>{{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span> | 130 | <span>{{ scope.row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span> |
| 61 | </template> | 131 | </template> |
| 62 | </el-table-column> | 132 | </el-table-column> |
| 63 | 133 | ||
| 64 | <el-table-column label="Importance"> | 134 | <el-table-column label="Importance"> |
| 65 | <template slot-scope="scope"> | 135 | <template slot-scope="scope"> |
| 66 | <svg-icon | 136 | <svg-icon |
| 67 | v-for="n in +scope.row.importance" | 137 | v-for="n in +scope.row.importance" |
| 68 | :key="n" | 138 | :key="n" |
| 69 | icon-class="star" | 139 | icon-class="star" |
| 70 | class="meta-item__icon" | 140 | class="meta-item__icon" |
| 71 | /> | 141 | /> |
| 72 | </template> | 142 | </template> |
| 73 | </el-table-column> | 143 | </el-table-column> |
| 74 | 144 | ||
| 75 | <el-table-column | 145 | <el-table-column |
| 76 | class-name="status-col" | 146 | class-name="status-col" |
| 77 | label="prod_status" | 147 | label="prod_status" |
| 78 | > | 148 | > |
| 79 | <template slot-scope="{row}"> | 149 | <template slot-scope="{row}"> |
| 80 | <el-tag :type="row.prod_status | statusFilter"> | 150 | <el-tag :type="row.prod_status | statusFilter"> |
| 81 | {{ row.prod_status }} | 151 | {{ row.prod_status }} |
| 82 | </el-tag> | 152 | </el-tag> |
| 83 | </template> | 153 | </template> |
| 84 | </el-table-column> | 154 | </el-table-column> |
| 85 | 155 | ||
| 86 | <el-table-column | 156 | <el-table-column |
| 87 | align="center" | 157 | align="center" |
| 88 | label="Actions" | 158 | label="Actions" |
| 89 | > | 159 | > |
| 90 | <template slot-scope="{row}"> | 160 | <template slot-scope="{row}"> |
| 91 | <router-link :to="'/prod/edit/'+row.pid"> | 161 | <router-link :to="'/prod/edit/'+row.pid"> |
| 92 | <el-button | 162 | <el-button |
| 93 | type="primary" | 163 | type="primary" |
| 94 | size="small" | 164 | size="small" |
| 95 | icon="el-icon-edit" | 165 | icon="el-icon-edit" |
| 96 | > | 166 | > |
| 97 | Edit1 | 167 | Edit1 |
| 98 | </el-button> | 168 | </el-button> |
| 99 | </router-link> | 169 | </router-link> |
| 100 | <router-link :to="'/prod/del/'+row.pid"> | 170 | <router-link :to="'/prod/del/'+row.pid"> |
| 101 | <el-button | 171 | <el-button |
| 102 | type="primary" | 172 | type="primary" |
| 103 | size="small" | 173 | size="small" |
| 104 | icon="el-icon-edit" | 174 | icon="el-icon-edit" |
| 105 | > | 175 | > |
| 106 | Edit2 | 176 | Edit2 |
| 107 | </el-button> | 177 | </el-button> |
| 108 | </router-link> | 178 | </router-link> |
| 109 | </template> | 179 | </template> |
| 110 | </el-table-column> | 180 | </el-table-column> |
| 111 | </el-table> | 181 | </el-table> |
| 112 | 182 | ||
| 113 | <pagination | 183 | <pagination |
| 114 | v-show="total>0" | 184 | v-show="total>0" |
| 115 | :total="total" | 185 | :total="total" |
| 116 | :page.sync="listQuery.page" | 186 | :page.sync="listQuery.page" |
| 117 | :limit.sync="listQuery.limit" | 187 | :limit.sync="listQuery.limit" |
| 118 | @pagination="getList" | 188 | @pagination="getList" |
| 119 | /> | 189 | /> |
| 120 | </div> | 190 | </div> |
| 121 | </template> | 191 | </template> |
| 122 | 192 | ||
| 123 | <script> | 193 | <script> |
| 124 | import { fetchList } from '@/api/prod' | 194 | import { fetchList } from '@/api/prod' |
| 125 | // import { Pagination } from "@/components/Pagination"; // Secondary package based on el-pagination | 195 | // import { Pagination } from "@/components/Pagination"; // Secondary package based on el-pagination |
| 126 | import Pagination from '@/components/Pagination' // Secondary package based on el-pagination | 196 | import Pagination from '@/components/Pagination' // Secondary package based on el-pagination |
| 127 | export default { | 197 | export default { |
| 128 | name: 'ProdList', | 198 | name: 'ProdList', |
| 129 | components: { Pagination }, | 199 | components: { Pagination }, |
| 130 | filters: { | 200 | filters: { |
| 131 | statusFilter(prod_status) { | 201 | statusFilter(prod_status) { |
| 132 | const statusMap = { | 202 | const statusMap = { |
| 133 | published: 'success', | 203 | published: 'success', |
| 134 | draft: 'info', | 204 | draft: 'info', |
| 135 | deleted: 'danger' | 205 | deleted: 'danger' |
| 136 | } | 206 | } |
| 137 | return statusMap[prod_status] | 207 | return statusMap[prod_status] |
| 138 | } | 208 | } |
| 139 | }, | 209 | }, |
| 140 | data() { | 210 | data() { |
| 141 | return { | 211 | return { |
| 212 | dialogVisible: false, | ||
| 142 | list: null, | 213 | list: null, |
| 143 | total: 0, | 214 | total: 0, |
| 144 | listLoading: true, | 215 | listLoading: true, |
| 145 | listQuery: { | 216 | listQuery: { |
| 146 | page: 1, | 217 | page: 1, |
| 147 | limit: 20 | 218 | limit: 20 |
| 148 | } | 219 | } |
| 149 | } | 220 | } |
| 150 | }, | 221 | }, |
| 151 | created() { | 222 | created() { |
| 152 | this.getList() | 223 | this.getList() |
| 153 | }, | 224 | }, |
| 154 | methods: { | 225 | methods: { |
| 226 | handleClose(done) { | ||
| 227 | this.$confirm('确认关闭?') | ||
| 228 | .then(_ => { | ||
| 229 | done() | ||
| 230 | }) | ||
| 231 | .catch(_ => {}) | ||
| 232 | }, | ||
| 155 | getList() { | 233 | getList() { |
| 156 | this.listLoading = true | 234 | this.listLoading = true |
| 157 | console.log('getList', 'dddddd') | 235 | console.log('getList', 'dddddd') |
| 158 | fetchList(this.listQuery).then(response => { | 236 | fetchList(this.listQuery).then(response => { |
| 159 | this.list = response.data.items | 237 | this.list = response.data.items |
| 160 | this.total = response.data.total | 238 | this.total = response.data.total |
| 161 | this.listLoading = false | 239 | this.listLoading = false |
| 162 | }) | 240 | }) |
| 163 | } | 241 | } |
| 164 | } | 242 | } |
| 165 | } | 243 | } |
| 166 | </script> | 244 | </script> |
| 167 | 245 | ||
| 168 | <style scoped> | 246 | <style scoped> |
| 169 | .edit-input { | 247 | .edit-input { |
| 170 | padding-right: 100px; | 248 | padding-right: 100px; |
| 171 | } | 249 | } |
| 172 | .cancel-btn { | 250 | .cancel-btn { |
| 173 | position: absolute; | 251 | position: absolute; |
| 174 | right: 15px; | 252 | right: 15px; |
| 175 | top: 10px; | 253 | top: 10px; |
| 176 | } | 254 | } |
| 177 | </style> | 255 | </style> |
| 178 | 256 |
src/views/site/list.vue
| 1 | <template> | 1 | <template> |
| 2 | <div class="app-container"> | 2 | <div class="app-container"> |
| 3 | <el-table | 3 | <el-table |
| 4 | v-loading="listLoading" | 4 | v-loading="listLoading" |
| 5 | :data="list" | 5 | :data="list" |
| 6 | border | 6 | border |
| 7 | fit | 7 | fit |
| 8 | highlight-current-row | 8 | highlight-current-row |
| 9 | style="width: 100%" | 9 | style="width: 100%" |
| 10 | > | 10 | > |
| 11 | <el-table-column | 11 | <el-table-column |
| 12 | align="center" | 12 | align="center" |
| 13 | label="ID" | 13 | label="ID" |
| 14 | width="80" | 14 | width="80" |
| 15 | > | 15 | > |
| 16 | <template slot-scope="{row}"> | 16 | <template slot-scope="{row}"> |
| 17 | <span>{{ row.id }}</span> | 17 | <span>{{ row.id }}</span> |
| 18 | </template> | 18 | </template> |
| 19 | </el-table-column> | 19 | </el-table-column> |
| 20 | 20 | ||
| 21 | <el-table-column | 21 | <el-table-column |
| 22 | width="180px" | 22 | width="180px" |
| 23 | align="center" | 23 | align="center" |
| 24 | label="Date" | 24 | label="Date" |
| 25 | > | 25 | > |
| 26 | <template slot-scope="{row}"> | 26 | <template slot-scope="{row}"> |
| 27 | <span>{{ row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span> | 27 | <span>{{ row.timestamp | parseTime('{y}-{m}-{d} {h}:{i}') }}</span> |
| 28 | </template> | 28 | </template> |
| 29 | </el-table-column> | 29 | </el-table-column> |
| 30 | 30 | ||
| 31 | <el-table-column | 31 | <el-table-column |
| 32 | width="120px" | 32 | width="120px" |
| 33 | align="center" | 33 | align="center" |
| 34 | label="Author" | 34 | label="Author" |
| 35 | > | 35 | > |
| 36 | <template slot-scope="{row}"> | 36 | <template slot-scope="{row}"> |
| 37 | <span>{{ row.author }}</span> | 37 | <span>{{ row.author }}</span> |
| 38 | </template> | 38 | </template> |
| 39 | </el-table-column> | 39 | </el-table-column> |
| 40 | 40 | ||
| 41 | <el-table-column | 41 | <el-table-column |
| 42 | width="100px" | 42 | width="100px" |
| 43 | label="Importance" | 43 | label="Importance" |
| 44 | > | 44 | > |
| 45 | <template slot-scope="{row}"> | 45 | <template slot-scope="{row}"> |
| 46 | <svg-icon | 46 | <svg-icon |
| 47 | v-for="n in + row.importance" | 47 | v-for="n in + row.importance" |
| 48 | :key="n" | 48 | :key="n" |
| 49 | icon-class="star" | 49 | icon-class="star" |
| 50 | class="meta-item__icon" | 50 | class="meta-item__icon" |
| 51 | /> | 51 | /> |
| 52 | </template> | 52 | </template> |
| 53 | </el-table-column> | 53 | </el-table-column> |
| 54 | 54 | ||
| 55 | <el-table-column | 55 | <el-table-column |
| 56 | class-name="status-col" | 56 | class-name="status-col" |
| 57 | label="Status" | 57 | label="Status" |
| 58 | width="110" | 58 | width="110" |
| 59 | > | 59 | > |
| 60 | <template slot-scope="{row}"> | 60 | <template slot-scope="{row}"> |
| 61 | <el-tag :type="row.status | statusFilter"> | 61 | <el-tag :type="row.status | statusFilter"> |
| 62 | {{ row.status }} | 62 | {{ row.status }} |
| 63 | </el-tag> | 63 | </el-tag> |
| 64 | </template> | 64 | </template> |
| 65 | </el-table-column> | 65 | </el-table-column> |
| 66 | 66 | ||
| 67 | <el-table-column | 67 | <el-table-column |
| 68 | min-width="300px" | 68 | min-width="300px" |
| 69 | label="Title" | 69 | label="Title" |
| 70 | > | 70 | > |
| 71 | <template slot-scope="{row}"> | 71 | <template slot-scope="{row}"> |
| 72 | <template v-if="row.edit"> | 72 | <template v-if="row.edit"> |
| 73 | <el-input | 73 | <el-input |
| 74 | v-model="row.title" | 74 | v-model="row.title" |
| 75 | class="edit-input" | 75 | class="edit-input" |
| 76 | size="small" | 76 | size="small" |
| 77 | /> | 77 | /> |
| 78 | <el-button | 78 | <el-button |
| 79 | class="cancel-btn" | 79 | class="cancel-btn" |
| 80 | size="small" | 80 | size="small" |
| 81 | icon="el-icon-refresh" | 81 | icon="el-icon-refresh" |
| 82 | type="warning" | 82 | type="warning" |
| 83 | @click="cancelEdit(row)" | 83 | @click="cancelEdit(row)" |
| 84 | > | 84 | > |
| 85 | cancel | 85 | cancel |
| 86 | </el-button> | 86 | </el-button> |
| 87 | </template> | 87 | </template> |
| 88 | <span v-else>{{ row.title }}</span> | 88 | <span v-else> |
| 89 | 运营官运营的比较好的,高评分的站点,流量大,一旦加入其站点,成为推广员,分享相关链接至私域流量 | ||
| 90 | 会容易获得较好的回报吗? | ||
| 91 | 不一定,但是,如果这个站点的产品好,漂亮,价格也好。 | ||
| 92 | 则容易转化率较高一些{{ row.title }}</span> | ||
| 89 | </template> | 93 | </template> |
| 90 | </el-table-column> | 94 | </el-table-column> |
| 91 | 95 | ||
| 92 | <el-table-column | 96 | <el-table-column |
| 93 | align="center" | 97 | align="center" |
| 94 | label="Actions" | 98 | label="Actions" |
| 95 | width="120" | 99 | width="120" |
| 96 | > | 100 | > |
| 97 | <template slot-scope="{row}"> | 101 | <template slot-scope="{row}"> |
| 98 | <el-button | 102 | <el-button |
| 99 | v-if="row.edit" | 103 | v-if="row.edit" |
| 100 | type="success" | 104 | type="success" |
| 101 | size="small" | 105 | size="small" |
| 102 | icon="el-icon-circle-check-outline" | 106 | icon="el-icon-circle-check-outline" |
| 103 | @click="confirmEdit(row)" | 107 | @click="confirmEdit(row)" |
| 104 | > | 108 | > |
| 105 | Ok | 109 | Ok |
| 106 | </el-button> | 110 | </el-button> |
| 107 | <el-button | 111 | <el-button |
| 108 | v-else | 112 | v-else |
| 109 | type="primary" | 113 | type="primary" |
| 110 | size="small" | 114 | size="small" |
| 111 | icon="el-icon-edit" | 115 | icon="el-icon-edit" |
| 112 | @click="row.edit=!row.edit" | 116 | @click="row.edit=!row.edit" |
| 113 | > | 117 | > |
| 114 | Edit | 118 | Edit |
| 115 | </el-button> | 119 | </el-button> |
| 116 | </template> | 120 | </template> |
| 117 | </el-table-column> | 121 | </el-table-column> |
| 118 | </el-table> | 122 | </el-table> |
| 119 | </div> | 123 | </div> |
| 120 | </template> | 124 | </template> |
| 121 | 125 | ||
| 122 | <script> | 126 | <script> |
| 123 | import { fetchList } from '@/api/article' | 127 | import { fetchList } from '@/api/article' |
| 124 | 128 | ||
| 125 | export default { | 129 | export default { |
| 126 | name: 'InlineEditTable', | 130 | name: 'InlineEditTable', |
| 127 | filters: { | 131 | filters: { |
| 128 | statusFilter(status) { | 132 | statusFilter(status) { |
| 129 | const statusMap = { | 133 | const statusMap = { |
| 130 | published: 'success', | 134 | published: 'success', |
| 131 | draft: 'info', | 135 | draft: 'info', |
| 132 | deleted: 'danger' | 136 | deleted: 'danger' |
| 133 | } | 137 | } |
| 134 | return statusMap[status] | 138 | return statusMap[status] |
| 135 | } | 139 | } |
| 136 | }, | 140 | }, |
| 137 | data() { | 141 | data() { |
| 138 | return { | 142 | return { |
| 139 | list: null, | 143 | list: null, |
| 140 | listLoading: true, | 144 | listLoading: true, |
| 141 | listQuery: { | 145 | listQuery: { |
| 142 | page: 1, | 146 | page: 1, |
| 143 | limit: 10 | 147 | limit: 10 |
| 144 | } | 148 | } |
| 145 | } | 149 | } |
| 146 | }, | 150 | }, |
| 147 | created() { | 151 | created() { |
| 148 | this.getList() | 152 | this.getList() |
| 149 | }, | 153 | }, |
| 150 | methods: { | 154 | methods: { |
| 151 | async getList() { | 155 | async getList() { |
| 152 | this.listLoading = true | 156 | this.listLoading = true |
| 153 | const { data } = await fetchList(this.listQuery) | 157 | const { data } = await fetchList(this.listQuery) |
| 154 | const items = data.items | 158 | const items = data.items |
| 155 | this.list = items.map(v => { | 159 | this.list = items.map(v => { |
| 156 | this.$set(v, 'edit', false) // https://vuejs.org/v2/guide/reactivity.html | 160 | this.$set(v, 'edit', false) // https://vuejs.org/v2/guide/reactivity.html |
| 157 | v.originalTitle = v.title // will be used when user click the cancel botton | 161 | v.originalTitle = v.title // will be used when user click the cancel botton |
| 158 | return v | 162 | return v |
| 159 | }) | 163 | }) |
| 160 | this.listLoading = false | 164 | this.listLoading = false |
| 161 | }, | 165 | }, |
| 162 | cancelEdit(row) { | 166 | cancelEdit(row) { |
| 163 | row.title = row.originalTitle | 167 | row.title = row.originalTitle |
| 164 | row.edit = false | 168 | row.edit = false |
| 165 | this.$message({ | 169 | this.$message({ |
| 166 | message: 'The title has been restored to the original value', | 170 | message: 'The title has been restored to the original value', |
| 167 | type: 'warning' | 171 | type: 'warning' |
| 168 | }) | 172 | }) |
| 169 | }, | 173 | }, |
| 170 | confirmEdit(row) { | 174 | confirmEdit(row) { |
| 171 | row.edit = false | 175 | row.edit = false |
| 172 | row.originalTitle = row.title | 176 | row.originalTitle = row.title |
| 173 | this.$message({ | 177 | this.$message({ |
| 174 | message: 'The title has been edited', | 178 | message: 'The title has been edited', |
| 175 | type: 'success' | 179 | type: 'success' |
| 176 | }) | 180 | }) |
| 177 | } | 181 | } |
| 178 | } | 182 | } |
| 179 | } | 183 | } |
| 180 | </script> | 184 | </script> |
| 181 | 185 | ||
| 182 | <style scoped> | 186 | <style scoped> |
| 183 | .edit-input { | 187 | .edit-input { |
| 184 | padding-right: 100px; | 188 | padding-right: 100px; |
| 185 | } | 189 | } |
| 186 | .cancel-btn { | 190 | .cancel-btn { |
| 187 | position: absolute; | 191 | position: absolute; |
| 188 | right: 15px; | 192 | right: 15px; |
| 189 | top: 10px; | 193 | top: 10px; |
| 190 | } | 194 | } |
| 191 | </style> | 195 | </style> |
| 192 | 196 |