Browse Source

首页拖拽控件

xiongzhu 7 years ago
parent
commit
170dd20688

File diff suppressed because it is too large
+ 250 - 250
src/main/vue/package-lock.json


+ 1 - 0
src/main/vue/package.json

@@ -24,6 +24,7 @@
     "vue-amap": "^0.5.8",
     "vue-axios": "^2.1.1",
     "vue-chartjs": "^3.3.1",
+    "vue-grid-layout": "^2.1.13",
     "vue-i18n": "^7.8.0",
     "vue-router": "^3.0.1",
     "vuex": "^3.0.1"

+ 1 - 1
src/main/vue/src/components/SysMenu.vue

@@ -5,7 +5,7 @@
     <el-submenu v-else :index="menu.id">
         <template slot="title">
             <i class="fa-fw" :class="menu.extra.icon" v-if="menu.extra.icon"></i>
-            {{menu.label}}
+            <span slot="title">{{menu.label}}</span>
         </template>
         <sys-menu v-for="item in menu.children" :menu="item" :key="item.id"></sys-menu>
     </el-submenu>

+ 10 - 6
src/main/vue/src/main.less

@@ -34,12 +34,17 @@ ul, li {
     list-style-type: none;
 }
 
-.el-menu-item {
-    background: #1F2D3D !important;
-}
-
-.el-submenu .el-submenu .el-submenu__title {
+//.el-menu-item {
+//    background: #1F2D3D !important;
+//}
+//
+//.el-submenu .el-submenu .el-submenu__title {
+//    background: #1F2D3D !important;
+//}
+
+.el-menu-item.is-active {
     background: #1F2D3D !important;
+    border-left: 2px solid rgb(32, 160, 255);
 }
 
 .el-menu {
@@ -47,7 +52,6 @@ ul, li {
         color: #BFCBD9;
     }
     .svg-inline--fa {
-        margin-bottom: 2px;
         margin-right: 6px;
     }
 }

+ 60 - 64
src/main/vue/src/pages/Dashboard.vue

@@ -1,84 +1,80 @@
 <template>
     <div>
-        <el-row :gutter="20">
-            <el-col :xs="24" :sm="12" :lg="6">
-                <el-card class="box-card">
-                    <i class="fa-fw fas fa-user fa-3x" style="color: #40c9c6;"></i>
-                    <div class="info">
-                        <div class="text">User</div>
-                        <div class="num">4,258</div>
-                    </div>
-                </el-card>
-            </el-col>
-            <el-col :xs="24" :sm="12" :lg="6">
-                <el-card class="box-card">
-                    <i class="fa-fw fas fa-envelope fa-3x" style="color: #36a3f7;"></i>
-                    <div class="info">
-                        <div class="text">Messages</div>
-                        <div class="num">4,258</div>
-                    </div>
-                </el-card>
-            </el-col>
-            <el-col :xs="24" :sm="12" :lg="6">
-                <el-card class="box-card">
-                    <i class="fa-fw fas fa-dollar-sign fa-3x" style="color: #f4516c;"></i>
-                    <div class="info">
-                        <div class="text">Payment</div>
-                        <div class="num">4,258</div>
-                    </div>
-                </el-card>
-            </el-col>
-            <el-col :xs="24" :sm="12" :lg="6">
-                <el-card class="box-card">
-                    <i class="fa-fw fas fa-shopping-cart fa-3x" style="color: #34bfa3;"></i>
-                    <div class="info">
-                        <div class="text">Shopping</div>
-                        <div class="num">4,258</div>
-                    </div>
-                </el-card>
-            </el-col>
-        </el-row>
-        <el-row :gutter="20">
-            <el-col :xs="24" :sm="12" :lg="6">
-                <weather-card></weather-card>
-            </el-col>
-        </el-row>
-
+        <el-button v-if="editable" size="small" @click="save">保存</el-button>
+        <el-button v-else size="small" @click="editable=true">编辑</el-button>
+        <grid-layout
+            style="margin:0 -10px;"
+            :layout="layout"
+            :col-num="12"
+            :row-height="30"
+            :is-draggable="editable"
+            :is-resizable="editable"
+            :is-mirrored="false"
+            :vertical-compact="true"
+            :margin="[10, 10]"
+            :use-css-transforms="true">
+            <grid-item v-for="item in layout"
+                       class="widget-wrapper"
+                       :x="item.x"
+                       :y="item.y"
+                       :w="item.w"
+                       :h="item.h"
+                       :i="item.i"
+                       :key="item.i">
+                <component :is="item.name"></component>
+            </grid-item>
+        </grid-layout>
     </div>
 </template>
 
 <script>
-    import WeatherCard from '../components/WeatherCard'
+    import {GridLayout, GridItem} from 'vue-grid-layout'
+    import WeatherWidget from '../widgets/WeatherWidget'
+    import UserWidget from '../widgets/UserWidget'
+    import LineChartWidget from '../widgets/LineChartWidget'
+    import BarChartWidget from '../widgets/BarChartWidget'
+    import PieChartWidget from '../widgets/PieChartWidget'
 
     export default {
         created() {
 
+        },
+        data() {
+            return {
+                layout: [
+                    {x: 0, y: 0, w: 6, h: 4, i: "0", name: 'WeatherWidget'},
+                    {x: 6, y: 0, w: 6, h: 4, i: "1", name: 'UserWidget'},
+                    {x: 0, y: 4, w: 6, h: 6, i: "2", name: 'BarChartWidget'},
+                    {x: 0, y: 10, w: 6, h: 6, i: "3", name: 'LineChartWidget'},
+                    {x: 6, y: 4, w: 6, h: 12, i: "4", name: 'PieChartWidget'},
+                ],
+                editable: false
+            }
+        },
+        methods: {
+            save() {
+                console.log(JSON.stringify(this.layout));
+                this.editable = false
+            }
         },
         components: {
-            WeatherCard
+            GridLayout,
+            GridItem,
+            WeatherWidget,
+            UserWidget,
+            LineChartWidget,
+            BarChartWidget,
+            PieChartWidget
         }
     }
 </script>
 
 <style lang="less">
-    .box-card {
-        margin-bottom: 20px;
-        .el-card__body {
-            display: flex;
-            align-items: center;
-            .info {
-                flex-grow: 1;
-                text-align: right;
-                .text {
-                    color: #999;
-                    font-size: 16px;
-                    margin-bottom: 12px;
-                }
-                .num {
-                    font-size: 20px;
-                    color: #333;
-                }
-            }
+    .widget-wrapper {
+        display: flex;
+        flex-direction: column;
+        .el-card {
+            flex-grow: 1;
         }
     }
 </style>

+ 67 - 0
src/main/vue/src/widgets/BarChartWidget.vue

@@ -0,0 +1,67 @@
+<template>
+    <widget-card :bodyStyle="bodyStyle" ref="container">
+        <canvas ref="chart" class="chart"></canvas>
+    </widget-card>
+</template>
+<script>
+    import WidgetCard from './WidgetCard'
+    import VueCharts from 'vue-chartjs'
+
+    export default {
+        data() {
+            return {
+                myChart: null,
+                bodyStyle: {
+                    display: 'flex',
+                    alignItems: 'center'
+                }
+            }
+        },
+        mounted() {
+            this.$refs.chart.width = this.$refs.container.$el.offsetWidth - 20;
+            this.$refs.chart.height = this.$refs.container.$el.offsetHeight - 20;
+            this.myChart = new Chart(this.$refs.chart.getContext('2d'), {
+                type: 'bar',
+                data: {
+                    labels: ["Red", "Blue", "Yellow", "Green", "Purple", "Orange"],
+                    datasets: [{
+                        label: '# of Votes',
+                        data: [12, 19, 3, 5, 2, 3],
+                        backgroundColor: [
+                            'rgba(255, 99, 132, 0.2)',
+                            'rgba(54, 162, 235, 0.2)',
+                            'rgba(255, 206, 86, 0.2)',
+                            'rgba(75, 192, 192, 0.2)',
+                            'rgba(153, 102, 255, 0.2)',
+                            'rgba(255, 159, 64, 0.2)'
+                        ],
+                        borderColor: [
+                            'rgba(255,99,132,1)',
+                            'rgba(54, 162, 235, 1)',
+                            'rgba(255, 206, 86, 1)',
+                            'rgba(75, 192, 192, 1)',
+                            'rgba(153, 102, 255, 1)',
+                            'rgba(255, 159, 64, 1)'
+                        ],
+                        borderWidth: 1
+                    }]
+                },
+                options: {
+                    maintainAspectRatio: false,
+                    scales: {
+                        yAxes: [{
+                            ticks: {
+                                beginAtZero: false
+                            }
+                        }]
+                    }
+                }
+            });
+        },
+        components: {
+            WidgetCard
+        }
+    }
+</script>
+<style lang="less" scoped>
+</style>

+ 50 - 0
src/main/vue/src/widgets/LineChartWidget.vue

@@ -0,0 +1,50 @@
+<template>
+    <widget-card :bodyStyle="bodyStyle" ref="container">
+        <canvas ref="chart" class="chart"></canvas>
+    </widget-card>
+</template>
+<script>
+    import WidgetCard from './WidgetCard'
+    import VueCharts from 'vue-chartjs'
+
+    export default {
+        data() {
+            return {
+                myChart: null,
+                bodyStyle: {
+                    display: 'flex',
+                    alignItems: 'center'
+                }
+            }
+        },
+        mounted() {
+            this.$refs.chart.width = this.$refs.container.$el.offsetWidth - 20;
+            this.$refs.chart.height = this.$refs.container.$el.offsetHeight - 20;
+            var gradient = this.$refs.chart.getContext('2d').createLinearGradient(0, 0, 0, 200);
+
+            gradient.addColorStop(0, 'rgba(32,160,255,0.7)');
+            gradient.addColorStop(1, 'rgba(32,160,255,0)');
+            this.myChart = new Chart(this.$refs.chart.getContext('2d'), {
+                type: 'line',
+                data: {
+                    labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
+                    datasets: [
+                        {
+                            label: 'Data One',
+                            backgroundColor: gradient,
+                            borderColor: '#20a0ff',
+                            borderWidth: '1px',
+                            data: [40, 39, 10, 40, 39, 80, 40]
+                        }
+                    ]
+                },
+                options: {responsive: true, maintainAspectRatio: false}
+            });
+        },
+        components: {
+            WidgetCard
+        }
+    }
+</script>
+<style lang="less" scoped>
+</style>

+ 48 - 0
src/main/vue/src/widgets/PieChartWidget.vue

@@ -0,0 +1,48 @@
+<template>
+    <widget-card :bodyStyle="bodyStyle" ref="container">
+        <canvas ref="chart" class="chart"></canvas>
+    </widget-card>
+</template>
+<script>
+    import WidgetCard from './WidgetCard'
+    import VueCharts from 'vue-chartjs'
+
+    export default {
+        data() {
+            return {
+                myChart: null,
+                bodyStyle: {
+                    display: 'flex',
+                    alignItems: 'center'
+                }
+            }
+        },
+        mounted() {
+            this.$refs.chart.width = this.$refs.container.$el.offsetWidth - 20;
+            this.$refs.chart.height = this.$refs.container.$el.offsetHeight - 20;
+            this.myChart = new Chart(this.$refs.chart.getContext('2d'), {
+                type: 'pie',
+                data: {
+                    labels: ['VueJs', 'EmberJs', 'ReactJs', 'AngularJs'],
+                    datasets: [
+                        {
+                            backgroundColor: [
+                                '#41B883',
+                                '#E46651',
+                                '#00D8FF',
+                                '#DD1B16'
+                            ],
+                            data: [40, 20, 80, 10]
+                        }
+                    ]
+                },
+                options: {responsive: true, maintainAspectRatio: false}
+            });
+        },
+        components: {
+            WidgetCard
+        }
+    }
+</script>
+<style lang="less" scoped>
+</style>

+ 41 - 0
src/main/vue/src/widgets/UserWidget.vue

@@ -0,0 +1,41 @@
+<template>
+    <widget-card :bodyStyle="bodyStyle">
+        <i class="fa-fw fas fa-user fa-3x" style="color: #40c9c6;"></i>
+        <div class="info">
+            <div class="text">User</div>
+            <div class="num">4,258</div>
+        </div>
+    </widget-card>
+</template>
+<script>
+    import WidgetCard from './WidgetCard'
+
+    export default {
+        data() {
+            return {
+                bodyStyle: {
+                    display: 'flex',
+                    alignItems: 'center'
+                }
+            }
+        },
+        components: {
+            WidgetCard
+        }
+    }
+</script>
+<style lang="less" scoped>
+    .info {
+        flex-grow: 1;
+        text-align: right;
+        .text {
+            color: #999;
+            font-size: 16px;
+            margin-bottom: 12px;
+        }
+        .num {
+            font-size: 20px;
+            color: #333;
+        }
+    }
+</style>

+ 32 - 27
src/main/vue/src/components/WeatherCard.vue → src/main/vue/src/widgets/WeatherWidget.vue

@@ -1,19 +1,21 @@
 <template>
-    <el-card>
+    <widget-card :bodyStyle="bodyStyle">
         <div slot="header" class="date">
             {{date}}
         </div>
-        <div class="weather-wrapper" v-if="weather">
+        <template v-if="weather">
             <div class="info">
-                <div class="city">{{weather ? weather.basic.location : ''}}&nbsp;&nbsp;&nbsp;{{weather.now.cond_txt}}</div>
+                <div class="city">{{weather ? weather.basic.location : ''}}&nbsp;&nbsp;&nbsp;{{weather.now.cond_txt}}
+                </div>
                 <div class="temp">{{weather.now.tmp}}°C</div>
             </div>
             <i :class="`icon wi ${iconMap[weather.now.cond_code]}`"></i>
-        </div>
-    </el-card>
+        </template>
+    </widget-card>
 </template>
 
 <script>
+    import WidgetCard from './WidgetCard'
     import {format} from 'date-fns'
     import zh from 'date-fns/locale/zh_cn'
     import axios from 'axios'
@@ -108,41 +110,44 @@
                     '513': 'wi-fog',
                     '514': 'wi-fog',
                     '515': 'wi-fog',
+                },
+                bodyStyle: {
+                    display: 'flex',
+                    alignItems: 'center'
                 }
             }
         },
