Commit 398cda401f1a6df9900737efbdd62ea1b3450755

Authored by Adam
1 parent a86b16bba6
Exists in master

auto commit the code by alias command

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
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