-        computed: {}
+        components: {
+            WidgetCard
+        }
     }
 </script>
-<style lang="less" scoped>
+<style lang="less">
     @import "../../static/weather_icons/less/weather-icons.less";
-
+</style>
+<style lang="less">
     .date {
         color: #666;
         font-size: 14px;
     }
 
-    .weather-wrapper {
+    .icon {
+        font-size: 72px;
+        color: #666;
+    }
+
+    .info {
         display: flex;
-        align-items: center;
-        .icon {
-            font-size: 72px;
-            color: #666;
+        flex-direction: column;
+        flex-grow: 1;
+        .city {
+            font-size: 12px;
+            color: #999;
         }
-        .info {
-            display: flex;
-            flex-direction: column;
-            flex-grow: 1;
-            .city {
-                font-size: 12px;
-                color: #999;
-            }
-            .temp {
-                font-size: 36px;
-                color: #333;
-                margin-top: 8px;
-            }
+        .temp {
+            font-size: 36px;
+            color: #333;
+            margin-top: 8px;
         }
     }
-
 </style>

+ 28 - 0
src/main/vue/src/widgets/WidgetCard.vue

@@ -0,0 +1,28 @@
+<template>
+    <el-card shadow="hover" :body-style="[mBodyStyle,bodyStyle]" class="dashboard-widget-card">
+        <template slot="header">
+            <slot name="header"></slot>
+        </template>
+        <template :class="className">
+            <slot></slot>
+        </template>
+    </el-card>
+</template>
+<script>
+    export default {
+        props: ['bodyStyle'],
+        data() {
+            return {
+                mBodyStyle: {
+                    flexGrow: 1
+                }
+            }
+        }
+    }
+</script>
+<style lang="less" scoped>
+    .dashboard-widget-card {
+        display: flex;
+        flex-direction: column;
+    }
+</style>

Some files were not shown because too many files changed in this diff